View Javadoc
1   package org.djunits.value.vfloat.matrix;
2   
3   import java.io.Serializable;
4   
5   import org.djunits.unit.AbsoluteLinearUnit;
6   import org.djunits.unit.Unit;
7   import org.djunits.value.Absolute;
8   import org.djunits.value.FunctionsAbs;
9   import org.djunits.value.StorageType;
10  import org.djunits.value.ValueException;
11  import org.djunits.value.vfloat.scalar.AbstractFloatScalarAbs;
12  
13  /**
14   * Absolute Immutable typed matrix.
15   * <p>
16   * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17   * BSD-style license. See <a href="http://djunits.org/docs/license.html">DJUNITS License</a>.
18   * <p>
19   * $LastChangedDate: 2015-09-29 14:14:28 +0200 (Tue, 29 Sep 2015) $, @version $Revision: 73 $, by $Author: pknoppers $, initial
20   * version Sep 5, 2015 <br>
21   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
22   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
23   * @param <AU> the absolute unit
24   * @param <RU> the relative unit
25   * @param <A> the absolute matrix type
26   * @param <R> the relative matrix type
27   * @param <MA> the mutable absolute matrix type
28   * @param <S> the absolute scalar type
29   */
30  abstract class AbstractFloatMatrixAbs<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
31          A extends AbstractFloatMatrixAbs<AU, RU, A, R, MA, S>, R extends AbstractFloatMatrixRel<RU, R, ?, ?>,
32          MA extends AbstractMutableFloatMatrixAbs<AU, RU, A, R, MA, S>, S extends AbstractFloatScalarAbs<AU, S, RU, ?>>
33          extends AbstractFloatMatrix<AU, A> implements FunctionsAbs<AU, RU, A, R>, FloatMatrixInterface<AU>, Absolute, Serializable
34  {
35      /** */
36      private static final long serialVersionUID = 20151006L;
37  
38      /**
39       * Construct a new Absolute Immutable FloatMatrix.
40       * @param values float[][]; the values of the entries in the new Absolute Immutable FloatMatrix
41       * @param unit AU; the unit of the new Absolute Immutable FloatMatrix
42       * @param storageType the data type to use (e.g., DENSE or SPARSE)
43       * @throws ValueException when values is null
44       */
45      AbstractFloatMatrixAbs(final float[][] values, final AU unit, final StorageType storageType) throws ValueException
46      {
47          super(unit, FloatMatrixData.instantiate(ensureRectangularAndNonEmpty(values), unit.getScale(), storageType));
48  
49      }
50  
51      /**
52       * Construct a new Absolute Immutable FloatMatrix.
53       * @param values S[][]; the values of the entries in the new Absolute Immutable FloatMatrix
54       * @param storageType the data type to use (e.g., DENSE or SPARSE)
55       * @throws ValueException when values has zero entries
56       */
57      AbstractFloatMatrixAbs(final S[][] values, final StorageType storageType) throws ValueException
58      {
59          super(checkUnit(values), FloatMatrixData.instantiate(values, storageType));
60      }
61  
62      /**
63       * Construct a new Relative Immutable FloatMatrix.
64       * @param data an internal data object
65       * @param unit the unit
66       */
67      AbstractFloatMatrixAbs(final FloatMatrixData data, final AU unit)
68      {
69          super(unit, data.copy());
70      }
71  
72      /**
73       * Create a mutable version of this FloatMatrix. <br>
74       * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation
75       * in the mutable version that modifies the data shall trigger a deep copy of the data.
76       * @return MA; mutable version of this FloatMatrix
77       */
78      public MA mutable()
79      {
80          return instantiateMutableType(getData(), getUnit());
81      }
82  
83      /**
84       * Construct a new Absolute Immutable FloatMatrix of the right type. Each extending class must implement this method.
85       * @param dmd an internal data object
86       * @param unit the unit
87       * @return M the Mutable FloatMatrix of the right type
88       */
89      protected abstract A instantiateTypeAbs(FloatMatrixData dmd, AU unit);
90  
91      /**
92       * Construct a new Relative Immutable FloatMatrix of the right type. Each extending class must implement this method.
93       * @param dmd an internal data object
94       * @param unit the unit
95       * @return M the Mutable FloatMatrix of the right type
96       */
97      protected abstract R instantiateTypeRel(FloatMatrixData dmd, RU unit);
98  
99      /**
100      * Construct a new Absolute Mutable FloatMatrix of the right type. Each extending class must implement this method.
101      * @param dmd an internal data object
102      * @param unit the unit
103      * @return M the Mutable FloatMatrix of the right type
104      */
105     protected abstract MA instantiateMutableType(FloatMatrixData dmd, AU unit);
106 
107     /**
108      * Construct a new Absolute Immutable FloatScalar of the right type. Each extending class must implement this method.
109      * @param value the value
110      * @param unit the unit
111      * @return S the Immutable FloatScalar of the right type
112      */
113     protected abstract S instantiateScalar(float value, AU unit);
114 
115     /**
116      * Return the Scalar value at the index position.
117      * @param row the row position
118      * @param column the column position
119      * @return S the scalar
120      * @throws ValueException when index out of bounds
121      */
122     @SuppressWarnings("checkstyle:designforextension")
123     public final S get(final int row, final int column) throws ValueException
124     {
125         checkIndex(row, column);
126         return instantiateScalar(getInUnit(row, column, getUnit()), getUnit());
127     }
128 
129     /**********************************************************************************/
130     /**************************** TYPED CALCULATION METHODS ***************************/
131     /**********************************************************************************/
132 
133     /** {@inheritDoc} */
134     @Override
135     public final A plus(final R rel) throws ValueException
136     {
137         return instantiateTypeAbs(this.getData().plus(rel.getData()), getUnit());
138     }
139 
140     /** {@inheritDoc} */
141     @Override
142     public final A minus(final R rel) throws ValueException
143     {
144         return instantiateTypeAbs(this.getData().minus(rel.getData()), getUnit());
145     }
146 
147     /** {@inheritDoc} */
148     @Override
149     public final R minus(final A abs) throws ValueException
150     {
151         return instantiateTypeRel(this.getData().minus(abs.getData()), getUnit().getRelativeUnit());
152     }
153 
154     /* ============================================================================================ */
155     /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */
156     /* ============================================================================================ */
157 
158     /**
159      * Check that a provided array can be used to create some descendant of a FloatMatrix, and return the Unit.
160      * @param dsArray the array to check and get the unit for
161      * @param <AU> the absolute unit
162      * @param <RU> the corresponding relative unit
163      * @param <S> the scalar type
164      * @return the unit of the object
165      * @throws ValueException when the array is null, has length equal to 0, or has first entry with length equal to 0
166      */
167     static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
168             S extends AbstractFloatScalarAbs<AU, S, RU, ?>> AU checkUnit(final S[][] dsArray) throws ValueException
169     {
170         ensureRectangularAndNonEmpty(dsArray);
171         return dsArray[0][0].getUnit();
172     }
173 
174     /**
175      * Check that a 2D array of FloatScalar&lt;?&gt; is rectangular; i.e. all rows have the same length and is non empty.
176      * @param values FloatScalar&lt;?&gt;[][]; the 2D array to check
177      * @param <AU> the absolute unit
178      * @param <RU> the corresponding relative unit
179      * @param <S> the scalar type
180      * @throws ValueException when values is not rectangular, or contains no data
181      */
182     protected static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
183             S extends AbstractFloatScalarAbs<AU, S, RU, ?>> void ensureRectangularAndNonEmpty(final S[][] values)
184                     throws ValueException
185     {
186         if (null == values)
187         {
188             throw new ValueException("Cannot create a FloatVector or MutableFloatVector from an empty array of FloatScalar");
189         }
190         if (0 == values.length || 0 == values[0].length)
191         {
192             throw new ValueException("Creating FloatVector or MutableFloatVector: "
193                     + "Cannot determine unit for FloatMatrix from an empty array of FloatScalar");
194         }
195         for (int row = values.length; --row >= 1;)
196         {
197             if (values[0].length != values[row].length)
198             {
199                 throw new ValueException("Creating FloatVector or MutableFloatVector: Lengths of rows are not all the same");
200             }
201         }
202     }
203 }