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 @Override
71 public final int cardinality()
72 {
73
74 return (int) IntStream.range(0, this.matrixSI.length).parallel().mapToDouble(i -> this.matrixSI[i])
75 .filter(d -> d != 0.0).count();
76 }
77
78 @Override
79 public final FloatMatrixDataDense assign(final FloatFunction floatFunction)
80 {
81 IntStream.range(0, this.rows() * this.cols()).parallel()
82 .forEach(i -> this.matrixSI[i] = floatFunction.apply(this.matrixSI[i]));
83 return this;
84 }
85
86 @Override
87 public final FloatMatrixDataDense assign(final FloatFunction2 floatFunction, final FloatMatrixData right)
88 {
89 if (right.isDense())
90 {
91 FloatMatrixDataDense rightDense = (FloatMatrixDataDense) right;
92 IntStream.range(0, this.rows() * this.cols()).parallel()
93 .forEach(i -> this.matrixSI[i] = floatFunction.apply(this.matrixSI[i], rightDense.matrixSI[i]));
94 }
95 else
96 {
97 IntStream.range(0, this.rows() * this.cols()).parallel().forEach(
98 i -> this.matrixSI[i] = floatFunction.apply(this.matrixSI[i], right.getSI(i / this.cols, i % this.cols)));
99 }
100 return this;
101 }
102
103 @Override
104 public final FloatMatrixDataDense toDense()
105 {
106 return this;
107 }
108
109 @Override
110 public final FloatMatrixDataSparse toSparse()
111 {
112 int length = cardinality();
113 float[] sparseSI = new float[length];
114 long[] indices = new long[length];
115 int count = 0;
116 for (int r = 0; r < this.rows; r++)
117 {
118 for (int c = 0; c < this.cols; c++)
119 {
120 int index = r * this.cols + c;
121 if (this.matrixSI[index] != 0.0)
122 {
123 sparseSI[count] = this.matrixSI[index];
124 indices[count] = index;
125 count++;
126 }
127 }
128 }
129 return new FloatMatrixDataSparse(sparseSI, indices, this.rows, this.cols);
130 }
131
132 @Override
133 public final float getSI(final int row, final int col)
134 {
135 return this.matrixSI[row * this.cols + col];
136 }
137
138 @Override
139 public final void setSI(final int row, final int col, final float valueSI)
140 {
141 this.matrixSI[row * this.cols + col] = valueSI;
142 }
143
144 @Override
145 public final float[][] getDenseMatrixSI()
146 {
147 float[][] matrix = new float[this.rows][];
148 for (int r = 0; r < this.rows; r++)
149 {
150 float[] row = new float[this.cols];
151 System.arraycopy(this.matrixSI, r * this.cols, row, 0, row.length);
152 matrix[r] = row;
153 }
154 return matrix;
155 }
156
157 @Override
158 public final double[][] getDoubleDenseMatrixSI()
159 {
160 double[][] matrix = new double[this.rows][];
161 for (int r = 0; r < this.rows; r++)
162 {
163 double[] row = new double[this.cols];
164 int offset = r * this.cols;
165 for (int c = 0; c < this.cols; c++)
166 {
167 row[c] = this.matrixSI[offset++];
168 }
169 matrix[r] = row;
170 }
171 return matrix;
172 }
173
174 @Override
175 public final FloatMatrixDataDense copy()
176 {
177 try
178 {
179 return new FloatMatrixDataDense(getDenseMatrixSI());
180 }
181 catch (ValueRuntimeException exception)
182 {
183 throw new RuntimeException(exception);
184 }
185 }
186
187 @Override
188 public FloatMatrixData plus(final FloatMatrixData right) throws ValueRuntimeException
189 {
190 checkSizes(right);
191 float[] fm = new float[this.rows * this.cols];
192 if (right.isDense())
193 {
194 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols).forEach(
195 c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] + right.matrixSI[r * this.cols + c]));
196 }
197 else
198 {
199 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols)
200 .forEach(c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] + right.getSI(r, c)));
201 }
202 return new FloatMatrixDataDense(fm, this.rows, this.cols);
203 }
204
205 @Override
206 public final FloatMatrixDataDense minus(final FloatMatrixData right)
207 {
208 checkSizes(right);
209 float[] fm = new float[this.rows * this.cols];
210 if (right.isDense())
211 {
212 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols).forEach(
213 c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] - right.matrixSI[r * this.cols + c]));
214 }
215 else
216 {
217 IntStream.range(0, this.rows).parallel().forEach(r -> IntStream.range(0, this.cols)
218 .forEach(c -> fm[r * this.cols + c] = this.matrixSI[r * this.cols + c] - right.getSI(r, c)));
219 }
220 return new FloatMatrixDataDense(fm, this.rows, this.cols);
221 }
222
223 @Override
224 public FloatMatrixData times(final FloatMatrixData right) throws ValueRuntimeException
225 {
226 if (right.isSparse())
227 {
228
229 return right.times(this);
230 }
231
232 checkSizes(right);
233 return this.copy().multiplyBy(right);
234 }
235
236 @Override
237 public FloatMatrixData divide(final FloatMatrixData right) throws ValueRuntimeException
238 {
239 checkSizes(right);
240 return this.copy().divideBy(right);
241 }
242
243 }