1 package org.djunits.vecmat.storage;
2
3 import java.util.Arrays;
4 import java.util.List;
5 import java.util.Objects;
6
7 import org.djunits.quantity.def.AbsBasic;
8 import org.djunits.quantity.def.Quantity;
9 import org.djunits.quantity.def.Reference;
10 import org.djunits.unit.Unit;
11 import org.djutils.exceptions.Throw;
12
13
14
15
16
17
18
19
20
21
22 public class DenseDoubleDataSi implements DataGridSi<DenseDoubleDataSi>
23 {
24
25 private static final long serialVersionUID = 601L;
26
27
28 private final double[] dataSi;
29
30
31 private final int rows;
32
33
34 private final int cols;
35
36
37
38
39
40
41
42
43
44
45 public DenseDoubleDataSi(final double[] dataSi, final int rows, final int cols)
46 {
47 Throw.whenNull(dataSi, "dataSi");
48 Throw.when(rows <= 0, IllegalArgumentException.class, "Number of rows <= 0");
49 Throw.when(cols <= 0, IllegalArgumentException.class, "Number of columns <= 0");
50 Throw.when(dataSi.length != rows * cols, IllegalArgumentException.class,
51 "Data object length != rows * cols, %d != %d * %d", dataSi.length, rows, cols);
52 this.dataSi = dataSi;
53 this.rows = rows;
54 this.cols = cols;
55 }
56
57
58
59
60
61
62
63
64
65
66 public static DenseDoubleDataSi ofSi(final double[] dataSi, final int rows, final int cols)
67 {
68 return new DenseDoubleDataSi(dataSi.clone(), rows, cols);
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82 public static <Q extends Quantity<Q>> DenseDoubleDataSi of(final double[] dataInUnit, final int rows, final int cols,
83 final Unit<?, Q> unit)
84 {
85 Throw.whenNull(dataInUnit, "dataInUnit");
86 Throw.whenNull(unit, "unit");
87 double[] dataSi = new double[dataInUnit.length];
88 for (int i = 0; i < dataInUnit.length; i++)
89 {
90 dataSi[i] = unit.toBaseValue(dataInUnit[i]);
91 }
92 return new DenseDoubleDataSi(dataSi, rows, cols);
93 }
94
95
96
97
98
99
100
101
102
103
104
105 public static <Q extends Quantity<Q>> DenseDoubleDataSi of(final Q[] data, final int rows, final int cols)
106 {
107 Throw.whenNull(data, "data");
108 Throw.when(data.length != rows * cols, IllegalArgumentException.class, "Q[] length != rows * cols");
109 double[] dataSi = new double[data.length];
110 for (int i = 0; i < data.length; i++)
111 {
112 Throw.whenNull(data[i], "data[%d] = null", i);
113 dataSi[i] = data[i].si();
114 }
115 return new DenseDoubleDataSi(dataSi, rows, cols);
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129 public static <A extends AbsBasic<A, Q, ?>, Q extends Quantity<Q>> DenseDoubleDataSi of(final A[] absData,
130 final int rows, final int cols)
131 {
132 Throw.whenNull(absData, "absData");
133 Throw.when(rows == 0, IllegalArgumentException.class, "rows = 0");
134 Throw.when(cols == 0, IllegalArgumentException.class, "cols = 0");
135 Throw.when(absData.length != rows * cols, IllegalArgumentException.class, "A[] length != rows * cols");
136 Throw.whenNull(absData[0], "absData[0] = null");
137 Reference<?, A, Q> reference = absData[0].getReference();
138 double[] dataSi = new double[rows * cols];
139 for (int i = 0; i < rows * cols; i++)
140 {
141 Throw.whenNull(absData[i], "absGrid[%d] = null", i);
142 Throw.when(!reference.equals(absData[i].getReference()), IllegalArgumentException.class,
143 "Reference of absData[%d] != %s, but %s", i, reference.toString(), absData[i].getReference().toString());
144 dataSi[i] = absData[i].si();
145 }
146 return new DenseDoubleDataSi(dataSi, rows, cols);
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160 public static <A extends AbsBasic<A, Q, ?>, Q extends Quantity<Q>> DenseDoubleDataSi of(final List<A> absData,
161 final int rows, final int cols)
162 {
163 Throw.whenNull(absData, "absData");
164 Throw.when(rows == 0, IllegalArgumentException.class, "rows = 0");
165 Throw.when(cols == 0, IllegalArgumentException.class, "cols = 0");
166 Throw.when(absData.size() != rows * cols, IllegalArgumentException.class, "List size != rows * cols");
167 Throw.whenNull(absData.get(0), "absData[0] = null");
168 Reference<?, A, Q> reference = absData.get(0).getReference();
169 double[] dataSi = new double[rows * cols];
170 for (int i = 0; i < rows * cols; i++)
171 {
172 Throw.whenNull(absData.get(i), "absData[%d] = null", i);
173 Throw.when(!reference.equals(absData.get(i).getReference()), IllegalArgumentException.class,
174 "Reference of absGrid[%d] != %s, but %s", i, reference.toString(),
175 absData.get(i).getReference().toString());
176 dataSi[i] = absData.get(i).si();
177 }
178 return new DenseDoubleDataSi(dataSi, rows, cols);
179 }
180
181
182
183
184
185
186
187 public static DenseDoubleDataSi ofSi(final double[][] gridSi)
188 {
189 Throw.whenNull(gridSi, "gridSi");
190 Throw.when(gridSi.length == 0, IllegalArgumentException.class, "Number of rows in the data grid = 0");
191 int rows = gridSi.length;
192 Throw.whenNull(gridSi[0], "gridSi[0] = null");
193 int cols = gridSi[0].length;
194 double[] dataSi = new double[rows * cols];
195 for (int r = 0; r < rows; r++)
196 {
197 Throw.whenNull(gridSi[r], "gridSi[%d] = null", r);
198 Throw.when(gridSi[r].length != cols, IllegalArgumentException.class,
199 "Number of columns in row %d (%d) is not equal to number of columns in row 0 (%d)", r, gridSi[r].length,
200 cols);
201 for (int c = 0; c < cols; c++)
202 {
203 dataSi[r * cols + c] = gridSi[r][c];
204 }
205 }
206 return new DenseDoubleDataSi(dataSi, rows, cols);
207 }
208
209
210
211
212
213
214
215
216
217 public static <Q extends Quantity<Q>> DenseDoubleDataSi of(final double[][] gridInUnit, final Unit<?, Q> unit)
218 {
219 Throw.whenNull(gridInUnit, "gridInUnit");
220 Throw.whenNull(unit, "unit");
221 Throw.when(gridInUnit.length == 0, IllegalArgumentException.class, "Number of rows in the data grid = 0");
222 int rows = gridInUnit.length;
223 Throw.whenNull(gridInUnit[0], "gridInUnit[0] = null");
224 int cols = gridInUnit[0].length;
225 double[] dataSi = new double[rows * cols];
226 for (int r = 0; r < rows; r++)
227 {
228 Throw.whenNull(gridInUnit[r], "gridInUnit[%d] = null", r);
229 Throw.when(gridInUnit[r].length != cols, IllegalArgumentException.class,
230 "Number of columns in row %d (%d) is not equal to number of columns in row 0 (%d)", r, gridInUnit[r].length,
231 cols);
232 for (int c = 0; c < cols; c++)
233 {
234 dataSi[r * cols + c] = unit.toBaseValue(gridInUnit[r][c]);
235 }
236 }
237 return new DenseDoubleDataSi(dataSi, rows, cols);
238 }
239
240
241
242
243
244
245
246
247 public static <Q extends Quantity<Q>> DenseDoubleDataSi of(final Q[][] grid)
248 {
249 Throw.whenNull(grid, "grid");
250 Throw.when(grid.length == 0, IllegalArgumentException.class, "Number of rows in the data grid = 0");
251 int rows = grid.length;
252 Throw.whenNull(grid[0], "grid[0] = null");
253 int cols = grid[0].length;
254 double[] dataSi = new double[rows * cols];
255 for (int r = 0; r < rows; r++)
256 {
257 Throw.whenNull(grid[r], "grid[%d] = null", r);
258 Throw.when(grid[r].length != cols, IllegalArgumentException.class,
259 "Number of columns in row %d (%d) is not equal to number of columns in row 0 (%d)", r, grid[r].length,
260 cols);
261 for (int c = 0; c < cols; c++)
262 {
263 Throw.whenNull(grid[r][c], "grid[%d][%d] = null", r, c);
264 dataSi[r * cols + c] = grid[r][c].si();
265 }
266 }
267 return new DenseDoubleDataSi(dataSi, rows, cols);
268 }
269
270
271
272
273
274
275
276
277
278 public static <A extends AbsBasic<A, Q, ?>, Q extends Quantity<Q>> DenseDoubleDataSi of(final A[][] absGrid)
279 {
280 Throw.whenNull(absGrid, "absGrid");
281 int rows = absGrid.length;
282 Throw.when(rows == 0, IllegalArgumentException.class, "rows = 0");
283 Throw.whenNull(absGrid[0], "absGrid[0] = null");
284 int cols = absGrid[0].length;
285 Throw.when(cols == 0, IllegalArgumentException.class, "cols = 0");
286 Throw.whenNull(absGrid[0][0], "absGrid[0][0] = null");
287 Reference<?, A, Q> reference = absGrid[0][0].getReference();
288 double[] dataSi = new double[rows * cols];
289 for (int r = 0; r < rows; r++)
290 {
291 Throw.whenNull(absGrid[r], "absGrid[%d] = null", r);
292 Throw.when(absGrid[r].length != cols, IllegalArgumentException.class,
293 "Number of columns in row %d (%d) is not equal to number of columns in row 0 (%d)", r, absGrid[r].length,
294 cols);
295 for (int c = 0; c < cols; c++)
296 {
297 Throw.whenNull(absGrid[r][c], "absGrid[%d][%d] = null", r, c);
298 Throw.when(!reference.equals(absGrid[r][c].getReference()), IllegalArgumentException.class,
299 "Reference of absGrid[%d][%d] != %s, but %s", r, c, reference.toString(),
300 absGrid[r][c].getReference().toString());
301 dataSi[r * cols + c] = absGrid[r][c].si();
302 }
303 }
304 return new DenseDoubleDataSi(dataSi, rows, cols);
305 }
306
307 @Override
308 public int rows()
309 {
310 return this.rows;
311 }
312
313 @Override
314 public int cols()
315 {
316 return this.cols;
317 }
318
319 @Override
320 public boolean isDense()
321 {
322 return true;
323 }
324
325 @Override
326 public boolean isDouble()
327 {
328 return true;
329 }
330
331
332
333
334
335
336
337 private void checkRowCol(final int row, final int col) throws IndexOutOfBoundsException
338 {
339 Throw.when(row < 0 || row >= this.rows, IndexOutOfBoundsException.class, "row %d not in range 0..%d", row, this.rows);
340 Throw.when(col < 0 || col >= this.cols, IndexOutOfBoundsException.class, "column %d not in range 0..%d", col,
341 this.cols);
342 }
343
344 @Override
345 public double get(final int row, final int col)
346 {
347 checkRowCol(row, col);
348 return this.dataSi[row * this.cols + col];
349 }
350
351 @Override
352 public double[] unsafeSiArray()
353 {
354 return this.dataSi;
355 }
356
357 @Override
358 public double[] getSiArray()
359 {
360 return this.dataSi.clone();
361 }
362
363 @Override
364 public DenseDoubleDataSi copy()
365 {
366 return new DenseDoubleDataSi(this.dataSi.clone(), rows(), cols());
367 }
368
369 @SuppressWarnings("checkstyle:needbraces")
370 @Override
371 public int nonZeroCount()
372 {
373 int result = 0;
374 for (int i = 0; i < this.dataSi.length; i++)
375 result += this.dataSi[i] == 0.0 ? 0 : 1;
376 return result;
377 }
378
379 @Override
380 public DenseDoubleDataSi instantiateNew(final double[] newData)
381 {
382 Throw.when(newData.length != rows() * cols(), IllegalArgumentException.class,
383 "Data object length != rows * cols, %d != %d * %d", newData.length, rows(), cols());
384 return new DenseDoubleDataSi(newData, rows(), cols());
385 }
386
387 @Override
388 public DenseDoubleDataSi instantiateNew(final double[] newData, final int newRows, final int newCols)
389 {
390 Throw.when(newData.length != newRows * newCols, IllegalArgumentException.class,
391 "Data object length != rows * cols, %d != %d * %d", newData.length, newRows, newCols);
392 return new DenseDoubleDataSi(newData, newRows, newCols);
393 }
394
395 @Override
396 public int hashCode()
397 {
398 final int prime = 31;
399 int result = 1;
400 result = prime * result + Arrays.hashCode(this.dataSi);
401 result = prime * result + Objects.hash(this.cols, this.rows);
402 return result;
403 }
404
405 @SuppressWarnings("checkstyle:needbraces")
406 @Override
407 public boolean equals(final Object obj)
408 {
409 if (this == obj)
410 return true;
411 if (obj == null)
412 return false;
413 if (getClass() != obj.getClass())
414 {
415 if (obj instanceof DataGridSi dg)
416 return this.cols == dg.cols() && this.rows == dg.rows() && Arrays.equals(this.dataSi, dg.unsafeSiArray());
417 return false;
418 }
419 DenseDoubleDataSi other = (DenseDoubleDataSi) obj;
420 return this.cols == other.cols && this.rows == other.rows && Arrays.equals(this.dataSi, other.dataSi);
421 }
422
423 }