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