View Javadoc
1   package org.djunits.value.vdouble.matrix;
2   
3   import java.util.stream.IntStream;
4   
5   import org.djunits.value.StorageType;
6   import org.djunits.value.ValueException;
7   import org.djunits.value.vdouble.DoubleFunction;
8   
9   /**
10   * Stores dense data for a DoubleMatrix and carries out basic operations.
11   * <p>
12   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
13   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
14   * </p>
15   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
16   * initial version Oct 3, 2015 <br>
17   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
18   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
19   */
20  public class DoubleMatrixDataDense extends DoubleMatrixData
21  {
22      /** */
23      private static final long serialVersionUID = 1L;
24  
25      /**
26       * Create a matrix with dense data.
27       * @param matrixSI double[]; the data to store
28       * @param rows int; the number of rows
29       * @param cols int; the number of columns
30       * @throws ValueException in case <tt>rows * cols != matrixSI.length</tt>
31       */
32      public DoubleMatrixDataDense(final double[] matrixSI, final int rows, final int cols) throws ValueException
33      {
34          super(StorageType.DENSE);
35          if (rows * cols != matrixSI.length)
36          {
37              throw new ValueException("DoubleMatrixDataDense constructor, rows * cols != matrixSI.length");
38          }
39          this.matrixSI = new double[matrixSI.length];
40          System.arraycopy(matrixSI, 0, this.matrixSI, 0, matrixSI.length);
41          this.rows = rows;
42          this.cols = cols;
43      }
44  
45      /**
46       * Create a matrix with dense data.
47       * @param matrixSI double[][]; the data to store
48       * @throws ValueException in case matrix is ragged
49       */
50      public DoubleMatrixDataDense(final double[][] matrixSI) throws ValueException
51      {
52          super(StorageType.DENSE);
53          if (matrixSI == null || matrixSI.length == 0)
54          {
55              throw new ValueException("DoubleMatrixDataDense constructor, matrixSI == null || matrixSI.length == 0");
56          }
57          this.rows = matrixSI.length;
58          this.cols = matrixSI[0].length;
59          this.matrixSI = new double[this.rows * this.cols];
60          for (int r = 0; r < this.rows; r++)
61          {
62              double[] row = matrixSI[r];
63              if (row.length != this.cols)
64              {
65                  throw new ValueException("DoubleMatrixDataDense constructor, ragged matrix");
66              }
67              System.arraycopy(row, 0, this.matrixSI, r * this.cols, row.length);
68          }
69      }
70  
71      /**
72       * @param doubleFunction DoubleFunction; the function to apply on the (mutable) data elements
73       */
74      public final void assign(final DoubleFunction doubleFunction)
75      {
76          IntStream.range(0, this.rows() * this.cols()).parallel()
77                  .forEach(i -> this.matrixSI[i] = doubleFunction.apply(this.matrixSI[i]));
78      }
79  
80      /** {@inheritDoc} */
81      @Override
82      public final DoubleMatrixDataSparse toSparse()
83      {
84          int length = cardinality();
85          double[] sparseSI = new double[length];
86          long[] indices = new long[length];
87          int count = 0;
88          for (int r = 0; r < this.rows; r++)
89          {
90              for (int c = 0; c < this.cols; c++)
91              {
92                  int index = r * this.cols + c;
93                  if (this.matrixSI[index] != 0.0)
94                  {
95                      sparseSI[count] = this.matrixSI[index];
96                      indices[count] = index;
97                      count++;
98                  }
99              }
100         }
101         return new DoubleMatrixDataSparse(sparseSI, indices, this.matrixSI.length, this.rows, this.cols);
102     }
103 
104     /** {@inheritDoc} */
105     @Override
106     public final double getSI(final int row, final int col)
107     {
108         return this.matrixSI[row * this.cols + col];
109     }
110 
111     /** {@inheritDoc} */
112     @Override
113     public final void setSI(final int row, final int col, final double valueSI)
114     {
115         this.matrixSI[row * this.cols + col] = valueSI;
116     }
117 
118     /** {@inheritDoc} */
119     @Override
120     public final double[][] getDenseMatrixSI()
121     {
122         double[][] matrix = new double[this.rows][];
123         for (int r = 0; r < this.rows; r++)
124         {
125             double[] row = new double[this.cols];
126             System.arraycopy(this.matrixSI, r * this.cols, row, 0, row.length);
127             matrix[r] = row;
128         }
129         return matrix;
130     }
131 
132     /** {@inheritDoc} */
133     @Override
134     public final DoubleMatrixDataDense copy()
135     {
136         try
137         {
138             return new DoubleMatrixDataDense(getDenseMatrixSI());
139         }
140         catch (ValueException exception)
141         {
142             throw new RuntimeException(exception); // should not happen -- original is not ragged...
143         }
144     }
145 
146     /** {@inheritDoc} */
147     @Override
148     public final void incrementBy(final DoubleMatrixData right) throws ValueException
149     {
150         IntStream.range(0, this.rows).parallel().forEach(
151                 r -> IntStream.range(0, this.cols).forEach(c -> this.matrixSI[r * this.cols + c] += right.getSI(r, c)));
152     }
153 
154     /** {@inheritDoc} */
155     @Override
156     public final void decrementBy(final DoubleMatrixData right) throws ValueException
157     {
158         IntStream.range(0, this.rows).parallel().forEach(
159                 r -> IntStream.range(0, this.cols).forEach(c -> this.matrixSI[r * this.cols + c] -= right.getSI(r, c)));
160     }
161 
162     /** {@inheritDoc} */
163     @Override
164     public final void multiplyBy(final DoubleMatrixData right) throws ValueException
165     {
166         IntStream.range(0, this.rows).parallel().forEach(
167                 r -> IntStream.range(0, this.cols).forEach(c -> this.matrixSI[r * this.cols + c] *= right.getSI(r, c)));
168     }
169 
170     /** {@inheritDoc} */
171     @Override
172     public final void divideBy(final DoubleMatrixData right) throws ValueException
173     {
174         IntStream.range(0, this.rows).parallel().forEach(
175                 r -> IntStream.range(0, this.cols).forEach(c -> this.matrixSI[r * this.cols + c] /= right.getSI(r, c)));
176     }
177 }