1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.matrix.impl;
25
26 import java.io.IOException;
27 import java.io.Serializable;
28 import java.io.ObjectInputStream;
29 import java.io.ObjectOutputStream;
30
31 import java.util.Map;
32 import java.util.HashMap;
33
34 import org.dishevelled.functor.UnaryProcedure;
35
36 import org.dishevelled.matrix.Matrix2D;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class SparseMatrix3D<E>
52 extends AbstractMatrix3D<E>
53 implements Serializable
54 {
55
56 private Map<Long, E> elements;
57
58
59 private static final float DEFAULT_LOAD_FACTOR = 0.75f;
60
61
62
63
64
65 private SparseMatrix3D()
66 {
67 elements = null;
68 }
69
70
71
72
73
74
75
76
77
78
79
80 public SparseMatrix3D(final long slices, final long rows, final long columns)
81 {
82 this(slices, rows, columns,
83 (int) Math.min(Integer.MAX_VALUE, ((slices * rows * columns) / DEFAULT_LOAD_FACTOR)),
84 DEFAULT_LOAD_FACTOR);
85 }
86
87
88
89
90
91
92
93
94
95
96
97 public SparseMatrix3D(final long slices,
98 final long rows,
99 final long columns,
100 final int initialCapacity,
101 final float loadFactor)
102 {
103 super(slices, rows, columns);
104 elements = new HashMap<Long, E>(initialCapacity, loadFactor);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 protected SparseMatrix3D(final long slices,
125 final long rows,
126 final long columns,
127 final long sliceZero,
128 final long rowZero,
129 final long columnZero,
130 final long sliceStride,
131 final long rowStride,
132 final long columnStride,
133 final boolean isView,
134 final Map<Long, E> elements)
135 {
136 super(slices, rows, columns,
137 sliceZero, rowZero, columnZero,
138 sliceStride, rowStride, columnStride, isView);
139 this.elements = elements;
140 }
141
142
143
144 public Object clone()
145 {
146 return new SparseMatrix3D<E>(slices, rows, columns,
147 sliceZero, rowZero, columnZero,
148 sliceStride, rowStride, columnStride,
149 isView, elements);
150 }
151
152
153 public E getQuick(final long slice, final long row, final long column)
154 {
155 long index = sliceZero + (slice * sliceStride)
156 + rowZero + (row * rowStride)
157 + columnZero + (column * columnStride);
158 return elements.get(index);
159 }
160
161
162 public void setQuick(final long slice, final long row, final long column, final E e)
163 {
164 long index = sliceZero + (slice * sliceStride)
165 + rowZero + (row * rowStride)
166 + columnZero + (column * columnStride);
167 if (e == null)
168 {
169 elements.remove(index);
170 }
171 else
172 {
173 elements.put(index, e);
174 }
175 }
176
177
178
179
180
181
182 public void clear()
183 {
184 if (isView)
185 {
186 super.clear();
187 }
188 else
189 {
190 elements.clear();
191 }
192 }
193
194
195
196
197
198
199 public void forEachNonNull(final UnaryProcedure<? super E> procedure)
200 {
201 if (isView)
202 {
203 super.forEachNonNull(procedure);
204 }
205 else
206 {
207 if (procedure == null)
208 {
209 throw new IllegalArgumentException("procedure must not be null");
210 }
211
212 for (E e : elements.values())
213 {
214 procedure.run(e);
215 }
216 }
217 }
218
219
220 public Matrix2D<E> viewSlice(final long slice)
221 {
222 return new SliceView(slice);
223 }
224
225
226 public Matrix2D<E> viewRow(final long row)
227 {
228 return new RowView(row);
229 }
230
231
232 public Matrix2D<E> viewColumn(final long column)
233 {
234 return new ColumnView(column);
235 }
236
237
238
239
240
241
242 protected Map<Long, E> elements()
243 {
244 return elements;
245 }
246
247
248
249
250
251
252
253
254 private void writeObject(final ObjectOutputStream out)
255 throws IOException
256 {
257 out.writeLong(slices);
258 out.writeLong(rows);
259 out.writeLong(columns);
260 out.writeLong(sliceZero);
261 out.writeLong(rowZero);
262 out.writeLong(columnZero);
263 out.writeLong(sliceStride);
264 out.writeLong(rowStride);
265 out.writeLong(columnStride);
266 out.writeBoolean(isView);
267 out.writeObject(elements);
268 }
269
270
271
272
273
274
275
276
277
278 private void readObject(final ObjectInputStream in)
279 throws IOException, ClassNotFoundException
280 {
281 super.slices = in.readLong();
282 super.rows = in.readLong();
283 super.columns = in.readLong();
284 super.sliceZero = in.readLong();
285 super.rowZero = in.readLong();
286 super.columnZero = in.readLong();
287 super.sliceStride = in.readLong();
288 super.rowStride = in.readLong();
289 super.columnStride = in.readLong();
290 super.isView = in.readBoolean();
291 this.elements = (Map<Long, E>) in.readObject();
292 }
293
294
295 public String toString()
296 {
297 StringBuffer sb = new StringBuffer(super.toString());
298 sb.append("\n slices=");
299 sb.append(slices);
300 sb.append(" rows=");
301 sb.append(rows);
302 sb.append(" columns=");
303 sb.append(columns);
304 sb.append(" sliceZero=");
305 sb.append(sliceZero);
306 sb.append(" rowZero=");
307 sb.append(rowZero);
308 sb.append(" columnZero=");
309 sb.append(columnZero);
310 sb.append(" sliceStride=");
311 sb.append(sliceStride);
312 sb.append(" rowStride=");
313 sb.append(rowStride);
314 sb.append(" columnStride=");
315 sb.append(columnStride);
316 sb.append("\n elements=");
317 sb.append(elements.toString());
318 sb.append("\n");
319 return sb.toString();
320 }
321
322
323
324
325 private class SliceView
326 extends SparseMatrix2D<E>
327 {
328
329
330
331
332
333
334 SliceView(final long slice)
335 {
336 super(SparseMatrix3D.this.rows,
337 SparseMatrix3D.this.columns,
338 SparseMatrix3D.this.rowZero,
339 SparseMatrix3D.this.columnZero
340 + (slice * SparseMatrix3D.this.sliceStride)
341 + SparseMatrix3D.this.sliceZero,
342 SparseMatrix3D.this.rowStride,
343 SparseMatrix3D.this.columnStride,
344 true,
345 SparseMatrix3D.this.elements);
346 }
347 }
348
349
350
351
352 private class RowView
353 extends SparseMatrix2D<E>
354 {
355
356
357
358
359
360
361 RowView(final long row)
362 {
363 super(SparseMatrix3D.this.slices,
364 SparseMatrix3D.this.columns,
365 SparseMatrix3D.this.sliceZero,
366 SparseMatrix3D.this.columnZero
367 + (row * SparseMatrix3D.this.rowStride)
368 + SparseMatrix3D.this.rowZero,
369 SparseMatrix3D.this.sliceStride,
370 SparseMatrix3D.this.columnStride,
371 true,
372 SparseMatrix3D.this.elements);
373 }
374 }
375
376
377
378
379 private class ColumnView
380 extends SparseMatrix2D<E>
381 {
382
383
384
385
386
387
388 ColumnView(final long column)
389 {
390 super(SparseMatrix3D.this.slices,
391 SparseMatrix3D.this.rows,
392 SparseMatrix3D.this.sliceZero,
393 SparseMatrix3D.this.rowZero
394 + (column * SparseMatrix3D.this.columnStride)
395 + SparseMatrix3D.this.columnZero,
396 SparseMatrix3D.this.sliceStride,
397 SparseMatrix3D.this.rowStride,
398 true,
399 SparseMatrix3D.this.elements);
400 }
401 }
402 }