1 package org.djunits.vecmat.storage;
2
3 import java.util.Arrays;
4 import java.util.Objects;
5
6 import org.djunits.quantity.def.Quantity;
7 import org.djunits.unit.UnitInterface;
8 import org.djutils.exceptions.Throw;
9
10
11
12
13
14
15
16
17
18 public class DenseDoubleDataSi implements DataGridSi<DenseDoubleDataSi>
19 {
20
21 private final double[] data;
22
23
24 private final int rows;
25
26
27 private final int cols;
28
29
30
31
32
33
34
35
36
37 public DenseDoubleDataSi(final double[] data, final int rows, final int cols)
38 {
39 Throw.whenNull(data, "data");
40 Throw.when(rows <= 0, IllegalArgumentException.class, "Number of rows <= 0");
41 Throw.when(cols <= 0, IllegalArgumentException.class, "Number of columns <= 0");
42 Throw.when(data.length != rows * cols, IllegalArgumentException.class,
43 "Data object length != rows * cols, %d != %d * %d", data.length, rows, cols);
44 this.data = data;
45 this.rows = rows;
46 this.cols = cols;
47 }
48
49
50
51
52
53
54 @SuppressWarnings("checkstyle:needbraces")
55 public DenseDoubleDataSi(final double[][] data)
56 {
57 Throw.whenNull(data, "data");
58 Throw.when(data.length == 0, IllegalArgumentException.class, "Number of rows in the data matrix = 0");
59 this.rows = data.length;
60 this.cols = data[0].length;
61 this.data = new double[this.rows * this.cols];
62 for (int r = 0; r < this.rows; r++)
63 {
64 Throw.when(data[r].length != this.cols, IllegalArgumentException.class,
65 "Number of columns in row %d (%d) is not equal to number of columns in row 0 (%d)", r, data[r].length,
66 this.cols);
67 for (int c = 0; c < this.cols; c++)
68 this.data[r * this.cols + c] = data[r][c];
69 }
70 }
71
72
73
74
75
76
77
78
79 @SuppressWarnings("checkstyle:needbraces")
80 public <Q extends Quantity<Q, U>, U extends UnitInterface<U, Q>> DenseDoubleDataSi(final Q[][] data)
81 {
82 Throw.whenNull(data, "data");
83 Throw.when(data.length == 0, IllegalArgumentException.class, "Number of rows in the data matrix = 0");
84 this.rows = data.length;
85 this.cols = data[0].length;
86 this.data = new double[this.rows * this.cols];
87 for (int r = 0; r < this.rows; r++)
88 {
89 Throw.when(data[r].length != this.cols, IllegalArgumentException.class,
90 "Number of columns in row %d (%d) is not equal to number of columns in row 0 (%d)", r, data[r].length,
91 this.cols);
92 for (int c = 0; c < this.cols; c++)
93 this.data[r * this.cols + c] = data[r][c].si();
94 }
95 }
96
97 @Override
98 public int rows()
99 {
100 return this.rows;
101 }
102
103 @Override
104 public int cols()
105 {
106 return this.cols;
107 }
108
109 @Override
110 public boolean isDense()
111 {
112 return true;
113 }
114
115 @Override
116 public boolean isDouble()
117 {
118 return true;
119 }
120
121
122
123
124
125
126
127 private void checkRowCol(final int row, final int col) throws IndexOutOfBoundsException
128 {
129 Throw.when(row < 0 || row >= this.rows, IndexOutOfBoundsException.class, "row %d not in range 0..%d", row, this.rows);
130 Throw.when(col < 0 || col >= this.cols, IndexOutOfBoundsException.class, "column %d not in range 0..%d", col,
131 this.cols);
132 }
133
134 @Override
135 public double get(final int row, final int col)
136 {
137 checkRowCol(row, col);
138 return this.data[row * this.cols + col];
139 }
140
141 @Override
142 public double[] getDataArray()
143 {
144 return this.data;
145 }
146
147 @Override
148 public DenseDoubleDataSi copy()
149 {
150 return new DenseDoubleDataSi(this.data.clone(), rows(), cols());
151 }
152
153 @SuppressWarnings("checkstyle:needbraces")
154 @Override
155 public int cardinality()
156 {
157 int result = 0;
158 for (int i = 0; i < this.data.length; i++)
159 result += this.data[i] == 0.0 ? 0 : 1;
160 return result;
161 }
162
163 @Override
164 public DenseDoubleDataSi instantiateNew(final double[] newData)
165 {
166 Throw.when(newData.length != rows() * cols(), IllegalArgumentException.class,
167 "Data object length != rows * cols, %d != %d * %d", newData.length, rows(), cols());
168 return new DenseDoubleDataSi(newData, rows(), cols());
169 }
170
171 @Override
172 public DenseDoubleDataSi instantiateNew(final double[] newData, final int newRows, final int newCols)
173 {
174 Throw.when(newData.length != newRows * newCols, IllegalArgumentException.class,
175 "Data object length != rows * cols, %d != %d * %d", newData.length, newRows, newCols);
176 return new DenseDoubleDataSi(newData, newRows, newCols);
177 }
178
179 @Override
180 public int hashCode()
181 {
182 final int prime = 31;
183 int result = 1;
184 result = prime * result + Arrays.hashCode(this.data);
185 result = prime * result + Objects.hash(this.cols, this.rows);
186 return result;
187 }
188
189 @SuppressWarnings("checkstyle:needbraces")
190 @Override
191 public boolean equals(final Object obj)
192 {
193 if (this == obj)
194 return true;
195 if (obj == null)
196 return false;
197 if (getClass() != obj.getClass())
198 {
199 if (obj instanceof DataGridSi dg)
200 return this.cols == dg.cols() && this.rows == dg.rows() && Arrays.equals(this.data, dg.getDataArray());
201 return false;
202 }
203 DenseDoubleDataSi other = (DenseDoubleDataSi) obj;
204 return this.cols == other.cols && this.rows == other.rows && Arrays.equals(this.data, other.data);
205 }
206
207 }