View Javadoc
1   package org.djunits.value.vfloat.vector.base;
2   
3   import java.io.Serializable;
4   import java.lang.reflect.Array;
5   import java.util.Iterator;
6   import java.util.NoSuchElementException;
7   
8   import org.djunits.Throw;
9   import org.djunits.unit.Unit;
10  import org.djunits.value.Absolute;
11  import org.djunits.value.AbstractIndexedValue;
12  import org.djunits.value.ValueRuntimeException;
13  import org.djunits.value.formatter.Format;
14  import org.djunits.value.storage.StorageType;
15  import org.djunits.value.util.ValueUtil;
16  import org.djunits.value.vfloat.function.FloatFunction;
17  import org.djunits.value.vfloat.function.FloatMathFunctions;
18  import org.djunits.value.vfloat.scalar.base.AbstractFloatScalar;
19  import org.djunits.value.vfloat.scalar.base.FloatScalar;
20  import org.djunits.value.vfloat.vector.data.FloatVectorData;
21  
22  /**
23   * The most basic abstract class for the FloatVector.
24   * <p>
25   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
26   * BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
27   * </p>
28   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
29   * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
30   * @author <a href="https://www.transport.citg.tudelft.nl">Wouter Schakel</a>
31   * @param <U> the unit
32   * @param <S> the scalar with unit U
33   * @param <V> the generic vector type
34   */
35  public abstract class AbstractFloatVector<U extends Unit<U>, S extends AbstractFloatScalar<U, S>,
36          V extends AbstractFloatVector<U, S, V>> extends AbstractIndexedValue<U, S, V, FloatVectorData>
37          implements FloatVectorInterface<U, S, V>
38  {
39      /** */
40      private static final long serialVersionUID = 20161015L;
41  
42      /** The stored data as an object, can be sparse or dense. */
43      @SuppressWarnings("checkstyle:visibilitymodifier")
44      protected FloatVectorData data;
45  
46      /**
47       * Construct a new FloatVector.
48       * @param data FloatVectorData; an internal data object
49       * @param unit U; the unit
50       */
51      AbstractFloatVector(final FloatVectorData data, final U unit)
52      {
53          super(unit);
54          Throw.whenNull(data, "data cannot be null");
55          this.data = data;
56      }
57  
58      /** {@inheritDoc} */
59      @Override
60      protected final FloatVectorData getData()
61      {
62          return this.data;
63      }
64  
65      /** {@inheritDoc} */
66      @Override
67      protected void setData(final FloatVectorData data)
68      {
69          this.data = data;
70      }
71  
72      /** {@inheritDoc} */
73      @Override
74      public final float[] getValuesSI()
75      {
76          return getData().getDenseVectorSI();
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public final float[] getValuesInUnit()
82      {
83          return getValuesInUnit(getDisplayUnit());
84      }
85  
86      /** {@inheritDoc} */
87      @Override
88      public final float[] getValuesInUnit(final U targetUnit)
89      {
90          float[] values = getValuesSI();
91          for (int i = values.length; --i >= 0;)
92          {
93              values[i] = (float) ValueUtil.expressAsUnit(values[i], targetUnit);
94          }
95          return values;
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public final int size()
101     {
102         return getData().size();
103     }
104 
105     /**
106      * Check that a provided index is valid.
107      * @param index int; the value to check
108      * @throws ValueRuntimeException when index is invalid
109      */
110     protected final void checkIndex(final int index) throws ValueRuntimeException
111     {
112         if (index < 0 || index >= size())
113         {
114             throw new ValueRuntimeException("index out of range (valid range is 0.." + (size() - 1) + ", got " + index + ")");
115         }
116     }
117 
118     /** {@inheritDoc} */
119     @Override
120     public final float getSI(final int index) throws ValueRuntimeException
121     {
122         checkIndex(index);
123         return getData().getSI(index);
124     }
125 
126     /** {@inheritDoc} */
127     @Override
128     public S get(final int index) throws ValueRuntimeException
129     {
130         return FloatScalar.instantiateSI(getSI(index), getDisplayUnit());
131     }
132 
133     /** {@inheritDoc} */
134     @Override
135     public final float getInUnit(final int index) throws ValueRuntimeException
136     {
137         return (float) ValueUtil.expressAsUnit(getSI(index), getDisplayUnit());
138     }
139 
140     /** {@inheritDoc} */
141     @Override
142     public final float getInUnit(final int index, final U targetUnit) throws ValueRuntimeException
143     {
144         return (float) ValueUtil.expressAsUnit(getSI(index), targetUnit);
145     }
146 
147     /** {@inheritDoc} */
148     @Override
149     public final void setSI(final int index, final float valueSI) throws ValueRuntimeException
150     {
151         checkIndex(index);
152         checkCopyOnWrite();
153         getData().setSI(index, valueSI);
154     }
155 
156     /** {@inheritDoc} */
157     @Override
158     public void setInUnit(final int index, final float valueInUnit) throws ValueRuntimeException
159     {
160         setSI(index, (float) ValueUtil.expressAsSIUnit(valueInUnit, getDisplayUnit()));
161     }
162 
163     /** {@inheritDoc} */
164     @Override
165     public void setInUnit(final int index, final float valueInUnit, final U valueUnit) throws ValueRuntimeException
166     {
167         setSI(index, (float) ValueUtil.expressAsSIUnit(valueInUnit, valueUnit));
168     }
169 
170     /** {@inheritDoc} */
171     @Override
172     public void set(final int index, final S value) throws ValueRuntimeException
173     {
174         setSI(index, value.si);
175     }
176 
177     /** {@inheritDoc} */
178     @SuppressWarnings("unchecked")
179     @Override
180     public S[] getScalars()
181     {
182         S[] array = (S[]) Array.newInstance(getScalarClass(), size());
183         for (int i = 0; i < size(); i++)
184         {
185             array[i] = get(i);
186         }
187         return array;
188     }
189 
190     /** {@inheritDoc} */
191     @SuppressWarnings("unchecked")
192     @Override
193     public V toSparse()
194     {
195         V result;
196         if (getStorageType().equals(StorageType.SPARSE))
197         {
198             result = (V) this;
199             result.setDisplayUnit(getDisplayUnit());
200         }
201         else
202         {
203             result = instantiateVector(getData().toSparse(), getDisplayUnit());
204         }
205         result.setDisplayUnit(getDisplayUnit());
206         return result;
207     }
208 
209     /** {@inheritDoc} */
210     @SuppressWarnings("unchecked")
211     @Override
212     public V toDense()
213     {
214         V result;
215         if (getStorageType().equals(StorageType.DENSE))
216         {
217             result = (V) this;
218             result.setDisplayUnit(getDisplayUnit());
219         }
220         else
221         {
222             result = instantiateVector(getData().toDense(), getDisplayUnit());
223         }
224         return result;
225     }
226 
227     /** {@inheritDoc} */
228     @SuppressWarnings("unchecked")
229     @Override
230     public final V assign(final FloatFunction floatFunction)
231     {
232         checkCopyOnWrite();
233         this.data.assign(floatFunction);
234         return (V) this;
235     }
236 
237     /** {@inheritDoc} */
238     @Override
239     public final V abs()
240     {
241         return assign(FloatMathFunctions.ABS);
242     }
243 
244     /** {@inheritDoc} */
245     @Override
246     public final V ceil()
247     {
248         return assign(FloatMathFunctions.CEIL);
249     }
250 
251     /** {@inheritDoc} */
252     @Override
253     public final V floor()
254     {
255         return assign(FloatMathFunctions.FLOOR);
256     }
257 
258     /** {@inheritDoc} */
259     @Override
260     public final V neg()
261     {
262         return assign(FloatMathFunctions.NEG);
263     }
264 
265     /** {@inheritDoc} */
266     @Override
267     public final V rint()
268     {
269         return assign(FloatMathFunctions.RINT);
270     }
271 
272     /** {@inheritDoc} */
273     @Override
274     public final String toString()
275     {
276         return toString(getDisplayUnit(), false, true);
277     }
278 
279     /** {@inheritDoc} */
280     @Override
281     public final String toString(final U displayUnit)
282     {
283         return toString(displayUnit, false, true);
284     }
285 
286     /** {@inheritDoc} */
287     @Override
288     public final String toString(final boolean verbose, final boolean withUnit)
289     {
290         return toString(getDisplayUnit(), verbose, withUnit);
291     }
292 
293     /** {@inheritDoc} */
294     @Override
295     public final String toString(final U displayUnit, final boolean verbose, final boolean withUnit)
296     {
297         StringBuffer buf = new StringBuffer();
298         if (verbose)
299         {
300             String ar = this instanceof Absolute ? "Abs " : "Rel ";
301             String ds = getData().isDense() ? "Dense  " : getData().isSparse() ? "Sparse " : "?????? ";
302             if (isMutable())
303             {
304                 buf.append("Mutable   " + ar + ds);
305             }
306             else
307             {
308                 buf.append("Immutable " + ar + ds);
309             }
310         }
311         buf.append("[");
312         for (int i = 0; i < size(); i++)
313         {
314             try
315             {
316                 float f = (float) ValueUtil.expressAsUnit(getSI(i), displayUnit);
317                 buf.append(" " + Format.format(f));
318             }
319             catch (ValueRuntimeException ve)
320             {
321                 buf.append(" " + "********************".substring(0, Format.DEFAULTSIZE));
322             }
323         }
324         buf.append("]");
325         if (withUnit)
326         {
327             buf.append(" " + displayUnit.getDefaultDisplayAbbreviation());
328         }
329         return buf.toString();
330     }
331 
332     /**
333      * Centralized size equality check.
334      * @param other AbstractFloatVector&lt;U, ?&gt;; other FloatVector
335      * @throws NullPointerException when other vector is null
336      * @throws ValueRuntimeException when vectors have unequal size
337      */
338     protected final void checkSize(final FloatVectorInterface<?, ?, ?> other) throws ValueRuntimeException
339     {
340         Throw.whenNull(other, "Other vector is null");
341         Throw.when(size() != other.size(), ValueRuntimeException.class, "The vectors have different sizes: %d != %d", size(),
342                 other.size());
343     }
344 
345     /** {@inheritDoc} */
346     @Override
347     @SuppressWarnings("checkstyle:designforextension")
348     public int hashCode()
349     {
350         final int prime = 31;
351         int result = getDisplayUnit().getStandardUnit().hashCode();
352         result = prime * result + ((this.data == null) ? 0 : this.data.hashCode());
353         return result;
354     }
355 
356     /** {@inheritDoc} */
357     @Override
358     @SuppressWarnings({"checkstyle:designforextension", "checkstyle:needbraces"})
359     public boolean equals(final Object obj)
360     {
361         if (this == obj)
362             return true;
363         if (obj == null)
364             return false;
365         if (getClass() != obj.getClass())
366             return false;
367         AbstractFloatVector<?, ?, ?> other = (AbstractFloatVector<?, ?, ?>) obj;
368         if (!getDisplayUnit().getStandardUnit().equals(other.getDisplayUnit().getStandardUnit()))
369             return false;
370         if (this.data == null)
371         {
372             if (other.data != null)
373                 return false;
374         }
375         else if (!this.data.equals(other.data))
376             return false;
377         return true;
378     }
379 
380     /* ============================================================================================ */
381     /* =============================== ITERATOR METHODS AND CLASS ================================= */
382     /* ============================================================================================ */
383 
384     /** {@inheritDoc} */
385     @Override
386     public Iterator<S> iterator()
387     {
388         return new Itr();
389     }
390 
391     /**
392      * The iterator class is loosely based in AbstractList.Itr. It does not throw a ConcurrentModificationException, because the
393      * size of the vector does not change. Normal (non-mutable) vectors cannot change their size, nor their content. The only
394      * thing for the MutableVector that can change is its content, not its length.
395      */
396     protected class Itr implements Iterator<S>, Serializable
397     {
398         /** ... */
399         private static final long serialVersionUID = 20191018L;
400 
401         /** index of next element to return. */
402         private int cursor = 0;
403 
404         /** {@inheritDoc} */
405         @Override
406         public boolean hasNext()
407         {
408             return this.cursor != size();
409         }
410 
411         /** {@inheritDoc} */
412         @Override
413         public S next()
414         {
415             if (this.cursor >= size())
416             {
417                 throw new NoSuchElementException();
418             }
419             try
420             {
421                 int i = this.cursor;
422                 S next = get(i);
423                 this.cursor = i + 1;
424                 return next;
425             }
426             catch (ValueRuntimeException exception)
427             {
428                 throw new RuntimeException(exception);
429             }
430         }
431 
432         /** {@inheritDoc} */
433         @Override
434         public void remove()
435         {
436             throw new RuntimeException("Remove function cannot be applied on fixed-size DJUNITS Vector");
437         }
438 
439         /** {@inheritDoc} */
440         @Override
441         public String toString()
442         {
443             return "Itr [cursor=" + this.cursor + "]";
444         }
445 
446     }
447 
448 }