1 package org.djunits.value.vfloat.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.matrix.AreaMatrix;
32 import org.djunits.value.vdouble.matrix.Determinant;
33 import org.djunits.value.vdouble.matrix.base.DoubleMatrix;
34 import org.djunits.value.vfloat.function.FloatMathFunctions;
35 import org.djunits.value.vfloat.matrix.base.AbstractFloatMatrixRel;
36 import org.djunits.value.vfloat.matrix.base.FloatMatrix;
37 import org.djunits.value.vfloat.matrix.base.FloatSparseValue;
38 import org.djunits.value.vfloat.matrix.data.FloatMatrixData;
39 import org.djunits.value.vfloat.scalar.FloatAbsoluteTemperature;
40 import org.djunits.value.vfloat.scalar.FloatArea;
41 import org.djunits.value.vfloat.scalar.FloatDirection;
42 import org.djunits.value.vfloat.scalar.FloatDuration;
43 import org.djunits.value.vfloat.scalar.FloatLength;
44 import org.djunits.value.vfloat.scalar.FloatPosition;
45 import org.djunits.value.vfloat.scalar.FloatTime;
46 import org.djunits.value.vfloat.vector.FLOATVECTOR;
47 import org.djunits.value.vfloat.vector.FloatAreaVector;
48 import org.junit.Test;
49
50
51
52
53 public class FloatMatrixMethodTest
54 {
55
56
57
58
59
60
61 @Test
62 public void testMatrixMethods() throws ValueRuntimeException, UnitException
63 {
64 float[][] denseTestData = FLOATMATRIX.denseRectArrays(10, 20);
65 float[][] sparseTestData = FLOATMATRIX.sparseRectArrays(10, 20);
66 float[][] reverseSparseTestData = new float[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.456f + row + 100 * col;
78 reverseSparseTestData[row][col] = 20000.567f + 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 float[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
87 FloatAreaMatrix am =
88 FloatMatrix.instantiate(FloatMatrixData.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, FloatMatrix.instantiate(
162 FloatMatrixData.instantiate(testData, LengthUnit.METER.getScale(), storageType), LengthUnit.METER));
163 assertNotEquals(am, am.divide(2.0f));
164
165
166 assertFalse(am.isMutable());
167 FloatAreaMatrix ammut = am.mutable();
168 assertTrue(ammut.isMutable());
169 assertFalse(am.isMutable());
170 FloatAreaMatrix 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 FloatAreaMatrix 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", Float.isNaN(ammut3.getSI(row, col)));
186
187 }
188 else
189 {
190 assertTrue("Value should be Infinite", Float.isInfinite(ammut3.getSI(row, col)));
191 }
192 }
193 }
194
195
196 FloatArea zSum = am.zSum();
197 float 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.0f ? 0 : 1;
205 }
206 }
207 assertEquals("zSum", sum, zSum.getInUnit(), 5f);
208 assertEquals("cardinality", card, am.cardinality());
209 FloatAreaMatrix ammutZero = ammut.multiplyBy(0.0f);
210 assertEquals("cardinality should be 0", 0, ammutZero.cardinality());
211 assertEquals("zSum should be 0", 0.0, ammutZero.zSum().getSI(), 0);
212
213
214 FloatAreaMatrix amold = am.clone();
215 FloatArea fa = FloatArea.of(10.0f, "m^2");
216 FloatAreaMatrix aminc = am.mutable().incrementBy(fa).immutable();
217 FloatAreaMatrix amdec = am.mutable().decrementBy(fa).immutable();
218 FloatAreaMatrix 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), 5f);
226 assertEquals("m + s = (m+s)", au.getScale().toStandardUnit(testData[row][col]) + 10.0,
227 aminc.getSI(row, col), 6f);
228 assertEquals("m - s = (m-s)", au.getScale().toStandardUnit(testData[row][col]) - 10.0,
229 amdec.getSI(row, col), 6f);
230 }
231 }
232
233
234 FloatAreaMatrix amt5 = am.mutable().multiplyBy(5.0f).immutable();
235 FloatAreaMatrix amd5 = am.mutable().divideBy(5.0f).immutable();
236 FloatAreaMatrix amtd = amt5.mutable().divideBy(5.0f);
237 FloatAreaMatrix amtimD = am.times(5.0d);
238 FloatAreaMatrix amtimF = am.times(5.0f);
239 FloatAreaMatrix amdivD = am.divide(5.0d);
240 FloatAreaMatrix 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.5);
247 assertEquals("m * 5.0 = (m*5.0)", au.getScale().toStandardUnit(testData[row][col]) * 5.0f,
248 amt5.getSI(row, col), 50f);
249 assertEquals("m / 5.0 = (m/5.0)", au.getScale().toStandardUnit(testData[row][col]) / 5.0f,
250 amd5.getSI(row, col), 2f);
251 assertEquals("amtimD", amt5.getSI(row, col), amtimD.getSI(row, col), 0.1f);
252 assertEquals("amtimF", amt5.getSI(row, col), amtimF.getSI(row, col), 0.1f);
253 assertEquals("amdivD", amd5.getSI(row, col), amdivD.getSI(row, col), 0.01f);
254 assertEquals("amdivD", amd5.getSI(row, col), amdivF.getSI(row, col), 0.01f);
255 }
256 }
257
258
259 assertEquals("get()", new FloatArea(testData[2][2], au), am.get(2, 2));
260 assertEquals("getSI()", au.getScale().toStandardUnit(testData[2][2]), am.getSI(2, 2), 1f);
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), 10f);
265
266
267 FloatArea fasqft = new FloatArea(10.5f, AreaUnit.SQUARE_FOOT);
268 FloatAreaMatrix famChange = am.clone().mutable();
269 famChange.set(2, 2, fasqft);
270 assertEquals("set()", fasqft.si, famChange.get(2, 2).si, 0.1f);
271 famChange = am.clone().mutable();
272 famChange.setSI(2, 2, 123.4f);
273 assertEquals("setSI()", 123.4f, famChange.get(2, 2).si, 0.1f);
274 famChange = am.clone().mutable();
275 famChange.setInUnit(2, 2, 1.2f);
276 assertEquals("setInUnit()", 1.2f, famChange.getInUnit(2, 2), 0.1f);
277 famChange = am.clone().mutable();
278 famChange.setInUnit(2, 2, 1.5f, AreaUnit.HECTARE);
279 assertEquals("setInUnit(unit)", 15000.0f, famChange.get(2, 2).si, 1.0f);
280
281
282 float[][] squareData = storageType.equals(StorageType.DENSE) ? FLOATMATRIX.denseRectArrays(12, 12)
283 : FLOATMATRIX.sparseRectArrays(12, 12);
284 FloatAreaMatrix amSquare =
285 FloatMatrix.instantiate(FloatMatrixData.instantiate(squareData, au.getScale(), storageType), au);
286 float[] row2si = am.getRowSI(2);
287 float[] col2si = am.getColumnSI(2);
288 float[] diagsi = amSquare.getDiagonalSI();
289 FloatAreaVector row2v = am.getRow(2);
290 FloatAreaVector col2v = am.getColumn(2);
291 FloatAreaVector diagv = amSquare.getDiagonal();
292 FloatArea[] row2scalar = am.getRowScalars(2);
293 FloatArea[] col2scalar = am.getColumnScalars(2);
294 FloatArea[] 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], 10f);
298 assertEquals("row2v", au.getScale().toStandardUnit(testData[2][col]), row2v.getSI(col), 10f);
299 assertEquals("row2scalar", au.getScale().toStandardUnit(testData[2][col]), row2scalar[col].si, 10f);
300 }
301 for (int row = 0; row < testData.length; row++)
302 {
303 assertEquals("col2si", au.getScale().toStandardUnit(testData[row][2]), col2si[row], 10f);
304 assertEquals("col2v", au.getScale().toStandardUnit(testData[row][2]), col2v.getSI(row), 10f);
305 assertEquals("col2scalar", au.getScale().toStandardUnit(testData[row][2]), col2scalar[row].si, 10f);
306 }
307 for (int diag = 0; diag < amSquare.rows(); diag++)
308 {
309 assertEquals("diag2si", au.getScale().toStandardUnit(squareData[diag][diag]), diagsi[diag], 0.1f);
310 assertEquals("diag2v", au.getScale().toStandardUnit(squareData[diag][diag]), diagv.getSI(diag), 0.1f);
311 assertEquals("diag2scalar", au.getScale().toStandardUnit(squareData[diag][diag]), diagscalar[diag].si,
312 0.1f);
313 }
314
315
316 float[][] valsi = am.getValuesSI();
317 float[][] valunit = am.getValuesInUnit();
318 float[][] valsqft = am.getValuesInUnit(AreaUnit.SQUARE_YARD);
319 FloatArea[][] 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], 5f);
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], 10f);
328 assertEquals("getValuesInUnit(unit)", au.getScale().toStandardUnit(testData[row][col]),
329 valscalars[row][col].si, 5f);
330 }
331 }
332
333
334 FloatAreaMatrix amdiv2 = am.divide(2.0f);
335 assertEquals(am.getStorageType(), amdiv2.getStorageType());
336 assertEquals(am.getDisplayUnit(), amdiv2.getDisplayUnit());
337 FloatAreaMatrix amAbs = amdiv2.mutable().abs().immutable();
338 assertEquals(am.getStorageType(), amAbs.getStorageType());
339 assertEquals(am.getDisplayUnit(), amAbs.getDisplayUnit());
340 FloatAreaMatrix amCeil = amdiv2.mutable().ceil().immutable();
341 assertEquals(am.getStorageType(), amCeil.getStorageType());
342 assertEquals(am.getDisplayUnit(), amCeil.getDisplayUnit());
343 FloatAreaMatrix amFloor = amdiv2.mutable().floor().immutable();
344 assertEquals(am.getStorageType(), amFloor.getStorageType());
345 assertEquals(am.getDisplayUnit(), amFloor.getDisplayUnit());
346 FloatAreaMatrix amNeg = amdiv2.mutable().neg().immutable();
347 assertEquals(am.getStorageType(), amNeg.getStorageType());
348 assertEquals(am.getDisplayUnit(), amNeg.getDisplayUnit());
349 FloatAreaMatrix 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.0f, amdiv2.getSI(row, col),
358 5f);
359 assertEquals("abs", (float) Math.abs(au.getScale().toStandardUnit(testData[row][col]) / 2.0f),
360 amAbs.getSI(row, col), 0.1f);
361 assertEquals("ceil", (float) Math.ceil(au.getScale().toStandardUnit(testData[row][col]) / 2.0f),
362 amCeil.getSI(row, col), 5f);
363 assertEquals("floor", (float) Math.floor(au.getScale().toStandardUnit(testData[row][col]) / 2.0f),
364 amFloor.getSI(row, col), 5f);
365 assertEquals("neg", -au.getScale().toStandardUnit(testData[row][col]) / 2.0f, amNeg.getSI(row, col),
366 5f);
367 assertEquals("rint", (float) Math.rint(au.getScale().toStandardUnit(testData[row][col]) / 2.0f),
368 amRint.getSI(row, col), 5f);
369 }
370 }
371
372 float[][] testData4x4 =
373 new float[][] { { 2, 3, 5, 7 }, { 11, 13, 17, 19 }, { 23, 29, 31, 37 }, { 41, 43, 47, 49 } };
374 FloatAreaMatrix am4x4 =
375 FloatMatrix.instantiate(FloatMatrixData.instantiate(testData4x4, au.getScale(), storageType), au);
376 float det = am4x4.determinant();
377 float detCalc = Determinant.det(am4x4.getValuesSI());
378 float err = Math.max(det, detCalc) / 1000.0f;
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 float 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 float[][] testData2 = storageType2.equals(StorageType.DENSE) ? denseTestData : reverseSparseTestData;
396 for (AreaUnit au2 : new AreaUnit[] { AreaUnit.SQUARE_METER, AreaUnit.ACRE })
397 {
398
399
400 FloatAreaMatrix am2 = FloatMatrix
401 .instantiate(FloatMatrixData.instantiate(testData2, au2.getScale(), storageType2), au2);
402 FloatAreaMatrix amSum1 = am.plus(am2);
403 FloatAreaMatrix amSum2 = am2.plus(am);
404 FloatAreaMatrix amSum3 = am.mutable().incrementBy(am2).immutable();
405 FloatAreaMatrix 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 float tolerance = Float.isFinite(amSum1.getSI(row, col))
414 ? Math.abs(amSum1.getSI(row, col) / 10000.0f) : 0.1f;
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 FloatAreaMatrix amDiff1 = am.minus(am2);
424 FloatAreaMatrix amDiff2 = am2.minus(am).mutable().neg();
425 FloatAreaMatrix 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 float tolerance = Float.isFinite(amDiff1.getSI(row, col))
433 ? Math.abs(amDiff1.getSI(row, col) / 10000.0f) : 0.1f;
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 FloatSIMatrix amTim = am.times(am2);
443 FloatSIMatrix 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 float tolerance = Float.isFinite(amTim.getSI(row, col))
453 ? Math.abs(amTim.getSI(row, col) / 10000.0f) : 0.1f;
454 assertEquals("value in m2 * m2 matches",
455 au.getScale().toStandardUnit(testData[row][col])
456 * au2.getScale().toStandardUnit(testData2[row][col]),
457 amTim.getSI(row, col), tolerance);
458 tolerance = Float.isFinite(amTim.getSI(row, col)) ? Math.abs(amDiv.getSI(row, col) / 10000.0f)
459 : 0.1f;
460 assertEquals("value in m2 / m2 matches (could be NaN)",
461 au.getScale().toStandardUnit(testData[row][col])
462 / au2.getScale().toStandardUnit(testData2[row][col]),
463 amDiv.getSI(row, col), tolerance);
464 }
465 }
466 }
467 }
468 }
469 }
470 }
471
472
473
474
475 @Test
476 public void testImmutableMatrix()
477 {
478 float[][] denseTestData = FLOATMATRIX.denseRectArrays(5, 10);
479 float[][] sparseTestData = FLOATMATRIX.sparseRectArrays(5, 10);
480
481 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
482 {
483 for (AreaUnit au : new AreaUnit[] { AreaUnit.SQUARE_METER, AreaUnit.ACRE })
484 {
485 float[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
486 FloatAreaMatrix am =
487 FloatMatrix.instantiate(FloatMatrixData.instantiate(testData, au.getScale(), storageType), au);
488 am = am.immutable();
489 final FloatAreaMatrix amPtr = am;
490 FloatArea fa = FloatArea.of(10.0f, "m^2");
491 new Try()
492 {
493 @Override
494 public void execute()
495 {
496 amPtr.assign(FloatMathFunctions.ABS);
497 }
498 }.test("ImmutableMatrix.assign(...) should throw error");
499 new Try()
500 {
501 @Override
502 public void execute()
503 {
504 amPtr.decrementBy(fa);
505 }
506 }.test("ImmutableMatrix.decrementBy(scalar) should throw error");
507 new Try()
508 {
509 @Override
510 public void execute()
511 {
512 amPtr.decrementBy(amPtr);
513 }
514 }.test("ImmutableMatrix.decrementBy(matrix) should throw error");
515 new Try()
516 {
517 @Override
518 public void execute()
519 {
520 amPtr.incrementBy(fa);
521 }
522 }.test("ImmutableMatrix.incrementBy(scalar) should throw error");
523 new Try()
524 {
525 @Override
526 public void execute()
527 {
528 amPtr.incrementBy(amPtr);
529 }
530 }.test("ImmutableMatrix.incrementBy(matrix) should throw error");
531 new Try()
532 {
533 @Override
534 public void execute()
535 {
536 amPtr.divideBy(2.0f);
537 }
538 }.test("ImmutableMatrix.divideBy(factor) should throw error");
539 new Try()
540 {
541 @Override
542 public void execute()
543 {
544 amPtr.multiplyBy(2.0f);
545 }
546 }.test("ImmutableMatrix.multiplyBy(factor) should throw error");
547 new Try()
548 {
549 @Override
550 public void execute()
551 {
552 amPtr.set(1, 1, fa);
553 }
554 }.test("ImmutableMatrix.set() should throw error");
555 new Try()
556 {
557 @Override
558 public void execute()
559 {
560 amPtr.setSI(1, 1, 20.1f);
561 }
562 }.test("ImmutableMatrix.setSI() should throw error");
563 new Try()
564 {
565 @Override
566 public void execute()
567 {
568 amPtr.setInUnit(1, 1, 15.2f);
569 }
570 }.test("ImmutableMatrix.setInUnit(f) should throw error");
571 new Try()
572 {
573 @Override
574 public void execute()
575 {
576 amPtr.setInUnit(1, 1, 15.2f, AreaUnit.ARE);
577 }
578 }.test("ImmutableMatrix.setInUnit(f, u) should throw error");
579 new Try()
580 {
581 @Override
582 public void execute()
583 {
584 amPtr.abs();
585 }
586 }.test("ImmutableMatrix.abs() should throw error");
587 new Try()
588 {
589 @Override
590 public void execute()
591 {
592 amPtr.ceil();
593 }
594 }.test("ImmutableMatrix.ceil() should throw error");
595 new Try()
596 {
597 @Override
598 public void execute()
599 {
600 amPtr.floor();
601 }
602 }.test("ImmutableMatrix.floor() should throw error");
603 new Try()
604 {
605 @Override
606 public void execute()
607 {
608 amPtr.neg();
609 }
610 }.test("ImmutableMatrix.neg() should throw error");
611 new Try()
612 {
613 @Override
614 public void execute()
615 {
616 amPtr.rint();
617 }
618 }.test("ImmutableMatrix.rint() should throw error");
619 }
620 }
621 }
622
623
624
625
626 @Test
627 public void testMatrixToString()
628 {
629 float[][] denseTestData = FLOATMATRIX.denseRectArrays(5, 10);
630 float[][] sparseTestData = FLOATMATRIX.sparseRectArrays(5, 10);
631
632 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
633 {
634 for (AreaUnit au : new AreaUnit[] { AreaUnit.SQUARE_METER, AreaUnit.ACRE })
635 {
636 float[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
637 FloatAreaMatrix am =
638 FloatMatrix.instantiate(FloatMatrixData.instantiate(testData, au.getScale(), storageType), au);
639 String s1 = am.toString();
640 assertTrue(s1.contains(au.getDefaultTextualAbbreviation()));
641 String s2 = am.toString(AreaUnit.SQUARE_INCH);
642 assertTrue(s2.contains(AreaUnit.SQUARE_INCH.getDefaultTextualAbbreviation()));
643 String s3 = am.toString(AreaUnit.SQUARE_INCH, true, true);
644 assertTrue(s3.contains(AreaUnit.SQUARE_INCH.getDefaultTextualAbbreviation()));
645 if (storageType.equals(StorageType.DENSE))
646 {
647 assertTrue(s3.contains("Dense"));
648 assertFalse(s3.contains("Sparse"));
649 }
650 else
651 {
652 assertFalse(s3.contains("Dense"));
653 assertTrue(s3.contains("Sparse"));
654 }
655 assertTrue(s3.contains("Rel"));
656 assertFalse(s3.contains("Abs"));
657 assertTrue(s3.contains("Immutable"));
658 assertFalse(s3.contains("Mutable"));
659 FloatAreaMatrix ammut = am.mutable();
660 String smut = ammut.toString(AreaUnit.SQUARE_INCH, true, true);
661 assertFalse(smut.contains("Immutable"));
662 assertTrue(smut.contains("Mutable"));
663 String sNotVerbose = ammut.toString(false, false);
664 assertFalse(sNotVerbose.contains("Rel"));
665 assertFalse(sNotVerbose.contains("Abs"));
666 assertFalse(sNotVerbose.contains("Immutable"));
667 assertFalse(sNotVerbose.contains("Mutable"));
668 assertFalse(sNotVerbose.contains(au.getDefaultTextualAbbreviation()));
669 }
670 }
671 FloatTimeMatrix tm = FloatMatrix.instantiate(
672 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
673 String st = tm.toString(TimeUnit.DEFAULT, true, true);
674 assertFalse(st.contains("Rel"));
675 assertTrue(st.contains("Abs"));
676 FloatLengthMatrix lm = FloatMatrix.instantiate(
677 FloatMatrixData.instantiate(denseTestData, LengthUnit.SI.getScale(), StorageType.DENSE), LengthUnit.SI);
678 String sl = lm.toString(LengthUnit.SI, true, true);
679 assertTrue(sl.contains("Rel"));
680 assertFalse(sl.contains("Abs"));
681 }
682
683
684
685
686 @Test
687 public void testSpecialMatrixMethodsRelWithAbs()
688 {
689 float[][] denseTestData = FLOATMATRIX.denseRectArrays(5, 10);
690 FloatTimeMatrix tm = FloatMatrix.instantiate(
691 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
692 FloatDurationMatrix dm = FloatMatrix.instantiate(
693 FloatMatrixData.instantiate(denseTestData, DurationUnit.MINUTE.getScale(), StorageType.DENSE),
694 DurationUnit.SECOND);
695 assertTrue(tm.isAbsolute());
696 assertFalse(dm.isAbsolute());
697 assertFalse(tm.isRelative());
698 assertTrue(dm.isRelative());
699
700 FloatTimeMatrix absPlusRel = tm.plus(dm);
701 FloatTimeMatrix absMinusRel = tm.minus(dm);
702 float[][] halfDenseData = FLOATMATRIX.denseRectArrays(5, 10);
703 for (int row = 0; row < halfDenseData.length; row++)
704 {
705 for (int col = 0; col < halfDenseData[row].length; col++)
706 {
707 halfDenseData[row][col] *= 0.5;
708 }
709 }
710 FloatTimeMatrix halfTimeMatrix = FloatMatrix.instantiate(
711 FloatMatrixData.instantiate(halfDenseData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
712 FloatDurationMatrix absMinusAbs = tm.minus(halfTimeMatrix);
713 FloatTimeMatrix absDecByRelS = tm.mutable().decrementBy(FloatDuration.of(1.0f, "min"));
714 FloatTimeMatrix absDecByRelM = tm.mutable().decrementBy(dm.divide(2.0f));
715 FloatTimeMatrix relPlusAbs = dm.plus(tm);
716 for (int row = 0; row < denseTestData.length; row++)
717 {
718 for (int col = 0; col < denseTestData[0].length; col++)
719 {
720 assertEquals("absPlusRel", 61.0 * denseTestData[row][col], absPlusRel.getSI(row, col), 0.01);
721 assertEquals("absMinusRel", -59.0 * denseTestData[row][col], absMinusRel.getSI(row, col), 0.01);
722 assertEquals("absMinusAbs", denseTestData[row][col] / 2.0, absMinusAbs.getSI(row, col), 0.01);
723 assertEquals("absDecByRelS", denseTestData[row][col] - 60.0, absDecByRelS.getSI(row, col), 0.01);
724 assertEquals("absDecByRelM", -29.0 * denseTestData[row][col], absDecByRelM.getSI(row, col), 0.01);
725 assertEquals("relPlusAbs", 61.0 * denseTestData[row][col], relPlusAbs.getSI(row, col), 0.01);
726 }
727 }
728 for (int dRows : new int[] { -1, 0, 1 })
729 {
730 for (int dCols : new int[] { -1, 0, 1 })
731 {
732 if (dRows == 0 && dCols == 0)
733 {
734 continue;
735 }
736 float[][] other = FLOATMATRIX.denseRectArrays(denseTestData.length + dRows, denseTestData[0].length + dCols);
737 FloatTimeMatrix wrongTimeMatrix = FloatMatrix.instantiate(
738 FloatMatrixData.instantiate(other, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
739 try
740 {
741 tm.mutable().minus(wrongTimeMatrix);
742 fail("Mismatching size should have thrown a ValueRuntimeException");
743 }
744 catch (ValueRuntimeException vre)
745 {
746
747 }
748 }
749 }
750 assertTrue("toString returns something informative",
751 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE).toString()
752 .startsWith("FloatMatrixData"));
753 }
754
755
756
757
758
759 @Test
760 public void memoryTest()
761 {
762 AreaMatrix am = DoubleMatrix.instantiate(new double[5][10], AreaUnit.SI, StorageType.SPARSE);
763 am = am.mutable();
764 double nonZeroValue = 123.456;
765
766 for (int compoundIndex = 0; compoundIndex < am.cols() * am.rows(); compoundIndex++)
767 {
768
769 int row = compoundIndex % am.rows();
770 int col = compoundIndex / am.rows();
771 assertEquals("initial value is 0", 0d, am.getSI(row, col), 0.0001);
772 am.setSI(row, col, nonZeroValue);
773 assertEquals("current value is nonZero", nonZeroValue, am.getSI(row, col), 0.0001);
774 }
775 for (int compoundIndex = am.cols() * am.rows(); --compoundIndex >= 0;)
776 {
777
778 int row = compoundIndex % am.rows();
779 int col = compoundIndex / am.rows();
780 assertEquals("current value is nonZero", nonZeroValue, am.getSI(row, col), 0.0001);
781 am.setSI(row, col, 0d);
782 assertEquals("final value is 0", 0d, am.getSI(row, col), 0.0001);
783 }
784 }
785
786
787
788
789 @Test
790 public void testInstantiateAbs()
791 {
792 float[][] denseTestData = FLOATMATRIX.denseRectArrays(10, 20);
793 FloatTimeMatrix timeMatrix = FloatMatrix.instantiate(
794 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
795 FloatDurationMatrix durationMatrix = FloatMatrix.instantiate(
796 FloatMatrixData.instantiate(denseTestData, DurationUnit.MINUTE.getScale(), StorageType.DENSE),
797 DurationUnit.SECOND);
798
799 float[] halfDenseData = FLOATVECTOR.denseArray(105);
800 for (int index = 0; index < halfDenseData.length; index++)
801 {
802 halfDenseData[index] *= 0.5;
803 }
804 FloatTimeMatrix relPlusAbsTime = durationMatrix.plus(timeMatrix);
805 for (int row = 0; row < denseTestData.length; row++)
806 {
807 for (int col = 0; col < denseTestData[0].length; col++)
808 {
809 assertEquals("relPlusAbsTime", 61.0 * denseTestData[row][col], relPlusAbsTime.getSI(row, col), 0.01);
810 }
811 }
812 FloatTime floatTime = durationMatrix.instantiateScalarAbsSI(123.456f, TimeUnit.EPOCH_DAY);
813 assertEquals("Unit of instantiateScalarAbsSI matches", TimeUnit.EPOCH_DAY, floatTime.getDisplayUnit());
814 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatTime.si, 0.1);
815
816 FloatAngleMatrix angleMatrix = FloatMatrix.instantiate(
817 FloatMatrixData.instantiate(denseTestData, AngleUnit.DEGREE.getScale(), StorageType.DENSE), AngleUnit.DEGREE);
818 FloatDirectionMatrix directionMatrix = FloatMatrix.instantiate(
819 FloatMatrixData.instantiate(denseTestData, DirectionUnit.EAST_DEGREE.getScale(), StorageType.DENSE),
820 DirectionUnit.EAST_DEGREE);
821
822 FloatDirectionMatrix relPlusAbsDirection = angleMatrix.plus(directionMatrix);
823 for (int row = 0; row < denseTestData.length; row++)
824 {
825 for (int col = 0; col < denseTestData[0].length; col++)
826 {
827 assertEquals("relPlusAbsTime", 2.0 / 180 * Math.PI * denseTestData[row][col],
828 relPlusAbsDirection.getSI(row, col), 0.01);
829 }
830 }
831 FloatDirection floatDirection = angleMatrix.instantiateScalarAbsSI(123.456f, DirectionUnit.NORTH_RADIAN);
832 assertEquals("Unit of instantiateScalarAbsSI matches", DirectionUnit.NORTH_RADIAN, floatDirection.getDisplayUnit());
833 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatDirection.si, 0.1);
834
835 FloatTemperatureMatrix temperatureMatrix = FloatMatrix.instantiate(
836 FloatMatrixData.instantiate(denseTestData, TemperatureUnit.DEGREE_FAHRENHEIT.getScale(), StorageType.DENSE),
837 TemperatureUnit.DEGREE_FAHRENHEIT);
838 FloatAbsoluteTemperatureMatrix absoluteTemperatureMatrix = FloatMatrix.instantiate(
839 FloatMatrixData.instantiate(denseTestData, AbsoluteTemperatureUnit.KELVIN.getScale(), StorageType.DENSE),
840 AbsoluteTemperatureUnit.KELVIN);
841
842 FloatAbsoluteTemperatureMatrix relPlusAbsTemperature = temperatureMatrix.plus(absoluteTemperatureMatrix);
843 for (int row = 0; row < denseTestData.length; row++)
844 {
845 for (int col = 0; col < denseTestData[0].length; col++)
846 {
847 assertEquals("relPlusAbsTime", (1.0 + 5.0 / 9.0) * denseTestData[row][col],
848 relPlusAbsTemperature.getSI(row, col), 0.01);
849 }
850 }
851 FloatAbsoluteTemperature floatAbsoluteTemperature =
852 temperatureMatrix.instantiateScalarAbsSI(123.456f, AbsoluteTemperatureUnit.DEGREE_FAHRENHEIT);
853 assertEquals("Unit of instantiateScalarAbsSI matches", AbsoluteTemperatureUnit.DEGREE_FAHRENHEIT,
854 floatAbsoluteTemperature.getDisplayUnit());
855 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatAbsoluteTemperature.si, 0.1);
856
857 FloatLengthMatrix lengthMatrix = FloatMatrix.instantiate(
858 FloatMatrixData.instantiate(denseTestData, LengthUnit.MILE.getScale(), StorageType.DENSE), LengthUnit.MILE);
859 FloatPositionMatrix positionMatrix = FloatMatrix.instantiate(
860 FloatMatrixData.instantiate(denseTestData, PositionUnit.KILOMETER.getScale(), StorageType.DENSE),
861 PositionUnit.KILOMETER);
862
863 FloatPositionMatrix relPlusAbsPosition = lengthMatrix.plus(positionMatrix);
864 for (int row = 0; row < denseTestData.length; row++)
865 {
866 for (int col = 0; col < denseTestData[0].length; col++)
867 {
868 assertEquals("relPlusAbsTime", 2609.344 * denseTestData[row][col], relPlusAbsPosition.getSI(row, col), 0.1);
869 }
870 }
871 FloatPosition floatPosition = lengthMatrix.instantiateScalarAbsSI(123.456f, PositionUnit.ANGSTROM);
872 assertEquals("Unit of instantiateScalarAbsSI matches", PositionUnit.ANGSTROM, floatPosition.getDisplayUnit());
873 assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatPosition.si, 0.1);
874 }
875
876
877
878
879
880
881
882
883
884
885
886
887 @SuppressWarnings("unchecked")
888 @Test
889 public <U extends Unit<U>> void testAsUnit() throws ClassNotFoundException, NoSuchMethodException, SecurityException,
890 IllegalAccessException, IllegalArgumentException, InvocationTargetException, UnitException
891 {
892 float[][] testValues = FLOATMATRIX.denseRectArrays(10, 20);
893 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
894 {
895 for (String type : CLASSNAMES.REL_LIST)
896 {
897 Class.forName("org.djunits.unit." + type + "Unit");
898 Quantity<U> quantity = (Quantity<U>) Quantities.INSTANCE.getQuantity(type + "Unit");
899 for (U unit : quantity.getUnitsById().values())
900 {
901 for (StorageType storageType2 : new StorageType[] { StorageType.DENSE, storageType })
902 {
903 SIUnit siUnit = SIUnit.of(unit.getQuantity().getSiDimensions());
904 FloatSIMatrix matrix = FloatSIMatrix.instantiate(testValues, siUnit, storageType2);
905 Method asMethod = FloatSIMatrix.class.getDeclaredMethod("as", Unit.class);
906 AbstractFloatMatrixRel<U, ?, ?, ?> asMatrix =
907 (AbstractFloatMatrixRel<U, ?, ?, ?>) asMethod.invoke(matrix, siUnit);
908 assertEquals(matrix.getDisplayUnit().getStandardUnit(), asMatrix.getDisplayUnit());
909 siUnit = SIUnit.of(AbsoluteTemperatureUnit.KELVIN.getQuantity().getSiDimensions());
910 for (int row = 0; row < testValues.length; row++)
911 {
912 for (int col = 0; col < testValues[0].length; col++)
913 {
914 assertEquals("Values should match", testValues[row][col], matrix.getInUnit(row, col), 0.001);
915 }
916 }
917 try
918 {
919 asMethod.invoke(matrix, siUnit);
920 fail("as method should not be able to cast to unrelated (absoluteTemperature) unit");
921 }
922 catch (InvocationTargetException ite)
923 {
924 Throwable cause = ite.getCause();
925 assertEquals("cause is UnitRuntimeException", UnitRuntimeException.class, cause.getClass());
926
927 }
928 }
929 }
930 }
931 }
932 }
933
934
935
936
937 @SuppressWarnings("unlikely-arg-type")
938 @Test
939 public void testEquals()
940 {
941 float[][] testData = FLOATMATRIX.denseRectArrays(12, 34);
942 testData[2][2] = 0;
943 for (StorageType storageType : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
944 {
945 FloatMatrixData fmd = FloatMatrixData.instantiate(testData, TemperatureUnit.KELVIN.getScale(), storageType);
946 assertTrue("Float matrix is equal to itself", fmd.equals(fmd));
947 assertFalse("Float matrix is not equal to null", fmd.equals(null));
948 assertFalse("Float matrix data is not equal to some string", fmd.equals("some string"));
949 assertTrue("Float matrix is equal to sparse version of itself", fmd.equals(fmd.toSparse()));
950 assertTrue("Float matrix is equal to dense version of itself", fmd.equals(fmd.toDense()));
951 for (StorageType storageType2 : new StorageType[] { StorageType.DENSE, StorageType.SPARSE })
952 {
953 FloatMatrixData dvd2 = FloatMatrixData.instantiate(testData, TemperatureUnit.KELVIN.getScale(), storageType2);
954 assertEquals(
955 "Float matrix data is equal to other double vector containing same values regardless of storage type",
956 fmd, dvd2);
957 float[][] testData2 = FLOATMATRIX.denseRectArrays(12, 33);
958 testData2[2][2] = 0;
959 dvd2 = FloatMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
960 assertFalse("Float matrix data is not equal to other double vector containing same values except last one",
961 fmd.equals(dvd2));
962 testData2 = FLOATMATRIX.denseRectArrays(13, 34);
963 testData2[2][2] = 0;
964 dvd2 = FloatMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
965 assertFalse("Float matrix data is not equal to other double vector containing same values except last one",
966 fmd.equals(dvd2));
967 testData2 = FLOATMATRIX.denseRectArrays(12, 34);
968 dvd2 = FloatMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
969 assertFalse("Float matrix data is not equal to other double vector containing same values except for one zero",
970 fmd.equals(dvd2));
971 }
972 }
973 }
974
975
976
977
978 @SuppressWarnings({ "rawtypes", "unchecked" })
979 @Test
980 public void sparseValueTest()
981 {
982 try
983 {
984 new FloatSparseValue(-1, 0, 123.456f);
985 fail("Negative row should have caused a ValueRuntimeException");
986 }
987 catch (ValueRuntimeException vre)
988 {
989
990 }
991
992 try
993 {
994 new FloatSparseValue(0, -1, 123.456f);
995 fail("Negative column should have caused a ValueRuntimeException");
996 }
997 catch (ValueRuntimeException vre)
998 {
999
1000 }
1001
1002 FloatLength length = FloatLength.valueOf("123 km");
1003 FloatSparseValue dsv = new FloatSparseValue(2, 3, length);
1004 assertEquals("row matches", 2, dsv.getRow());
1005 assertEquals("column matches", 3, dsv.getColumn());
1006 assertEquals("value matches", 123000, dsv.getValueSI(), 0.1);
1007 dsv = new FloatSparseValue(2, 3, 123.000f, LengthUnit.KILOMETER);
1008 assertEquals("row matches", 2, dsv.getRow());
1009 assertEquals("column matches", 3, dsv.getColumn());
1010 assertEquals("value matches", 123000, dsv.getValueSI(), 0.1);
1011 }
1012
1013 }