1 package org.djunits.value.vdouble.matrix;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNotEquals;
6 import static org.junit.Assert.assertTrue;
7 import static org.junit.Assert.fail;
8
9 import java.lang.reflect.InvocationTargetException;
10 import java.lang.reflect.Method;
11
12 import org.djunits.Try;
13 import org.djunits.unit.AbsoluteTemperatureUnit;
14 import org.djunits.unit.AngleUnit;
15 import org.djunits.unit.AreaUnit;
16 import org.djunits.unit.DirectionUnit;
17 import org.djunits.unit.DurationUnit;
18 import org.djunits.unit.LengthUnit;
19 import org.djunits.unit.PositionUnit;
20 import org.djunits.unit.SIUnit;
21 import org.djunits.unit.TemperatureUnit;
22 import org.djunits.unit.TimeUnit;
23 import org.djunits.unit.Unit;
24 import org.djunits.unit.quantity.Quantities;
25 import org.djunits.unit.quantity.Quantity;
26 import org.djunits.unit.util.UnitException;
27 import org.djunits.unit.util.UnitRuntimeException;
28 import org.djunits.value.CLASSNAMES;
29 import org.djunits.value.ValueRuntimeException;
30 import org.djunits.value.storage.StorageType;
31 import org.djunits.value.vdouble.function.DoubleMathFunctions;
32 import org.djunits.value.vdouble.matrix.base.AbstractDoubleMatrixRel;
33 import org.djunits.value.vdouble.matrix.base.DoubleMatrix;
34 import org.djunits.value.vdouble.matrix.base.DoubleSparseValue;
35 import org.djunits.value.vdouble.matrix.data.DoubleMatrixData;
36 import org.djunits.value.vdouble.scalar.AbsoluteTemperature;
37 import org.djunits.value.vdouble.scalar.Area;
38 import org.djunits.value.vdouble.scalar.Direction;
39 import org.djunits.value.vdouble.scalar.Duration;
40 import org.djunits.value.vdouble.scalar.Length;
41 import org.djunits.value.vdouble.scalar.Position;
42 import org.djunits.value.vdouble.scalar.Time;
43 import org.djunits.value.vdouble.vector.AreaVector;
44 import org.djunits.value.vfloat.matrix.FloatAreaMatrix;
45 import org.djunits.value.vfloat.matrix.base.FloatMatrix;
46 import org.djunits.value.vfloat.vector.FLOATVECTOR;
47 import org.junit.Test;
48
49
50
51
52 public class DoubleMatrixMethodTest
53 {
54
55
56
57
58
59
60 @Test
61 @SuppressWarnings("checkstyle:methodlength")
62 public void testMatrixMethods() throws ValueRuntimeException, UnitException
63 {
64 double[][] denseTestData = DOUBLEMATRIX.denseRectArrays(10, 20);
65 double[][] sparseTestData = DOUBLEMATRIX.sparseRectArrays(10, 20);
66 double[][] reverseSparseTestData = new double[sparseTestData.length][];
67
68 for (int index = 0; index < sparseTestData.length; index++)
69 {
70 reverseSparseTestData[reverseSparseTestData.length - 1 - index] = sparseTestData[index];
71 }
72
73 for (int row = 1; row < 8; row++)
74 {
75 for (int col = 2; col < 18; col++)
76 {
77 sparseTestData[row][col] = 10000.456 + row + 100 * col;
78 reverseSparseTestData[row][col] = 20000.567 + row + 100 * col;
79 }
80 }
81
82 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
83 {
84 for (AreaUnit au : new AreaUnit[] { AreaUnit.SQUARE_METER, AreaUnit.ACRE })
85 {
86 double[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
87 AreaMatrix am =
88 DoubleMatrix.instantiate(DoubleMatrixData.instantiate(testData, au.getScale(), storageType), au);
89
90
91 for (int row : new int[] { -1, 0, denseTestData.length - 1, denseTestData.length })
92 {
93 for (int col : new int[] { -1, 0, denseTestData[0].length - 1, denseTestData[0].length })
94 {
95 if (row < 0 || col < 0 || row >= denseTestData.length || col >= denseTestData[0].length)
96 {
97 try
98 {
99 am.get(row, col);
100 fail("bad row or bad column value should have thrown a ValueRuntimeException");
101 }
102 catch (ValueRuntimeException vre)
103 {
104
105 }
106 }
107 else
108 {
109 am.get(row, col);
110 }
111 }
112 if (row < 0 || row >= denseTestData.length)
113 {
114 try
115 {
116 am.getRow(row);
117 fail("getRow with bad row value should have thrown a ValueRuntimeException");
118 }
119 catch (ValueRuntimeException vre)
120 {
121
122 }
123 }
124 }
125 for (int col : new int[] { -1, 0, denseTestData[0].length - 1, denseTestData[0].length })
126 {
127 if (col < 0 || col >= denseTestData[0].length)
128 {
129 try
130 {
131 am.getColumn(col);
132 fail("getColumn with bad column value should have thrown a ValueRuntimeException");
133 }
134 catch (ValueRuntimeException vre)
135 {
136
137 }
138 }
139 else
140 {
141 am.getColumn(col);
142 }
143 }
144
145
146 assertEquals(am, am.toSparse());
147 assertEquals(am, am.toDense());
148 assertEquals(am, am.toSparse().toDense());
149 assertEquals(am, am.toDense().toSparse());
150 assertEquals(am.hashCode(), am.toSparse().hashCode());
151 assertEquals(am.hashCode(), am.toDense().hashCode());
152 assertTrue(am.toDense().isDense());
153 assertFalse(am.toDense().isSparse());
154 assertTrue(am.toSparse().isSparse());
155 assertFalse(am.toSparse().isDense());
156
157
158 assertEquals(am, am);
159 assertNotEquals(am, new Object());
160 assertNotEquals(am, null);
161 assertNotEquals(am, DoubleMatrix.instantiate(
162 DoubleMatrixData.instantiate(testData, LengthUnit.METER.getScale(), storageType), LengthUnit.METER));
163 assertNotEquals(am, am.divide(2.0d));
164
165
166 assertFalse(am.isMutable());
167 AreaMatrix ammut = am.mutable();
168 assertTrue(ammut.isMutable());
169 assertFalse(am.isMutable());
170 AreaMatrix ammut2 = ammut.multiplyBy(1.0);
171 assertEquals(am, ammut2);
172 assertTrue(ammut.isMutable());
173 assertFalse(am.isMutable());
174 assertTrue(ammut2.isMutable());
175 ammut2 = ammut2.mutable().divideBy(2.0);
176 assertEquals(am, ammut);
177 assertNotEquals(am, ammut2);
178 AreaMatrix ammut3 = ammut2.mutable().divideBy(0.0);
179 for (int row = 0; row < ammut3.rows(); row++)
180 {
181 for (int col = 0; col < ammut3.cols(); col++)
182 {
183 if (ammut2.getSI(row, col) == 0)
184 {
185 assertTrue("Value should be NaN", Double.isNaN(ammut3.getSI(row, col)));
186
187 }
188 else
189 {
190 assertTrue("Value should be Infinite", Double.isInfinite(ammut3.getSI(row, col)));
191 }
192 }
193 }
194
195
196 Area zSum = am.zSum();
197 double sum = 0;
198 int card = 0;
199 for (int row = 0; row < testData.length; row++)
200 {
201 for (int col = 0; col < testData[0].length; col++)
202 {
203 sum += testData[row][col];
204 card += testData[row][col] == 0.0d ? 0 : 1;
205 }
206 }
207 assertEquals("zSum", sum, zSum.getInUnit(), 0.1);
208 assertEquals("cardinality", card, am.cardinality());
209 AreaMatrix ammutZero = ammut.multiplyBy(0.0);
210 assertEquals("cardinality should be 0", 0, ammutZero.cardinality());
211 assertEquals("zSum should be 0", 0.0, ammutZero.zSum().getSI(), 0);
212
213
214 AreaMatrix amold = am.clone();
215 Area fa = Area.of(10.0d, "m^2");
216 AreaMatrix aminc = am.mutable().incrementBy(fa).immutable();
217 AreaMatrix amdec = am.mutable().decrementBy(fa).immutable();
218 AreaMatrix amid = aminc.mutable().decrementBy(fa);
219 assertEquals("immutable matrix should not change when converted to mutable", am, amold);
220 for (int row = 0; row < testData.length; row++)
221 {
222 for (int col = 0; col < testData[0].length; col++)
223 {
224 assertEquals("increment and decrement with scalar should result in same matrix", am.getSI(row, col),
225 amid.getSI(row, col), 0.1);
226 assertEquals("m + s = (m+s)", au.getScale().toStandardUnit(testData[row][col]) + 10.0,
227 aminc.getSI(row, col), 0.1);
228 assertEquals("m - s = (m-s)", au.getScale().toStandardUnit(testData[row][col]) - 10.0,
229 amdec.getSI(row, col), 0.1);
230 }
231 }
232
233
234 AreaMatrix amt5 = am.mutable().multiplyBy(5.0d).immutable();
235 AreaMatrix amd5 = am.mutable().divideBy(5.0d).immutable();
236 AreaMatrix amtd = amt5.mutable().divideBy(5.0d);
237 AreaMatrix amtimD = am.times(5.0d);
238 AreaMatrix amtimF = am.times(5.0f);
239 AreaMatrix amdivD = am.divide(5.0d);
240 AreaMatrix amdivF = am.divide(5.0f);
241 for (int row = 0; row < testData.length; row++)
242 {
243 for (int col = 0; col < testData[0].length; col++)
244 {
245 assertEquals("times followed by divide with constant should result in same matrix", am.getSI(row, col),
246 amtd.getSI(row, col), 0.1);
247 assertEquals("m * 5.0 = (m*5.0)", au.getScale().toStandardUnit(testData[row][col]) * 5.0d,
248 amt5.getSI(row, col), 0.1);
249 assertEquals("m / 5.0 = (m/5.0)", au.getScale().toStandardUnit(testData[row][col]) / 5.0d,
250 amd5.getSI(row, col), 0.1);
251 assertEquals("amtimD", amt5.getSI(row, col), amtimD.getSI(row, col), 0.1d);
252 assertEquals("amtimF", amt5.getSI(row, col), amtimF.getSI(row, col), 0.1d);
253 assertEquals("amdivD", amd5.getSI(row, col), amdivD.getSI(row, col), 0.01d);
254 assertEquals("amdivD", amd5.getSI(row, col), amdivF.getSI(row, col), 0.01d);
255 }
256 }
257
258
259 assertEquals("get()", new Area(testData[2][2], au), am.get(2, 2));
260 assertEquals("getSI()", au.getScale().toStandardUnit(testData[2][2]), am.getSI(2, 2), 0.1);
261 assertEquals("getInUnit()", testData[2][2], am.getInUnit(2, 2), 0.1);
262 assertEquals("getInUnit(unit)",
263 AreaUnit.SQUARE_YARD.getScale().fromStandardUnit(au.getScale().toStandardUnit(testData[2][2])),
264 am.getInUnit(2, 2, AreaUnit.SQUARE_YARD), 0.1);
265
266
267 Area fasqft = new Area(10.5d, AreaUnit.SQUARE_FOOT);
268 AreaMatrix famChange = am.clone().mutable();
269 famChange.set(2, 2, fasqft);
270 assertEquals("set()", fasqft.si, famChange.get(2, 2).si, 0.1d);
271 famChange = am.clone().mutable();
272 famChange.setSI(2, 2, 123.4d);
273 assertEquals("setSI()", 123.4d, famChange.get(2, 2).si, 0.1d);
274 famChange = am.clone().mutable();
275 famChange.setInUnit(2, 2, 1.2d);
276 assertEquals("setInUnit()", 1.2d, famChange.getInUnit(2, 2), 0.1d);
277 famChange = am.clone().mutable();
278 famChange.setInUnit(2, 2, 1.5d, AreaUnit.HECTARE);
279 assertEquals("setInUnit(unit)", 15000.0d, famChange.get(2, 2).si, 1.0d);
280
281
282 double[][] squareData = storageType.equals(StorageType.DENSE) ? DOUBLEMATRIX.denseRectArrays(12, 12)
283 : DOUBLEMATRIX.sparseRectArrays(12, 12);
284 AreaMatrix amSquare =
285 DoubleMatrix.instantiate(DoubleMatrixData.instantiate(squareData, au.getScale(), storageType), au);
286 double[] row2si = am.getRowSI(2);
287 double[] col2si = am.getColumnSI(2);
288 double[] diagsi = amSquare.getDiagonalSI();
289 AreaVector row2v = am.getRow(2);
290 AreaVector col2v = am.getColumn(2);
291 AreaVector diagv = amSquare.getDiagonal();
292 Area[] row2scalar = am.getRowScalars(2);
293 Area[] col2scalar = am.getColumnScalars(2);
294 Area[] diagscalar = amSquare.getDiagonalScalars();
295 for (int col = 0; col < testData[0].length; col++)
296 {
297 assertEquals("row2si", au.getScale().toStandardUnit(testData[2][col]), row2si[col], 0.1d);
298 assertEquals("row2v", au.getScale().toStandardUnit(testData[2][col]), row2v.getSI(col), 0.1d);
299 assertEquals("row2scalar", au.getScale().toStandardUnit(testData[2][col]), row2scalar[col].si, 0.1d);
300 }
301 for (int row = 0; row < testData.length; row++)
302 {
303 assertEquals("col2si", au.getScale().toStandardUnit(testData[row][2]), col2si[row], 0.1d);
304 assertEquals("col2v", au.getScale().toStandardUnit(testData[row][2]), col2v.getSI(row), 0.1d);
305 assertEquals("col2scalar", au.getScale().toStandardUnit(testData[row][2]), col2scalar[row].si, 0.1d);
306 }
307 for (int diag = 0; diag < amSquare.rows(); diag++)
308 {
309 assertEquals("diag2si", au.getScale().toStandardUnit(squareData[diag][diag]), diagsi[diag], 0.1d);
310 assertEquals("diag2v", au.getScale().toStandardUnit(squareData[diag][diag]), diagv.getSI(diag), 0.1d);
311 assertEquals("diag2scalar", au.getScale().toStandardUnit(squareData[diag][diag]), diagscalar[diag].si,
312 0.1d);
313 }
314
315
316 double[][] valsi = am.getValuesSI();
317 double[][] valunit = am.getValuesInUnit();
318 double[][] valsqft = am.getValuesInUnit(AreaUnit.SQUARE_YARD);
319 Area[][] valscalars = am.getScalars();
320 for (int row = 0; row < testData.length; row++)
321 {
322 for (int col = 0; col < testData[0].length; col++)
323 {
324 assertEquals("getValuesSI()", au.getScale().toStandardUnit(testData[row][col]), valsi[row][col], 0.1);
325 assertEquals("getValuesInUnit()", testData[row][col], valunit[row][col], 0.1);
326 assertEquals("getValuesInUnit(unit)", AreaUnit.SQUARE_YARD.getScale()
327 .fromStandardUnit(au.getScale().toStandardUnit(testData[row][col])), valsqft[row][col], 0.1);
328 assertEquals("getValuesInUnit(unit)", au.getScale().toStandardUnit(testData[row][col]),
329 valscalars[row][col].si, 0.1);
330 }
331 }
332
333
334 AreaMatrix amdiv2 = am.divide(2.0d);
335 assertEquals(am.getStorageType(), amdiv2.getStorageType());
336 assertEquals(am.getDisplayUnit(), amdiv2.getDisplayUnit());
337 AreaMatrix amAbs = amdiv2.mutable().abs().immutable();
338 assertEquals(am.getStorageType(), amAbs.getStorageType());
339 assertEquals(am.getDisplayUnit(), amAbs.getDisplayUnit());
340 AreaMatrix amCeil = amdiv2.mutable().ceil().immutable();
341 assertEquals(am.getStorageType(), amCeil.getStorageType());
342 assertEquals(am.getDisplayUnit(), amCeil.getDisplayUnit());
343 AreaMatrix amFloor = amdiv2.mutable().floor().immutable();
344 assertEquals(am.getStorageType(), amFloor.getStorageType());
345 assertEquals(am.getDisplayUnit(), amFloor.getDisplayUnit());
346 AreaMatrix amNeg = amdiv2.mutable().neg().immutable();
347 assertEquals(am.getStorageType(), amNeg.getStorageType());
348 assertEquals(am.getDisplayUnit(), amNeg.getDisplayUnit());
349 AreaMatrix amRint = amdiv2.mutable().rint().immutable();
350 assertEquals(am.getStorageType(), amRint.getStorageType());
351 assertEquals(am.getDisplayUnit(), amRint.getDisplayUnit());
352 for (int row = 0; row < testData.length; row++)
353 {
354 for (int col = 0; col < testData[0].length; col++)
355 {
356
357 assertEquals("div2", au.getScale().toStandardUnit(testData[row][col]) / 2.0d, amdiv2.getSI(row, col),
358 0.1d);
359 assertEquals("abs", Math.abs(au.getScale().toStandardUnit(testData[row][col]) / 2.0d),
360 amAbs.getSI(row, col), 0.1d);
361 assertEquals("ceil", Math.ceil(au.getScale().toStandardUnit(testData[row][col]) / 2.0d),
362 amCeil.getSI(row, col), 0.1d);
363 assertEquals("floor", Math.floor(au.getScale().toStandardUnit(testData[row][col]) / 2.0d),
364 amFloor.getSI(row, col), 0.1d);
365 assertEquals("neg", -au.getScale().toStandardUnit(testData[row][col]) / 2.0d, amNeg.getSI(row, col),
366 0.1d);
367 assertEquals("rint", Math.rint(au.getScale().toStandardUnit(testData[row][col]) / 2.0d),
368 amRint.getSI(row, col), 0.1d);
369 }
370 }
371
372 double[][] testData4x4 =
373 new double[][] { { 2, 3, 5, 7 }, { 11, 13, 17, 19 }, { 23, 29, 31, 37 }, { 41, 43, 47, 49 } };
374 AreaMatrix am4x4 =
375 DoubleMatrix.instantiate(DoubleMatrixData.instantiate(testData4x4, au.getScale(), storageType), au);
376 double det = am4x4.determinant();
377 double detCalc = Determinant.det(am4x4.getValuesSI());
378 double err = Math.max(det, detCalc) / 10000.0;
379 assertEquals("Determinant of square matrix with unit " + au.getDefaultTextualAbbreviation() + ", storage = "
380 + storageType + " = " + det + " but should have been " + detCalc, detCalc, det, err);
381 new Try()
382 {
383 @Override
384 public void execute()
385 {
386 double detErr = am.determinant();
387 System.out.println(detErr);
388 }
389 }.test("Determinant of non-square matrix should have thrown exception");
390
391
392
393 for (StorageType storageType2 : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
394 {
395 double[][] testData2 = storageType2.equals(StorageType.DENSE) ? denseTestData : reverseSparseTestData;
396 for (AreaUnit au2 : new AreaUnit[] { AreaUnit.SQUARE_METER, AreaUnit.ACRE })
397 {
398
399
400 AreaMatrix am2 = DoubleMatrix
401 .instantiate(DoubleMatrixData.instantiate(testData2, au2.getScale(), storageType2), au2);
402 AreaMatrix amSum1 = am.plus(am2);
403 AreaMatrix amSum2 = am2.plus(am);
404 AreaMatrix amSum3 = am.mutable().incrementBy(am2).immutable();
405 AreaMatrix amSum4 = am2.mutable().incrementBy(am).immutable();
406 assertEquals("a+b == b+a", amSum1, amSum2);
407 assertEquals("a+b == b+a", amSum1, amSum3);
408 assertEquals("a+b == b+a", amSum1, amSum4);
409 for (int row = 0; row < testData.length; row++)
410 {
411 for (int col = 0; col < testData[0].length; col++)
412 {
413 double tolerance = Double.isFinite(amSum1.getSI(row, col))
414 ? Math.abs(amSum1.getSI(row, col) / 10000.0d) : 0.1d;
415 assertEquals("value in matrix matches",
416 au.getScale().toStandardUnit(testData[row][col])
417 + au2.getScale().toStandardUnit(testData2[row][col]),
418 amSum1.getSI(row, col), tolerance);
419 }
420 }
421
422
423 AreaMatrix amDiff1 = am.minus(am2);
424 AreaMatrix amDiff2 = am2.minus(am).mutable().neg();
425 AreaMatrix amDiff3 = am.mutable().decrementBy(am2).immutable();
426 assertEquals("a-b == -(b-a)", amDiff1, amDiff2);
427 assertEquals("a-b == -(b-a)", amDiff1, amDiff3);
428 for (int row = 0; row < testData.length; row++)
429 {
430 for (int col = 0; col < testData[0].length; col++)
431 {
432 double tolerance = Double.isFinite(amDiff1.getSI(row, col))
433 ? Math.abs(amDiff1.getSI(row, col) / 10000.0d) : 0.1d;
434 assertEquals("value in matrix matches",
435 au.getScale().toStandardUnit(testData[row][col])
436 - au2.getScale().toStandardUnit(testData2[row][col]),
437 amDiff1.getSI(row, col), tolerance);
438 }
439 }
440
441
442 SIMatrix amTim = am.times(am2);
443 SIMatrix amDiv = am.divide(am2);
444 assertEquals("unit of m2 * m2 should be m4", "m4",
445 amTim.getDisplayUnit().getQuantity().getSiDimensions().toString(false, false, false));
446 assertEquals("unit of m2 / m2 should be 1", "1",
447 amDiv.getDisplayUnit().getQuantity().getSiDimensions().toString(false, false, false));
448 for (int row = 0; row < testData.length; row++)
449 {
450 for (int col = 0; col < testData[0].length; col++)
451 {
452 double tolerance = Double.isFinite(amTim.getSI(row, col))
453 ? Math.abs(amTim.getSI(row, col) / 10000.0d) : 0.1d;
454 if (Math.abs(au.getScale().toStandardUnit(testData[row][col])
455 * au2.getScale().toStandardUnit(testData2[row][col])
456 - amTim.getSI(row, col)) > tolerance)
457 {
458 System.out.println(
459 "mismatch at row " + row + ", col " + col + ", got " + amTim.getSI(row, col)
460 + ", expected " + au.getScale().toStandardUnit(testData[row][col])
461 * au2.getScale().toStandardUnit(testData2[row][col]));
462 am.times(am2);
463 }
464 assertEquals("value in m2 * m2 matches",
465 au.getScale().toStandardUnit(testData[row][col])
466 * au2.getScale().toStandardUnit(testData2[row][col]),
467 amTim.getSI(row, col), tolerance);
468 tolerance = Double.isFinite(amTim.getSI(row, col)) ? Math.abs(amDiv.getSI(row, col) / 10000.0d)
469 : 0.1d;
470 assertEquals("value in m2 / m2 matches (could be NaN)",
471 au.getScale().toStandardUnit(testData[row][col])
472 / au2.getScale().toStandardUnit(testData2[row][col]),
473 amDiv.getSI(row, col), tolerance);
474 }
475 }
476 }
477 }
478 }
479 }
480 }
481
482
483
484
485 @Test
486 public void testImmutableMatrix()
487 {
488 double[][] denseTestData = DOUBLEMATRIX.denseRectArrays(5, 10);
489 double[][] sparseTestData = DOUBLEMATRIX.sparseRectArrays(5, 10);
490
491 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
492 {
493 for (AreaUnit au : new AreaUnit[] { AreaUnit.SQUARE_METER, AreaUnit.ACRE })
494 {
495 double[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
496 AreaMatrix am =
497 DoubleMatrix.instantiate(DoubleMatrixData.instantiate(testData, au.getScale(), storageType), au);
498 am = am.immutable();
499 final AreaMatrix amPtr = am;
500 Area fa = Area.of(10.0d, "m^2");
501 new Try()
502 {
503 @Override
504 public void execute()
505 {
506 amPtr.assign(DoubleMathFunctions.ABS);
507 }
508 }.test("ImmutableMatrix.assign(...) should throw error");
509 new Try()
510 {
511 @Override
512 public void execute()
513 {
514 amPtr.decrementBy(fa);
515 }
516 }.test("ImmutableMatrix.decrementBy(scalar) should throw error");
517 new Try()
518 {
519 @Override
520 public void execute()
521 {
522 amPtr.decrementBy(amPtr);
523 }
524 }.test("ImmutableMatrix.decrementBy(matrix) should throw error");
525 new Try()
526 {
527 @Override
528 public void execute()
529 {
530 amPtr.incrementBy(fa);
531 }
532 }.test("ImmutableMatrix.incrementBy(scalar) should throw error");
533 new Try()
534 {
535 @Override
536 public void execute()
537 {
538 amPtr.incrementBy(amPtr);
539 }
540 }.test("ImmutableMatrix.incrementBy(matrix) should throw error");
541 new Try()
542 {
543 @Override
544 public void execute()
545 {
546 amPtr.divideBy(2.0d);
547 }
548 }.test("ImmutableMatrix.divideBy(factor) should throw error");
549 new Try()
550 {
551 @Override
552 public void execute()
553 {
554 amPtr.multiplyBy(2.0d);
555 }
556 }.test("ImmutableMatrix.multiplyBy(factor) should throw error");
557 new Try()
558 {
559 @Override
560 public void execute()
561 {
562 amPtr.set(1, 1, fa);
563 }
564 }.test("ImmutableMatrix.set() should throw error");
565 new Try()
566 {
567 @Override
568 public void execute()
569 {
570 amPtr.setSI(1, 1, 20.1d);
571 }
572 }.test("ImmutableMatrix.setSI() should throw error");
573 new Try()
574 {
575 @Override
576 public void execute()
577 {
578 amPtr.setInUnit(1, 1, 15.2d);
579 }
580 }.test("ImmutableMatrix.setInUnit(f) should throw error");
581 new Try()
582 {
583 @Override
584 public void execute()
585 {
586 amPtr.setInUnit(1, 1, 15.2d, AreaUnit.ARE);
587 }
588 }.test("ImmutableMatrix.setInUnit(f, u) should throw error");
589 new Try()
590 {
591 @Override
592 public void execute()
593 {
594 amPtr.abs();
595 }
596 }.test("ImmutableMatrix.abs() should throw error");
597 new Try()
598 {
599 @Override
600 public void execute()
601 {
602 amPtr.ceil();
603 }
604 }.test("ImmutableMatrix.ceil() should throw error");
605 new Try()
606 {
607 @Override
608 public void execute()
609 {
610 amPtr.floor();
611 }
612 }.test("ImmutableMatrix.floor() should throw error");
613 new Try()
614 {
615 @Override
616 public void execute()
617 {
618 amPtr.neg();
619 }
620 }.test("ImmutableMatrix.neg() should throw error");
621 new Try()
622 {
623 @Override
624 public void execute()
625 {
626 amPtr.rint();
627 }
628 }.test("ImmutableMatrix.rint() should throw error");
629 }
630 }
631 }
632
633
634
635
636 @Test
637 public void testMatrixToString()
638 {
639 double[][] denseTestData = DOUBLEMATRIX.denseRectArrays(5, 10);
640 double[][] sparseTestData = DOUBLEMATRIX.sparseRectArrays(5, 10);
641
642 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
643 {
644 for (AreaUnit au : new AreaUnit[] { AreaUnit.SQUARE_METER, AreaUnit.ACRE })
645 {
646 double[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
647 AreaMatrix am =
648 DoubleMatrix.instantiate(DoubleMatrixData.instantiate(testData, au.getScale(), storageType), au);
649 String s1 = am.toString();
650 assertTrue(s1.contains(au.getDefaultTextualAbbreviation()));
651 String s2 = am.toString(AreaUnit.SQUARE_INCH);
652 assertTrue(s2.contains(AreaUnit.SQUARE_INCH.getDefaultTextualAbbreviation()));
653 String s3 = am.toString(AreaUnit.SQUARE_INCH, true, true);
654 assertTrue(s3.contains(AreaUnit.SQUARE_INCH.getDefaultTextualAbbreviation()));
655 if (storageType.equals(StorageType.DENSE))
656 {
657 assertTrue(s3.contains("Dense"));
658 assertFalse(s3.contains("Sparse"));
659 }
660 else
661 {
662 assertFalse(s3.contains("Dense"));
663 assertTrue(s3.contains("Sparse"));
664 }
665 assertTrue(s3.contains("Rel"));
666 assertFalse(s3.contains("Abs"));
667 assertTrue(s3.contains("Immutable"));
668 assertFalse(s3.contains("Mutable"));
669 AreaMatrix ammut = am.mutable();
670 String smut = ammut.toString(AreaUnit.SQUARE_INCH, true, true);
671 assertFalse(smut.contains("Immutable"));
672 assertTrue(smut.contains("Mutable"));
673 String sNotVerbose = ammut.toString(false, false);
674 assertFalse(sNotVerbose.contains("Rel"));
675 assertFalse(sNotVerbose.contains("Abs"));
676 assertFalse(sNotVerbose.contains("Immutable"));
677 assertFalse(sNotVerbose.contains("Mutable"));
678 assertFalse(sNotVerbose.contains(au.getDefaultTextualAbbreviation()));
679 }
680 }
681 TimeMatrix tm = DoubleMatrix.instantiate(
682 DoubleMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
683 String st = tm.toString(TimeUnit.DEFAULT, true, true);
684 assertFalse(st.contains("Rel"));
685 assertTrue(st.contains("Abs"));
686 LengthMatrix lm = DoubleMatrix.instantiate(
687 DoubleMatrixData.instantiate(denseTestData, LengthUnit.SI.getScale(), StorageType.DENSE), LengthUnit.SI);
688 String sl = lm.toString(LengthUnit.SI, true, true);
689 assertTrue(sl.contains("Rel"));
690 assertFalse(sl.contains("Abs"));
691 }
692
693
694
695
696 @Test
697 public void testSpecialMatrixMethodsRelWithAbs()
698 {
699 double[][] denseTestData = DOUBLEMATRIX.denseRectArrays(5, 10);
700 TimeMatrix tm = DoubleMatrix.instantiate(
701 DoubleMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
702 DurationMatrix dm = DoubleMatrix.instantiate(
703 DoubleMatrixData.instantiate(denseTestData, DurationUnit.MINUTE.getScale(), StorageType.DENSE),
704 DurationUnit.SECOND);
705 assertTrue(tm.isAbsolute());
706 assertFalse(dm.isAbsolute());
707 assertFalse(tm.isRelative());
708 assertTrue(dm.isRelative());
709
710 TimeMatrix absPlusRel = tm.plus(dm);
711 TimeMatrix absMinusRel = tm.minus(dm);
712 double[][] halfDenseData = DOUBLEMATRIX.denseRectArrays(5, 10);
713 for (int row = 0; row < halfDenseData.length; row++)
714 {
715 for (int col = 0; col < halfDenseData[row].length; col++)
716 {
717 halfDenseData[row][col] *= 0.5;
718 }
719 }
720 TimeMatrix halfTimeMatrix = DoubleMatrix.instantiate(
721 DoubleMatrixData.instantiate(halfDenseData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
722 DurationMatrix absMinusAbs = tm.minus(halfTimeMatrix);
723 TimeMatrix absDecByRelS = tm.mutable().decrementBy(Duration.of(1.0d, "min"));
724 TimeMatrix absDecByRelM = tm.mutable().decrementBy(dm.divide(2.0d));
725 TimeMatrix relPlusAbs = dm.plus(tm);
726 for (int row = 0; row < denseTestData.length; row++)
727 {
728 for (int col = 0; col < denseTestData[0].length; col++)
729 {
730 assertEquals("absPlusRel", 61.0 * denseTestData[row][col], absPlusRel.getSI(row, col), 0.01);
731 assertEquals("absMinusRel", -59.0 * denseTestData[row][col], absMinusRel.getSI(row, col), 0.01);
732 assertEquals("absMinusAbs", denseTestData[row][col] / 2.0, absMinusAbs.getSI(row, col), 0.01);
733 assertEquals("absDecByRelS", denseTestData[row][col] - 60.0, absDecByRelS.getSI(row, col), 0.01);
734 assertEquals("absDecByRelM", -29.0 * denseTestData[row][col], absDecByRelM.getSI(row, col), 0.01);
735 assertEquals("relPlusAbs", 61.0 * denseTestData[row][col], relPlusAbs.getSI(row, col), 0.01);
736 }
737 }
738 for (int dRows : new int[] { -1, 0, 1 })
739 {
740 for (int dCols : new int[] { -1, 0, 1 })
741 {
742 if (dRows == 0 && dCols == 0)
743 {
744 continue;
745 }
746 double[][] other = DOUBLEMATRIX.denseRectArrays(denseTestData.length + dRows, denseTestData[0].length + dCols);
747 TimeMatrix wrongTimeMatrix = DoubleMatrix.instantiate(
748 DoubleMatrixData.instantiate(other, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
749 try
750 {
751 tm.mutable().minus(wrongTimeMatrix);
752 fail("Mismatching size should have thrown a ValueRuntimeException");
753 }
754 catch (ValueRuntimeException vre)
755 {
756
757 }
758 }
759 }
760 assertTrue("toString returns something informative",
761 DoubleMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE).toString()
762 .startsWith("DoubleMatrixData"));
763 }
764
765
766
767
768
769 @Test
770 public void memoryTest()
771 {
772 FloatAreaMatrix am = FloatMatrix.instantiate(new float[5][10], AreaUnit.SI, StorageType.SPARSE);
773 am = am.mutable();
774 float nonZeroValue = 123.456f;
775
776 for (int compoundIndex = 0; compoundIndex < am.cols() * am.rows(); compoundIndex++)
777 {
778
779 int row = compoundIndex % am.rows();
780 int col = compoundIndex / am.rows();
781 assertEquals("initial value is 0", 0f, am.getSI(row, col), 0.0001);
782 am.setSI(row, col, nonZeroValue);
783 assertEquals("current value is nonZero", nonZeroValue, am.getSI(row, col), 0.0001);
784 }
785 for (int compoundIndex = am.cols() * am.rows(); --compoundIndex >= 0;)
786 {
787
788 int row = compoundIndex % am.rows();
789 int col = compoundIndex / am.rows();
790 assertEquals("current value is nonZero", nonZeroValue, am.getSI(row, col), 0.0001);
791 am.setSI(row, col, 0f);
792 assertEquals("final value is 0", 0f, am.getSI(row, col), 0.0001);
793 }
794 }
795
796
797
798
799 @Test
800 public void testInstantiateAbs()
801 {
802 double[][] denseTestData = DOUBLEMATRIX.denseRectArrays(10, 20);
803 TimeMatrix timeMatrix = DoubleMatrix.instantiate(
804 DoubleMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
805 DurationMatrix durationMatrix = DoubleMatrix.instantiate(
806 DoubleMatrixData.instantiate(denseTestData, DurationUnit.MINUTE.getScale(), StorageType.DENSE),
807 DurationUnit.SECOND);
808
809 float[] halfDenseData = FLOATVECTOR.denseArray(105);
810 for (int index = 0; index < halfDenseData.length; index++)
811 {
812 halfDenseData[index] *= 0.5;
813 }
814 TimeMatrix relPlusAbsTime = durationMatrix.plus(timeMatrix);
815 for (int row = 0; row < denseTestData.length; row++)
816 {
817 for (int col = 0; col < denseTestData[0].length; col++)
818 {
819 assertEquals("relPlusAbsTime", 61.0 * denseTestData[row][col], relPlusAbsTime.getSI(row, col), 0.01);
820 }
821 }
822 Time time = durationMatrix.instantiateScalarAbsSI(123.456f, TimeUnit.EPOCH_DAY);
823 assertEquals("Unit of instantiateScalarAbsSI matches", TimeUnit.EPOCH_DAY, time.getDisplayUnit());
824 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, time.si, 0.1);
825
826 AngleMatrix angleMatrix = DoubleMatrix.instantiate(
827 DoubleMatrixData.instantiate(denseTestData, AngleUnit.DEGREE.getScale(), StorageType.DENSE), AngleUnit.DEGREE);
828 DirectionMatrix directionMatrix = DoubleMatrix.instantiate(
829 DoubleMatrixData.instantiate(denseTestData, DirectionUnit.EAST_DEGREE.getScale(), StorageType.DENSE),
830 DirectionUnit.EAST_DEGREE);
831
832 DirectionMatrix relPlusAbsDirection = angleMatrix.plus(directionMatrix);
833 for (int row = 0; row < denseTestData.length; row++)
834 {
835 for (int col = 0; col < denseTestData[0].length; col++)
836 {
837 assertEquals("relPlusAbsTime", 2.0 / 180 * Math.PI * denseTestData[row][col],
838 relPlusAbsDirection.getSI(row, col), 0.01);
839 }
840 }
841 Direction direction = angleMatrix.instantiateScalarAbsSI(123.456f, DirectionUnit.NORTH_RADIAN);
842 assertEquals("Unit of instantiateScalarAbsSI matches", DirectionUnit.NORTH_RADIAN, direction.getDisplayUnit());
843 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, direction.si, 0.1);
844
845 TemperatureMatrix temperatureMatrix = DoubleMatrix.instantiate(
846 DoubleMatrixData.instantiate(denseTestData, TemperatureUnit.DEGREE_FAHRENHEIT.getScale(), StorageType.DENSE),
847 TemperatureUnit.DEGREE_FAHRENHEIT);
848 AbsoluteTemperatureMatrix absoluteTemperatureMatrix = DoubleMatrix.instantiate(
849 DoubleMatrixData.instantiate(denseTestData, AbsoluteTemperatureUnit.KELVIN.getScale(), StorageType.DENSE),
850 AbsoluteTemperatureUnit.KELVIN);
851
852 AbsoluteTemperatureMatrix relPlusAbsTemperature = temperatureMatrix.plus(absoluteTemperatureMatrix);
853 for (int row = 0; row < denseTestData.length; row++)
854 {
855 for (int col = 0; col < denseTestData[0].length; col++)
856 {
857 assertEquals("relPlusAbsTime", (1.0 + 5.0 / 9.0) * denseTestData[row][col],
858 relPlusAbsTemperature.getSI(row, col), 0.01);
859 }
860 }
861 AbsoluteTemperature absoluteTemperature =
862 temperatureMatrix.instantiateScalarAbsSI(123.456f, AbsoluteTemperatureUnit.DEGREE_FAHRENHEIT);
863 assertEquals("Unit of instantiateScalarAbsSI matches", AbsoluteTemperatureUnit.DEGREE_FAHRENHEIT,
864 absoluteTemperature.getDisplayUnit());
865 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, absoluteTemperature.si, 0.1);
866
867 LengthMatrix lengthMatrix = DoubleMatrix.instantiate(
868 DoubleMatrixData.instantiate(denseTestData, LengthUnit.MILE.getScale(), StorageType.DENSE), LengthUnit.MILE);
869 PositionMatrix positionMatrix = DoubleMatrix.instantiate(
870 DoubleMatrixData.instantiate(denseTestData, PositionUnit.KILOMETER.getScale(), StorageType.DENSE),
871 PositionUnit.KILOMETER);
872
873 PositionMatrix relPlusAbsPosition = lengthMatrix.plus(positionMatrix);
874 for (int row = 0; row < denseTestData.length; row++)
875 {
876 for (int col = 0; col < denseTestData[0].length; col++)
877 {
878 assertEquals("relPlusAbsTime", 2609.344 * denseTestData[row][col], relPlusAbsPosition.getSI(row, col), 0.1);
879 }
880 }
881 Position position = lengthMatrix.instantiateScalarAbsSI(123.456f, PositionUnit.ANGSTROM);
882 assertEquals("Unit of instantiateScalarAbsSI matches", PositionUnit.ANGSTROM, position.getDisplayUnit());
883 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, position.si, 0.01);
884 }
885
886
887
888
889
890
891
892
893
894
895
896
897 @SuppressWarnings("unchecked")
898 @Test
899 public <U extends Unit<U>> void testAsUnit() throws ClassNotFoundException, NoSuchMethodException, SecurityException,
900 IllegalAccessException, IllegalArgumentException, InvocationTargetException, UnitException
901 {
902 double[][] testValues = DOUBLEMATRIX.denseRectArrays(10, 20);
903 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
904 {
905 for (String type : CLASSNAMES.REL_LIST)
906 {
907 Class.forName("org.djunits.unit." + type + "Unit");
908 Quantity<U> quantity = (Quantity<U>) Quantities.INSTANCE.getQuantity(type + "Unit");
909 for (U unit : quantity.getUnitsById().values())
910 {
911 for (StorageType storageType2 : new StorageType[] { StorageType.DENSE, storageType })
912 {
913 SIUnit siUnit = SIUnit.of(unit.getQuantity().getSiDimensions());
914 SIMatrix matrix = SIMatrix.instantiate(testValues, siUnit, storageType2);
915 Method asMethod = SIMatrix.class.getDeclaredMethod("as", Unit.class);
916 AbstractDoubleMatrixRel<U, ?, ?, ?> asMatrix =
917 (AbstractDoubleMatrixRel<U, ?, ?, ?>) asMethod.invoke(matrix, siUnit);
918 assertEquals(matrix.getDisplayUnit().getStandardUnit(), asMatrix.getDisplayUnit());
919 siUnit = SIUnit.of(AbsoluteTemperatureUnit.KELVIN.getQuantity().getSiDimensions());
920 for (int row = 0; row < testValues.length; row++)
921 {
922 for (int col = 0; col < testValues[0].length; col++)
923 {
924 assertEquals("Values should match", testValues[row][col], matrix.getInUnit(row, col), 0.001);
925 }
926 }
927 try
928 {
929 asMethod.invoke(matrix, siUnit);
930 fail("as method should not be able to cast to unrelated (absoluteTemperature) unit");
931 }
932 catch (InvocationTargetException ite)
933 {
934 Throwable cause = ite.getCause();
935 assertEquals("cause is UnitRuntimeException", UnitRuntimeException.class, cause.getClass());
936
937 }
938 }
939 }
940 }
941 }
942 }
943
944
945
946
947 @SuppressWarnings("unlikely-arg-type")
948 @Test
949 public void testEquals()
950 {
951 double[][] testData = DOUBLEMATRIX.denseRectArrays(12, 34);
952 testData[2][2] = 0;
953 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
954 {
955 DoubleMatrixData dmd = DoubleMatrixData.instantiate(testData, TemperatureUnit.KELVIN.getScale(), storageType);
956 assertTrue("Double matrix is equal to itself", dmd.equals(dmd));
957 assertFalse("Double matrix is not equal to null", dmd.equals(null));
958 assertFalse("Double matrix data is not equal to some string", dmd.equals("some string"));
959 assertTrue("Double matrix is equal to sparse version of itself", dmd.equals(dmd.toSparse()));
960 assertTrue("Double matrix is equal to dense version of itself", dmd.equals(dmd.toDense()));
961 for (StorageType storageType2 : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
962 {
963 DoubleMatrixData dvd2 = DoubleMatrixData.instantiate(testData, TemperatureUnit.KELVIN.getScale(), storageType2);
964 assertEquals(
965 "Double matrix data is equal to other double vector containing same values regardless of storage type",
966 dmd, dvd2);
967 double[][] testData2 = DOUBLEMATRIX.denseRectArrays(12, 33);
968 testData2[2][2] = 0;
969 dvd2 = DoubleMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
970 assertFalse("Double matrix data is not equal to other double vector containing same values except last one",
971 dmd.equals(dvd2));
972 testData2 = DOUBLEMATRIX.denseRectArrays(13, 34);
973 testData2[2][2] = 0;
974 dvd2 = DoubleMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
975 assertFalse("Double matrix data is not equal to other double vector containing same values except last one",
976 dmd.equals(dvd2));
977 testData2 = DOUBLEMATRIX.denseRectArrays(12, 34);
978 dvd2 = DoubleMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
979 assertFalse("Double matrix data is not equal to other double vector containing same values except for one zero",
980 dmd.equals(dvd2));
981 }
982 }
983 }
984
985
986
987
988 @SuppressWarnings({ "rawtypes", "unchecked" })
989 @Test
990 public void sparseValueTest()
991 {
992 try
993 {
994 new DoubleSparseValue(-1, 0, 123.456);
995 fail("Negative row should have caused a ValueRuntimeException");
996 }
997 catch (ValueRuntimeException vre)
998 {
999
1000 }
1001
1002 try
1003 {
1004 new DoubleSparseValue(0, -1, 123.456);
1005 fail("Negative column should have caused a ValueRuntimeException");
1006 }
1007 catch (ValueRuntimeException vre)
1008 {
1009
1010 }
1011
1012 Length length = Length.valueOf("123 km");
1013 DoubleSparseValue dsv = new DoubleSparseValue(2, 3, length);
1014 assertEquals("row matches", 2, dsv.getRow());
1015 assertEquals("column matches", 3, dsv.getColumn());
1016 assertEquals("value matches", 123000, dsv.getValueSI(), 0.1);
1017 dsv = new DoubleSparseValue(2, 3, 123.000, LengthUnit.KILOMETER);
1018 assertEquals("row matches", 2, dsv.getRow());
1019 assertEquals("column matches", 3, dsv.getColumn());
1020 assertEquals("value matches", 123000, dsv.getValueSI(), 0.1);
1021 }
1022
1023 }