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