1 package org.djunits.value.vfloat.matrix.data;
2
3 import java.util.stream.IntStream;
4
5 import org.djunits.value.ValueRuntimeException;
6 import org.djunits.value.storage.StorageType;
7 import org.djunits.value.vfloat.function.FloatFunction;
8 import org.djunits.value.vfloat.function.FloatFunction2;
9 import org.djutils.exceptions.Throw;
10
11
12
13
14
15
16
17
18
19
20 public class FloatMatrixDataDense extends FloatMatrixData
21 {
22
23 private static final long serialVersionUID = 1L;
24
25
26
27
28
29
30
31
32 public FloatMatrixDataDense(final float[] 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("FloatMatrixDataDense constructor, rows * cols != matrixSI.length");
38 }
39 this.matrixSI = new float[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
52 public FloatMatrixDataDense(final float[][] matrixSI) throws ValueRuntimeException
53 {
54 super(StorageType.DENSE);
55 Throw.whenNull(matrixSI, "DoubleMatrixDataDense constructor, matrixSI == null");
56 this.rows = matrixSI.length;
57 this.cols = this.rows == 0 ? 0 : matrixSI[0].length;
58 this.matrixSI = new float[this.rows * this.cols];
59 for (int r = 0; r < this.rows; r++)
60 {
61 float[] row = matrixSI[r];
62 if (row.length != this.cols)
63 {
64 throw new ValueRuntimeException("FloatMatrixDataDense constructor, ragged matrix");
65 }
66 System.arraycopy(row, 0, this.matrixSI, r * this.cols, row.length);
67 }
68 }
69
70
71 @Override
72 public final int cardinality()
73 {
74
75 return (int) IntStream.range(0, this.matrixSI.length).parallel().mapToDouble(i -> this.matrixSI[i])
76 .filter(d -> d != 0.0).count();
77 }
78
79
80 @Override
81 public final FloatMatrixDataDense assign(final FloatFunction floatFunction)
82 {
83 IntStream.range(0, this.rows() * this.cols()).parallel()
84 .forEach(i -> this.matrixSI[i] = floatFunction.apply(this.matrixSI[i]));
85 return this;
86 }
87
88
89 @Override
90 public final FloatMatrixDataDense assign(final FloatFunction2 floatFunction, final FloatMatrixData right)
91 {
92 if (right.isDense())
93 {
94 FloatMatrixDataDense rightDense = (FloatMatrixDataDense) right;
95 IntStream.range(0, this.rows() * this.cols()).parallel()
96 .forEach(i -> this.matrixSI[i] = floatFunction.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] = floatFunction.apply(this.matrixSI[i], right.getSI(i / this.cols, i % this.cols)));
102 }
103 return this;
104 }
105
106
107 @Override
108 public final FloatMatrixDataDense toDense()
109 {
110 return this;
111 }
112
113
114 @Override
115 public final FloatMatrixDataSparse toSparse()
116 {
117 int length = cardinality();
118 float[] sparseSI = new float[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 FloatMatrixDataSparse(sparseSI, indices, this.rows, this.cols);
135 }
136
137
138 @Override
139 public final float 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 float valueSI)
147 {
148 this.matrixSI[row * this.cols + col] = valueSI;
149 }
150
151
152 @Override
153 public final float[][] getDenseMatrixSI()
154 {
155 float[][] matrix = new float[this.rows][];
156 for (int r = 0; r < this.rows; r++)
157 {
158 float[] row = new float[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 double[][] getDoubleDenseMatrixSI()
168 {
169 double[][] matrix = new double[this.rows][];
170 for (int r = 0; r < this.rows; r++)
171 {
172 double[] row = new double[this.cols];
173 int offset = r * this.cols;
174 for (int c = 0; c < this.cols; c++)
175 {
176 row[c] = this.matrixSI[offset++];
177 }
178 matrix[r] = row;
179 }
180 return matrix;
181 }
182
183
184 @Override
185 public final FloatMatrixDataDense copy()
186 {
187 try
188 {
189 return new FloatMatrixDataDense(getDenseMatrixSI());
190 }
191 catch (ValueRuntimeException exception)
192 {
193 throw new RuntimeException(exception);
194 }
195 }
196
197
198 @Override
199 public FloatMatrixData plus(final FloatMatrixData right) throws ValueRuntimeException
200 {
201 checkSizes(right);
202 float[] fm = new float[this.rows * this.cols];
203 if (right.isDense())
204 {
205 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols).forEach(
206 c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] + right.matrixSI[r * this.cols + c]));
207 }
208 else
209 {
210 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols)
211 .forEach(c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] + right.getSI(r, c)));
212 }
213 return new FloatMatrixDataDense(fm, this.rows, this.cols);
214 }
215
216
217 @Override
218 public final FloatMatrixDataDense minus(final FloatMatrixData right)
219 {
220 checkSizes(right);
221 float[] fm = new float[this.rows * this.cols];
222 if (right.isDense())
223 {
224 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols).forEach(
225 c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] - right.matrixSI[r * this.cols + c]));
226 }
227 else
228 {
229 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols)
230 .forEach(c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] - right.getSI(r, c)));
231 }
232 return new FloatMatrixDataDense(fm, this.rows, this.cols);
233 }
234
235
236 @Override
237 public FloatMatrixData times(final FloatMatrixData right) throws ValueRuntimeException
238 {
239 if (right.isSparse())
240 {
241
242 return right.times(this);
243 }
244
245 checkSizes(right);
246 return this.copy().multiplyBy(right);
247 }
248
249
250 @Override
251 public FloatMatrixData divide(final FloatMatrixData right) throws ValueRuntimeException
252 {
253 checkSizes(right);
254 return this.copy().divideBy(right);
255 }
256
257 }