View Javadoc
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       * Test the standard methods of all matrix classes.
58       * @throws UnitException on error
59       * @throws ValueRuntimeException on error
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          // sparseTestData and reverseSparseTestData should not "run out of values" at the same index
68          for (int index = 0; index < sparseTestData.length; index++)
69          {
70              reverseSparseTestData[reverseSparseTestData.length - 1 - index] = sparseTestData[index];
71          }
72          // Ensure that there are > 50% positions where both have a non-zero value
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                  // INDEX CHECKING
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                                 // Ignore expected exception
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                             // Ignore expected exception
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                             // Ignore expected exception
137                         }
138                     }
139                     else
140                     {
141                         am.getColumn(col);
142                     }
143                 }
144 
145                 // SPARSE AND DENSE
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                 // EQUALS
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                 // MUTABLE
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                 // ZSUM and CARDINALITY
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                 // INCREMENTBY(SCALAR) and DECREMENTBY(SCALAR)
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                 // MULTIPLYBY() and DIVIDEBY(), TIMES(), DIVIDE()
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                 // GET(), GETINUNIT()
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                 // SET(), SETINUNIT()
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                 // GETROW(), GETCOLUMN(), GETDIAGONAL
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                 // GETVALUES(), GETSCALARS()
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                 // ASSIGN FUNCTION ABS, CEIL, FLOOR, NEG, RINT
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                         // TODO: Should be rounded IN THE UNIT rather than BY SI VALUES
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 = new float[][] {{2, 3, 5, 7}, {11, 13, 17, 19}, {23, 29, 31, 37}, {41, 43, 47, 49}};
373                 FloatAreaMatrix am4x4 =
374                         FloatMatrix.instantiate(FloatMatrixData.instantiate(testData4x4, au.getScale(), storageType), au);
375                 float det = am4x4.determinant();
376                 float detCalc = Determinant.det(am4x4.getValuesSI());
377                 float err = Math.max(det, detCalc) / 1000.0f;
378                 assertEquals("Determinant of square matrix with unit " + au.getDefaultTextualAbbreviation() + ", storage = "
379                         + storageType + " = " + det + " but should have been " + detCalc, detCalc, det, err);
380                 new Try()
381                 {
382                     @Override
383                     public void execute()
384                     {
385                         float detErr = am.determinant();
386                         System.out.println(detErr);
387                     }
388                 }.test("Determinant of non-square matrix should have thrown exception");
389 
390                 // TEST METHODS THAT INVOLVE TWO MATRIX INSTANCES
391 
392                 for (StorageType storageType2 : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
393                 {
394                     float[][] testData2 = storageType2.equals(StorageType.DENSE) ? denseTestData : reverseSparseTestData;
395                     for (AreaUnit au2 : new AreaUnit[] {AreaUnit.SQUARE_METER, AreaUnit.ACRE})
396                     {
397 
398                         // PLUS and INCREMENTBY(MATRIX)
399                         FloatAreaMatrix am2 = FloatMatrix
400                                 .instantiate(FloatMatrixData.instantiate(testData2, au2.getScale(), storageType2), au2);
401                         FloatAreaMatrix amSum1 = am.plus(am2);
402                         FloatAreaMatrix amSum2 = am2.plus(am);
403                         FloatAreaMatrix amSum3 = am.mutable().incrementBy(am2).immutable();
404                         FloatAreaMatrix amSum4 = am2.mutable().incrementBy(am).immutable();
405                         assertEquals("a+b == b+a", amSum1, amSum2);
406                         assertEquals("a+b == b+a", amSum1, amSum3);
407                         assertEquals("a+b == b+a", amSum1, amSum4);
408                         for (int row = 0; row < testData.length; row++)
409                         {
410                             for (int col = 0; col < testData[0].length; col++)
411                             {
412                                 float tolerance = Float.isFinite(amSum1.getSI(row, col))
413                                         ? Math.abs(amSum1.getSI(row, col) / 10000.0f) : 0.1f;
414                                 assertEquals("value in matrix matches",
415                                         au.getScale().toStandardUnit(testData[row][col])
416                                                 + au2.getScale().toStandardUnit(testData2[row][col]),
417                                         amSum1.getSI(row, col), tolerance);
418                             }
419                         }
420 
421                         // MINUS and DECREMENTBY(MATRIX)
422                         FloatAreaMatrix amDiff1 = am.minus(am2);
423                         FloatAreaMatrix amDiff2 = am2.minus(am).mutable().neg();
424                         FloatAreaMatrix amDiff3 = am.mutable().decrementBy(am2).immutable();
425                         assertEquals("a-b == -(b-a)", amDiff1, amDiff2);
426                         assertEquals("a-b == -(b-a)", amDiff1, amDiff3);
427                         for (int row = 0; row < testData.length; row++)
428                         {
429                             for (int col = 0; col < testData[0].length; col++)
430                             {
431                                 float tolerance = Float.isFinite(amDiff1.getSI(row, col))
432                                         ? Math.abs(amDiff1.getSI(row, col) / 10000.0f) : 0.1f;
433                                 assertEquals("value in matrix matches",
434                                         au.getScale().toStandardUnit(testData[row][col])
435                                                 - au2.getScale().toStandardUnit(testData2[row][col]),
436                                         amDiff1.getSI(row, col), tolerance);
437                             }
438                         }
439 
440                         // TIMES(MATRIX) and DIVIDE(MATRIX)
441                         FloatSIMatrix amTim = am.times(am2);
442                         FloatSIMatrix amDiv = am.divide(am2);
443                         assertEquals("unit of m2 * m2 should be m4", "m4",
444                                 amTim.getDisplayUnit().getQuantity().getSiDimensions().toString(false, false, false));
445                         assertEquals("unit of m2 / m2 should be 1", "1",
446                                 amDiv.getDisplayUnit().getQuantity().getSiDimensions().toString(false, false, false));
447                         for (int row = 0; row < testData.length; row++)
448                         {
449                             for (int col = 0; col < testData[0].length; col++)
450                             {
451                                 float tolerance = Float.isFinite(amTim.getSI(row, col))
452                                         ? Math.abs(amTim.getSI(row, col) / 10000.0f) : 0.1f;
453                                 assertEquals("value in m2 * m2 matches",
454                                         au.getScale().toStandardUnit(testData[row][col])
455                                                 * au2.getScale().toStandardUnit(testData2[row][col]),
456                                         amTim.getSI(row, col), tolerance);
457                                 tolerance = Float.isFinite(amTim.getSI(row, col)) ? Math.abs(amDiv.getSI(row, col) / 10000.0f)
458                                         : 0.1f;
459                                 assertEquals("value in m2 / m2 matches (could be NaN)",
460                                         au.getScale().toStandardUnit(testData[row][col])
461                                                 / au2.getScale().toStandardUnit(testData2[row][col]),
462                                         amDiv.getSI(row, col), tolerance);
463                             }
464                         }
465                     }
466                 }
467             }
468         }
469     }
470 
471     /**
472      * Test if mutable methods give an error in case the matrix is immutable.
473      */
474     @Test
475     public void testImmutableMatrix()
476     {
477         float[][] denseTestData = FLOATMATRIX.denseRectArrays(5, 10);
478         float[][] sparseTestData = FLOATMATRIX.sparseRectArrays(5, 10);
479 
480         for (StorageType storageType : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
481         {
482             for (AreaUnit au : new AreaUnit[] {AreaUnit.SQUARE_METER, AreaUnit.ACRE})
483             {
484                 float[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
485                 FloatAreaMatrix am =
486                         FloatMatrix.instantiate(FloatMatrixData.instantiate(testData, au.getScale(), storageType), au);
487                 am = am.immutable();
488                 final FloatAreaMatrix amPtr = am;
489                 FloatArea fa = FloatArea.of(10.0f, "m^2");
490                 new Try()
491                 {
492                     @Override
493                     public void execute()
494                     {
495                         amPtr.assign(FloatMathFunctions.ABS);
496                     }
497                 }.test("ImmutableMatrix.assign(...) should throw error");
498                 new Try()
499                 {
500                     @Override
501                     public void execute()
502                     {
503                         amPtr.decrementBy(fa);
504                     }
505                 }.test("ImmutableMatrix.decrementBy(scalar) should throw error");
506                 new Try()
507                 {
508                     @Override
509                     public void execute()
510                     {
511                         amPtr.decrementBy(amPtr);
512                     }
513                 }.test("ImmutableMatrix.decrementBy(matrix) should throw error");
514                 new Try()
515                 {
516                     @Override
517                     public void execute()
518                     {
519                         amPtr.incrementBy(fa);
520                     }
521                 }.test("ImmutableMatrix.incrementBy(scalar) should throw error");
522                 new Try()
523                 {
524                     @Override
525                     public void execute()
526                     {
527                         amPtr.incrementBy(amPtr);
528                     }
529                 }.test("ImmutableMatrix.incrementBy(matrix) should throw error");
530                 new Try()
531                 {
532                     @Override
533                     public void execute()
534                     {
535                         amPtr.divideBy(2.0f);
536                     }
537                 }.test("ImmutableMatrix.divideBy(factor) should throw error");
538                 new Try()
539                 {
540                     @Override
541                     public void execute()
542                     {
543                         amPtr.multiplyBy(2.0f);
544                     }
545                 }.test("ImmutableMatrix.multiplyBy(factor) should throw error");
546                 new Try()
547                 {
548                     @Override
549                     public void execute()
550                     {
551                         amPtr.set(1, 1, fa);
552                     }
553                 }.test("ImmutableMatrix.set() should throw error");
554                 new Try()
555                 {
556                     @Override
557                     public void execute()
558                     {
559                         amPtr.setSI(1, 1, 20.1f);
560                     }
561                 }.test("ImmutableMatrix.setSI() should throw error");
562                 new Try()
563                 {
564                     @Override
565                     public void execute()
566                     {
567                         amPtr.setInUnit(1, 1, 15.2f);
568                     }
569                 }.test("ImmutableMatrix.setInUnit(f) should throw error");
570                 new Try()
571                 {
572                     @Override
573                     public void execute()
574                     {
575                         amPtr.setInUnit(1, 1, 15.2f, AreaUnit.ARE);
576                     }
577                 }.test("ImmutableMatrix.setInUnit(f, u) should throw error");
578                 new Try()
579                 {
580                     @Override
581                     public void execute()
582                     {
583                         amPtr.abs();
584                     }
585                 }.test("ImmutableMatrix.abs() should throw error");
586                 new Try()
587                 {
588                     @Override
589                     public void execute()
590                     {
591                         amPtr.ceil();
592                     }
593                 }.test("ImmutableMatrix.ceil() should throw error");
594                 new Try()
595                 {
596                     @Override
597                     public void execute()
598                     {
599                         amPtr.floor();
600                     }
601                 }.test("ImmutableMatrix.floor() should throw error");
602                 new Try()
603                 {
604                     @Override
605                     public void execute()
606                     {
607                         amPtr.neg();
608                     }
609                 }.test("ImmutableMatrix.neg() should throw error");
610                 new Try()
611                 {
612                     @Override
613                     public void execute()
614                     {
615                         amPtr.rint();
616                     }
617                 }.test("ImmutableMatrix.rint() should throw error");
618             }
619         }
620     }
621 
622     /**
623      * Test toString() methods. TODO: expand?
624      */
625     @Test
626     public void testMatrixToString()
627     {
628         float[][] denseTestData = FLOATMATRIX.denseRectArrays(5, 10);
629         float[][] sparseTestData = FLOATMATRIX.sparseRectArrays(5, 10);
630 
631         for (StorageType storageType : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
632         {
633             for (AreaUnit au : new AreaUnit[] {AreaUnit.SQUARE_METER, AreaUnit.ACRE})
634             {
635                 float[][] testData = storageType.equals(StorageType.DENSE) ? denseTestData : sparseTestData;
636                 FloatAreaMatrix am =
637                         FloatMatrix.instantiate(FloatMatrixData.instantiate(testData, au.getScale(), storageType), au);
638                 String s1 = am.toString(); // non-verbose with unit
639                 assertTrue(s1.contains(au.getDefaultTextualAbbreviation()));
640                 String s2 = am.toString(AreaUnit.SQUARE_INCH); // non-verbose with unit
641                 assertTrue(s2.contains(AreaUnit.SQUARE_INCH.getDefaultTextualAbbreviation()));
642                 String s3 = am.toString(AreaUnit.SQUARE_INCH, true, true); // verbose with unit
643                 assertTrue(s3.contains(AreaUnit.SQUARE_INCH.getDefaultTextualAbbreviation()));
644                 if (storageType.equals(StorageType.DENSE))
645                 {
646                     assertTrue(s3.contains("Dense"));
647                     assertFalse(s3.contains("Sparse"));
648                 }
649                 else
650                 {
651                     assertFalse(s3.contains("Dense"));
652                     assertTrue(s3.contains("Sparse"));
653                 }
654                 assertTrue(s3.contains("Rel"));
655                 assertFalse(s3.contains("Abs"));
656                 assertTrue(s3.contains("Immutable"));
657                 assertFalse(s3.contains("Mutable"));
658                 FloatAreaMatrix ammut = am.mutable();
659                 String smut = ammut.toString(AreaUnit.SQUARE_INCH, true, true); // verbose with unit
660                 assertFalse(smut.contains("Immutable"));
661                 assertTrue(smut.contains("Mutable"));
662                 String sNotVerbose = ammut.toString(false, false);
663                 assertFalse(sNotVerbose.contains("Rel"));
664                 assertFalse(sNotVerbose.contains("Abs"));
665                 assertFalse(sNotVerbose.contains("Immutable"));
666                 assertFalse(sNotVerbose.contains("Mutable"));
667                 assertFalse(sNotVerbose.contains(au.getDefaultTextualAbbreviation()));
668             }
669         }
670         FloatTimeMatrix tm = FloatMatrix.instantiate(
671                 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
672         String st = tm.toString(TimeUnit.DEFAULT, true, true); // verbose with unit
673         assertFalse(st.contains("Rel"));
674         assertTrue(st.contains("Abs"));
675         FloatLengthMatrix lm = FloatMatrix.instantiate(
676                 FloatMatrixData.instantiate(denseTestData, LengthUnit.SI.getScale(), StorageType.DENSE), LengthUnit.SI);
677         String sl = lm.toString(LengthUnit.SI, true, true); // verbose with unit
678         assertTrue(sl.contains("Rel"));
679         assertFalse(sl.contains("Abs"));
680     }
681 
682     /**
683      * Test the extra methods that Absolute and Relative with Absolute matrices implement.
684      */
685     @Test
686     public void testSpecialMatrixMethodsRelWithAbs()
687     {
688         float[][] denseTestData = FLOATMATRIX.denseRectArrays(5, 10);
689         FloatTimeMatrix tm = FloatMatrix.instantiate(
690                 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
691         FloatDurationMatrix dm = FloatMatrix.instantiate(
692                 FloatMatrixData.instantiate(denseTestData, DurationUnit.MINUTE.getScale(), StorageType.DENSE),
693                 DurationUnit.SECOND);
694         assertTrue(tm.isAbsolute());
695         assertFalse(dm.isAbsolute());
696         assertFalse(tm.isRelative());
697         assertTrue(dm.isRelative());
698 
699         FloatTimeMatrix absPlusRel = tm.plus(dm);
700         FloatTimeMatrix absMinusRel = tm.minus(dm);
701         float[][] halfDenseData = FLOATMATRIX.denseRectArrays(5, 10);
702         for (int row = 0; row < halfDenseData.length; row++)
703         {
704             for (int col = 0; col < halfDenseData[row].length; col++)
705             {
706                 halfDenseData[row][col] *= 0.5;
707             }
708         }
709         FloatTimeMatrix halfTimeMatrix = FloatMatrix.instantiate(
710                 FloatMatrixData.instantiate(halfDenseData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
711         FloatDurationMatrix absMinusAbs = tm.minus(halfTimeMatrix);
712         FloatTimeMatrix absDecByRelS = tm.mutable().decrementBy(FloatDuration.of(1.0f, "min"));
713         FloatTimeMatrix absDecByRelM = tm.mutable().decrementBy(dm.divide(2.0f));
714         FloatTimeMatrix relPlusAbs = dm.plus(tm);
715         for (int row = 0; row < denseTestData.length; row++)
716         {
717             for (int col = 0; col < denseTestData[0].length; col++)
718             {
719                 assertEquals("absPlusRel", 61.0 * denseTestData[row][col], absPlusRel.getSI(row, col), 0.01);
720                 assertEquals("absMinusRel", -59.0 * denseTestData[row][col], absMinusRel.getSI(row, col), 0.01);
721                 assertEquals("absMinusAbs", denseTestData[row][col] / 2.0, absMinusAbs.getSI(row, col), 0.01);
722                 assertEquals("absDecByRelS", denseTestData[row][col] - 60.0, absDecByRelS.getSI(row, col), 0.01);
723                 assertEquals("absDecByRelM", -29.0 * denseTestData[row][col], absDecByRelM.getSI(row, col), 0.01);
724                 assertEquals("relPlusAbs", 61.0 * denseTestData[row][col], relPlusAbs.getSI(row, col), 0.01);
725             }
726         }
727         for (int dRows : new int[] {-1, 0, 1})
728         {
729             for (int dCols : new int[] {-1, 0, 1})
730             {
731                 if (dRows == 0 && dCols == 0)
732                 {
733                     continue;
734                 }
735                 float[][] other = FLOATMATRIX.denseRectArrays(denseTestData.length + dRows, denseTestData[0].length + dCols);
736                 FloatTimeMatrix wrongTimeMatrix = FloatMatrix.instantiate(
737                         FloatMatrixData.instantiate(other, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
738                 try
739                 {
740                     tm.mutable().minus(wrongTimeMatrix);
741                     fail("Mismatching size should have thrown a ValueRuntimeException");
742                 }
743                 catch (ValueRuntimeException vre)
744                 {
745                     // Ignore expected exception
746                 }
747             }
748         }
749         assertTrue("toString returns something informative",
750                 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE).toString()
751                         .startsWith("FloatMatrixData"));
752     }
753 
754     /**
755      * Execute a mats++-like memory test on a sparse matrix. See
756      * <a href="http://www.eng.auburn.edu/~agrawvd/COURSE/E7250_05/REPORTS_TERM/Raghuraman_Mem.doc">Memory Test</a>.
757      */
758     @Test
759     public void memoryTest()
760     {
761         AreaMatrix am = DoubleMatrix.instantiate(new double[5][10], AreaUnit.SI, StorageType.SPARSE);
762         am = am.mutable();
763         double nonZeroValue = 123.456;
764         // Initially the array is filled with zero values; we can skip the initialization phase
765         for (int compoundIndex = 0; compoundIndex < am.cols() * am.rows(); compoundIndex++)
766         {
767             // Let the row count fastest
768             int row = compoundIndex % am.rows();
769             int col = compoundIndex / am.rows();
770             assertEquals("initial value is 0", 0d, am.getSI(row, col), 0.0001);
771             am.setSI(row, col, nonZeroValue);
772             assertEquals("current value is nonZero", nonZeroValue, am.getSI(row, col), 0.0001);
773         }
774         for (int compoundIndex = am.cols() * am.rows(); --compoundIndex >= 0;)
775         {
776             // Let the row count fastest
777             int row = compoundIndex % am.rows();
778             int col = compoundIndex / am.rows();
779             assertEquals("current value is nonZero", nonZeroValue, am.getSI(row, col), 0.0001);
780             am.setSI(row, col, 0d);
781             assertEquals("final value is 0", 0d, am.getSI(row, col), 0.0001);
782         }
783     }
784 
785     /**
786      * Test the instantiateAbs method and instantiateScalarAbsSI method.
787      */
788     @Test
789     public void testInstantiateAbs()
790     {
791         float[][] denseTestData = FLOATMATRIX.denseRectArrays(10, 20);
792         FloatTimeMatrix timeMatrix = FloatMatrix.instantiate(
793                 FloatMatrixData.instantiate(denseTestData, TimeUnit.DEFAULT.getScale(), StorageType.DENSE), TimeUnit.DEFAULT);
794         FloatDurationMatrix durationMatrix = FloatMatrix.instantiate(
795                 FloatMatrixData.instantiate(denseTestData, DurationUnit.MINUTE.getScale(), StorageType.DENSE),
796                 DurationUnit.SECOND);
797 
798         float[] halfDenseData = FLOATVECTOR.denseArray(105);
799         for (int index = 0; index < halfDenseData.length; index++)
800         {
801             halfDenseData[index] *= 0.5;
802         }
803         FloatTimeMatrix relPlusAbsTime = durationMatrix.plus(timeMatrix);
804         for (int row = 0; row < denseTestData.length; row++)
805         {
806             for (int col = 0; col < denseTestData[0].length; col++)
807             {
808                 assertEquals("relPlusAbsTime", 61.0 * denseTestData[row][col], relPlusAbsTime.getSI(row, col), 0.01);
809             }
810         }
811         FloatTime floatTime = durationMatrix.instantiateScalarAbsSI(123.456f, TimeUnit.EPOCH_DAY);
812         assertEquals("Unit of instantiateScalarAbsSI matches", TimeUnit.EPOCH_DAY, floatTime.getDisplayUnit());
813         assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatTime.si, 0.1);
814 
815         FloatAngleMatrix angleMatrix = FloatMatrix.instantiate(
816                 FloatMatrixData.instantiate(denseTestData, AngleUnit.DEGREE.getScale(), StorageType.DENSE), AngleUnit.DEGREE);
817         FloatDirectionMatrix directionMatrix = FloatMatrix.instantiate(
818                 FloatMatrixData.instantiate(denseTestData, DirectionUnit.EAST_DEGREE.getScale(), StorageType.DENSE),
819                 DirectionUnit.EAST_DEGREE);
820 
821         FloatDirectionMatrix relPlusAbsDirection = angleMatrix.plus(directionMatrix);
822         for (int row = 0; row < denseTestData.length; row++)
823         {
824             for (int col = 0; col < denseTestData[0].length; col++)
825             {
826                 assertEquals("relPlusAbsTime", 2.0 / 180 * Math.PI * denseTestData[row][col],
827                         relPlusAbsDirection.getSI(row, col), 0.01);
828             }
829         }
830         FloatDirection floatDirection = angleMatrix.instantiateScalarAbsSI(123.456f, DirectionUnit.NORTH_RADIAN);
831         assertEquals("Unit of instantiateScalarAbsSI matches", DirectionUnit.NORTH_RADIAN, floatDirection.getDisplayUnit());
832         assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatDirection.si, 0.1);
833 
834         FloatTemperatureMatrix temperatureMatrix = FloatMatrix.instantiate(
835                 FloatMatrixData.instantiate(denseTestData, TemperatureUnit.DEGREE_FAHRENHEIT.getScale(), StorageType.DENSE),
836                 TemperatureUnit.DEGREE_FAHRENHEIT);
837         FloatAbsoluteTemperatureMatrix absoluteTemperatureMatrix = FloatMatrix.instantiate(
838                 FloatMatrixData.instantiate(denseTestData, AbsoluteTemperatureUnit.KELVIN.getScale(), StorageType.DENSE),
839                 AbsoluteTemperatureUnit.KELVIN);
840 
841         FloatAbsoluteTemperatureMatrix relPlusAbsTemperature = temperatureMatrix.plus(absoluteTemperatureMatrix);
842         for (int row = 0; row < denseTestData.length; row++)
843         {
844             for (int col = 0; col < denseTestData[0].length; col++)
845             {
846                 assertEquals("relPlusAbsTime", (1.0 + 5.0 / 9.0) * denseTestData[row][col],
847                         relPlusAbsTemperature.getSI(row, col), 0.01);
848             }
849         }
850         FloatAbsoluteTemperature floatAbsoluteTemperature =
851                 temperatureMatrix.instantiateScalarAbsSI(123.456f, AbsoluteTemperatureUnit.DEGREE_FAHRENHEIT);
852         assertEquals("Unit of instantiateScalarAbsSI matches", AbsoluteTemperatureUnit.DEGREE_FAHRENHEIT,
853                 floatAbsoluteTemperature.getDisplayUnit());
854         assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatAbsoluteTemperature.si, 0.1);
855 
856         FloatLengthMatrix lengthMatrix = FloatMatrix.instantiate(
857                 FloatMatrixData.instantiate(denseTestData, LengthUnit.MILE.getScale(), StorageType.DENSE), LengthUnit.MILE);
858         FloatPositionMatrix positionMatrix = FloatMatrix.instantiate(
859                 FloatMatrixData.instantiate(denseTestData, PositionUnit.KILOMETER.getScale(), StorageType.DENSE),
860                 PositionUnit.KILOMETER);
861 
862         FloatPositionMatrix relPlusAbsPosition = lengthMatrix.plus(positionMatrix);
863         for (int row = 0; row < denseTestData.length; row++)
864         {
865             for (int col = 0; col < denseTestData[0].length; col++)
866             {
867                 assertEquals("relPlusAbsTime", 2609.344 * denseTestData[row][col], relPlusAbsPosition.getSI(row, col), 0.1);
868             }
869         }
870         FloatPosition floatPosition = lengthMatrix.instantiateScalarAbsSI(123.456f, PositionUnit.ANGSTROM);
871         assertEquals("Unit of instantiateScalarAbsSI matches", PositionUnit.ANGSTROM, floatPosition.getDisplayUnit());
872         assertEquals("Value of instantiateScalarAbsSI matches", 123.456f, floatPosition.si, 0.1);
873     }
874 
875     /**
876      * Test the <code>as</code> method of the FloatSIMatrix class.
877      * @throws SecurityException on error
878      * @throws NoSuchMethodException on error
879      * @throws InvocationTargetException on error
880      * @throws IllegalArgumentException on error
881      * @throws IllegalAccessException on error
882      * @throws ClassNotFoundException on error
883      * @throws UnitException on error
884      * @param <U> the unit type
885      */
886     @SuppressWarnings("unchecked")
887     @Test
888     public <U extends Unit<U>> void testAsUnit() throws ClassNotFoundException, NoSuchMethodException, SecurityException,
889             IllegalAccessException, IllegalArgumentException, InvocationTargetException, UnitException
890     {
891         float[][] testValues = FLOATMATRIX.denseRectArrays(10, 20);
892         for (StorageType storageType : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
893         {
894             for (String type : CLASSNAMES.REL_LIST)
895             {
896                 Class.forName("org.djunits.unit." + type + "Unit");
897                 Quantity<U> quantity = (Quantity<U>) Quantities.INSTANCE.getQuantity(type + "Unit");
898                 for (U unit : quantity.getUnitsById().values())
899                 {
900                     for (StorageType storageType2 : new StorageType[] {StorageType.DENSE, storageType})
901                     {
902                         SIUnit siUnit = SIUnit.of(unit.getQuantity().getSiDimensions());
903                         FloatSIMatrix matrix = FloatSIMatrix.instantiate(testValues, siUnit, storageType2);
904                         Method asMethod = FloatSIMatrix.class.getDeclaredMethod("as", Unit.class);
905                         AbstractFloatMatrixRel<U, ?, ?, ?> asMatrix =
906                                 (AbstractFloatMatrixRel<U, ?, ?, ?>) asMethod.invoke(matrix, siUnit);
907                         assertEquals(matrix.getDisplayUnit().getStandardUnit(), asMatrix.getDisplayUnit());
908                         siUnit = SIUnit.of(AbsoluteTemperatureUnit.KELVIN.getQuantity().getSiDimensions());
909                         for (int row = 0; row < testValues.length; row++)
910                         {
911                             for (int col = 0; col < testValues[0].length; col++)
912                             {
913                                 assertEquals("Values should match", testValues[row][col], matrix.getInUnit(row, col), 0.001);
914                             }
915                         }
916                         try
917                         {
918                             asMethod.invoke(matrix, siUnit);
919                             fail("as method should not be able to cast to unrelated (absoluteTemperature) unit");
920                         }
921                         catch (InvocationTargetException ite)
922                         {
923                             Throwable cause = ite.getCause();
924                             assertEquals("cause is UnitRuntimeException", UnitRuntimeException.class, cause.getClass());
925                             // Otherwise ignore expected exception
926                         }
927                     }
928                 }
929             }
930         }
931     }
932 
933     /**
934      * Test the equals method.
935      */
936     @SuppressWarnings("unlikely-arg-type")
937     @Test
938     public void testEquals()
939     {
940         float[][] testData = FLOATMATRIX.denseRectArrays(12, 34);
941         testData[2][2] = 0;
942         for (StorageType storageType : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
943         {
944             FloatMatrixData fmd = FloatMatrixData.instantiate(testData, TemperatureUnit.KELVIN.getScale(), storageType);
945             assertTrue("Float matrix is equal to itself", fmd.equals(fmd));
946             assertFalse("Float matrix is not equal to null", fmd.equals(null));
947             assertFalse("Float matrix data is not equal to some string", fmd.equals("some string"));
948             assertTrue("Float matrix is equal to sparse version of itself", fmd.equals(fmd.toSparse()));
949             assertTrue("Float matrix is equal to dense version of itself", fmd.equals(fmd.toDense()));
950             for (StorageType storageType2 : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
951             {
952                 FloatMatrixData dvd2 = FloatMatrixData.instantiate(testData, TemperatureUnit.KELVIN.getScale(), storageType2);
953                 assertEquals(
954                         "Float matrix data is equal to other double vector containing same values regardless of storage type",
955                         fmd, dvd2);
956                 float[][] testData2 = FLOATMATRIX.denseRectArrays(12, 33);
957                 testData2[2][2] = 0;
958                 dvd2 = FloatMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
959                 assertFalse("Float matrix data is not equal to other double vector containing same values except last one",
960                         fmd.equals(dvd2));
961                 testData2 = FLOATMATRIX.denseRectArrays(13, 34);
962                 testData2[2][2] = 0;
963                 dvd2 = FloatMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
964                 assertFalse("Float matrix data is not equal to other double vector containing same values except last one",
965                         fmd.equals(dvd2));
966                 testData2 = FLOATMATRIX.denseRectArrays(12, 34);
967                 dvd2 = FloatMatrixData.instantiate(testData2, TemperatureUnit.KELVIN.getScale(), storageType2);
968                 assertFalse("Float matrix data is not equal to other double vector containing same values except for one zero",
969                         fmd.equals(dvd2));
970             }
971         }
972     }
973 
974     /**
975      * Test the sparse value class.
976      */
977     @SuppressWarnings({"rawtypes", "unchecked"})
978     @Test
979     public void sparseValueTest()
980     {
981         try
982         {
983             new FloatSparseValue(-1, 0, 123.456f);
984             fail("Negative row should have caused a ValueRuntimeException");
985         }
986         catch (ValueRuntimeException vre)
987         {
988             // Ignore expected exception
989         }
990 
991         try
992         {
993             new FloatSparseValue(0, -1, 123.456f);
994             fail("Negative column should have caused a ValueRuntimeException");
995         }
996         catch (ValueRuntimeException vre)
997         {
998             // Ignore expected exception
999         }
1000 
1001         FloatLength length = FloatLength.valueOf("123 km");
1002         FloatSparseValue dsv = new FloatSparseValue(2, 3, length);
1003         assertEquals("row matches", 2, dsv.getRow());
1004         assertEquals("column matches", 3, dsv.getColumn());
1005         assertEquals("value matches", 123000, dsv.getValueSI(), 0.1);
1006         dsv = new FloatSparseValue(2, 3, 123.000f, LengthUnit.KILOMETER);
1007         assertEquals("row matches", 2, dsv.getRow());
1008         assertEquals("column matches", 3, dsv.getColumn());
1009         assertEquals("value matches", 123000, dsv.getValueSI(), 0.1);
1010     }
1011 
1012 }