View Javadoc
1   package org.djunits.value.vfloat.matrix;
2   
3   import org.djunits.unit.Unit;
4   import org.djunits.value.MathFunctionsRel;
5   import org.djunits.value.Mutable;
6   import org.djunits.value.StorageType;
7   import org.djunits.value.ValueException;
8   import org.djunits.value.ValueUtil;
9   import org.djunits.value.vfloat.FloatFunction;
10  import org.djunits.value.vfloat.FloatMathFunctions;
11  import org.djunits.value.vfloat.scalar.AbstractFloatScalarRel;
12  
13  /**
14   * Relative Mutable typed Matrix.
15   * <p>
16   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17   * BSD-style license. See <a href="http://djunits.org/docs/license.html">DJUNITS License</a>.
18   * <p>
19   * $LastChangedDate: 2015-09-29 14:14:28 +0200 (Tue, 29 Sep 2015) $, @version $Revision: 73 $, by $Author: pknoppers $, initial
20   * version Sep 5, 2015 <br>
21   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
22   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
23   * @param <U> the unit
24   * @param <R> the matrix type
25   * @param <MR> the mutable matrix type
26   * @param <S> the scalar type
27   */
28  abstract class AbstractMutableFloatMatrixRel<U extends Unit<U>, R extends AbstractFloatMatrixRel<U, R, MR, S>,
29          MR extends AbstractMutableFloatMatrixRel<U, R, MR, S>, S extends AbstractFloatScalarRel<U, S>>
30          extends AbstractFloatMatrixRel<U, R, MR, S> implements Mutable, MathFunctionsRel<MR>, FloatMathFunctions<MR>
31  {
32      /** */
33      private static final long serialVersionUID = 20151006L;
34  
35      /** If set, any modification of the data must be preceded by replacing the data with a local copy. */
36      private boolean copyOnWrite = false;
37  
38      /**
39       * Construct a new Relative Mutable FloatMatrix.
40       * @param values float[][]; the values of the entries in the new Relative Immutable FloatMatrix
41       * @param unit U; the unit of the new Absolute Immutable FloatMatrix
42       * @param storageType the data type to use (e.g., DENSE or SPARSE)
43       * @throws ValueException when values is null
44       */
45      AbstractMutableFloatMatrixRel(final float[][] values, final U unit, final StorageType storageType) throws ValueException
46      {
47          super(values, unit, storageType);
48      }
49  
50      /**
51       * Construct a new Relative Mutable FloatMatrix.
52       * @param values S[][]; the values of the entries in the new Relative Immutable FloatMatrix
53       * @param storageType the data type to use (e.g., DENSE or SPARSE)
54       * @throws ValueException when values has zero entries
55       */
56      AbstractMutableFloatMatrixRel(final S[][] values, final StorageType storageType) throws ValueException
57      {
58          super(values, storageType);
59      }
60  
61      /**
62       * Construct a new Relative Mutable FloatMatrix.
63       * @param data an internal data object
64       * @param unit the unit
65       */
66      AbstractMutableFloatMatrixRel(final FloatMatrixData data, final U unit)
67      {
68          super(data, unit);
69      }
70  
71      /**
72       * Retrieve the value of the copyOnWrite flag.
73       * @return boolean
74       */
75      private boolean isCopyOnWrite()
76      {
77          return this.copyOnWrite;
78      }
79  
80      /**
81       * Change the copyOnWrite flag.
82       * @param copyOnWrite boolean; the new value for the copyOnWrite flag
83       */
84      final void setCopyOnWrite(final boolean copyOnWrite)
85      {
86          this.copyOnWrite = copyOnWrite;
87      }
88  
89      /** {@inheritDoc} */
90      @Override
91      public final MR mutable()
92      {
93          setCopyOnWrite(true);
94          final MR result = instantiateMutableType(getData(), getUnit());
95          result.setCopyOnWrite(true);
96          return result;
97      }
98  
99      /**
100      * Create a immutable version of this MutableFloatMatrix. <br>
101      * @return FloatMatrix&lt;U&gt;; mutable version of this MutableFloatMatrix
102      */
103     public final R immutable()
104     {
105         setCopyOnWrite(true);
106         return instantiateType(getData(), getUnit());
107     }
108 
109     /**********************************************************************************/
110     /**************************** TYPED CALCULATION METHODS ***************************/
111     /**********************************************************************************/
112 
113     /**
114      * Create a deep copy of this MutableFloatMatrix. <br>
115      * @return FloatMatrix&lt;U&gt;; deep copy of this MutableFloatMatrix
116      */
117     public final MR copy()
118     {
119         return mutable();
120     }
121 
122     /**
123      * Increment the value by the supplied value and return the changed matrix.
124      * @param increment FloatMatrix.Rel&lt;U&gt;; amount by which the value is incremented
125      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
126      * @throws ValueException when the size of increment is not identical to the size of this
127      */
128     @SuppressWarnings("unchecked")
129     public final MR incrementBy(final R increment) throws ValueException
130     {
131         checkCopyOnWrite();
132         this.data.incrementBy(increment.getData());
133         return (MR) this;
134     }
135 
136     /**
137      * Increment the value by the supplied value and return the changed matrix.
138      * @param increment FloatScalar.Rel&lt;U&gt;; amount by which the value is incremented
139      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
140      */
141     public final MR incrementBy(final S increment)
142     {
143         return incrementBy(increment.si);
144     }
145 
146     /**
147      * Increment the value by the supplied constant and return the changed matrix.
148      * @param increment amount by which the value is incremented
149      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
150      */
151     @SuppressWarnings("unchecked")
152     public final MR incrementBy(final float increment)
153     {
154         checkCopyOnWrite();
155         this.data.incrementBy(increment);
156         return (MR) this;
157     }
158 
159     /**
160      * Decrement the value by the supplied value and return the changed matrix.
161      * @param decrement FloatMatrix.Rel&lt;U&gt;; amount by which the value is decremented
162      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
163      * @throws ValueException when the size of increment is not identical to the size of this
164      */
165     @SuppressWarnings("unchecked")
166     public final MR decrementBy(final R decrement) throws ValueException
167     {
168         checkCopyOnWrite();
169         this.data.decrementBy(decrement.getData());
170         return (MR) this;
171     }
172 
173     /**
174      * Decrement the value by the supplied value and return the changed matrix.
175      * @param decrement FloatScalar.Rel&lt;U&gt;; amount by which the value is decremented
176      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
177      */
178     public final MR decrementBy(final S decrement)
179     {
180         return decrementBy(decrement.si);
181     }
182 
183     /**
184      * Decrement the value by the supplied constant and return the changed matrix.
185      * @param decrement amount by which the value is decremented
186      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
187      */
188     @SuppressWarnings("unchecked")
189     public final MR decrementBy(final float decrement)
190     {
191         checkCopyOnWrite();
192         this.data.decrementBy(decrement);
193         return (MR) this;
194     }
195 
196     /**
197      * Multiply the values in the matrix by the supplied values and return the changed matrix.
198      * @param factors FloatMatrix.Rel&lt;U&gt;; amounts by which the value is multiplied
199      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
200      * @throws ValueException when the size of the factors is not identical to the size of this
201      */
202     @SuppressWarnings("unchecked")
203     public final MR multiplyBy(final R factors) throws ValueException
204     {
205         checkCopyOnWrite();
206         this.data.multiplyBy(factors.getData());
207         return (MR) this;
208     }
209 
210     /**
211      * Multiply the values in the matrix by the supplied value and return the changed matrix.
212      * @param factor FloatScalar.Rel&lt;U&gt;; amount by which the values in the matrix are multiplied
213      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
214      */
215     public final MR multiplyBy(final S factor)
216     {
217         return multiplyBy(factor.si);
218     }
219 
220     /** {@inheritDoc} */
221     @SuppressWarnings("unchecked")
222     @Override
223     public final MR multiplyBy(final float factor)
224     {
225         checkCopyOnWrite();
226         this.data.multiplyBy(factor);
227         return (MR) this;
228     }
229 
230     /**
231      * Divide the values in the matrix by the supplied values and return the changed matrix.
232      * @param factors FloatMatrix.Rel&lt;U&gt;; amounts by which the value is divided
233      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
234      * @throws ValueException when the size of the factors is not identical to the size of this
235      */
236     @SuppressWarnings("unchecked")
237     public final MR divideBy(final R factors) throws ValueException
238     {
239         checkCopyOnWrite();
240         this.data.divideBy(factors.getData());
241         return (MR) this;
242     }
243 
244     /** {@inheritDoc} */
245     @Override
246     @SuppressWarnings({ "checkstyle:designforextension", "unchecked" })
247     public MR divideBy(final float factor)
248     {
249         this.data.divideBy(factor);
250         return (MR) this;
251     }
252 
253     /**
254      * Divide the values in the matrix by the supplied value and return the changed matrix.
255      * @param factor FloatScalar.Rel&lt;U&gt;; amount by which the values in the matrix are divided
256      * @return the changed MutableFloatMatrix.Rel&lt;U&gt;
257      */
258     public final MR divideBy(final S factor)
259     {
260         return divideBy(factor.si);
261     }
262 
263     /**********************************************************************************/
264     /********************************** MATH METHODS **********************************/
265     /**********************************************************************************/
266 
267     /**
268      * Execute a function on a cell by cell basis. Note: because many functions have to act on zero cells or can generate cells
269      * with a zero value, the functions have to be applied on a dense dataset which has to be transformed back to a sparse
270      * dataset if necessary.
271      * @param floatFunction the function to apply
272      */
273     public final void assign(final FloatFunction floatFunction)
274     {
275         checkCopyOnWrite();
276         if (this.data instanceof FloatMatrixDataDense)
277         {
278             ((FloatMatrixDataDense) this.data).assign(floatFunction);
279         }
280         else
281         {
282             FloatMatrixDataDense dvdd = ((FloatMatrixDataSparse) this.data).toDense();
283             dvdd.assign(floatFunction);
284             this.data = dvdd.toSparse();
285         }
286     }
287 
288     /** {@inheritDoc} */
289     @SuppressWarnings("unchecked")
290     @Override
291     public final MR abs()
292     {
293         assign(FloatMathFunctions.ABS);
294         return (MR) this;
295     }
296 
297     /** {@inheritDoc} */
298     @Override
299     @SuppressWarnings("unchecked")
300     public final MR ceil()
301     {
302         assign(FloatMathFunctions.CEIL);
303         return (MR) this;
304     }
305 
306     /** {@inheritDoc} */
307     @Override
308     @SuppressWarnings("unchecked")
309     public final MR floor()
310     {
311         assign(FloatMathFunctions.FLOOR);
312         return (MR) this;
313     }
314 
315     /** {@inheritDoc} */
316     @Override
317     @SuppressWarnings("unchecked")
318     public final MR neg()
319     {
320         assign(FloatMathFunctions.NEG);
321         return (MR) this;
322     }
323 
324     /** {@inheritDoc} */
325     @Override
326     @SuppressWarnings("unchecked")
327     public final MR rint()
328     {
329         assign(FloatMathFunctions.RINT);
330         return (MR) this;
331     }
332 
333     /** {@inheritDoc} */
334     @Override
335     @SuppressWarnings("unchecked")
336     public final MR round()
337     {
338         assign(FloatMathFunctions.ROUND);
339         return (MR) this;
340     }
341 
342     /**
343      * Check the copyOnWrite flag and, if it is set, make a deep copy of the data and clear the flag.
344      */
345     protected final void checkCopyOnWrite()
346     {
347         if (isCopyOnWrite())
348         {
349             this.data = this.data.copy();
350             setCopyOnWrite(false);
351         }
352     }
353 
354     /**
355      * Set the value for a cell in the matrix.
356      * @param row the row
357      * @param column the column
358      * @param valueSI the value, expressed in the SI unit
359      * @throws ValueException when the row/column is out of range
360      */
361     public final void setSI(final int row, final int column, final float valueSI) throws ValueException
362     {
363         checkIndex(row, column);
364         checkCopyOnWrite();
365         this.data.setSI(row, column, valueSI);
366     }
367 
368     /**
369      * Set the value for a cell in the matrix.
370      * @param row the row
371      * @param column the column
372      * @param value the value
373      * @throws ValueException when the row/column is out of range
374      */
375     public final void set(final int row, final int column, final S value) throws ValueException
376     {
377         setSI(row, column, value.getSI());
378     }
379 
380     /**
381      * Set the value for a cell in the matrix.
382      * @param row the row
383      * @param column the column
384      * @param value the value, expressed in the given unit
385      * @param valueUnit the unit of the value
386      * @throws ValueException when the row/column is out of range
387      */
388     public final void setInUnit(final int row, final int column, final float value, final U valueUnit) throws ValueException
389     {
390         setSI(row, column, (float) ValueUtil.expressAsSIUnit(value, valueUnit));
391     }
392 
393     /**
394      * Normalize the matrix, i.e. scale the values to make the sum equal to 1.
395      * @throws ValueException when the sum of the values is zero and normalization is not possible
396      */
397     public final void normalize() throws ValueException
398     {
399         float sum = zSum();
400         if (0 == sum)
401         {
402             throw new ValueException("zSum is 0; cannot normalize");
403         }
404         checkCopyOnWrite();
405         this.data.divideBy(sum);
406     }
407 }