View Javadoc
1   package org.djunits.vecmat.def;
2   
3   import java.lang.reflect.Array;
4   import java.util.Iterator;
5   import java.util.NoSuchElementException;
6   
7   import org.djunits.formatter.VectorFormat;
8   import org.djunits.formatter.VectorFormatter;
9   import org.djunits.quantity.def.AbsQuantity;
10  import org.djunits.quantity.def.Quantity;
11  import org.djunits.quantity.def.Reference;
12  import org.djunits.unit.Unit;
13  import org.djunits.value.Value;
14  import org.djutils.exceptions.Throw;
15  
16  /**
17   * AbsVector contains the contract for Vector classes with absolute values.
18   * <p>
19   * Copyright (c) 2025-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
20   * for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
21   * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
22   * @author Alexander Verbraeck
23   * @param <A> the absolute quantity type
24   * @param <Q> the corresponding relative quantity type
25   * @param <VA> the absolute vector or matrix type
26   * @param <VQ> the relative vector or matrix type
27   * @param <VAT> the type of the transposed version of the absolute vector
28   */
29  public abstract class AbsVector<A extends AbsQuantity<A, Q, ?>, Q extends Quantity<Q>, VA extends AbsVector<A, Q, VA, VQ, VAT>,
30          VQ extends Vector<Q, VQ, ?, ?, ?>, VAT extends AbsVector<A, Q, VAT, ?, VA>> extends AbsVectorMatrix<A, Q, VA, VQ, VAT>
31          implements Iterable<A>
32  {
33      /** */
34      private static final long serialVersionUID = 600L;
35  
36      /**
37       * Create a new vector of absolute values with a reference point.
38       * @param vector the underlying relative vector with SI values relative to the reference point
39       * @param reference the reference point for the absolute values
40       */
41      public AbsVector(final VQ vector, final Reference<?, A, Q> reference)
42      {
43          super(vector, reference);
44      }
45  
46      /**
47       * Retrieve the size of the vector.
48       * @return the size of the vector
49       */
50      public int size()
51      {
52          return getRelativeVecMat().size();
53      }
54  
55      /**
56       * Return whether this vector is a column vector.
57       * @return whether this vector is a column vector
58       */
59      public boolean isColumnVector()
60      {
61          return getRelativeVecMat().isColumnVector();
62      }
63  
64      /**
65       * Return whether this vector is a row vector.
66       * @return whether this vector is a row vector
67       */
68      public boolean isRowVector()
69      {
70          return getRelativeVecMat().isRowVector();
71      }
72  
73      /**
74       * Retrieve an si-value from the vector.
75       * @param index the index (0-based) to retrieve the value from
76       * @return the value as a Scalar
77       * @throws IndexOutOfBoundsException in case index is out of bounds
78       */
79      public double si(final int index) throws IndexOutOfBoundsException
80      {
81          return getRelativeVecMat().si(index);
82      }
83  
84      /**
85       * Retrieve an si-value from the vector, based on a 1-valued index.
86       * @param mIndex the index (1-based) to retrieve the value from
87       * @return the value as a Scalar
88       * @throws IndexOutOfBoundsException in case index is out of bounds
89       */
90      public double msi(final int mIndex) throws IndexOutOfBoundsException
91      {
92          return getRelativeVecMat().msi(mIndex);
93      }
94  
95      /**
96       * Retrieve a value from the vector.
97       * @param index the index (0-based) to retrieve the value from
98       * @return the value as a Scalar
99       * @throws IndexOutOfBoundsException in case index is out of bounds
100      */
101     public A get(final int index) throws IndexOutOfBoundsException
102     {
103         return getReference().instantiate(getDisplayUnit().ofSi(si(index))).setDisplayUnit(getDisplayUnit());
104     }
105 
106     /**
107      * Retrieve a value from the vector, based on a 1-valued index.
108      * @param mIndex the index (1-based) to retrieve the value from
109      * @return the value as a Scalar
110      * @throws IndexOutOfBoundsException in case index is out of bounds
111      */
112     public A mget(final int mIndex) throws IndexOutOfBoundsException
113     {
114         return getReference().instantiate(getDisplayUnit().ofSi(si(mIndex - 1))).setDisplayUnit(getDisplayUnit());
115     }
116 
117     /**
118      * Return the vector as an array of scalars.
119      * @return the vector as an array of scalars
120      */
121     @SuppressWarnings("unchecked")
122     public A[] getScalarArray()
123     {
124         // Determine the runtime type of Q using the first cell; constructors guarantee rows, cols >= 0.
125         final A first = getReference().instantiate(getDisplayUnit().ofSi(0.0));
126         final Class<?> aClass = first.getClass();
127         final A[] out = (A[]) Array.newInstance(aClass, size());
128         for (int i = 0; i < size(); i++)
129         {
130             out[i] = get(i);
131         }
132         return out;
133     }
134 
135     /**
136      * Return the vector as an array of SI values.
137      * @return the vector as an array of SI valies
138      */
139     public double[] getSiArray()
140     {
141         final double[] out = new double[size()];
142         for (int i = 0; i < size(); i++)
143         {
144             out[i] = si(i);
145         }
146         return out;
147     }
148 
149     /* *********************************************************************************/
150     /* ************************************ ITERATOR ***********************************/
151     /* *********************************************************************************/
152 
153     /**
154      * Create and return an iterator over the scalars in this vector in proper sequence.
155      * @return an iterator over the scalars in this vector in proper sequence
156      */
157     @Override
158     public Iterator<A> iterator()
159     {
160         return new AbsVectorIterator();
161     }
162 
163     /** The iterator class for elements of an absolute vector. */
164     class AbsVectorIterator implements Iterator<A>
165     {
166         /** The index for iteration. */
167         private int index = 0;
168 
169         @Override
170         public boolean hasNext()
171         {
172             return this.index < size();
173         }
174 
175         @Override
176         public A next()
177         {
178             Throw.when(!hasNext(), NoSuchElementException.class, "No more elements in absolute vector");
179             return get(this.index++);
180         }
181     }
182 
183     /* *********************************************************************************/
184     /* ************************** STRING AND FORMATTING METHODS ************************/
185     /* *********************************************************************************/
186 
187     /**
188      * Formatting methods for absolute column vector.
189      * @param <V> the vector type
190      * @param <Q> the quantity type
191      */
192     public interface Col<V extends Value<V, Q>, Q extends Quantity<Q>> extends Value<V, Q>
193     {
194         /**
195          * Concise description of this vector.
196          * @return a String with the vector, with the unit attached.
197          */
198         @Override
199         default String format()
200         {
201             return format(VectorFormat.Col.defaults());
202         }
203 
204         /**
205          * String representation of this vector after applying the format.
206          * @param format the format to apply for the vector
207          * @return a String representation of this vector, formatted according to the given format
208          */
209         default String format(final VectorFormat.Col format)
210         {
211             return VectorFormatter.format((AbsVector<?, ?, ?, ?, ?>) this, format);
212         }
213 
214         /**
215          * String representation of this vector, expressed in the specified unit.
216          * @param targetUnit the unit into which the values of the vector are converted for display
217          * @return printable string with the vector's values expressed in the specified unit
218          */
219         @Override
220         default String format(final Unit<?, Q> targetUnit)
221         {
222             return format(VectorFormat.Col.defaults().setDisplayUnit(targetUnit));
223         }
224     }
225 
226     /**
227      * Formatting methods for absolute row vector.
228      * @param <V> the vector type
229      * @param <Q> the quantity type
230      */
231     public interface Row<V extends Value<V, Q>, Q extends Quantity<Q>> extends Value<V, Q>
232     {
233         /**
234          * Concise description of this vector.
235          * @return a String with the vector, with the unit attached.
236          */
237         @Override
238         default String format()
239         {
240             return format(VectorFormat.Row.defaults());
241         }
242 
243         /**
244          * String representation of this vector after applying the format.
245          * @param format the format to apply for the vector
246          * @return a String representation of this vector, formatted according to the given format
247          */
248         default String format(final VectorFormat.Row format)
249         {
250             return VectorFormatter.format((AbsVector<?, ?, ?, ?, ?>) this, format);
251         }
252 
253         /**
254          * String representation of this vector, expressed in the specified unit.
255          * @param targetUnit the unit into which the values of the vector are converted for display
256          * @return printable string with the vector's values expressed in the specified unit
257          */
258         @Override
259         default String format(final Unit<?, Q> targetUnit)
260         {
261             return format(VectorFormat.Row.defaults().setDisplayUnit(targetUnit));
262         }
263     }
264 
265 }