View Javadoc
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-2023 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 }