View Javadoc
1   package org.djunits.value.vfloat.matrix;
2   
3   import static org.junit.Assert.assertArrayEquals;
4   import static org.junit.Assert.assertEquals;
5   import static org.junit.Assert.assertFalse;
6   import static org.junit.Assert.assertNotEquals;
7   import static org.junit.Assert.assertTrue;
8   import static org.junit.Assert.fail;
9   
10  import java.util.ArrayList;
11  import java.util.Collection;
12  import java.util.Map;
13  import java.util.SortedMap;
14  import java.util.TreeMap;
15  
16  import org.djunits.unit.AbsoluteLinearUnit;
17  import org.djunits.unit.AreaUnit;
18  import org.djunits.unit.LengthUnit;
19  import org.djunits.unit.SIUnit;
20  import org.djunits.unit.SpeedUnit;
21  import org.djunits.unit.Unit;
22  import org.djunits.unit.quantity.Quantities;
23  import org.djunits.unit.quantity.Quantity;
24  import org.djunits.unit.util.UNITS;
25  import org.djunits.unit.util.UnitException;
26  import org.djunits.value.CLASSNAMES;
27  import org.djunits.value.storage.StorageType;
28  import org.djunits.value.vfloat.matrix.base.AbstractFloatMatrixAbs;
29  import org.djunits.value.vfloat.matrix.base.AbstractFloatMatrixRelWithAbs;
30  import org.djunits.value.vfloat.matrix.base.FloatMatrix;
31  import org.djunits.value.vfloat.matrix.base.FloatMatrixInterface;
32  import org.djunits.value.vfloat.matrix.base.FloatSparseValue;
33  import org.djunits.value.vfloat.matrix.data.FloatMatrixData;
34  import org.djunits.value.vfloat.scalar.FloatArea;
35  import org.djunits.value.vfloat.scalar.FloatLength;
36  import org.djunits.value.vfloat.scalar.FloatSIScalar;
37  import org.djunits.value.vfloat.scalar.FloatSpeed;
38  import org.djunits.value.vfloat.scalar.base.AbstractFloatScalarAbs;
39  import org.djunits.value.vfloat.scalar.base.AbstractFloatScalarRelWithAbs;
40  import org.djunits.value.vfloat.scalar.base.FloatScalarInterface;
41  import org.djunits.value.vfloat.vector.FloatSIVector;
42  import org.djunits.value.vfloat.vector.base.AbstractFloatVectorAbs;
43  import org.djunits.value.vfloat.vector.base.AbstractFloatVectorRelWithAbs;
44  import org.djunits.value.vfloat.vector.base.FloatVectorInterface;
45  import org.djunits.value.vfloat.vector.data.FloatVectorData;
46  import org.djutils.exceptions.Try;
47  import org.junit.Test;
48  
49  /**
50   * FloatMatrixInstantiateTest.java.
51   * <p>
52   * Copyright (c) 2019-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
53   * BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
54   * <p>
55   * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank">Alexander Verbraeck</a>
56   */
57  public class FloatMatrixInstantiateTest
58  {
59      /**
60       * Test the constructors of all matrix classes.
61       * @param <U> the unit type
62       * @param <S> the scalar type
63       * @param <V> the vector type
64       * @param <M> the matrix type
65       */
66      @Test
67      public <U extends Unit<U>, S extends FloatScalarInterface<U, S>, V extends FloatVectorInterface<U, S, V>,
68              M extends FloatMatrixInterface<U, S, V, M>> void instatiateAllMatrixTypes()
69      {
70          // Force loading of all classes
71          LengthUnit length = UNITS.METER;
72          if (length == null)
73          {
74              fail();
75          }
76  
77          for (String scalarName : CLASSNAMES.ALL_LIST)
78          {
79              @SuppressWarnings("unchecked")
80              Quantity<U> quantity = (Quantity<U>) Quantities.INSTANCE.getQuantity(scalarName + "Unit");
81              U standardUnit = quantity.getStandardUnit();
82              for (StorageType storageType : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
83              {
84                  float[][] testValues = FLOATMATRIX.denseRectArrays(5, 10);
85                  FloatMatrixData dmd = FloatMatrixData.instantiate(testValues, standardUnit.getScale(), storageType);
86                  FloatMatrixInterface<U, S, V, M> floatMatrix = FloatMatrix.instantiate(testValues, standardUnit, storageType);
87                  Class<S> scalarClass = floatMatrix.getScalarClass();
88                  assertEquals("scalar class should have the right name", "Float" + scalarName, scalarClass.getSimpleName());
89                  Class<V> vectorClass = floatMatrix.getVectorClass();
90                  assertEquals("vector class should have the right name", "Float" + scalarName + "Vector",
91                          vectorClass.getSimpleName());
92                  FloatMatrixInterface<U, S, V, M> floatMatrix2 = floatMatrix.instantiateMatrix(dmd, standardUnit);
93                  assertEquals("matrix constructed from FloatMatrixData should be equal to matrix constructed from float[][]",
94                          floatMatrix, floatMatrix2);
95                  FloatVectorData dvd =
96                          FloatVectorData.instantiate(floatMatrix.getRowSI(0), standardUnit.getScale(), storageType);
97                  FloatVectorInterface<U, S, V> floatVector = floatMatrix.instantiateVector(dvd, standardUnit);
98                  assertArrayEquals("Float vector contains values from row 0", new float[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
99                          floatVector.getValuesSI(), 0.001f);
100                 // TODO next cast should be unnecessary
101                 FloatScalarInterface<U, S> floatScalar = floatMatrix.instantiateScalarSI(1.234f, standardUnit);
102                 assertEquals("Constructed scalar has correct value", 1.234f, floatScalar.getSI(), 0.001);
103                 assertEquals("Constructed scalar has correct unit", standardUnit, floatScalar.getDisplayUnit());
104             }
105         }
106     }
107 
108     /**
109      * Test the extra methods that Absolute and Relative with Absolute matrices implement.
110      * @param <AU> the absolute unit type
111      * @param <RU> the relative unit type
112      */
113     @SuppressWarnings("unchecked")
114     @Test
115     public <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>> void instantiateRelAbsMatrixTypes()
116     {
117         // Force loading of all classes
118         LengthUnit length = UNITS.METER;
119         if (length == null)
120         {
121             fail();
122         }
123 
124         for (int classIndex = 0; classIndex < CLASSNAMES.REL_WITH_ABS_LIST.size(); classIndex++)
125         {
126             String relScalarName = CLASSNAMES.REL_WITH_ABS_LIST.get(classIndex);
127             String absScalarName = CLASSNAMES.ABS_LIST.get(classIndex);
128             Quantity<RU> relQuantity = (Quantity<RU>) Quantities.INSTANCE.getQuantity(relScalarName + "Unit");
129             Quantity<AU> absQuantity = (Quantity<AU>) Quantities.INSTANCE.getQuantity(absScalarName + "Unit");
130             RU relStandardUnit = relQuantity.getStandardUnit();
131             AU absStandardUnit = absQuantity.getStandardUnit();
132             for (StorageType storageType : new StorageType[] {StorageType.DENSE, StorageType.SPARSE})
133             {
134                 float[][] testValues = FLOATMATRIX.denseRectArrays(5, 10);
135                 FloatMatrixData dmd = FloatMatrixData.instantiate(testValues, relStandardUnit.getScale(), storageType);
136                 AbstractFloatMatrixRelWithAbs<AU, ?, ?, ?, RU, ?, ?, ?> relFloatMatrix = (AbstractFloatMatrixRelWithAbs<AU, ?,
137                         ?, ?, RU, ?, ?, ?>) FloatMatrix.instantiate(testValues, relStandardUnit, storageType);
138                 AbstractFloatMatrixAbs<AU, ?, ?, ?, RU, ?, ?, ?> absFloatMatrix = (AbstractFloatMatrixAbs<AU, ?, ?, ?, RU, ?, ?,
139                         ?>) FloatMatrix.instantiate(testValues, absStandardUnit, storageType);
140 
141                 FloatMatrixInterface<AU, ?, ?, ?> absFloatMatrix2 = relFloatMatrix.instantiateMatrixAbs(dmd, absStandardUnit);
142                 assertEquals("matrix constructed from FloatMatrixData should be equal to matrix constructed from float[][]",
143                         absFloatMatrix, absFloatMatrix2);
144                 FloatVectorData dvd =
145                         FloatVectorData.instantiate(relFloatMatrix.getRowSI(0), relStandardUnit.getScale(), storageType);
146                 AbstractFloatVectorAbs<AU, ?, ?, RU, ?, ?> absFloatVector =
147                         relFloatMatrix.instantiateVectorAbs(dvd, absStandardUnit);
148                 assertArrayEquals("Float vector contains values from row 0", new float[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
149                         absFloatVector.getValuesSI(), 0.001f);
150                 AbstractFloatScalarAbs<AU, ?, RU, ?> absFloatScalar =
151                         relFloatMatrix.instantiateScalarAbsSI(1.234f, absStandardUnit);
152                 assertEquals("Constructed scalar has correct value", 1.234f, absFloatScalar.si, 0.001f);
153                 assertEquals("Constructed scalar has correct unit", absStandardUnit, absFloatScalar.getDisplayUnit());
154 
155                 FloatMatrixInterface<RU, ?, ?, ?> relFloatMatrix2 = absFloatMatrix.instantiateMatrixRel(dmd, relStandardUnit);
156                 assertEquals("matrix constructed from FloatMatrixData should be equal to matrix constructed from float[][]",
157                         relFloatMatrix, relFloatMatrix2);
158                 dvd = FloatVectorData.instantiate(absFloatMatrix.getRowSI(0), absStandardUnit.getScale(), storageType);
159                 AbstractFloatVectorRelWithAbs<AU, ?, ?, RU, ?, ?> relFloatVector =
160                         absFloatMatrix.instantiateVectorRel(dvd, relStandardUnit);
161                 assertArrayEquals("Float vector contains values from row 0", new float[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
162                         relFloatVector.getValuesSI(), 0.001f);
163                 AbstractFloatScalarRelWithAbs<AU, ?, RU, ?> relFloatScalar =
164                         absFloatMatrix.instantiateScalarRelSI(1.234f, relStandardUnit);
165                 assertEquals("Constructed scalar has correct value", 1.234f, relFloatScalar.si, 0.001f);
166                 assertEquals("Constructed scalar has correct unit", relStandardUnit, relFloatScalar.getDisplayUnit());
167 
168             }
169         }
170     }
171 
172     /**
173      * Test the instantiation of dense and sparse matrix types with dense data (no zeros).
174      */
175     @Test
176     public void testInstantiateSquareDenseData()
177     {
178         FloatLengthMatrix lmdkm10 =
179                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 10), LengthUnit.KILOMETER, StorageType.DENSE);
180         assertEquals(10, lmdkm10.rows());
181         assertEquals(10, lmdkm10.cols());
182         assertEquals(100, lmdkm10.cardinality());
183         assertEquals(50 * 101 * 1000.0, lmdkm10.zSum().getSI(), 0.001);
184         assertEquals(LengthUnit.KILOMETER, lmdkm10.getDisplayUnit());
185 
186         FloatLengthMatrix lmskm10 =
187                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 10), LengthUnit.KILOMETER, StorageType.SPARSE);
188         assertEquals(10, lmskm10.rows());
189         assertEquals(10, lmskm10.cols());
190         assertEquals(100, lmskm10.cardinality());
191         assertEquals(50 * 101 * 1000.0, lmskm10.zSum().getSI(), 0.001);
192         assertEquals(LengthUnit.KILOMETER, lmskm10.getDisplayUnit());
193 
194         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
195         assertEquals(lmskm10, lmskm10.toDense().toSparse());
196         assertEquals(lmdkm10, lmskm10.toDense());
197         assertEquals(lmskm10, lmdkm10.toSparse());
198         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
199         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
200         assertEquals(lmdkm10, lmdkm10.toDense());
201         assertEquals(lmskm10, lmskm10.toSparse());
202 
203         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
204         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
205         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
206         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
207         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
208         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
209         assertEquals(lmdkm10.hashCode(), lmdkm10.toDense().hashCode());
210         assertEquals(lmskm10.hashCode(), lmskm10.toSparse().hashCode());
211 
212         assertTrue(lmdkm10.isDense());
213         assertTrue(lmskm10.isSparse());
214 
215         FloatLengthMatrix lmdsi10 =
216                 FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(10, 10), LengthUnit.CENTIMETER, StorageType.DENSE);
217         assertEquals(10, lmdsi10.rows());
218         assertEquals(10, lmdsi10.cols());
219         assertEquals(100, lmdsi10.cardinality());
220         assertEquals(50 * 101, lmdsi10.zSum().getSI(), 0.001);
221         assertEquals(LengthUnit.CENTIMETER, lmdsi10.getDisplayUnit());
222 
223         FloatLengthMatrix lmssi10 =
224                 FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(10, 10), LengthUnit.CENTIMETER, StorageType.SPARSE);
225         assertEquals(10, lmssi10.rows());
226         assertEquals(10, lmssi10.cols());
227         assertEquals(100, lmssi10.cardinality());
228         assertEquals(50 * 101, lmssi10.zSum().getSI(), 0.001);
229         assertEquals(LengthUnit.CENTIMETER, lmssi10.getDisplayUnit());
230 
231         FloatLengthMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(10, 10, FloatLength.class),
232                 LengthUnit.HECTOMETER, StorageType.DENSE);
233         assertEquals(10, lmdsc10.rows());
234         assertEquals(10, lmdsc10.cols());
235         assertEquals(100, lmdsc10.cardinality());
236         assertEquals(50 * 101, lmdsc10.zSum().getSI(), 0.001);
237         assertEquals(LengthUnit.HECTOMETER, lmdsc10.getDisplayUnit());
238 
239         FloatLengthMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(10, 10, FloatLength.class),
240                 LengthUnit.HECTOMETER, StorageType.SPARSE);
241         assertEquals(10, lmssc10.rows());
242         assertEquals(10, lmssc10.cols());
243         assertEquals(100, lmssc10.cardinality());
244         assertEquals(50 * 101, lmssc10.zSum().getSI(), 0.001);
245         assertEquals(LengthUnit.HECTOMETER, lmssc10.getDisplayUnit());
246     }
247 
248     /**
249      * Test the instantiation of dense and sparse matrix types with sparse data (90% zeros).
250      */
251     @Test
252     public void testInstantiatSquareSparseData()
253     {
254         FloatLengthMatrix lmdkm10 =
255                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 10), LengthUnit.KILOMETER, StorageType.DENSE);
256         assertEquals(10, lmdkm10.rows());
257         assertEquals(10, lmdkm10.cols());
258         assertEquals(10, lmdkm10.cardinality());
259         assertEquals(5 * 11 * 1000.0, lmdkm10.zSum().getSI(), 0.001);
260         assertEquals(LengthUnit.KILOMETER, lmdkm10.getDisplayUnit());
261 
262         FloatLengthMatrix lmskm10 =
263                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 10), LengthUnit.KILOMETER, StorageType.SPARSE);
264         assertEquals(10, lmskm10.rows());
265         assertEquals(10, lmskm10.cols());
266         assertEquals(10, lmskm10.cardinality());
267         assertEquals(5 * 11 * 1000.0, lmskm10.zSum().getSI(), 0.001);
268         assertEquals(LengthUnit.KILOMETER, lmskm10.getDisplayUnit());
269 
270         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
271         assertEquals(lmskm10, lmskm10.toDense().toSparse());
272         assertEquals(lmdkm10, lmskm10.toDense());
273         assertEquals(lmskm10, lmdkm10.toSparse());
274         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
275         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
276 
277         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
278         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
279         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
280         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
281         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
282         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
283 
284         FloatLengthMatrix lmdsi10 =
285                 FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(10, 10), LengthUnit.CENTIMETER, StorageType.DENSE);
286         assertEquals(10, lmdsi10.rows());
287         assertEquals(10, lmdsi10.cols());
288         assertEquals(10, lmdsi10.cardinality());
289         assertEquals(5 * 11, lmdsi10.zSum().getSI(), 0.001);
290         assertEquals(LengthUnit.CENTIMETER, lmdsi10.getDisplayUnit());
291 
292         FloatLengthMatrix lmssi10 =
293                 FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(10, 10), LengthUnit.CENTIMETER, StorageType.SPARSE);
294         assertEquals(10, lmssi10.rows());
295         assertEquals(10, lmssi10.cols());
296         assertEquals(10, lmssi10.cardinality());
297         assertEquals(5 * 11, lmssi10.zSum().getSI(), 0.001);
298         assertEquals(LengthUnit.CENTIMETER, lmssi10.getDisplayUnit());
299 
300         FloatLengthMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(10, 10, FloatLength.class),
301                 LengthUnit.HECTOMETER, StorageType.DENSE);
302         assertEquals(10, lmdsc10.rows());
303         assertEquals(10, lmdsc10.cols());
304         assertEquals(10, lmdsc10.cardinality());
305         assertEquals(5 * 11, lmdsc10.zSum().getSI(), 0.001);
306         assertEquals(LengthUnit.HECTOMETER, lmdsc10.getDisplayUnit());
307 
308         FloatLengthMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(10, 10, FloatLength.class),
309                 LengthUnit.HECTOMETER, StorageType.SPARSE);
310         assertEquals(10, lmssc10.rows());
311         assertEquals(10, lmssc10.cols());
312         assertEquals(10, lmssc10.cardinality());
313         assertEquals(5 * 11, lmssc10.zSum().getSI(), 0.001);
314         assertEquals(LengthUnit.HECTOMETER, lmssc10.getDisplayUnit());
315 
316         FloatLengthMatrix lmdtu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(10, 10, FloatLength.class), 10, 10,
317                 LengthUnit.NANOMETER, StorageType.DENSE);
318         assertEquals(10, lmdtu10.rows());
319         assertEquals(10, lmdtu10.cols());
320         assertEquals(10, lmdtu10.cardinality());
321         assertEquals(5 * 11, lmdtu10.zSum().getSI(), 0.001);
322         assertEquals(LengthUnit.NANOMETER, lmdtu10.getDisplayUnit());
323 
324         FloatLengthMatrix lmstu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(10, 10, FloatLength.class), 10, 10,
325                 LengthUnit.NANOMETER, StorageType.SPARSE);
326         assertEquals(10, lmstu10.rows());
327         assertEquals(10, lmstu10.cols());
328         assertEquals(10, lmstu10.cardinality());
329         assertEquals(5 * 11, lmstu10.zSum().getSI(), 0.001);
330         assertEquals(LengthUnit.NANOMETER, lmstu10.getDisplayUnit());
331     }
332 
333     /**
334      * Test the instantiation of dense and sparse matrix types with dense data (no zeros).
335      */
336     @Test
337     public void testInstantiateSquareDenseDataWithClass()
338     {
339         FloatAreaMatrix lmdkm10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 10), AreaUnit.SQUARE_KILOMETER,
340                 StorageType.DENSE, FloatAreaMatrix.class);
341         assertEquals(10, lmdkm10.rows());
342         assertEquals(10, lmdkm10.cols());
343         assertEquals(100, lmdkm10.cardinality());
344         assertEquals(50 * 101 * 1.0E6, lmdkm10.zSum().getSI(), 1000);
345         assertEquals(AreaUnit.SQUARE_KILOMETER, lmdkm10.getDisplayUnit());
346 
347         FloatAreaMatrix lmskm10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 10), AreaUnit.SQUARE_KILOMETER,
348                 StorageType.SPARSE, FloatAreaMatrix.class);
349         assertEquals(10, lmskm10.rows());
350         assertEquals(10, lmskm10.cols());
351         assertEquals(100, lmskm10.cardinality());
352         assertEquals(50 * 101 * 1.0E6, lmskm10.zSum().getSI(), 1000);
353         assertEquals(AreaUnit.SQUARE_KILOMETER, lmskm10.getDisplayUnit());
354 
355         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
356         assertEquals(lmskm10, lmskm10.toDense().toSparse());
357         assertEquals(lmdkm10, lmskm10.toDense());
358         assertEquals(lmskm10, lmdkm10.toSparse());
359         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
360         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
361 
362         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
363         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
364         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
365         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
366         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
367         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
368 
369         FloatAreaMatrix lmdsi10 = FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(10, 10), AreaUnit.SQUARE_CENTIMETER,
370                 StorageType.DENSE, FloatAreaMatrix.class);
371         assertEquals(10, lmdsi10.rows());
372         assertEquals(10, lmdsi10.cols());
373         assertEquals(100, lmdsi10.cardinality());
374         assertEquals(50 * 101, lmdsi10.zSum().getSI(), 0.001);
375         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmdsi10.getDisplayUnit());
376 
377         FloatAreaMatrix lmssi10 = FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(10, 10), AreaUnit.SQUARE_CENTIMETER,
378                 StorageType.SPARSE, FloatAreaMatrix.class);
379         assertEquals(10, lmssi10.rows());
380         assertEquals(10, lmssi10.cols());
381         assertEquals(100, lmssi10.cardinality());
382         assertEquals(50 * 101, lmssi10.zSum().getSI(), 0.001);
383         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmssi10.getDisplayUnit());
384 
385         FloatAreaMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(10, 10, FloatArea.class),
386                 AreaUnit.SQUARE_HECTOMETER, StorageType.DENSE, FloatAreaMatrix.class);
387         assertEquals(10, lmdsc10.rows());
388         assertEquals(10, lmdsc10.cols());
389         assertEquals(100, lmdsc10.cardinality());
390         assertEquals(50 * 101, lmdsc10.zSum().getSI(), 0.001);
391         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmdsc10.getDisplayUnit());
392 
393         FloatAreaMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(10, 10, FloatArea.class),
394                 AreaUnit.SQUARE_HECTOMETER, StorageType.SPARSE, FloatAreaMatrix.class);
395         assertEquals(10, lmssc10.rows());
396         assertEquals(10, lmssc10.cols());
397         assertEquals(100, lmssc10.cardinality());
398         assertEquals(50 * 101, lmssc10.zSum().getSI(), 0.001);
399         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmssc10.getDisplayUnit());
400     }
401 
402     /**
403      * Test the instantiation of dense and sparse matrix types with sparse data (90% zeros).
404      */
405     @Test
406     public void testInstantiatSquareSparseDataWithClass()
407     {
408         FloatAreaMatrix lmdkm10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 10), AreaUnit.SQUARE_KILOMETER,
409                 StorageType.DENSE, FloatAreaMatrix.class);
410         assertEquals(10, lmdkm10.rows());
411         assertEquals(10, lmdkm10.cols());
412         assertEquals(10, lmdkm10.cardinality());
413         assertEquals(5 * 11 * 1.0E6, lmdkm10.zSum().getSI(), 0.1);
414         assertEquals(AreaUnit.SQUARE_KILOMETER, lmdkm10.getDisplayUnit());
415 
416         FloatAreaMatrix lmskm10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 10), AreaUnit.SQUARE_KILOMETER,
417                 StorageType.SPARSE, FloatAreaMatrix.class);
418         assertEquals(10, lmskm10.rows());
419         assertEquals(10, lmskm10.cols());
420         assertEquals(10, lmskm10.cardinality());
421         assertEquals(5 * 11 * 1.0E6, lmskm10.zSum().getSI(), 0.1);
422         assertEquals(AreaUnit.SQUARE_KILOMETER, lmskm10.getDisplayUnit());
423 
424         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
425         assertEquals(lmskm10, lmskm10.toDense().toSparse());
426         assertEquals(lmdkm10, lmskm10.toDense());
427         assertEquals(lmskm10, lmdkm10.toSparse());
428         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
429         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
430 
431         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
432         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
433         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
434         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
435         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
436         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
437 
438         FloatAreaMatrix lmdsi10 = FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(10, 10), AreaUnit.SQUARE_CENTIMETER,
439                 StorageType.DENSE, FloatAreaMatrix.class);
440         assertEquals(10, lmdsi10.rows());
441         assertEquals(10, lmdsi10.cols());
442         assertEquals(10, lmdsi10.cardinality());
443         assertEquals(5 * 11, lmdsi10.zSum().getSI(), 0.001);
444         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmdsi10.getDisplayUnit());
445 
446         FloatAreaMatrix lmssi10 = FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(10, 10), AreaUnit.SQUARE_CENTIMETER,
447                 StorageType.SPARSE, FloatAreaMatrix.class);
448         assertEquals(10, lmssi10.rows());
449         assertEquals(10, lmssi10.cols());
450         assertEquals(10, lmssi10.cardinality());
451         assertEquals(5 * 11, lmssi10.zSum().getSI(), 0.001);
452         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmssi10.getDisplayUnit());
453 
454         FloatAreaMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(10, 10, FloatArea.class),
455                 AreaUnit.SQUARE_HECTOMETER, StorageType.DENSE, FloatAreaMatrix.class);
456         assertEquals(10, lmdsc10.rows());
457         assertEquals(10, lmdsc10.cols());
458         assertEquals(10, lmdsc10.cardinality());
459         assertEquals(5 * 11, lmdsc10.zSum().getSI(), 0.001);
460         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmdsc10.getDisplayUnit());
461 
462         FloatAreaMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(10, 10, FloatArea.class),
463                 AreaUnit.SQUARE_HECTOMETER, StorageType.SPARSE, FloatAreaMatrix.class);
464         assertEquals(10, lmssc10.rows());
465         assertEquals(10, lmssc10.cols());
466         assertEquals(10, lmssc10.cardinality());
467         assertEquals(5 * 11, lmssc10.zSum().getSI(), 0.001);
468         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmssc10.getDisplayUnit());
469 
470         FloatAreaMatrix lmdtu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(10, 10, FloatArea.class), 10, 10,
471                 AreaUnit.ACRE, StorageType.DENSE, FloatAreaMatrix.class);
472         assertEquals(10, lmdtu10.rows());
473         assertEquals(10, lmdtu10.cols());
474         assertEquals(10, lmdtu10.cardinality());
475         assertEquals(5 * 11, lmdtu10.zSum().getSI(), 0.001);
476         assertEquals(AreaUnit.ACRE, lmdtu10.getDisplayUnit());
477 
478         FloatAreaMatrix lmstu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(10, 10, FloatArea.class), 10, 10,
479                 AreaUnit.ACRE, StorageType.SPARSE, FloatAreaMatrix.class);
480         assertEquals(10, lmstu10.rows());
481         assertEquals(10, lmstu10.cols());
482         assertEquals(10, lmstu10.cardinality());
483         assertEquals(5 * 11, lmstu10.zSum().getSI(), 0.001);
484         assertEquals(AreaUnit.ACRE, lmstu10.getDisplayUnit());
485     }
486 
487     /**
488      * Test the instantiation of dense and sparse matrix types with dense data (no zeros).
489      * @throws UnitException on error
490      */
491     @Test
492     public void testInstantiateSquareSIUnit() throws UnitException
493     {
494         FloatSIMatrix si10dd =
495                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 10), SIUnit.of("m2/s3"), StorageType.DENSE);
496         assertEquals(10, si10dd.rows());
497         assertEquals(10, si10dd.cols());
498         assertEquals(100, si10dd.cardinality());
499         assertEquals(50 * 101, si10dd.zSum().getSI(), 0.001);
500         assertEquals("m2/s3", si10dd.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
501 
502         FloatSIMatrix si10ds =
503                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 10), SIUnit.of("m2/s3"), StorageType.SPARSE);
504         assertEquals(10, si10ds.rows());
505         assertEquals(10, si10ds.cols());
506         assertEquals(100, si10ds.cardinality());
507         assertEquals(50 * 101, si10ds.zSum().getSI(), 0.001);
508         assertEquals("m2/s3", si10ds.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
509 
510         FloatSIMatrix si10sd =
511                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 10), SIUnit.of("m2/s3"), StorageType.DENSE);
512         assertEquals(10, si10sd.rows());
513         assertEquals(10, si10sd.cols());
514         assertEquals(10, si10sd.cardinality());
515         assertEquals(5 * 11, si10sd.zSum().getSI(), 0.001);
516         assertEquals("m2/s3", si10sd.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
517 
518         FloatSIMatrix si10ss =
519                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 10), SIUnit.of("m2/s3"), StorageType.SPARSE);
520         assertEquals(10, si10ss.rows());
521         assertEquals(10, si10ss.cols());
522         assertEquals(10, si10ss.cardinality());
523         assertEquals(5 * 11, si10ss.zSum().getSI(), 0.001);
524         assertEquals("m2/s3", si10ss.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
525 
526         assertEquals(si10dd, si10ds.toDense());
527         assertEquals(si10ds, si10dd.toSparse());
528         assertEquals(si10dd, si10dd.toDense());
529         assertEquals(si10ds, si10ds.toSparse());
530         assertEquals(si10dd, si10dd.toSparse().toDense());
531         assertEquals(si10ds, si10ds.toDense().toSparse());
532 
533         assertEquals(si10dd.hashCode(), si10ds.toDense().hashCode());
534         assertEquals(si10ds.hashCode(), si10dd.toSparse().hashCode());
535         assertEquals(si10dd.hashCode(), si10dd.toDense().hashCode());
536         assertEquals(si10ds.hashCode(), si10ds.toSparse().hashCode());
537         assertEquals(si10dd.hashCode(), si10dd.toSparse().toDense().hashCode());
538         assertEquals(si10ds.hashCode(), si10ds.toDense().toSparse().hashCode());
539         assertEquals(si10dd.hashCode(), si10dd.toSparse().hashCode());
540         assertEquals(si10ds.hashCode(), si10ds.toDense().hashCode());
541 
542         assertEquals(si10sd, si10ss.toDense());
543         assertEquals(si10ss, si10sd.toSparse());
544         assertEquals(si10sd, si10sd.toDense());
545         assertEquals(si10ss, si10ss.toSparse());
546         assertEquals(si10sd, si10sd.toSparse().toDense());
547         assertEquals(si10ss, si10ss.toDense().toSparse());
548 
549         assertEquals(si10sd.hashCode(), si10ss.toDense().hashCode());
550         assertEquals(si10ss.hashCode(), si10sd.toSparse().hashCode());
551         assertEquals(si10sd.hashCode(), si10sd.toDense().hashCode());
552         assertEquals(si10ss.hashCode(), si10ss.toSparse().hashCode());
553         assertEquals(si10sd.hashCode(), si10sd.toSparse().toDense().hashCode());
554         assertEquals(si10ss.hashCode(), si10ss.toDense().toSparse().hashCode());
555         assertEquals(si10sd.hashCode(), si10sd.toSparse().hashCode());
556         assertEquals(si10ss.hashCode(), si10ss.toDense().hashCode());
557     }
558 
559     // =============================================== RECTANGULAR MATRICES ===================================================
560 
561     /**
562      * Test the instantiation of dense and sparse matrix types with dense data (no zeros).
563      */
564     @Test
565     public void testInstantiateRectDenseData()
566     {
567         FloatLengthMatrix lmdkm10 =
568                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(20, 10), LengthUnit.KILOMETER, StorageType.DENSE);
569         assertEquals(20, lmdkm10.rows());
570         assertEquals(10, lmdkm10.cols());
571         assertEquals(200, lmdkm10.cardinality());
572         assertEquals(100 * 201 * 1000.0, lmdkm10.zSum().getSI(), 0.001);
573         assertEquals(LengthUnit.KILOMETER, lmdkm10.getDisplayUnit());
574 
575         FloatLengthMatrix lmskm10 =
576                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(20, 10), LengthUnit.KILOMETER, StorageType.SPARSE);
577         assertEquals(20, lmskm10.rows());
578         assertEquals(10, lmskm10.cols());
579         assertEquals(200, lmskm10.cardinality());
580         assertEquals(100 * 201 * 1000.0, lmskm10.zSum().getSI(), 0.001);
581         assertEquals(LengthUnit.KILOMETER, lmskm10.getDisplayUnit());
582 
583         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
584         assertEquals(lmskm10, lmskm10.toDense().toSparse());
585         assertEquals(lmdkm10, lmskm10.toDense());
586         assertEquals(lmskm10, lmdkm10.toSparse());
587         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
588         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
589         assertEquals(lmdkm10, lmdkm10.toDense());
590         assertEquals(lmskm10, lmskm10.toSparse());
591 
592         assertTrue(lmdkm10.isDense());
593         assertTrue(lmskm10.isSparse());
594 
595         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
596         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
597         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
598         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
599         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
600         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
601         assertEquals(lmdkm10.hashCode(), lmdkm10.toDense().hashCode());
602         assertEquals(lmskm10.hashCode(), lmskm10.toSparse().hashCode());
603 
604         FloatLengthMatrix lmdsi10 =
605                 FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(20, 10), LengthUnit.CENTIMETER, StorageType.DENSE);
606         assertEquals(20, lmdsi10.rows());
607         assertEquals(10, lmdsi10.cols());
608         assertEquals(200, lmdsi10.cardinality());
609         assertEquals(100 * 201, lmdsi10.zSum().getSI(), 0.001);
610         assertEquals(LengthUnit.CENTIMETER, lmdsi10.getDisplayUnit());
611 
612         FloatLengthMatrix lmssi10 =
613                 FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(20, 10), LengthUnit.CENTIMETER, StorageType.SPARSE);
614         assertEquals(20, lmssi10.rows());
615         assertEquals(10, lmssi10.cols());
616         assertEquals(200, lmssi10.cardinality());
617         assertEquals(100 * 201, lmssi10.zSum().getSI(), 0.001);
618         assertEquals(LengthUnit.CENTIMETER, lmssi10.getDisplayUnit());
619 
620         FloatLengthMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(20, 10, FloatLength.class),
621                 LengthUnit.HECTOMETER, StorageType.DENSE);
622         assertEquals(20, lmdsc10.rows());
623         assertEquals(10, lmdsc10.cols());
624         assertEquals(200, lmdsc10.cardinality());
625         assertEquals(100 * 201, lmdsc10.zSum().getSI(), 0.001);
626         assertEquals(LengthUnit.HECTOMETER, lmdsc10.getDisplayUnit());
627 
628         FloatLengthMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(20, 10, FloatLength.class),
629                 LengthUnit.HECTOMETER, StorageType.SPARSE);
630         assertEquals(20, lmssc10.rows());
631         assertEquals(10, lmssc10.cols());
632         assertEquals(200, lmssc10.cardinality());
633         assertEquals(100 * 201, lmssc10.zSum().getSI(), 0.001);
634         assertEquals(LengthUnit.HECTOMETER, lmssc10.getDisplayUnit());
635     }
636 
637     /**
638      * Test the instantiation of dense and sparse matrix types with sparse data (90% zeros).
639      */
640     @Test
641     public void testInstantiatRectSparseData()
642     {
643         FloatLengthMatrix lmdkm10 =
644                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(20, 10), LengthUnit.KILOMETER, StorageType.DENSE);
645         assertEquals(20, lmdkm10.rows());
646         assertEquals(10, lmdkm10.cols());
647         assertEquals(10, lmdkm10.cardinality());
648         assertEquals(5 * 11 * 1000.0, lmdkm10.zSum().getSI(), 0.001);
649         assertEquals(LengthUnit.KILOMETER, lmdkm10.getDisplayUnit());
650 
651         FloatLengthMatrix lmskm10 =
652                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(20, 10), LengthUnit.KILOMETER, StorageType.SPARSE);
653         assertEquals(20, lmskm10.rows());
654         assertEquals(10, lmskm10.cols());
655         assertEquals(10, lmskm10.cardinality());
656         assertEquals(5 * 11 * 1000.0, lmskm10.zSum().getSI(), 0.001);
657         assertEquals(LengthUnit.KILOMETER, lmskm10.getDisplayUnit());
658 
659         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
660         assertEquals(lmskm10, lmskm10.toDense().toSparse());
661         assertEquals(lmdkm10, lmskm10.toDense());
662         assertEquals(lmskm10, lmdkm10.toSparse());
663         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
664         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
665 
666         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
667         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
668         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
669         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
670         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
671         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
672         assertEquals(lmdkm10.hashCode(), lmdkm10.toDense().hashCode());
673         assertEquals(lmskm10.hashCode(), lmskm10.toSparse().hashCode());
674 
675         FloatLengthMatrix lmdsi10 =
676                 FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(20, 10), LengthUnit.CENTIMETER, StorageType.DENSE);
677         assertEquals(20, lmdsi10.rows());
678         assertEquals(10, lmdsi10.cols());
679         assertEquals(10, lmdsi10.cardinality());
680         assertEquals(5 * 11, lmdsi10.zSum().getSI(), 0.001);
681         assertEquals(LengthUnit.CENTIMETER, lmdsi10.getDisplayUnit());
682 
683         FloatLengthMatrix lmssi10 =
684                 FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(20, 10), LengthUnit.CENTIMETER, StorageType.SPARSE);
685         assertEquals(20, lmssi10.rows());
686         assertEquals(10, lmssi10.cols());
687         assertEquals(10, lmssi10.cardinality());
688         assertEquals(5 * 11, lmssi10.zSum().getSI(), 0.001);
689         assertEquals(LengthUnit.CENTIMETER, lmssi10.getDisplayUnit());
690 
691         FloatLengthMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(20, 10, FloatLength.class),
692                 LengthUnit.HECTOMETER, StorageType.DENSE);
693         assertEquals(20, lmdsc10.rows());
694         assertEquals(10, lmdsc10.cols());
695         assertEquals(10, lmdsc10.cardinality());
696         assertEquals(5 * 11, lmdsc10.zSum().getSI(), 0.001);
697         assertEquals(LengthUnit.HECTOMETER, lmdsc10.getDisplayUnit());
698 
699         FloatLengthMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(20, 10, FloatLength.class),
700                 LengthUnit.HECTOMETER, StorageType.SPARSE);
701         assertEquals(20, lmssc10.rows());
702         assertEquals(10, lmssc10.cols());
703         assertEquals(10, lmssc10.cardinality());
704         assertEquals(5 * 11, lmssc10.zSum().getSI(), 0.001);
705         assertEquals(LengthUnit.HECTOMETER, lmssc10.getDisplayUnit());
706 
707         FloatLengthMatrix lmdtu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(20, 10, FloatLength.class), 20, 10,
708                 LengthUnit.NANOMETER, StorageType.DENSE);
709         assertEquals(20, lmdtu10.rows());
710         assertEquals(10, lmdtu10.cols());
711         assertEquals(10, lmdtu10.cardinality());
712         assertEquals(5 * 11, lmdtu10.zSum().getSI(), 0.001);
713         assertEquals(LengthUnit.NANOMETER, lmdtu10.getDisplayUnit());
714 
715         FloatLengthMatrix lmstu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(20, 10, FloatLength.class), 20, 10,
716                 LengthUnit.NANOMETER, StorageType.SPARSE);
717         assertEquals(20, lmstu10.rows());
718         assertEquals(10, lmstu10.cols());
719         assertEquals(10, lmstu10.cardinality());
720         assertEquals(5 * 11, lmstu10.zSum().getSI(), 0.001);
721         assertEquals(LengthUnit.NANOMETER, lmstu10.getDisplayUnit());
722     }
723 
724     /**
725      * Test the instantiation of dense and sparse matrix types with dense data (no zeros).
726      */
727     @Test
728     public void testInstantiateRectDenseDataWithClass()
729     {
730         FloatAreaMatrix lmdkm10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(20, 10), AreaUnit.SQUARE_KILOMETER,
731                 StorageType.DENSE, FloatAreaMatrix.class);
732         assertEquals(20, lmdkm10.rows());
733         assertEquals(10, lmdkm10.cols());
734         assertEquals(200, lmdkm10.cardinality());
735         assertEquals(100 * 201 * 1.0E6, lmdkm10.zSum().getSI(), 1000);
736         assertEquals(AreaUnit.SQUARE_KILOMETER, lmdkm10.getDisplayUnit());
737 
738         FloatAreaMatrix lmskm10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(20, 10), AreaUnit.SQUARE_KILOMETER,
739                 StorageType.SPARSE, FloatAreaMatrix.class);
740         assertEquals(20, lmskm10.rows());
741         assertEquals(10, lmskm10.cols());
742         assertEquals(200, lmskm10.cardinality());
743         assertEquals(100 * 201 * 1.0E6, lmskm10.zSum().getSI(), 1000);
744         assertEquals(AreaUnit.SQUARE_KILOMETER, lmskm10.getDisplayUnit());
745 
746         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
747         assertEquals(lmskm10, lmskm10.toDense().toSparse());
748         assertEquals(lmdkm10, lmskm10.toDense());
749         assertEquals(lmskm10, lmdkm10.toSparse());
750         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
751         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
752 
753         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
754         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
755         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
756         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
757         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
758         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
759         assertEquals(lmdkm10.hashCode(), lmdkm10.toDense().hashCode());
760         assertEquals(lmskm10.hashCode(), lmskm10.toSparse().hashCode());
761 
762         FloatAreaMatrix lmdsi10 = FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(20, 10), AreaUnit.SQUARE_CENTIMETER,
763                 StorageType.DENSE, FloatAreaMatrix.class);
764         assertEquals(20, lmdsi10.rows());
765         assertEquals(10, lmdsi10.cols());
766         assertEquals(200, lmdsi10.cardinality());
767         assertEquals(100 * 201, lmdsi10.zSum().getSI(), 0.001);
768         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmdsi10.getDisplayUnit());
769 
770         FloatAreaMatrix lmssi10 = FloatMatrix.instantiateSI(FLOATMATRIX.denseRectArrays(20, 10), AreaUnit.SQUARE_CENTIMETER,
771                 StorageType.SPARSE, FloatAreaMatrix.class);
772         assertEquals(20, lmssi10.rows());
773         assertEquals(10, lmssi10.cols());
774         assertEquals(200, lmssi10.cardinality());
775         assertEquals(100 * 201, lmssi10.zSum().getSI(), 0.001);
776         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmssi10.getDisplayUnit());
777 
778         FloatAreaMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(20, 10, FloatArea.class),
779                 AreaUnit.SQUARE_HECTOMETER, StorageType.DENSE, FloatAreaMatrix.class);
780         assertEquals(20, lmdsc10.rows());
781         assertEquals(10, lmdsc10.cols());
782         assertEquals(200, lmdsc10.cardinality());
783         assertEquals(100 * 201, lmdsc10.zSum().getSI(), 0.001);
784         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmdsc10.getDisplayUnit());
785 
786         FloatAreaMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.denseRectScalarArrays(20, 10, FloatArea.class),
787                 AreaUnit.SQUARE_HECTOMETER, StorageType.SPARSE, FloatAreaMatrix.class);
788         assertEquals(20, lmssc10.rows());
789         assertEquals(10, lmssc10.cols());
790         assertEquals(200, lmssc10.cardinality());
791         assertEquals(100 * 201, lmssc10.zSum().getSI(), 0.001);
792         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmssc10.getDisplayUnit());
793     }
794 
795     /**
796      * Test the instantiation of dense and sparse matrix types with sparse data (90% zeros).
797      */
798     @Test
799     public void testInstantiatRectSparseDataWithClass()
800     {
801         FloatAreaMatrix lmdkm10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(20, 10), AreaUnit.SQUARE_KILOMETER,
802                 StorageType.DENSE, FloatAreaMatrix.class);
803         assertEquals(20, lmdkm10.rows());
804         assertEquals(10, lmdkm10.cols());
805         assertEquals(10, lmdkm10.cardinality());
806         assertEquals(5 * 11 * 1.0E6, lmdkm10.zSum().getSI(), 0.1);
807         assertEquals(AreaUnit.SQUARE_KILOMETER, lmdkm10.getDisplayUnit());
808 
809         FloatAreaMatrix lmskm10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(20, 10), AreaUnit.SQUARE_KILOMETER,
810                 StorageType.SPARSE, FloatAreaMatrix.class);
811         assertEquals(20, lmskm10.rows());
812         assertEquals(10, lmskm10.cols());
813         assertEquals(10, lmskm10.cardinality());
814         assertEquals(5 * 11 * 1.0E6, lmskm10.zSum().getSI(), 0.1);
815         assertEquals(AreaUnit.SQUARE_KILOMETER, lmskm10.getDisplayUnit());
816 
817         assertEquals(lmdkm10, lmdkm10.toSparse().toDense());
818         assertEquals(lmskm10, lmskm10.toDense().toSparse());
819         assertEquals(lmdkm10, lmskm10.toDense());
820         assertEquals(lmskm10, lmdkm10.toSparse());
821         assertEquals(lmdkm10, lmdkm10.toSparse()); // dense and sparse are the same if content is the same
822         assertEquals(lmskm10, lmskm10.toDense()); // dense and sparse are the same if content is the same
823 
824         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().toDense().hashCode());
825         assertEquals(lmskm10.hashCode(), lmskm10.toDense().toSparse().hashCode());
826         assertEquals(lmdkm10.hashCode(), lmskm10.toDense().hashCode());
827         assertEquals(lmskm10.hashCode(), lmdkm10.toSparse().hashCode());
828         assertEquals(lmdkm10.hashCode(), lmdkm10.toSparse().hashCode());
829         assertEquals(lmskm10.hashCode(), lmskm10.toDense().hashCode());
830         assertEquals(lmdkm10.hashCode(), lmdkm10.toDense().hashCode());
831         assertEquals(lmskm10.hashCode(), lmskm10.toSparse().hashCode());
832 
833         FloatAreaMatrix lmdsi10 = FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(20, 10), AreaUnit.SQUARE_CENTIMETER,
834                 StorageType.DENSE, FloatAreaMatrix.class);
835         assertEquals(20, lmdsi10.rows());
836         assertEquals(10, lmdsi10.cols());
837         assertEquals(10, lmdsi10.cardinality());
838         assertEquals(5 * 11, lmdsi10.zSum().getSI(), 0.001);
839         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmdsi10.getDisplayUnit());
840 
841         FloatAreaMatrix lmssi10 = FloatMatrix.instantiateSI(FLOATMATRIX.sparseRectArrays(20, 10), AreaUnit.SQUARE_CENTIMETER,
842                 StorageType.SPARSE, FloatAreaMatrix.class);
843         assertEquals(20, lmssi10.rows());
844         assertEquals(10, lmssi10.cols());
845         assertEquals(10, lmssi10.cardinality());
846         assertEquals(5 * 11, lmssi10.zSum().getSI(), 0.001);
847         assertEquals(AreaUnit.SQUARE_CENTIMETER, lmssi10.getDisplayUnit());
848 
849         FloatAreaMatrix lmdsc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(20, 10, FloatArea.class),
850                 AreaUnit.SQUARE_HECTOMETER, StorageType.DENSE, FloatAreaMatrix.class);
851         assertEquals(20, lmdsc10.rows());
852         assertEquals(10, lmdsc10.cols());
853         assertEquals(10, lmdsc10.cardinality());
854         assertEquals(5 * 11, lmdsc10.zSum().getSI(), 0.001);
855         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmdsc10.getDisplayUnit());
856 
857         FloatAreaMatrix lmssc10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectScalarArrays(20, 10, FloatArea.class),
858                 AreaUnit.SQUARE_HECTOMETER, StorageType.SPARSE, FloatAreaMatrix.class);
859         assertEquals(20, lmssc10.rows());
860         assertEquals(10, lmssc10.cols());
861         assertEquals(10, lmssc10.cardinality());
862         assertEquals(5 * 11, lmssc10.zSum().getSI(), 0.001);
863         assertEquals(AreaUnit.SQUARE_HECTOMETER, lmssc10.getDisplayUnit());
864 
865         FloatAreaMatrix lmdtu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(20, 10, FloatArea.class), 20, 10,
866                 AreaUnit.ACRE, StorageType.DENSE, FloatAreaMatrix.class);
867         assertEquals(20, lmdtu10.rows());
868         assertEquals(10, lmdtu10.cols());
869         assertEquals(10, lmdtu10.cardinality());
870         assertEquals(5 * 11, lmdtu10.zSum().getSI(), 0.001);
871         assertEquals(AreaUnit.ACRE, lmdtu10.getDisplayUnit());
872 
873         FloatAreaMatrix lmstu10 = FloatMatrix.instantiate(FLOATMATRIX.sparseRectTuples(20, 10, FloatArea.class), 20, 10,
874                 AreaUnit.ACRE, StorageType.SPARSE, FloatAreaMatrix.class);
875         assertEquals(20, lmstu10.rows());
876         assertEquals(10, lmstu10.cols());
877         assertEquals(10, lmstu10.cardinality());
878         assertEquals(5 * 11, lmstu10.zSum().getSI(), 0.001);
879         assertEquals(AreaUnit.ACRE, lmstu10.getDisplayUnit());
880 
881         assertNotEquals(lmdkm10, lmdsi10);
882         assertNotEquals(lmdkm10, lmssi10);
883         assertNotEquals(lmskm10, lmdsi10);
884         assertNotEquals(lmskm10, lmssi10);
885         assertNotEquals(lmdkm10, lmdtu10);
886         assertNotEquals(lmdkm10, lmstu10);
887         assertNotEquals(lmskm10, lmdtu10);
888         assertNotEquals(lmskm10, lmstu10);
889 
890         assertNotEquals(lmdkm10.hashCode(), lmdsi10.hashCode());
891         assertNotEquals(lmdkm10.hashCode(), lmssi10.hashCode());
892         assertNotEquals(lmskm10.hashCode(), lmdsi10.hashCode());
893         assertNotEquals(lmskm10.hashCode(), lmssi10.hashCode());
894         assertNotEquals(lmdkm10.hashCode(), lmdtu10.hashCode());
895         assertNotEquals(lmdkm10.hashCode(), lmstu10.hashCode());
896         assertNotEquals(lmskm10.hashCode(), lmdtu10.hashCode());
897         assertNotEquals(lmskm10.hashCode(), lmstu10.hashCode());
898     }
899 
900     /**
901      * Test the instantiation of dense and sparse matrix types with dense data (no zeros).
902      * @throws UnitException on error
903      */
904     @Test
905     public void testInstantiateRectSIUnit() throws UnitException
906     {
907         FloatSIMatrix si10dd =
908                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(20, 10), SIUnit.of("m2/s3"), StorageType.DENSE);
909         assertEquals(20, si10dd.rows());
910         assertEquals(10, si10dd.cols());
911         assertEquals(200, si10dd.cardinality());
912         assertEquals(100 * 201, si10dd.zSum().getSI(), 0.001);
913         assertEquals("m2/s3", si10dd.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
914         assertEquals("getScalarClass returns FloatSIScalar", FloatSIScalar.class, si10dd.getScalarClass());
915         assertEquals("getVectorClass returns FloatSIVector", FloatSIVector.class, si10dd.getVectorClass());
916 
917         FloatSIMatrix si10ds =
918                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(20, 10), SIUnit.of("m2/s3"), StorageType.SPARSE);
919         assertEquals(20, si10ds.rows());
920         assertEquals(10, si10ds.cols());
921         assertEquals(200, si10ds.cardinality());
922         assertEquals(100 * 201, si10ds.zSum().getSI(), 0.001);
923         assertEquals("m2/s3", si10ds.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
924 
925         FloatSIMatrix si10sd =
926                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(20, 10), SIUnit.of("m2/s3"), StorageType.DENSE);
927         assertEquals(20, si10sd.rows());
928         assertEquals(10, si10sd.cols());
929         assertEquals(10, si10sd.cardinality());
930         assertEquals(5 * 11, si10sd.zSum().getSI(), 0.001);
931         assertEquals("m2/s3", si10sd.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
932 
933         FloatSIMatrix si10ss =
934                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(20, 10), SIUnit.of("m2/s3"), StorageType.SPARSE);
935         assertEquals(20, si10ss.rows());
936         assertEquals(10, si10ss.cols());
937         assertEquals(10, si10ss.cardinality());
938         assertEquals(5 * 11, si10ss.zSum().getSI(), 0.001);
939         assertEquals("m2/s3", si10ss.getDisplayUnit().getQuantity().getSiDimensions().toString(true, false, false));
940 
941         assertEquals(si10dd, si10ds.toDense());
942         assertEquals(si10ds, si10dd.toSparse());
943         assertEquals(si10dd, si10dd.toDense());
944         assertEquals(si10ds, si10ds.toSparse());
945         assertEquals(si10dd, si10dd.toSparse().toDense());
946         assertEquals(si10ds, si10ds.toDense().toSparse());
947 
948         assertEquals(si10sd, si10ss.toDense());
949         assertEquals(si10ss, si10sd.toSparse());
950         assertEquals(si10sd, si10sd.toDense());
951         assertEquals(si10ss, si10ss.toSparse());
952         assertEquals(si10sd, si10sd.toSparse().toDense());
953         assertEquals(si10ss, si10ss.toDense().toSparse());
954 
955         assertEquals(si10dd.hashCode(), si10ds.toDense().hashCode());
956         assertEquals(si10ds.hashCode(), si10dd.toSparse().hashCode());
957         assertEquals(si10dd.hashCode(), si10dd.toDense().hashCode());
958         assertEquals(si10ds.hashCode(), si10ds.toSparse().hashCode());
959         assertEquals(si10dd.hashCode(), si10dd.toSparse().toDense().hashCode());
960         assertEquals(si10ds.hashCode(), si10ds.toDense().toSparse().hashCode());
961         assertEquals(si10dd.hashCode(), si10dd.toSparse().hashCode());
962         assertEquals(si10ds.hashCode(), si10ds.toDense().hashCode());
963 
964         assertEquals(si10sd.hashCode(), si10ss.toDense().hashCode());
965         assertEquals(si10ss.hashCode(), si10sd.toSparse().hashCode());
966         assertEquals(si10sd.hashCode(), si10sd.toDense().hashCode());
967         assertEquals(si10ss.hashCode(), si10ss.toSparse().hashCode());
968         assertEquals(si10sd.hashCode(), si10sd.toSparse().hashCode());
969         assertEquals(si10ss.hashCode(), si10ss.toDense().hashCode());
970     }
971 
972     // =============================================== EDGE CASE MATRICES ===================================================
973 
974     /**
975      * Test the instantiation of dense and sparse matrix types with one row or one column, and errors with null pointers.
976      */
977     @Test
978     @SuppressWarnings({"checkstyle:methodlength", "checkstyle:localvariablename"})
979     public void testInstantiateEdgeCases()
980     {
981         // DENSE DATA
982 
983         FloatSpeedMatrix row1dd =
984                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(1, 10), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
985         assertEquals(1, row1dd.rows());
986         assertEquals(10, row1dd.cols());
987         assertEquals(10, row1dd.cardinality());
988         assertEquals(5 * 11, row1dd.zSum().getSI(), 0.001);
989         assertEquals(SpeedUnit.METER_PER_SECOND, row1dd.getDisplayUnit());
990 
991         FloatSpeedMatrix col1dd =
992                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 1), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
993         assertEquals(10, col1dd.rows());
994         assertEquals(1, col1dd.cols());
995         assertEquals(10, col1dd.cardinality());
996         assertEquals(5 * 11, col1dd.zSum().getSI(), 0.001);
997         assertEquals(SpeedUnit.METER_PER_SECOND, col1dd.getDisplayUnit());
998 
999         FloatSpeedMatrix row1ds =
1000                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(1, 10), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1001         assertEquals(1, row1ds.rows());
1002         assertEquals(10, row1ds.cols());
1003         assertEquals(10, row1ds.cardinality());
1004         assertEquals(5 * 11, row1ds.zSum().getSI(), 0.001);
1005         assertEquals(SpeedUnit.METER_PER_SECOND, row1ds.getDisplayUnit());
1006 
1007         FloatSpeedMatrix col1ds =
1008                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(10, 1), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1009         assertEquals(10, col1ds.rows());
1010         assertEquals(1, col1ds.cols());
1011         assertEquals(10, col1ds.cardinality());
1012         assertEquals(5 * 11, col1ds.zSum().getSI(), 0.001);
1013         assertEquals(SpeedUnit.METER_PER_SECOND, col1ds.getDisplayUnit());
1014 
1015         // SPARSE DATA
1016 
1017         FloatSpeedMatrix row1sd =
1018                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(1, 10), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
1019         assertEquals(1, row1sd.rows());
1020         assertEquals(10, row1sd.cols());
1021         assertEquals(1, row1sd.cardinality());
1022         assertEquals(1, row1sd.zSum().getSI(), 0.001);
1023         assertEquals(SpeedUnit.METER_PER_SECOND, row1sd.getDisplayUnit());
1024 
1025         FloatSpeedMatrix col1sd =
1026                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 1), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
1027         assertEquals(10, col1sd.rows());
1028         assertEquals(1, col1sd.cols());
1029         assertEquals(1, col1sd.cardinality());
1030         assertEquals(1, col1sd.zSum().getSI(), 0.001);
1031         assertEquals(SpeedUnit.METER_PER_SECOND, col1sd.getDisplayUnit());
1032 
1033         FloatSpeedMatrix row1ss =
1034                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(1, 10), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1035         assertEquals(1, row1ss.rows());
1036         assertEquals(10, row1ss.cols());
1037         assertEquals(1, row1ss.cardinality());
1038         assertEquals(1, row1ss.zSum().getSI(), 0.001);
1039         assertEquals(SpeedUnit.METER_PER_SECOND, row1ss.getDisplayUnit());
1040 
1041         FloatSpeedMatrix col1ss =
1042                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(10, 1), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1043         assertEquals(10, col1ss.rows());
1044         assertEquals(1, col1ss.cols());
1045         assertEquals(1, col1ss.cardinality());
1046         assertEquals(1, col1ss.zSum().getSI(), 0.001);
1047         assertEquals(SpeedUnit.METER_PER_SECOND, col1ss.getDisplayUnit());
1048 
1049         // equals
1050 
1051         assertEquals(row1dd, row1dd);
1052         assertEquals(row1ss, row1ss);
1053         assertEquals(row1dd, row1ds);
1054         assertEquals(col1dd, col1ds);
1055         assertEquals(row1sd, row1ss);
1056         assertEquals(col1sd, col1ss);
1057         assertEquals(row1ds, row1dd);
1058         assertEquals(col1ds, col1dd);
1059         assertEquals(row1ss, row1sd);
1060         assertEquals(col1ss, col1sd);
1061         assertNotEquals(row1dd, col1dd);
1062         assertNotEquals(col1dd, row1dd);
1063         assertNotEquals(row1ss, col1ss);
1064         assertNotEquals(col1ss, row1ss);
1065         assertNotEquals(row1ds, col1sd);
1066         assertNotEquals(col1ds, row1sd);
1067         assertNotEquals(row1sd, col1ds);
1068         assertNotEquals(col1sd, row1ds);
1069 
1070         assertEquals(row1dd.hashCode(), row1dd.hashCode());
1071         assertEquals(row1ss.hashCode(), row1ss.hashCode());
1072         assertEquals(row1dd.hashCode(), row1ds.hashCode());
1073         assertEquals(col1dd.hashCode(), col1ds.hashCode());
1074         assertEquals(row1sd.hashCode(), row1ss.hashCode());
1075         assertEquals(col1sd.hashCode(), col1ss.hashCode());
1076         assertEquals(row1ds.hashCode(), row1dd.hashCode());
1077         assertEquals(col1ds.hashCode(), col1dd.hashCode());
1078         assertEquals(row1ss.hashCode(), row1sd.hashCode());
1079         assertEquals(col1ss.hashCode(), col1sd.hashCode());
1080         assertNotEquals(row1dd.hashCode(), col1dd.hashCode());
1081         assertNotEquals(col1dd.hashCode(), row1dd.hashCode());
1082         assertNotEquals(row1ss.hashCode(), col1ss.hashCode());
1083         assertNotEquals(col1ss.hashCode(), row1ss.hashCode());
1084         assertNotEquals(row1ds.hashCode(), col1sd.hashCode());
1085         assertNotEquals(col1ds.hashCode(), row1sd.hashCode());
1086         assertNotEquals(row1sd.hashCode(), col1ds.hashCode());
1087         assertNotEquals(col1sd.hashCode(), row1ds.hashCode());
1088 
1089         // 1 x 1 DENSE DATA
1090 
1091         FloatSpeedMatrix row11dd =
1092                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
1093         assertEquals(1, row11dd.rows());
1094         assertEquals(1, row11dd.cols());
1095         assertEquals(1, row11dd.cardinality());
1096         assertEquals(1, row11dd.zSum().getSI(), 0.001);
1097         assertEquals(SpeedUnit.METER_PER_SECOND, row11dd.getDisplayUnit());
1098 
1099         FloatSpeedMatrix col11dd =
1100                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
1101         assertEquals(1, col11dd.rows());
1102         assertEquals(1, col11dd.cols());
1103         assertEquals(1, col11dd.cardinality());
1104         assertEquals(1, col11dd.zSum().getSI(), 0.001);
1105         assertEquals(SpeedUnit.METER_PER_SECOND, col11dd.getDisplayUnit());
1106 
1107         FloatSpeedMatrix row11ds =
1108                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1109         assertEquals(1, row11ds.rows());
1110         assertEquals(1, row11ds.cols());
1111         assertEquals(1, row11ds.cardinality());
1112         assertEquals(1, row11ds.zSum().getSI(), 0.001);
1113         assertEquals(SpeedUnit.METER_PER_SECOND, row11ds.getDisplayUnit());
1114 
1115         FloatSpeedMatrix col11ds =
1116                 FloatMatrix.instantiate(FLOATMATRIX.denseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1117         assertEquals(1, col11ds.rows());
1118         assertEquals(1, col11ds.cols());
1119         assertEquals(1, col11ds.cardinality());
1120         assertEquals(1, col11ds.zSum().getSI(), 0.001);
1121         assertEquals(SpeedUnit.METER_PER_SECOND, col11ds.getDisplayUnit());
1122 
1123         // 1 x 1 SPARSE DATA
1124 
1125         FloatSpeedMatrix row11sd =
1126                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
1127         assertEquals(1, row11sd.rows());
1128         assertEquals(1, row11sd.cols());
1129         assertEquals(1, row11sd.cardinality());
1130         assertEquals(1, row11sd.zSum().getSI(), 0.001);
1131         assertEquals(SpeedUnit.METER_PER_SECOND, row11sd.getDisplayUnit());
1132 
1133         FloatSpeedMatrix col11sd =
1134                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.DENSE);
1135         assertEquals(1, col11sd.rows());
1136         assertEquals(1, col11sd.cols());
1137         assertEquals(1, col11sd.cardinality());
1138         assertEquals(1, col11sd.zSum().getSI(), 0.001);
1139         assertEquals(SpeedUnit.METER_PER_SECOND, col11sd.getDisplayUnit());
1140 
1141         FloatSpeedMatrix row11ss =
1142                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1143         assertEquals(1, row11ss.rows());
1144         assertEquals(1, row11ss.cols());
1145         assertEquals(1, row11ss.cardinality());
1146         assertEquals(1, row11ss.zSum().getSI(), 0.001);
1147         assertEquals(SpeedUnit.METER_PER_SECOND, row11ss.getDisplayUnit());
1148 
1149         FloatSpeedMatrix col11ss =
1150                 FloatMatrix.instantiate(FLOATMATRIX.sparseRectArrays(1, 1), SpeedUnit.METER_PER_SECOND, StorageType.SPARSE);
1151         assertEquals(1, col11ss.rows());
1152         assertEquals(1, col11ss.cols());
1153         assertEquals(1, col11ss.cardinality());
1154         assertEquals(1, col11ss.zSum().getSI(), 0.001);
1155         assertEquals(SpeedUnit.METER_PER_SECOND, col11ss.getDisplayUnit());
1156 
1157         // NULL
1158 
1159         float[][] d1_1 = new float[1][];
1160         d1_1[0] = new float[1];
1161 
1162         Try.testFail(() -> FloatMatrix.instantiate((float[][]) null, SpeedUnit.METER_PER_SECOND, StorageType.DENSE),
1163                 "constructing matrix with null input should have thrown an exception", NullPointerException.class);
1164         Try.testFail(() -> FloatMatrix.instantiate(d1_1, null, StorageType.DENSE),
1165                 "constructing matrix with null unit should have thrown an exception", NullPointerException.class);
1166         Try.testFail(() -> FloatMatrix.instantiate(d1_1, SpeedUnit.METER_PER_SECOND, null),
1167                 "constructing matrix with null storage type should have thrown an exception", NullPointerException.class);
1168     }
1169 
1170     /**
1171      * Test matrix construction and operations with zero length.
1172      */
1173     @Test
1174     public void testInstantiateZero()
1175     {
1176         float[][] floatMatrix00 = new float[0][0];
1177         float[][] floatMatrix10 = new float[1][];
1178         floatMatrix10[0] = new float[] {};
1179         FloatSpeed[][] speedMatrix00 = new FloatSpeed[0][0];
1180         FloatSpeed[][] speedMatrix10 = new FloatSpeed[1][];
1181         speedMatrix10[0] = new FloatSpeed[] {};
1182         Collection<FloatSparseValue<SpeedUnit, FloatSpeed>> speedList = new ArrayList<>();
1183         SortedMap<Integer, FloatSpeedMatrix> smMap = new TreeMap<>();
1184         smMap.put(0,
1185                 FloatMatrix.instantiate(
1186                         FloatMatrixData.instantiate(floatMatrix00, SpeedUnit.KM_PER_HOUR.getScale(), StorageType.DENSE),
1187                         SpeedUnit.KM_PER_HOUR));
1188         smMap.put(1,
1189                 FloatMatrix.instantiate(
1190                         FloatMatrixData.instantiate(floatMatrix00, SpeedUnit.KM_PER_HOUR.getScale(), StorageType.SPARSE),
1191                         SpeedUnit.KM_PER_HOUR));
1192         smMap.put(2,
1193                 FloatMatrix.instantiate(FloatMatrixData.instantiate(speedMatrix00, StorageType.DENSE), SpeedUnit.KM_PER_HOUR));
1194         smMap.put(3,
1195                 FloatMatrix.instantiate(FloatMatrixData.instantiate(speedMatrix00, StorageType.SPARSE), SpeedUnit.KM_PER_HOUR));
1196         smMap.put(4, FloatMatrix.instantiate(FloatMatrixData.instantiate(speedList, 0, 0, StorageType.DENSE),
1197                 SpeedUnit.KM_PER_HOUR));
1198         smMap.put(5, FloatMatrix.instantiate(FloatMatrixData.instantiate(speedList, 0, 0, StorageType.SPARSE),
1199                 SpeedUnit.KM_PER_HOUR));
1200         smMap.put(6,
1201                 FloatMatrix.instantiate(
1202                         FloatMatrixData.instantiate(floatMatrix10, SpeedUnit.KM_PER_HOUR.getScale(), StorageType.DENSE),
1203                         SpeedUnit.KM_PER_HOUR));
1204         smMap.put(7,
1205                 FloatMatrix.instantiate(
1206                         FloatMatrixData.instantiate(floatMatrix10, SpeedUnit.KM_PER_HOUR.getScale(), StorageType.SPARSE),
1207                         SpeedUnit.KM_PER_HOUR));
1208         smMap.put(8,
1209                 FloatMatrix.instantiate(FloatMatrixData.instantiate(speedMatrix10, StorageType.DENSE), SpeedUnit.KM_PER_HOUR));
1210         smMap.put(9,
1211                 FloatMatrix.instantiate(FloatMatrixData.instantiate(speedMatrix10, StorageType.SPARSE), SpeedUnit.KM_PER_HOUR));
1212 
1213         for (Map.Entry<Integer, FloatSpeedMatrix> entry : smMap.entrySet())
1214         {
1215             int key = entry.getKey();
1216             FloatSpeedMatrix sv = entry.getValue();
1217             assertEquals("key=" + key, 0, sv.rows());
1218             assertEquals("key=" + key, 0, sv.cols());
1219             assertEquals("key=" + key, 0, sv.cardinality());
1220             assertEquals("key=" + key, 0, sv.getScalars().length);
1221             assertEquals("key=" + key, SpeedUnit.KM_PER_HOUR, sv.getDisplayUnit());
1222             assertEquals("DENSE/SPARSE: key = " + key, sv.getStorageType(),
1223                     key % 2 == 0 ? StorageType.DENSE : StorageType.SPARSE);
1224             assertFalse("key=" + key, sv.isMutable());
1225             FloatSpeedMatrix svm = sv.mutable();
1226             assertTrue("key=" + key, svm.isMutable());
1227             assertEquals(SpeedUnit.KM_PER_HOUR, svm.getDisplayUnit());
1228             assertEquals("DENSE/SPARSE: key = " + key, svm.getStorageType(),
1229                     key % 2 == 0 ? StorageType.DENSE : StorageType.SPARSE);
1230             FloatSpeedMatrix svr = svm.abs();
1231             assertEquals("key=" + key, 0, sv.rows());
1232             assertEquals("key=" + key, 0, sv.cols());
1233             assertEquals(SpeedUnit.KM_PER_HOUR, svr.getDisplayUnit());
1234             svm = svm.ceil();
1235             assertEquals("key=" + key, 0, sv.rows());
1236             assertEquals("key=" + key, 0, sv.cols());
1237             assertEquals("key=" + key, SpeedUnit.KM_PER_HOUR, svr.getDisplayUnit());
1238             svr = svm.decrementBy(FloatSpeed.ONE);
1239             assertEquals("key=" + key, 0, sv.rows());
1240             assertEquals("key=" + key, 0, sv.cols());
1241             assertEquals("key=" + key, SpeedUnit.KM_PER_HOUR, svr.getDisplayUnit());
1242             svr = svm.incrementBy(FloatSpeed.ONE);
1243             assertEquals("key=" + key, 0, sv.rows());
1244             assertEquals("key=" + key, 0, sv.cols());
1245             assertEquals(SpeedUnit.KM_PER_HOUR, svr.getDisplayUnit());
1246             svr = svm.plus(sv);
1247             assertEquals("key=" + key, 0, sv.rows());
1248             assertEquals("key=" + key, 0, sv.cols());
1249             assertEquals("key=" + key, SpeedUnit.KM_PER_HOUR, svr.getDisplayUnit());
1250             assertEquals("DENSE/SPARSE: key = " + key, svr.getStorageType(),
1251                     key % 2 == 0 ? StorageType.DENSE : StorageType.SPARSE);
1252             svr = sv.toDense();
1253             assertEquals("key=" + key, StorageType.DENSE, svr.getStorageType());
1254             svr = sv.toSparse();
1255             assertEquals("key=" + key, StorageType.SPARSE, svr.getStorageType());
1256             assertEquals("key=" + key, 0, sv.getValuesSI().length);
1257             assertEquals("key=" + key, 0, sv.getValuesInUnit().length);
1258             assertEquals("key=" + key, 0, sv.getValuesInUnit(SpeedUnit.KNOT).length);
1259             svr = sv.times(2.0);
1260             assertEquals("key=" + key, 0, sv.rows());
1261             assertEquals("key=" + key, 0, sv.cols());
1262             assertEquals("key=" + key, SpeedUnit.KM_PER_HOUR, svr.getDisplayUnit());
1263         }
1264     }
1265 
1266 }