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 }