View Javadoc
1   package org.djunits.value.vfloat.vector;
2   
3   import java.io.Serializable;
4   import java.util.Iterator;
5   import java.util.List;
6   import java.util.NoSuchElementException;
7   import java.util.SortedMap;
8   
9   import org.djunits.unit.AbsoluteLinearUnit;
10  import org.djunits.unit.Unit;
11  import org.djunits.value.Absolute;
12  import org.djunits.value.FunctionsAbs;
13  import org.djunits.value.StorageType;
14  import org.djunits.value.ValueException;
15  import org.djunits.value.vfloat.scalar.AbstractFloatScalarAbs;
16  
17  /**
18   * Absolute Immutable typed vector.
19   * <p>
20   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
21   * BSD-style license. See <a href="http://djunits.org/docs/license.html">DJUNITS License</a>.
22   * <p>
23   * $LastChangedDate: 2015-09-29 14:14:28 +0200 (Tue, 29 Sep 2015) $, @version $Revision: 73 $, by $Author: pknoppers $, initial
24   * version Sep 5, 2015 <br>
25   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
26   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
27   * @param <AU> the absolute unit
28   * @param <RU> the relative unit
29   * @param <A> the absolute vector type
30   * @param <R> the relative vector type
31   * @param <MA> the mutable absolute vector type
32   * @param <S> the absolute scalar type
33   */
34  abstract class AbstractFloatVectorAbs<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
35          A extends AbstractFloatVectorAbs<AU, RU, A, R, MA, S>, R extends AbstractFloatVectorRel<RU, R, ?, ?>,
36          MA extends AbstractMutableFloatVectorAbs<AU, RU, A, R, MA, S>, S extends AbstractFloatScalarAbs<AU, S, RU, ?>>
37          extends AbstractFloatVector<AU, A> implements FunctionsAbs<AU, RU, A, R>, Absolute, Serializable, Iterable<S>
38  {
39      /** */
40      private static final long serialVersionUID = 20151006L;
41  
42      /**
43       * Construct a new Absolute Immutable FloatVector.
44       * @param values float[]; the values of the entries in the new Absolute Immutable FloatVector
45       * @param unit AU; the unit of the new Absolute Immutable FloatVector
46       * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE)
47       * @throws ValueException when values is null
48       */
49      AbstractFloatVectorAbs(final float[] values, final AU unit, final StorageType storageType) throws ValueException
50      {
51          super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType));
52      }
53  
54      /**
55       * Construct a new Absolute Immutable FloatVector.
56       * @param values List&lt;Float&gt;; the values of the entries in the new Absolute Immutable FloatVector
57       * @param unit AU; the unit of the new Absolute Immutable FloatVector
58       * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE)
59       * @throws ValueException when values is null
60       */
61      AbstractFloatVectorAbs(final List<Float> values, final AU unit, final StorageType storageType) throws ValueException
62      {
63          super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType));
64      }
65  
66      /**
67       * Construct a new Absolute Immutable FloatVector.
68       * @param values S[]; the values of the entries in the new Absolute Immutable FloatVector
69       * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE)
70       * @throws ValueException when values has zero entries
71       */
72      AbstractFloatVectorAbs(final S[] values, final StorageType storageType) throws ValueException
73      {
74          super(checkUnit(values), FloatVectorData.instantiate(values, storageType));
75      }
76  
77      /**
78       * Construct a new Absolute Immutable FloatVector.
79       * @param values List&lt;S&gt;; the values of the entries in the new Absolute Immutable FloatVector
80       * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE)
81       * @throws ValueException when values has zero entries
82       */
83      AbstractFloatVectorAbs(final List<S> values, final StorageType storageType) throws ValueException
84      {
85          super(checkUnit(values), FloatVectorData.instantiateLD(values, storageType));
86      }
87  
88      /**
89       * Construct a new Absolute Immutable FloatVector.
90       * @param values SortedMap&lt;Integer, S&gt;; the values of the entries in the new Absolute Sparse Mutable FloatVector
91       * @param length int; the size of the vector
92       * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE)
93       * @throws ValueException when values has zero entries
94       */
95      AbstractFloatVectorAbs(final SortedMap<Integer, S> values, final int length, final StorageType storageType)
96              throws ValueException
97      {
98          super(checkUnit(values), FloatVectorData.instantiateMD(values, length, storageType));
99      }
100 
101     /**
102      * Construct a new Absolute Immutable FloatVector.
103      * @param values SortedMap&lt;Integer, Float&gt;; the map of indexes to values of the Absolute Sparse Mutable FloatVector
104      * @param unit AU; the unit of the new Absolute Sparse Mutable FloatVector
105      * @param length int; the size of the vector
106      * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE)
107      * @throws ValueException when values is null
108      */
109     AbstractFloatVectorAbs(final SortedMap<Integer, Float> values, final AU unit, final int length,
110             final StorageType storageType) throws ValueException
111     {
112         super(unit, FloatVectorData.instantiate(values, length, unit.getScale(), storageType));
113     }
114 
115     /**
116      * Construct a new Relative Immutable FloatVector.
117      * @param data FloatVectorData; an internal data object
118      * @param unit AU; the unit
119      */
120     AbstractFloatVectorAbs(final FloatVectorData data, final AU unit)
121     {
122         super(unit, data.copy());
123     }
124 
125     /**
126      * Create a mutable version of this FloatVector. <br>
127      * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation
128      * in the mutable version that modifies the data shall trigger a deep copy of the data.
129      * @return MA; mutable version of this FloatVector
130      */
131     @Override
132     public MA mutable()
133     {
134         return instantiateMutableType(getData(), getUnit());
135     }
136 
137     /**
138      * Construct a new Absolute Immutable FloatVector of the right type. Each extending class must implement this method.
139      * @param dvd FloatVectorData; an internal data object
140      * @param unit AU; the unit
141      * @return M the Mutable FloatVector of the right type
142      */
143     protected abstract A instantiateTypeAbs(FloatVectorData dvd, AU unit);
144 
145     /**
146      * Construct a new Relative Immutable FloatVector of the right type. Each extending class must implement this method.
147      * @param dvd FloatVectorData; an internal data object
148      * @param unit RU; the unit
149      * @return M the Mutable FloatVector of the right type
150      */
151     protected abstract R instantiateTypeRel(FloatVectorData dvd, RU unit);
152 
153     /**
154      * Construct a new Absolute Mutable FloatVector of the right type. Each extending class must implement this method.
155      * @param dvd FloatVectorData; an internal data object
156      * @param unit AU; the unit
157      * @return M the Mutable FloatVector of the right type
158      */
159     protected abstract MA instantiateMutableType(FloatVectorData dvd, AU unit);
160 
161     /**
162      * Construct a new Absolute Immutable FloatScalar of the right type. Each extending class must implement this method.
163      * @param value float; the value
164      * @param unit AU; the unit
165      * @return S the Immutable FloatScalar of the right type
166      */
167     protected abstract S instantiateScalar(float value, AU unit);
168 
169     /** {@inheritDoc} */
170     @Override
171     public S get(final int index) throws ValueException
172     {
173         return instantiateScalar(getInUnit(index, getUnit()), getUnit());
174     }
175 
176     /**********************************************************************************/
177     /**************************** TYPED CALCULATION METHODS ***************************/
178     /**********************************************************************************/
179 
180     /** {@inheritDoc} */
181     @Override
182     public final A plus(final R rel) throws ValueException
183     {
184         return instantiateTypeAbs(this.getData().plus(rel.getData()), getUnit());
185     }
186 
187     /** {@inheritDoc} */
188     @Override
189     public A minus(final R rel) throws ValueException
190     {
191         return instantiateTypeAbs(this.getData().minus(rel.getData()), getUnit());
192     }
193 
194     /** {@inheritDoc} */
195     @Override
196     public R minus(final A abs) throws ValueException
197     {
198         return instantiateTypeRel(this.getData().minus(abs.getData()), getUnit().getRelativeUnit());
199     }
200 
201     /* ============================================================================================ */
202     /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */
203     /* ============================================================================================ */
204 
205     /**
206      * Check that a provided array can be used to create some descendant of a FloatVector, and return the Unit.
207      * @param dsArray S[]; the array to check and get the unit for
208      * @param <AU> the absolute unit
209      * @param <RU> the corresponding relative unit
210      * @param <S> the scalar type
211      * @return the unit of the object
212      * @throws ValueException when the array has length equal to 0
213      */
214     static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
215             S extends AbstractFloatScalarAbs<AU, S, RU, ?>> AU checkUnit(final S[] dsArray) throws ValueException
216     {
217         if (dsArray != null && dsArray.length > 0)
218         {
219             return dsArray[0].getUnit();
220         }
221         throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty array of FloatScalar");
222     }
223 
224     /**
225      * Check that a provided list can be used to create some descendant of a FloatVector, and return the Unit.
226      * @param dsList List&lt;S&gt;; the list to check and get the unit for
227      * @param <AU> the absolute unit of the scalars in the list
228      * @param <RU> the corresponding relative unit
229      * @param <S> the scalar in the list
230      * @return the unit of the object
231      * @throws ValueException when the array has length equal to 0
232      */
233     static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
234             S extends AbstractFloatScalarAbs<AU, S, RU, ?>> AU checkUnit(final List<S> dsList) throws ValueException
235     {
236         if (dsList != null && dsList.size() > 0)
237         {
238             return dsList.get(0).getUnit();
239         }
240         throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty list of FloatScalar");
241     }
242 
243     /**
244      * Check that a provided Map can be used to create some descendant of a FloatVector.
245      * @param dsMap SortedMap&lt;Integer,S&gt;; the provided map
246      * @param <AU> the absolute unit of the scalars in the map
247      * @param <RU> the corresponding relative unit
248      * @param <S> the scalar in the list
249      * @return List the provided list
250      * @throws ValueException when the list has size equal to 0
251      */
252     static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
253             S extends AbstractFloatScalarAbs<AU, S, RU, ?>> AU checkUnit(final SortedMap<Integer, S> dsMap)
254                     throws ValueException
255     {
256         if (dsMap != null && dsMap.size() > 0)
257         {
258             return dsMap.get(dsMap.firstKey()).getUnit();
259         }
260         throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty Map of FloatScalar");
261     }
262 
263     /* ============================================================================================ */
264     /* =============================== ITERATOR METHODS AND CLASS ================================= */
265     /* ============================================================================================ */
266 
267     /**
268      * Returns an iterator over the scalars in this vector in proper sequence.
269      * @return an iterator over the scalars in this vector in proper sequence
270      */
271     @Override
272     public Iterator<S> iterator()
273     {
274         return new Itr();
275     }
276 
277     /**
278      * The iterator class is loosely based in AbstractList.Itr. It does not throw a ConcurrentModificationException, because the
279      * size of the vector does not change. Normal (non-mutable) vectors cannot change their size, nor their content. The only
280      * thing for the MutableVector that can change is its content, not its length.
281      */
282     protected class Itr implements Iterator<S>
283     {
284         /** index of next element to return. */
285         private int cursor = 0;
286 
287         @Override
288         public boolean hasNext()
289         {
290             return this.cursor != size();
291         }
292 
293         /** {@inheritDoc} */
294         @Override
295         public S next()
296         {
297             if (this.cursor >= size())
298             {
299                 throw new NoSuchElementException();
300             }
301             try
302             {
303                 int i = this.cursor;
304                 S next = get(i);
305                 this.cursor = i + 1;
306                 return next;
307             }
308             catch (ValueException exception)
309             {
310                 throw new RuntimeException(exception);
311             }
312         }
313 
314         /** {@inheritDoc} */
315         @Override
316         public void remove()
317         {
318             throw new RuntimeException("Remove function cannot be applied on fixed-size DJUNITS Vector");
319         }
320     }
321 
322 }