source: src/main/java/agents/anac/y2019/harddealer/math3/linear/OpenMapRealMatrix.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

  • Property svn:executable set to *
File size: 10.9 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package agents.anac.y2019.harddealer.math3.linear;
19
20import java.io.Serializable;
21
22import agents.anac.y2019.harddealer.math3.exception.DimensionMismatchException;
23import agents.anac.y2019.harddealer.math3.exception.NotStrictlyPositiveException;
24import agents.anac.y2019.harddealer.math3.exception.NumberIsTooLargeException;
25import agents.anac.y2019.harddealer.math3.exception.OutOfRangeException;
26import agents.anac.y2019.harddealer.math3.util.OpenIntToDoubleHashMap;
27
28/**
29 * Sparse matrix implementation based on an open addressed map.
30 *
31 * <p>
32 * Caveat: This implementation assumes that, for any {@code x},
33 * the equality {@code x * 0d == 0d} holds. But it is is not true for
34 * {@code NaN}. Moreover, zero entries will lose their sign.
35 * Some operations (that involve {@code NaN} and/or infinities) may
36 * thus give incorrect results.
37 * </p>
38 * @since 2.0
39 */
40public class OpenMapRealMatrix extends AbstractRealMatrix
41 implements SparseRealMatrix, Serializable {
42 /** Serializable version identifier. */
43 private static final long serialVersionUID = -5962461716457143437L;
44 /** Number of rows of the matrix. */
45 private final int rows;
46 /** Number of columns of the matrix. */
47 private final int columns;
48 /** Storage for (sparse) matrix elements. */
49 private final OpenIntToDoubleHashMap entries;
50
51 /**
52 * Build a sparse matrix with the supplied row and column dimensions.
53 *
54 * @param rowDimension Number of rows of the matrix.
55 * @param columnDimension Number of columns of the matrix.
56 * @throws NotStrictlyPositiveException if row or column dimension is not
57 * positive.
58 * @throws NumberIsTooLargeException if the total number of entries of the
59 * matrix is larger than {@code Integer.MAX_VALUE}.
60 */
61 public OpenMapRealMatrix(int rowDimension, int columnDimension)
62 throws NotStrictlyPositiveException, NumberIsTooLargeException {
63 super(rowDimension, columnDimension);
64 long lRow = rowDimension;
65 long lCol = columnDimension;
66 if (lRow * lCol >= Integer.MAX_VALUE) {
67 throw new NumberIsTooLargeException(lRow * lCol, Integer.MAX_VALUE, false);
68 }
69 this.rows = rowDimension;
70 this.columns = columnDimension;
71 this.entries = new OpenIntToDoubleHashMap(0.0);
72 }
73
74 /**
75 * Build a matrix by copying another one.
76 *
77 * @param matrix matrix to copy.
78 */
79 public OpenMapRealMatrix(OpenMapRealMatrix matrix) {
80 this.rows = matrix.rows;
81 this.columns = matrix.columns;
82 this.entries = new OpenIntToDoubleHashMap(matrix.entries);
83 }
84
85 /** {@inheritDoc} */
86 @Override
87 public OpenMapRealMatrix copy() {
88 return new OpenMapRealMatrix(this);
89 }
90
91 /**
92 * {@inheritDoc}
93 *
94 * @throws NumberIsTooLargeException if the total number of entries of the
95 * matrix is larger than {@code Integer.MAX_VALUE}.
96 */
97 @Override
98 public OpenMapRealMatrix createMatrix(int rowDimension, int columnDimension)
99 throws NotStrictlyPositiveException, NumberIsTooLargeException {
100 return new OpenMapRealMatrix(rowDimension, columnDimension);
101 }
102
103 /** {@inheritDoc} */
104 @Override
105 public int getColumnDimension() {
106 return columns;
107 }
108
109 /**
110 * Compute the sum of this matrix and {@code m}.
111 *
112 * @param m Matrix to be added.
113 * @return {@code this} + {@code m}.
114 * @throws MatrixDimensionMismatchException if {@code m} is not the same
115 * size as {@code this}.
116 */
117 public OpenMapRealMatrix add(OpenMapRealMatrix m)
118 throws MatrixDimensionMismatchException {
119
120 MatrixUtils.checkAdditionCompatible(this, m);
121
122 final OpenMapRealMatrix out = new OpenMapRealMatrix(this);
123 for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) {
124 iterator.advance();
125 final int row = iterator.key() / columns;
126 final int col = iterator.key() - row * columns;
127 out.setEntry(row, col, getEntry(row, col) + iterator.value());
128 }
129
130 return out;
131
132 }
133
134 /** {@inheritDoc} */
135 @Override
136 public OpenMapRealMatrix subtract(final RealMatrix m)
137 throws MatrixDimensionMismatchException {
138 try {
139 return subtract((OpenMapRealMatrix) m);
140 } catch (ClassCastException cce) {
141 return (OpenMapRealMatrix) super.subtract(m);
142 }
143 }
144
145 /**
146 * Subtract {@code m} from this matrix.
147 *
148 * @param m Matrix to be subtracted.
149 * @return {@code this} - {@code m}.
150 * @throws MatrixDimensionMismatchException if {@code m} is not the same
151 * size as {@code this}.
152 */
153 public OpenMapRealMatrix subtract(OpenMapRealMatrix m)
154 throws MatrixDimensionMismatchException {
155 MatrixUtils.checkAdditionCompatible(this, m);
156
157 final OpenMapRealMatrix out = new OpenMapRealMatrix(this);
158 for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) {
159 iterator.advance();
160 final int row = iterator.key() / columns;
161 final int col = iterator.key() - row * columns;
162 out.setEntry(row, col, getEntry(row, col) - iterator.value());
163 }
164
165 return out;
166 }
167
168 /**
169 * {@inheritDoc}
170 *
171 * @throws NumberIsTooLargeException if {@code m} is an
172 * {@code OpenMapRealMatrix}, and the total number of entries of the product
173 * is larger than {@code Integer.MAX_VALUE}.
174 */
175 @Override
176 public RealMatrix multiply(final RealMatrix m)
177 throws DimensionMismatchException, NumberIsTooLargeException {
178 try {
179 return multiply((OpenMapRealMatrix) m);
180 } catch (ClassCastException cce) {
181
182 MatrixUtils.checkMultiplicationCompatible(this, m);
183
184 final int outCols = m.getColumnDimension();
185 final BlockRealMatrix out = new BlockRealMatrix(rows, outCols);
186 for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) {
187 iterator.advance();
188 final double value = iterator.value();
189 final int key = iterator.key();
190 final int i = key / columns;
191 final int k = key % columns;
192 for (int j = 0; j < outCols; ++j) {
193 out.addToEntry(i, j, value * m.getEntry(k, j));
194 }
195 }
196
197 return out;
198 }
199 }
200
201 /**
202 * Postmultiply this matrix by {@code m}.
203 *
204 * @param m Matrix to postmultiply by.
205 * @return {@code this} * {@code m}.
206 * @throws DimensionMismatchException if the number of rows of {@code m}
207 * differ from the number of columns of {@code this} matrix.
208 * @throws NumberIsTooLargeException if the total number of entries of the
209 * product is larger than {@code Integer.MAX_VALUE}.
210 */
211 public OpenMapRealMatrix multiply(OpenMapRealMatrix m)
212 throws DimensionMismatchException, NumberIsTooLargeException {
213 // Safety check.
214 MatrixUtils.checkMultiplicationCompatible(this, m);
215
216 final int outCols = m.getColumnDimension();
217 OpenMapRealMatrix out = new OpenMapRealMatrix(rows, outCols);
218 for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) {
219 iterator.advance();
220 final double value = iterator.value();
221 final int key = iterator.key();
222 final int i = key / columns;
223 final int k = key % columns;
224 for (int j = 0; j < outCols; ++j) {
225 final int rightKey = m.computeKey(k, j);
226 if (m.entries.containsKey(rightKey)) {
227 final int outKey = out.computeKey(i, j);
228 final double outValue =
229 out.entries.get(outKey) + value * m.entries.get(rightKey);
230 if (outValue == 0.0) {
231 out.entries.remove(outKey);
232 } else {
233 out.entries.put(outKey, outValue);
234 }
235 }
236 }
237 }
238
239 return out;
240 }
241
242 /** {@inheritDoc} */
243 @Override
244 public double getEntry(int row, int column) throws OutOfRangeException {
245 MatrixUtils.checkRowIndex(this, row);
246 MatrixUtils.checkColumnIndex(this, column);
247 return entries.get(computeKey(row, column));
248 }
249
250 /** {@inheritDoc} */
251 @Override
252 public int getRowDimension() {
253 return rows;
254 }
255
256 /** {@inheritDoc} */
257 @Override
258 public void setEntry(int row, int column, double value)
259 throws OutOfRangeException {
260 MatrixUtils.checkRowIndex(this, row);
261 MatrixUtils.checkColumnIndex(this, column);
262 if (value == 0.0) {
263 entries.remove(computeKey(row, column));
264 } else {
265 entries.put(computeKey(row, column), value);
266 }
267 }
268
269 /** {@inheritDoc} */
270 @Override
271 public void addToEntry(int row, int column, double increment)
272 throws OutOfRangeException {
273 MatrixUtils.checkRowIndex(this, row);
274 MatrixUtils.checkColumnIndex(this, column);
275 final int key = computeKey(row, column);
276 final double value = entries.get(key) + increment;
277 if (value == 0.0) {
278 entries.remove(key);
279 } else {
280 entries.put(key, value);
281 }
282 }
283
284 /** {@inheritDoc} */
285 @Override
286 public void multiplyEntry(int row, int column, double factor)
287 throws OutOfRangeException {
288 MatrixUtils.checkRowIndex(this, row);
289 MatrixUtils.checkColumnIndex(this, column);
290 final int key = computeKey(row, column);
291 final double value = entries.get(key) * factor;
292 if (value == 0.0) {
293 entries.remove(key);
294 } else {
295 entries.put(key, value);
296 }
297 }
298
299 /**
300 * Compute the key to access a matrix element
301 * @param row row index of the matrix element
302 * @param column column index of the matrix element
303 * @return key within the map to access the matrix element
304 */
305 private int computeKey(int row, int column) {
306 return row * columns + column;
307 }
308
309
310}
Note: See TracBrowser for help on using the repository browser.