1 package org.djunits.value.vdouble.matrix.data;
2
3 import java.util.Arrays;
4 import java.util.stream.IntStream;
5
6 import org.djunits.value.ValueRuntimeException;
7 import org.djunits.value.storage.StorageType;
8 import org.djunits.value.vdouble.function.DoubleFunction;
9 import org.djunits.value.vdouble.function.DoubleFunction2;
10
11
12
13
14
15
16
17
18
19
20 public class DoubleMatrixDataDense extends DoubleMatrixData
21 {
22
23 private static final long serialVersionUID = 1L;
24
25
26
27
28
29
30
31
32 public DoubleMatrixDataDense(final double[] matrixSI, final int rows, final int cols) throws ValueRuntimeException
33 {
34 super(StorageType.DENSE);
35 if (rows * cols != matrixSI.length)
36 {
37 throw new ValueRuntimeException("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
47
48
49
50
51 public DoubleMatrixDataDense(final double[][] matrixSI) throws ValueRuntimeException
52 {
53 super(StorageType.DENSE);
54 if (matrixSI == null || matrixSI.length == 0)
55 {
56 throw new ValueRuntimeException("DoubleMatrixDataDense constructor, matrixSI == null || matrixSI.length == 0");
57 }
58 this.rows = matrixSI.length;
59 this.cols = matrixSI[0].length;
60 this.matrixSI = new double[this.rows * this.cols];
61 for (int r = 0; r < this.rows; r++)
62 {
63 double[] row = matrixSI[r];
64 if (row.length != this.cols)
65 {
66 throw new ValueRuntimeException("DoubleMatrixDataDense constructor, ragged matrix");
67 }
68 System.arraycopy(row, 0, this.matrixSI, r * this.cols, row.length);
69 }
70 }
71
72
73 @Override
74 public final int cardinality()
75 {
76 return (int) Arrays.stream(this.matrixSI).parallel().filter(d -> d != 0.0).count();
77 }
78
79
80 @Override
81 public final DoubleMatrixDataDense assign(final DoubleFunction doubleFunction)
82 {
83 IntStream.range(0, this.rows() * this.cols()).parallel()
84 .forEach(i -> this.matrixSI[i] = doubleFunction.apply(this.matrixSI[i]));
85 return this;
86 }
87
88
89 @Override
90 public final DoubleMatrixDataDense assign(final DoubleFunction2 doubleFunction, final DoubleMatrixData right)
91 {
92 if (right.isDense())
93 {
94 DoubleMatrixDataDenserg/djunits/value/vdouble/matrix/data/DoubleMatrixDataDense.html#DoubleMatrixDataDense">DoubleMatrixDataDense rightDense = (DoubleMatrixDataDense) right;
95 IntStream.range(0, this.rows() * this.cols()).parallel()
96 .forEach(i -> this.matrixSI[i] = doubleFunction.apply(this.matrixSI[i], rightDense.matrixSI[i]));
97 }
98 else
99 {
100 IntStream.range(0, this.rows() * this.cols()).parallel().forEach(
101 i -> this.matrixSI[i] = doubleFunction.apply(this.matrixSI[i], right.getSI(i / this.cols, i % this.cols)));
102 }
103 return this;
104 }
105
106
107 @Override
108 public final DoubleMatrixDataDense toDense()
109 {
110 return this;
111 }
112
113
114 @Override
115 public final DoubleMatrixDataSparse toSparse()
116 {
117 int length = cardinality();
118 double[] sparseSI = new double[length];
119 long[] indices = new long[length];
120 int count = 0;
121 for (int r = 0; r < this.rows; r++)
122 {
123 for (int c = 0; c < this.cols; c++)
124 {
125 int index = r * this.cols + c;
126 if (this.matrixSI[index] != 0.0)
127 {
128 sparseSI[count] = this.matrixSI[index];
129 indices[count] = index;
130 count++;
131 }
132 }
133 }
134 return new DoubleMatrixDataSparse(sparseSI, indices, this.rows, this.cols);
135 }
136
137
138 @Override
139 public final double getSI(final int row, final int col)
140 {
141 return this.matrixSI[row * this.cols + col];
142 }
143
144
145 @Override
146 public final void setSI(final int row, final int col, final double valueSI)
147 {
148 this.matrixSI[row * this.cols + col] = valueSI;
149 }
150
151
152 @Override
153 public final double[][] getDenseMatrixSI()
154 {
155 double[][] matrix = new double[this.rows][];
156 for (int r = 0; r < this.rows; r++)
157 {
158 double[] row = new double[this.cols];
159 System.arraycopy(this.matrixSI, r * this.cols, row, 0, row.length);
160 matrix[r] = row;
161 }
162 return matrix;
163 }
164
165
166 @Override
167 public final DoubleMatrixDataDense copy()
168 {
169 try
170 {
171 return new DoubleMatrixDataDense(getDenseMatrixSI());
172 }
173 catch (ValueRuntimeException exception)
174 {
175 throw new RuntimeException(exception);
176 }
177 }
178
179
180 @Override
181 public DoubleMatrixDataix/data/DoubleMatrixData.html#DoubleMatrixData">DoubleMatrixData plus(final DoubleMatrixData right) throws ValueRuntimeException
182 {
183 checkSizes(right);
184 double[] dm = new double[this.rows * this.cols];
185 if (right.isDense())
186 {
187 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols).forEach(
188 c -> dm[r * this.cols + c] = this.matrixSI[r * this.cols + c] + right.matrixSI[r * this.cols + c]));
189 }
190 else
191 {
192 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols)
193 .forEach(c -> dm[r * this.cols + c] = this.matrixSI[r * this.cols + c] + right.getSI(r, c)));
194 }
195 return new DoubleMatrixDataDense(dm, this.rows, this.cols);
196 }
197
198
199 @Override
200 public final DoubleMatrixDataDense minus(final DoubleMatrixData right)
201 {
202 checkSizes(right);
203 double[] dm = new double[this.rows * this.cols];
204 if (right.isDense())
205 {
206 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols).forEach(
207 c -> dm[r * this.cols + c] = this.matrixSI[r * this.cols + c] - right.matrixSI[r * this.cols + c]));
208 }
209 else
210 {
211 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols)
212 .forEach(c -> dm[r * this.cols + c] = this.matrixSI[r * this.cols + c] - right.getSI(r, c)));
213 }
214 return new DoubleMatrixDataDense(dm, this.rows, this.cols);
215 }
216
217
218 @Override
219 public DoubleMatrixDatax/data/DoubleMatrixData.html#DoubleMatrixData">DoubleMatrixData times(final DoubleMatrixData right) throws ValueRuntimeException
220 {
221 if (right.isSparse())
222 {
223
224 return right.times(this);
225 }
226
227 checkSizes(right);
228 return this.copy().multiplyBy(right);
229 }
230
231
232 @Override
233 public DoubleMatrixData/data/DoubleMatrixData.html#DoubleMatrixData">DoubleMatrixData divide(final DoubleMatrixData right) throws ValueRuntimeException
234 {
235 checkSizes(right);
236 double[] dm = new double[this.rows * this.cols];
237 if (right.isDense())
238 {
239 IntStream.range(0, this.rows * this.cols).parallel().forEach(i -> dm[i] = this.matrixSI[i] / right.matrixSI[i]);
240 }
241 else
242 {
243 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols)
244 .forEach(c -> dm[r * this.cols + c] = this.matrixSI[r * this.cols + c] / right.getSI(r, c)));
245 }
246 return new DoubleMatrixDataDense(dm, this.rows, this.cols);
247 }
248
249
250 @Override
251 public String toString()
252 {
253 return "DoubleMatrixDataDense [storageType=" + getStorageType() + ", matrixSI=" + Arrays.toString(this.matrixSI) + "]";
254 }
255
256 }