1 package org.djunits.value.vdouble.vector;
2
3 import java.util.Arrays;
4 import java.util.stream.IntStream;
5
6 import org.djunits.value.StorageType;
7 import org.djunits.value.ValueException;
8
9
10
11
12
13
14
15
16
17
18
19
20 public class DoubleVectorDataSparse extends DoubleVectorData
21 {
22
23 private static final long serialVersionUID = 1L;
24
25
26 private int[] indices;
27
28
29 private final int size;
30
31
32
33
34
35
36
37 public DoubleVectorDataSparse(final double[] vectorSI, final int[] indices, final int size)
38 {
39 super(StorageType.SPARSE);
40 this.vectorSI = vectorSI;
41 this.indices = indices;
42 this.size = size;
43 }
44
45
46 @Override
47 public final DoubleVectorDataDense toDense()
48 {
49 double[] denseSI = new double[this.size];
50 for (int index = 0; index < this.vectorSI.length; index++)
51 {
52 denseSI[this.indices[index]] = this.vectorSI[index];
53 }
54 return new DoubleVectorDataDense(denseSI);
55 }
56
57
58 @Override
59 public final int size()
60 {
61 return this.size;
62 }
63
64
65 @Override
66 public final double getSI(final int index)
67 {
68 int internalIndex = Arrays.binarySearch(this.indices, index);
69 return internalIndex < 0 ? 0.0 : this.vectorSI[internalIndex];
70 }
71
72
73 @Override
74 public final void setSI(final int index, final double valueSI)
75 {
76 int internalIndex = Arrays.binarySearch(this.indices, index);
77 if (internalIndex >= 0)
78 {
79 this.vectorSI[internalIndex] = valueSI;
80 return;
81 }
82
83
84 internalIndex = -internalIndex - 1;
85 int[] indicesNew = new int[this.indices.length + 1];
86 double[] vectorSINew = new double[this.vectorSI.length + 1];
87 System.arraycopy(this.indices, 0, indicesNew, 0, internalIndex);
88 System.arraycopy(this.vectorSI, 0, vectorSINew, 0, internalIndex);
89
90
91
92 System.arraycopy(this.indices, internalIndex, indicesNew, internalIndex + 1, this.indices.length - internalIndex);
93 System.arraycopy(this.vectorSI, internalIndex, vectorSINew, internalIndex + 1, this.indices.length - internalIndex);
94
95
96 indicesNew[internalIndex] = index;
97 vectorSINew[internalIndex] = valueSI;
98 this.indices = indicesNew;
99 this.vectorSI = vectorSINew;
100 }
101
102
103 @Override
104 public final double[] getDenseVectorSI()
105 {
106 return toDense().vectorSI;
107 }
108
109
110 @Override
111 public final DoubleVectorDataSparse copy()
112 {
113 double[] vCopy = new double[this.vectorSI.length];
114 System.arraycopy(this.vectorSI, 0, vCopy, 0, this.vectorSI.length);
115 int[] iCopy = new int[this.indices.length];
116 System.arraycopy(this.indices, 0, iCopy, 0, this.indices.length);
117 return new DoubleVectorDataSparse(vCopy, iCopy, this.size);
118 }
119
120
121
122
123
124
125 public static DoubleVectorDataSparse instantiate(final double[] valuesSI)
126 {
127
128 int length = (int) Arrays.stream(valuesSI).parallel().filter(d -> d != 0.0).count();
129 double[] sparseSI = new double[length];
130 int[] indices = new int[length];
131
132
133 int count = 0;
134 for (int i = 0; i < valuesSI.length; i++)
135 {
136 if (valuesSI[i] != 0.0)
137 {
138 sparseSI[count] = valuesSI[i];
139 indices[count] = i;
140 count++;
141 }
142 }
143 return new DoubleVectorDataSparse(sparseSI, indices, valuesSI.length);
144 }
145
146
147 @Override
148 public final void incrementBy(final DoubleVectorData right) throws ValueException
149 {
150 int newLength =
151 (int) IntStream.range(0, size()).parallel().filter(i -> this.getSI(i) != 0.0 || right.getSI(i) != 0.0).count();
152 double[] newVectorSI = new double[newLength];
153 int[] newIndices = new int[newLength];
154
155
156
157 int count = 0;
158 for (int i = 0; i < size(); i++)
159 {
160 if (this.getSI(i) != 0.0 || right.getSI(i) != 0.0)
161 {
162 newVectorSI[count] = getSI(i) + right.getSI(i);
163 newIndices[count] = i;
164 count++;
165 }
166 }
167
168 this.indices = newIndices;
169 this.vectorSI = newVectorSI;
170 }
171
172
173 @Override
174 public final void decrementBy(final DoubleVectorData right) throws ValueException
175 {
176 int newLength =
177 (int) IntStream.range(0, size()).parallel().filter(i -> this.getSI(i) != 0.0 || right.getSI(i) != 0.0).count();
178 double[] newVectorSI = new double[newLength];
179 int[] newIndices = new int[newLength];
180
181
182
183 int count = 0;
184 for (int i = 0; i < size(); i++)
185 {
186 if (this.getSI(i) != 0.0 || right.getSI(i) != 0.0)
187 {
188 newVectorSI[count] = getSI(i) - right.getSI(i);
189 newIndices[count] = i;
190 count++;
191 }
192 }
193
194 this.indices = newIndices;
195 this.vectorSI = newVectorSI;
196 }
197
198
199 @Override
200 public final void multiplyBy(final DoubleVectorData right) throws ValueException
201 {
202 int newLength =
203 (int) IntStream.range(0, size()).parallel().filter(i -> this.getSI(i) != 0.0 && right.getSI(i) != 0.0).count();
204 double[] newVectorSI = new double[newLength];
205 int[] newIndices = new int[newLength];
206
207
208 int count = 0;
209 for (int i = 0; i < size(); i++)
210 {
211 if (this.getSI(i) != 0.0 && right.getSI(i) != 0.0)
212 {
213 newVectorSI[count] = getSI(i) * right.getSI(i);
214 newIndices[count] = i;
215 count++;
216 }
217 }
218
219 this.indices = newIndices;
220 this.vectorSI = newVectorSI;
221 }
222
223
224 @Override
225 public final void divideBy(final DoubleVectorData right) throws ValueException
226 {
227 int newLength =
228 (int) IntStream.range(0, size()).parallel().filter(i -> this.getSI(i) != 0.0 && right.getSI(i) != 0.0).count();
229 double[] newVectorSI = new double[newLength];
230 int[] newIndices = new int[newLength];
231
232
233 int count = 0;
234 for (int i = 0; i < size(); i++)
235 {
236 if (this.getSI(i) != 0.0 && right.getSI(i) != 0.0)
237 {
238 newVectorSI[count] = getSI(i) / right.getSI(i);
239 newIndices[count] = i;
240 count++;
241 }
242 }
243
244 this.indices = newIndices;
245 this.vectorSI = newVectorSI;
246 }
247
248
249 @Override
250 @SuppressWarnings("checkstyle:designforextension")
251 public int hashCode()
252 {
253 final int prime = 31;
254 int result = super.hashCode();
255 result = prime * result + Arrays.hashCode(this.indices);
256 result = prime * result + this.size;
257 return result;
258 }
259
260
261 @SuppressWarnings({"checkstyle:needbraces", "checkstyle:designforextension"})
262 @Override
263 public boolean equals(final Object obj)
264 {
265 if (this == obj)
266 return true;
267 if (!super.equals(obj))
268 return false;
269 if (getClass() != obj.getClass())
270 return false;
271 DoubleVectorDataSparse other = (DoubleVectorDataSparse) obj;
272 if (!Arrays.equals(this.indices, other.indices))
273 return false;
274 if (this.size != other.size)
275 return false;
276 return true;
277 }
278 }