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