View Javadoc
1   package org.djunits.value.vfloat.vector;
2   
3   import java.io.Serializable;
4   import java.util.List;
5   import java.util.SortedMap;
6   
7   import org.djunits.unit.Unit;
8   import org.djunits.value.Relative;
9   import org.djunits.value.StorageType;
10  import org.djunits.value.ValueException;
11  import org.djunits.value.vfloat.scalar.AbstractFloatScalarRel;
12  
13  /**
14   * Relative Immutable typed vector.
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 <U> the unit
24   * @param <R> the relative vector type
25   * @param <MR> the mutable relative vector type
26   * @param <S> the relative scalar type
27   */
28  abstract class AbstractFloatVectorRel<U extends Unit<U>, R extends AbstractFloatVectorRel<U, R, MR, S>,
29          MR extends AbstractMutableFloatVectorRel<U, R, MR, S>, S extends AbstractFloatScalarRel<U, S>>
30          extends AbstractFloatVector<U, R> implements Relative, Serializable
31  {
32      /** */
33      private static final long serialVersionUID = 20151006L;
34  
35      /**
36       * Construct a new Relative Immutable FloatVector.
37       * @param values float[]; the values of the entries in the new Relative Immutable FloatVector
38       * @param unit U; the unit of the new Relative Immutable FloatVector
39       * @param storageType the data type to use (e.g., DENSE or SPARSE)
40       * @throws ValueException when values is null
41       */
42      AbstractFloatVectorRel(final float[] values, final U unit, final StorageType storageType) throws ValueException
43      {
44          super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType));
45      }
46  
47      /**
48       * Construct a new Relative Immutable FloatVector.
49       * @param values List; the values of the entries in the new Relative Immutable FloatVector
50       * @param unit U; the unit of the new Relative Immutable FloatVector
51       * @param storageType the data type to use (e.g., DENSE or SPARSE)
52       * @throws ValueException when values is null
53       */
54      AbstractFloatVectorRel(final List<Float> values, final U unit, final StorageType storageType) throws ValueException
55      {
56          super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType));
57      }
58  
59      /**
60       * Construct a new Relative Immutable FloatVector.
61       * @param values FloatScalar.Rel&lt;U&gt;[]; the values of the entries in the new Relative Immutable FloatVector
62       * @param storageType the data type to use (e.g., DENSE or SPARSE)
63       * @throws ValueException when values has zero entries
64       */
65      AbstractFloatVectorRel(final S[] values, final StorageType storageType) throws ValueException
66      {
67          super(checkUnit(values), FloatVectorData.instantiate(values, storageType));
68      }
69  
70      /**
71       * Construct a new Relative Immutable FloatVector.
72       * @param values List; the values of the entries in the new Relative Immutable FloatVector
73       * @param storageType the data type to use (e.g., DENSE or SPARSE)
74       * @throws ValueException when values has zero entries
75       */
76      AbstractFloatVectorRel(final List<S> values, final StorageType storageType) throws ValueException
77      {
78          super(checkUnit(values), FloatVectorData.instantiateLD(values, storageType));
79      }
80  
81      /**
82       * Construct a new Relative Immutable FloatVector.
83       * @param values FloatScalar.Rel&lt;U&gt;[]; the values of the entries in the new Relative Sparse Mutable FloatVector
84       * @param length the size of the vector
85       * @param storageType the data type to use (e.g., DENSE or SPARSE)
86       * @throws ValueException when values has zero entries
87       */
88      AbstractFloatVectorRel(final SortedMap<Integer, S> values, final int length, final StorageType storageType)
89              throws ValueException
90      {
91          super(checkUnit(values), FloatVectorData.instantiateMD(values, length, storageType));
92      }
93  
94      /**
95       * Construct a new Relative Immutable FloatVector.
96       * @param values Map; the map of indexes to values of the Relative Sparse Mutable FloatVector
97       * @param unit U; the unit of the new Relative Sparse Mutable FloatVector
98       * @param length the size of the vector
99       * @param storageType the data type to use (e.g., DENSE or SPARSE)
100      * @throws ValueException when values is null
101      */
102     AbstractFloatVectorRel(final SortedMap<Integer, Float> values, final U unit, final int length,
103             final StorageType storageType) throws ValueException
104     {
105         super(unit, FloatVectorData.instantiate(values, length, unit.getScale(), storageType));
106     }
107 
108     /**
109      * Construct a new Relative Immutable FloatVector.
110      * @param data an internal data object
111      * @param unit the unit
112      */
113     AbstractFloatVectorRel(final FloatVectorData data, final U unit)
114     {
115         super(unit, data.copy());
116     }
117 
118     /**
119      * Create a mutable version of this FloatVector. <br>
120      * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation
121      * in the mutable version that modifies the data shall trigger a deep copy of the data.
122      * @return MR; mutable version of this FloatVector
123      */
124     @Override
125     public MR mutable()
126     {
127         return instantiateMutableType(getData(), getUnit());
128     }
129 
130     /**
131      * Construct a new Relative Immutable FloatVector of the right type. Each extending class must implement this method.
132      * @param dvd an internal data object
133      * @param unit the unit
134      * @return R the FloatVector of the right type
135      */
136     protected abstract R instantiateType(FloatVectorData dvd, U unit);
137 
138     /**
139      * Construct a new Relative Mutable FloatVector of the right type. Each extending class must implement this method.
140      * @param dvd an internal data object
141      * @param unit the unit
142      * @return MR the Mutable FloatVector of the right type
143      */
144     protected abstract MR instantiateMutableType(FloatVectorData dvd, U unit);
145 
146     /**
147      * Construct a new Relative Immutable FloatScalar of the right type. Each extending class must implement this method.
148      * @param value the value
149      * @param unit the unit
150      * @return S the Immutable FloatScalar of the right type
151      */
152     protected abstract S instantiateScalar(float value, U unit);
153 
154     /** {@inheritDoc} */
155     @Override
156     public S get(final int index) throws ValueException
157     {
158         return instantiateScalar(getInUnit(index, getUnit()), getUnit());
159     }
160 
161     /**********************************************************************************/
162     /**************************** TYPED CALCULATION METHODS ***************************/
163     /**********************************************************************************/
164 
165     /**
166      * Add a Relative value to this Relative value for a vector or matrix. The addition is done value by value and store the
167      * result in a new Relative value. If both operands are sparse, the result is a sparse vector or matrix, otherwise the
168      * result is a dense vector or matrix.
169      * @param rel the right operand
170      * @return the addition of this vector and the operand
171      * @throws ValueException in case this vector or matrix and the operand have a different size
172      */
173     public final R plus(final R rel) throws ValueException
174     {
175         return instantiateType(this.getData().plus(rel.getData()), getUnit());
176     }
177 
178     /**
179      * Subtract a Relative value from this Relative value for a vector or matrix. The subtraction is done value by value and
180      * store the result in a new Relative value. If both operands are sparse, the result is a sparse vector or matrix, otherwise
181      * the result is a dense vector or matrix.
182      * @param rel the right operand
183      * @return the subtraction of this vector and the operand
184      * @throws ValueException in case this vector or matrix and the operand have a different size
185      */
186     public final R minus(final R rel) throws ValueException
187     {
188         return instantiateType(this.getData().minus(rel.getData()), getUnit());
189     }
190 
191     /**
192      * Multiply a Relative value with this Relative value for a vector or matrix. The multiplication is done value by value and
193      * store the result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise
194      * the result is a sparse vector or matrix.
195      * @param rel the right operand
196      * @return the multiplication of this vector and the operand
197      * @throws ValueException in case this vector or matrix and the operand have a different size
198      */
199     public final R times(final R rel) throws ValueException
200     {
201         return instantiateType(this.getData().times(rel.getData()), getUnit());
202     }
203 
204     /**
205      * Divide this Relative value by a Relative value for a vector or matrix. The division is done value by value and store the
206      * result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise the result
207      * is a sparse vector or matrix.
208      * @param rel the right operand
209      * @return the division of this vector and the operand
210      * @throws ValueException in case this vector or matrix and the operand have a different size
211      */
212     public final R divide(final R rel) throws ValueException
213     {
214         return instantiateType(this.getData().divide(rel.getData()), getUnit());
215     }
216 
217     /* ============================================================================================ */
218     /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */
219     /* ============================================================================================ */
220 
221     /**
222      * Check that a provided array can be used to create some descendant of a FloatVector, and return the Unit.
223      * @param dsArray the array to check and get the unit for
224      * @param <U> the unit
225      * @param <S> the scalar type
226      * @return the unit of the object
227      * @throws ValueException when the array has length equal to 0
228      */
229     static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final AbstractFloatScalarRel<U, S>[] dsArray)
230             throws ValueException
231     {
232         if (dsArray != null && dsArray.length > 0)
233         {
234             return dsArray[0].getUnit();
235         }
236         throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty array of FloatScalar");
237     }
238 
239     /**
240      * Check that a provided list can be used to create some descendant of a FloatVector, and return the Unit.
241      * @param dsList the list to check and get the unit for
242      * @param <U> the unit
243      * @param <S> the scalar in the list
244      * @return the unit of the object
245      * @throws ValueException when the array has length equal to 0
246      */
247     static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final List<S> dsList) throws ValueException
248     {
249         if (dsList != null && dsList.size() > 0)
250         {
251             return dsList.get(0).getUnit();
252         }
253         throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty list of FloatScalar");
254     }
255 
256     /**
257      * Check that a provided Map can be used to create some descendant of a FloatVector.
258      * @param dsMap the provided map
259      * @param <U> Unit; the unit of the FloatScalar list
260      * @param <S> the scalar in the list
261      * @return List the provided list
262      * @throws ValueException when the list has size equal to 0
263      */
264     static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final SortedMap<Integer, S> dsMap)
265             throws ValueException
266     {
267         if (dsMap != null && dsMap.size() > 0)
268         {
269             return dsMap.get(dsMap.firstKey()).getUnit();
270         }
271         throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty Map of FloatScalar");
272     }
273 
274 }