1 package org.djunits.value.vdouble.matrix;
2
3 import org.djunits.unit.Unit;
4 import org.djunits.value.Absolute;
5 import org.djunits.value.AbstractValue;
6 import org.djunits.value.Mutable;
7 import org.djunits.value.StorageType;
8 import org.djunits.value.ValueException;
9 import org.djunits.value.ValueUtil;
10 import org.djunits.value.formatter.Format;
11 import org.ojalgo.access.Access2D.Factory;
12 import org.ojalgo.matrix.BasicMatrix;
13 import org.ojalgo.matrix.PrimitiveMatrix;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 public abstract class AbstractDoubleMatrix<U extends Unit<U>, T extends AbstractDoubleMatrix<U, T>> extends AbstractValue<U>
30 implements DoubleMatrixInterface<U>
31 {
32
33 private static final long serialVersionUID = 20161015L;
34
35
36 @SuppressWarnings("checkstyle:visibilitymodifier")
37 protected DoubleMatrixData data;
38
39
40
41
42
43
44 AbstractDoubleMatrix(final U unit, final DoubleMatrixData data)
45 {
46 super(unit);
47 this.data = data;
48 }
49
50
51
52
53 protected final DoubleMatrixData getData()
54 {
55 return this.data;
56 }
57
58
59
60
61
62 public final StorageType getStorageType()
63 {
64 return this.data.getStorageType();
65 }
66
67
68 @Override
69 public final double[][] getValuesSI()
70 {
71 return this.data.getDenseMatrixSI();
72 }
73
74
75 @Override
76 public final double[][] getValuesInUnit()
77 {
78 return getValuesInUnit(getUnit());
79 }
80
81
82 @Override
83 public final double[][] getValuesInUnit(final U targetUnit)
84 {
85 double[][] values = getValuesSI();
86 for (int row = rows(); --row >= 0;)
87 {
88 for (int column = columns(); --column >= 0;)
89 {
90 values[row][column] = ValueUtil.expressAsUnit(values[row][column], targetUnit);
91 }
92 }
93 return values;
94 }
95
96
97 @Override
98 public final int rows()
99 {
100 return this.data.rows();
101 }
102
103
104 @Override
105 public final int columns()
106 {
107 return this.data.cols();
108 }
109
110
111 @Override
112 public final double getSI(final int row, final int column) throws ValueException
113 {
114 checkIndex(row, column);
115 return this.data.getSI(row, column);
116 }
117
118
119 @Override
120 public final double getInUnit(final int row, final int column) throws ValueException
121 {
122 return expressAsSpecifiedUnit(getSI(row, column));
123 }
124
125
126 @Override
127 public final double getInUnit(final int row, final int column, final U targetUnit) throws ValueException
128 {
129 return ValueUtil.expressAsUnit(getSI(row, column), targetUnit);
130 }
131
132
133 @Override
134 public final double zSum()
135 {
136 return this.data.zSum();
137 }
138
139
140 @Override
141 public final int cardinality()
142 {
143 return this.data.cardinality();
144 }
145
146
147 @Override
148 public final String toString()
149 {
150 return toString(getUnit(), false, true);
151 }
152
153
154 @Override
155 public final String toString(final U displayUnit)
156 {
157 return toString(displayUnit, false, true);
158 }
159
160
161 @Override
162 public final String toString(final boolean verbose, final boolean withUnit)
163 {
164 return toString(getUnit(), verbose, withUnit);
165 }
166
167
168 @Override
169 public final String toString(final U displayUnit, final boolean verbose, final boolean withUnit)
170 {
171 StringBuffer buf = new StringBuffer();
172 if (verbose)
173 {
174 String ab = this instanceof Absolute ? "Abs " : "Rel ";
175 String ds = this.data.isDense() ? "Dense " : this.data.isSparse() ? "Sparse " : "?????? ";
176 if (this instanceof Mutable)
177 {
178 buf.append("Mutable " + ab + ds);
179 }
180 else
181 {
182 buf.append("Immutable " + ab + ds);
183 }
184 }
185 for (int row = 0; row < rows(); row++)
186 {
187 buf.append("\r\n\t");
188 for (int column = 0; column < columns(); column++)
189 {
190 try
191 {
192 double d = ValueUtil.expressAsUnit(getSI(row, column), displayUnit);
193 buf.append(" " + Format.format(d));
194 }
195 catch (ValueException ve)
196 {
197 buf.append(" " + "********************".substring(0, Format.DEFAULTSIZE));
198 }
199 }
200 }
201 buf.append("\n");
202 if (withUnit)
203 {
204 buf.append(displayUnit.getAbbreviation());
205 }
206 return buf.toString();
207 }
208
209
210
211
212
213
214 protected final void checkSize(final AbstractDoubleMatrixRel<?, ?, ?, ?> other) throws ValueException
215 {
216 if (null == other)
217 {
218 throw new ValueException("other is null");
219 }
220 if (rows() != other.rows() || columns() != other.columns())
221 {
222 throw new ValueException("The matrices have different sizes: " + rows() + "x" + columns() + " != " + other.rows()
223 + "x" + other.columns());
224 }
225 }
226
227
228
229
230
231
232
233 protected static double[][] ensureRectangularAndNonEmpty(final double[][] values) throws ValueException
234 {
235 if (null == values)
236 {
237 throw new ValueException("Cannot create a DoubleVector or MutableDoubleVector from a null array of double[][]");
238 }
239 if (values.length > 0 && null == values[0])
240 {
241 throw new ValueException("Creating DoubleVector or MutableDoubleVector: Row 0 is null");
242 }
243 for (int row = values.length; --row >= 1;)
244 {
245 if (null == values[row] || values[0].length != values[row].length)
246 {
247 throw new ValueException("Creating DoubleVector or MutableDoubleVector: Lengths of rows are not all the same");
248 }
249 }
250 return values;
251 }
252
253
254
255
256
257
258 protected final void checkSize(final double[][] other) throws ValueException
259 {
260 ensureRectangularAndNonEmpty(other);
261 final int otherColumns = other[0].length;
262 if (rows() != other.length || columns() != otherColumns)
263 {
264 throw new ValueException("The matrix and the array have different sizes: " + rows() + "x" + columns() + " != "
265 + other.length + "x" + otherColumns);
266 }
267 }
268
269
270
271
272
273
274
275 protected final void checkIndex(final int row, final int column) throws ValueException
276 {
277 if (row < 0 || row >= rows() || column < 0 || column >= columns())
278 {
279 throw new ValueException("index out of range (valid range is 0.." + (rows() - 1) + ", 0.." + (columns() - 1)
280 + ", got " + row + ", " + column + ")");
281 }
282 }
283
284
285 @Override
286 public final double determinant() throws ValueException
287 {
288 try
289 {
290 final Factory<PrimitiveMatrix> matrixFactory = PrimitiveMatrix.FACTORY;
291 final BasicMatrix m = matrixFactory.rows(this.data.getDenseMatrixSI());
292 return m.getDeterminant().doubleValue();
293 }
294 catch (IllegalArgumentException exception)
295 {
296 throw new ValueException(exception);
297 }
298 }
299
300
301 @Override
302 @SuppressWarnings("checkstyle:designforextension")
303 public int hashCode()
304 {
305 final int prime = 31;
306 int result = getUnit().getStandardUnit().hashCode();
307 result = prime * result + ((this.data == null) ? 0 : this.data.hashCode());
308 return result;
309 }
310
311
312 @Override
313 @SuppressWarnings({ "checkstyle:designforextension", "checkstyle:needbraces", "unchecked" })
314 public boolean equals(final Object obj)
315 {
316 if (this == obj)
317 return true;
318 if (obj == null)
319 return false;
320 if (getClass() != obj.getClass())
321 return false;
322 AbstractDoubleMatrix<U, T> other = (AbstractDoubleMatrix<U, T>) obj;
323 if (!getUnit().getStandardUnit().equals(other.getUnit().getStandardUnit()))
324 return false;
325 if (this.data == null)
326 {
327 if (other.data != null)
328 return false;
329 }
330 else if (!this.data.equals(other.data))
331 return false;
332 return true;
333 }
334
335 }