View Javadoc
1   package org.djunits.value.vdouble.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.vdouble.scalar.AbstractDoubleScalarAbs;
16  
17  /**
18   * Absolute Immutable typed vector.
19   * <p>
20   * Copyright (c) 2013-2018 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 AbstractDoubleVectorAbs<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
35          A extends AbstractDoubleVectorAbs<AU, RU, A, R, MA, S>, R extends AbstractDoubleVectorRel<RU, R, ?, ?>,
36          MA extends AbstractMutableDoubleVectorAbs<AU, RU, A, R, MA, S>, S extends AbstractDoubleScalarAbs<AU, S, RU, ?>>
37          extends AbstractDoubleVector<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 DoubleVector.
44       * @param values double[]; the values of the entries in the new Absolute Immutable DoubleVector
45       * @param unit AU; the unit of the new Absolute Immutable DoubleVector
46       * @param storageType the data type to use (e.g., DENSE or SPARSE)
47       * @throws ValueException when values is null
48       */
49      AbstractDoubleVectorAbs(final double[] values, final AU unit, final StorageType storageType) throws ValueException
50      {
51          super(unit, DoubleVectorData.instantiate(values, unit.getScale(), storageType));
52      }
53  
54      /**
55       * Construct a new Absolute Immutable DoubleVector.
56       * @param values List; the values of the entries in the new Absolute Immutable DoubleVector
57       * @param unit AU; the unit of the new Absolute Immutable DoubleVector
58       * @param storageType the data type to use (e.g., DENSE or SPARSE)
59       * @throws ValueException when values is null
60       */
61      AbstractDoubleVectorAbs(final List<Double> values, final AU unit, final StorageType storageType) throws ValueException
62      {
63          super(unit, DoubleVectorData.instantiate(values, unit.getScale(), storageType));
64      }
65  
66      /**
67       * Construct a new Absolute Immutable DoubleVector.
68       * @param values DoubleScalar.Abs&lt;U&gt;[]; the values of the entries in the new Absolute Immutable DoubleVector
69       * @param storageType the data type to use (e.g., DENSE or SPARSE)
70       * @throws ValueException when values has zero entries
71       */
72      AbstractDoubleVectorAbs(final S[] values, final StorageType storageType) throws ValueException
73      {
74          super(checkUnit(values), DoubleVectorData.instantiate(values, storageType));
75      }
76  
77      /**
78       * Construct a new Absolute Immutable DoubleVector.
79       * @param values List; the values of the entries in the new Absolute Immutable DoubleVector
80       * @param storageType the data type to use (e.g., DENSE or SPARSE)
81       * @throws ValueException when values has zero entries
82       */
83      AbstractDoubleVectorAbs(final List<S> values, final StorageType storageType) throws ValueException
84      {
85          super(checkUnit(values), DoubleVectorData.instantiateLD(values, storageType));
86      }
87  
88      /**
89       * Construct a new Absolute Immutable DoubleVector.
90       * @param values DoubleScalar.Abs&lt;U&gt;[]; the values of the entries in the new Absolute Sparse Mutable DoubleVector
91       * @param length the size of the vector
92       * @param storageType the data type to use (e.g., DENSE or SPARSE)
93       * @throws ValueException when values has zero entries
94       */
95      AbstractDoubleVectorAbs(final SortedMap<Integer, S> values, final int length, final StorageType storageType)
96              throws ValueException
97      {
98          super(checkUnit(values), DoubleVectorData.instantiateMD(values, length, storageType));
99      }
100 
101     /**
102      * Construct a new Absolute Immutable DoubleVector.
103      * @param values Map; the map of indexes to values of the Absolute Sparse Mutable DoubleVector
104      * @param unit AU; the unit of the new Absolute Sparse Mutable DoubleVector
105      * @param length the size of the vector
106      * @param storageType the data type to use (e.g., DENSE or SPARSE)
107      * @throws ValueException when values is null
108      */
109     AbstractDoubleVectorAbs(final SortedMap<Integer, Double> values, final AU unit, final int length,
110             final StorageType storageType) throws ValueException
111     {
112         super(unit, DoubleVectorData.instantiate(values, length, unit.getScale(), storageType));
113     }
114 
115     /**
116      * Construct a new Relative Immutable DoubleVector.
117      * @param data an internal data object
118      * @param unit the unit
119      */
120     AbstractDoubleVectorAbs(final DoubleVectorData data, final AU unit)
121     {
122         super(unit, data.copy());
123     }
124 
125     /**
126      * Create a mutable version of this DoubleVector. <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 DoubleVector
130      */
131     @Override
132     public MA mutable()
133     {
134         return instantiateMutableType(getData(), getUnit());
135     }
136 
137     /**
138      * Construct a new Absolute Immutable DoubleVector of the right type. Each extending class must implement this method.
139      * @param dvd an internal data object
140      * @param unit the unit
141      * @return M the Mutable DoubleVector of the right type
142      */
143     protected abstract A instantiateTypeAbs(DoubleVectorData dvd, AU unit);
144 
145     /**
146      * Construct a new Relative Immutable DoubleVector of the right type. Each extending class must implement this method.
147      * @param dvd an internal data object
148      * @param unit the unit
149      * @return M the Mutable DoubleVector of the right type
150      */
151     protected abstract R instantiateTypeRel(DoubleVectorData dvd, RU unit);
152 
153     /**
154      * Construct a new Absolute Mutable DoubleVector of the right type. Each extending class must implement this method.
155      * @param dvd an internal data object
156      * @param unit the unit
157      * @return M the Mutable DoubleVector of the right type
158      */
159     protected abstract MA instantiateMutableType(DoubleVectorData dvd, AU unit);
160 
161     /**
162      * Construct a new Absolute Immutable DoubleScalar of the right type. Each extending class must implement this method.
163      * @param value the value
164      * @param unit the unit
165      * @return S the Immutable DoubleScalar of the right type
166      */
167     protected abstract S instantiateScalar(double value, AU unit);
168 
169     /** {@inheritDoc} */
170     @Override
171     public final 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 DoubleVector, and return the Unit.
207      * @param dsArray 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 AbstractDoubleScalarAbs<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(
222                 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty array of DoubleScalar");
223     }
224 
225     /**
226      * Check that a provided list can be used to create some descendant of a DoubleVector, and return the Unit.
227      * @param dsList the list to check and get the unit for
228      * @param <AU> the absolute unit of the scalars in the list
229      * @param <RU> the corresponding relative unit
230      * @param <S> the scalar in the list
231      * @return the unit of the object
232      * @throws ValueException when the array has length equal to 0
233      */
234     static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
235             S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> AU checkUnit(final List<S> dsList) throws ValueException
236     {
237         if (dsList != null && dsList.size() > 0)
238         {
239             return dsList.get(0).getUnit();
240         }
241         throw new ValueException(
242                 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty list of DoubleScalar");
243     }
244 
245     /**
246      * Check that a provided Map can be used to create some descendant of a DoubleVector.
247      * @param dsMap the provided map
248      * @param <AU> the absolute unit of the scalars in the map
249      * @param <RU> the corresponding relative unit
250      * @param <S> the scalar in the list
251      * @return List the provided list
252      * @throws ValueException when the list has size equal to 0
253      */
254     static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
255             S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> AU checkUnit(final SortedMap<Integer, S> dsMap)
256                     throws ValueException
257     {
258         if (dsMap != null && dsMap.size() > 0)
259         {
260             return dsMap.get(dsMap.firstKey()).getUnit();
261         }
262         throw new ValueException(
263                 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty Map of DoubleScalar");
264     }
265 
266     /* ============================================================================================ */
267     /* =============================== ITERATOR METHODS AND CLASS ================================= */
268     /* ============================================================================================ */
269 
270     /**
271      * Returns an iterator over the scalars in this vector in proper sequence.
272      * @return an iterator over the scalars in this vector in proper sequence
273      */
274     @Override
275     public Iterator<S> iterator()
276     {
277         return new Itr();
278     }
279 
280     /**
281      * The iterator class is loosely based in AbstractList.Itr. It does not throw a ConcurrentModificationException, because the
282      * size of the vector does not change. Normal (non-mutable) vectors cannot change their size, nor their content. The only
283      * thing for the MutableVector that can change is its content, not its length.
284      */
285     protected class Itr implements Iterator<S>
286     {
287         /** index of next element to return. */
288         private int cursor = 0;
289 
290         @Override
291         public boolean hasNext()
292         {
293             return this.cursor != size();
294         }
295 
296         /** {@inheritDoc} */
297         @Override
298         public S next()
299         {
300             if (this.cursor >= size())
301             {
302                 throw new NoSuchElementException();
303             }
304             try
305             {
306                 int i = this.cursor;
307                 S next = get(i);
308                 this.cursor = i + 1;
309                 return next;
310             }
311             catch (ValueException exception)
312             {
313                 throw new RuntimeException(exception);
314             }
315         }
316 
317         /** {@inheritDoc} */
318         @Override
319         public void remove()
320         {
321             throw new RuntimeException("Remove function cannot be applied on fixed-size DJUNITS Vector");
322         }
323     }
324 
325 }