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-2019 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, ?>> extends
33          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 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 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 FloatMatrixData; an internal data object
65       * @param unit AU; 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 FloatMatrixData; an internal data object
86       * @param unit AU; 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 FloatMatrixData; an internal data object
94       * @param unit RU; 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 FloatMatrixData; an internal data object
102      * @param unit AU; 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 float; the value
110      * @param unit AU; the unit
111      * @return S the Immutable FloatScalar of the right type
112      */
113     protected abstract S instantiateScalar(float value, AU unit);
114 
115     /** {@inheritDoc} */
116     @Override
117     @SuppressWarnings("checkstyle:designforextension")
118     public final S get(final int row, final int column) throws ValueException
119     {
120         checkIndex(row, column);
121         return instantiateScalar(getInUnit(row, column, getUnit()), getUnit());
122     }
123 
124     /**********************************************************************************/
125     /**************************** TYPED CALCULATION METHODS ***************************/
126     /**********************************************************************************/
127 
128     /** {@inheritDoc} */
129     @Override
130     public final A plus(final R rel) throws ValueException
131     {
132         return instantiateTypeAbs(this.getData().plus(rel.getData()), getUnit());
133     }
134 
135     /** {@inheritDoc} */
136     @Override
137     public final A minus(final R rel) throws ValueException
138     {
139         return instantiateTypeAbs(this.getData().minus(rel.getData()), getUnit());
140     }
141 
142     /** {@inheritDoc} */
143     @Override
144     public final R minus(final A abs) throws ValueException
145     {
146         return instantiateTypeRel(this.getData().minus(abs.getData()), getUnit().getRelativeUnit());
147     }
148 
149     /* ============================================================================================ */
150     /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */
151     /* ============================================================================================ */
152 
153     /**
154      * Check that a provided array can be used to create some descendant of a FloatMatrix, and return the Unit.
155      * @param dsArray S[][]; the array to check and get the unit for
156      * @param <AU> the absolute unit
157      * @param <RU> the corresponding relative unit
158      * @param <S> the scalar type
159      * @return the unit of the object
160      * @throws ValueException when the array is null, has length equal to 0, or has first entry with length equal to 0
161      */
162     static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
163             S extends AbstractFloatScalarAbs<AU, S, RU, ?>> AU checkUnit(final S[][] dsArray) throws ValueException
164     {
165         ensureRectangularAndNonEmpty(dsArray);
166         return dsArray[0][0].getUnit();
167     }
168 
169     /**
170      * Check that a 2D array of FloatScalar&lt;?&gt; is rectangular; i.e. all rows have the same length and is non empty.
171      * @param values S[][]; the 2D array to check
172      * @param <AU> the absolute unit
173      * @param <RU> the corresponding relative unit
174      * @param <S> the scalar type
175      * @throws ValueException when values is not rectangular, or contains no data
176      */
177     protected static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
178             S extends AbstractFloatScalarAbs<AU, S, RU, ?>> void ensureRectangularAndNonEmpty(final S[][] values)
179                     throws ValueException
180     {
181         if (null == values)
182         {
183             throw new ValueException("Cannot create a FloatVector or MutableFloatVector from an empty array of FloatScalar");
184         }
185         if (0 == values.length || 0 == values[0].length)
186         {
187             throw new ValueException("Creating FloatVector or MutableFloatVector: "
188                     + "Cannot determine unit for FloatMatrix from an empty array of FloatScalar");
189         }
190         for (int row = values.length; --row >= 1;)
191         {
192             if (values[0].length != values[row].length)
193             {
194                 throw new ValueException("Creating FloatVector or MutableFloatVector: Lengths of rows are not all the same");
195             }
196         }
197     }
198 }