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