1 package org.djunits.value.vdouble.vector.base;
2
3 import org.djunits.unit.SIUnit;
4 import org.djunits.unit.Unit;
5 import org.djunits.unit.util.UnitException;
6 import org.djunits.value.Relative;
7 import org.djunits.value.ValueRuntimeException;
8 import org.djunits.value.vdouble.function.DoubleMathFunctions;
9 import org.djunits.value.vdouble.scalar.base.DoubleScalarRel;
10 import org.djunits.value.vdouble.vector.SIVector;
11 import org.djunits.value.vdouble.vector.data.DoubleVectorData;
12
13 /**
14 * AbstractMutableDoubleVectorRel.java.
15 * <p>
16 * Copyright (c) 2019-2025 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17 * BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
18 * </p>
19 * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank">Alexander Verbraeck</a>
20 * @param <U> the unit
21 * @param <S> the scalar type belonging to the vector type
22 * @param <RV> the relative vector type with this unit
23 */
24 public abstract class DoubleVectorRel<U extends Unit<U>, S extends DoubleScalarRel<U, S>, RV extends DoubleVectorRel<U, S, RV>>
25 extends DoubleVector<U, S, RV> implements Relative<U, RV>
26 {
27 /** */
28 private static final long serialVersionUID = 20190908L;
29
30 /**
31 * Construct a new Relative Mutable DoubleVector.
32 * @param data an internal data object
33 * @param unit the unit
34 */
35 protected DoubleVectorRel(final DoubleVectorData data, final U unit)
36 {
37 super(data.copy(), unit);
38 }
39
40 /**
41 * Compute the sum of all SI values of this vector.
42 * @return the sum of all SI values of this vector with the same display unit as this vector
43 */
44 public final S zSum()
45 {
46 return instantiateScalarSI(getData().zSum(), getDisplayUnit());
47 }
48
49 @Override
50 public final RV plus(final RV rel) throws ValueRuntimeException
51 {
52 return instantiateVector(this.getData().plus(rel.getData()), getDisplayUnit());
53 }
54
55 @Override
56 public final RV minus(final RV rel) throws ValueRuntimeException
57 {
58 return instantiateVector(this.getData().minus(rel.getData()), getDisplayUnit());
59 }
60
61 /**
62 * Increment all values of this vector by the increment. This only works if the vector is mutable.
63 * @param increment the scalar by which to increment all values
64 * @return this modified vector
65 * @throws ValueRuntimeException in case this vector is immutable
66 */
67 @SuppressWarnings("unchecked")
68 public RV incrementBy(final S increment)
69 {
70 checkCopyOnWrite();
71 assign(DoubleMathFunctions.INC(increment.si));
72 return (RV) this;
73 }
74
75 /**
76 * Increment all values of this vector by the increment on a value by value basis. This only works if this vector is
77 * mutable.
78 * @param increment the vector that contains the values by which to increment the corresponding values
79 * @return this modified vector
80 * @throws ValueRuntimeException in case this vector is immutable, when the sizes of the vectors differ, or
81 * <code>increment</code> is null
82 */
83 @SuppressWarnings("unchecked")
84 public RV incrementBy(final RV increment)
85 {
86 checkCopyOnWrite();
87 getData().incrementBy(increment.getData());
88 return (RV) this;
89 }
90
91 /**
92 * Decrement all values of this vector by the decrement. This only works if the vector is mutable.
93 * @param decrement the scalar by which to decrement all values
94 * @return this modified vector
95 * @throws ValueRuntimeException in case this vector is immutable
96 */
97 @SuppressWarnings("unchecked")
98 public RV decrementBy(final S decrement)
99 {
100 checkCopyOnWrite();
101 assign(DoubleMathFunctions.DEC(decrement.si));
102 return (RV) this;
103 }
104
105 /**
106 * Decrement all values of this vector by the decrement on a value by value basis. This only works if this vector is
107 * mutable.
108 * @param decrement the vector that contains the values by which to decrement the corresponding values
109 * @return this modified vector
110 * @throws ValueRuntimeException in case this vector is immutable, when the sizes of the vectors differ, or
111 * <code>decrement</code> is null
112 */
113 @SuppressWarnings("unchecked")
114 public RV decrementBy(final RV decrement)
115 {
116 checkCopyOnWrite();
117 getData().decrementBy(decrement.getData());
118 return (RV) this;
119 }
120
121 /**
122 * Multiply all values of this vector by the multiplier. This only works if the vector is mutable.
123 * @param multiplier the factor by which to multiply all values
124 * @return this modified vector
125 * @throws ValueRuntimeException in case the vector is immutable
126 */
127 public RV multiplyBy(final double multiplier)
128 {
129 return assign(DoubleMathFunctions.MULT(multiplier));
130 }
131
132 /**
133 * Divide all values of this vector by the divisor. This only works if the vector is mutable.
134 * @param divisor the value by which to divide all values
135 * @return this modified vector
136 * @throws ValueRuntimeException in case the vector is immutable
137 */
138 public RV divideBy(final double divisor)
139 {
140 return assign(DoubleMathFunctions.DIV(divisor));
141 }
142
143 /**
144 * Multiply a Relative value with this Relative value for a vector or matrix. The multiplication is done value by value and
145 * store the result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise
146 * the result is a sparse vector or matrix.
147 * @param rel the right operand, which can be any vector type
148 * @return the multiplication of this vector and the operand
149 * @throws ValueRuntimeException in case this vector or matrix and the operand have a different size
150 * @throws UnitException on unit error
151 * @param <UT> the unit type of the multiplier
152 * @param <ST> the scalar type of the multiplier
153 * @param <VT> the vector type of the multiplier
154 */
155 public final <UT extends Unit<UT>, ST extends DoubleScalarRel<UT, ST>,
156 VT extends DoubleVectorRel<UT, ST, VT> & Relative<UT, VT>> SIVector times(final VT rel)
157 throws ValueRuntimeException, UnitException
158 {
159 checkSize(rel);
160 return new SIVector(this.getData().times(rel.getData()), SIUnit.of(
161 getDisplayUnit().getQuantity().getSiDimensions().plus(rel.getDisplayUnit().getQuantity().getSiDimensions())));
162 }
163
164 /**
165 * Divide this Relative value by a Relative value for a vector or matrix. The division is done value by value and store the
166 * result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise the result
167 * is a sparse vector or matrix.
168 * @param rel the right operand, which can be any vector type
169 * @return the division of this vector and the operand
170 * @throws ValueRuntimeException in case this vector or matrix and the operand have a different size
171 * @throws UnitException on unit error
172 * @param <UT> the unit type of the multiplier
173 * @param <ST> the scalar type of the multiplier
174 * @param <VT> the vector type of the multiplier
175 */
176 public final <UT extends Unit<UT>, ST extends DoubleScalarRel<UT, ST>,
177 VT extends DoubleVectorRel<UT, ST, VT>> SIVector divide(final VT rel) throws ValueRuntimeException, UnitException
178 {
179 checkSize(rel);
180 return new SIVector(this.getData().divide(rel.getData()), SIUnit.of(
181 getDisplayUnit().getQuantity().getSiDimensions().minus(rel.getDisplayUnit().getQuantity().getSiDimensions())));
182 }
183
184 @Override
185 public RV times(final double multiplier)
186 {
187 return clone().mutable().assign(DoubleMathFunctions.MULT(multiplier)).immutable();
188 }
189
190 @Override
191 public RV divide(final double divisor)
192 {
193 return clone().mutable().assign(DoubleMathFunctions.DIV(divisor)).immutable();
194 }
195
196 @Override
197 public RV times(final float multiplier)
198 {
199 return times((double) multiplier);
200 }
201
202 @Override
203 public RV divide(final float divisor)
204 {
205 return divide((double) divisor);
206 }
207
208 }