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.util.Iterator;
27 import java.util.NoSuchElementException;
28
29 import org.dishevelled.matrix.BitMatrix1D;
30 import org.dishevelled.matrix.Matrix1D;
31
32 import org.dishevelled.functor.UnaryFunction;
33 import org.dishevelled.functor.UnaryProcedure;
34 import org.dishevelled.functor.UnaryPredicate;
35 import org.dishevelled.functor.BinaryFunction;
36 import org.dishevelled.functor.BinaryProcedure;
37 import org.dishevelled.functor.BinaryPredicate;
38
39
40
41
42
43
44
45 abstract class AbstractMatrix1D<E>
46 implements Matrix1D<E>
47 {
48
49 protected long size;
50
51
52 protected long zero;
53
54
55 protected long stride;
56
57
58 protected boolean isView;
59
60
61
62
63
64 protected AbstractMatrix1D()
65 {
66
67 }
68
69
70
71
72
73
74
75 protected AbstractMatrix1D(final long size)
76 {
77 if (size < 0)
78 {
79 throw new IllegalArgumentException(size + " < 0");
80 }
81
82 this.size = size;
83 this.zero = 0L;
84 this.stride = 1L;
85 this.isView = false;
86 }
87
88
89
90
91
92
93
94
95
96 protected AbstractMatrix1D(final long size,
97 final long zero,
98 final long stride,
99 final boolean isView)
100 {
101 if (size < 0)
102 {
103 throw new IllegalArgumentException(size + " < 0");
104 }
105
106 this.size = size;
107 this.zero = zero;
108 this.stride = stride;
109 this.isView = isView;
110 }
111
112
113
114 public long size()
115 {
116 return size;
117 }
118
119
120 public long cardinality()
121 {
122 long cardinality = 0;
123 for (E e : this)
124 {
125 if (e != null)
126 {
127 cardinality++;
128 }
129 }
130 return cardinality;
131 }
132
133
134 public boolean isEmpty()
135 {
136 return (0 == cardinality());
137 }
138
139
140 public void clear()
141 {
142 forEach(new BinaryProcedure<Long, E>()
143 {
144 public void run(final Long index, final E e)
145 {
146 if (e != null)
147 {
148 set(index, null);
149 }
150 }
151 });
152 }
153
154
155 public Iterator<E> iterator()
156 {
157 return new ObjectMatrix1DIterator();
158 }
159
160
161 public E get(final long index)
162 {
163 if (index < 0)
164 {
165 throw new IndexOutOfBoundsException(index + " < 0");
166 }
167 if (index >= size)
168 {
169 throw new IndexOutOfBoundsException(index + " >= " + size);
170 }
171
172 return getQuick(index);
173 }
174
175
176 public void set(final long index, final E e)
177 {
178 if (index < 0)
179 {
180 throw new IndexOutOfBoundsException(index + " < 0");
181 }
182 if (index >= size)
183 {
184 throw new IndexOutOfBoundsException(index + " > " + size);
185 }
186
187 setQuick(index, e);
188 }
189
190
191 public void setQuick(final long index, final E e)
192 {
193 throw new UnsupportedOperationException();
194 }
195
196
197 public Matrix1D<E> assign(final E e)
198 {
199 forEach(new BinaryProcedure<Long, E>()
200 {
201 public void run(final Long index, final E ignore)
202 {
203 setQuick(index, e);
204 }
205 });
206
207 return this;
208 }
209
210
211 public Matrix1D<E> assign(final UnaryFunction<E, E> function)
212 {
213 if (function == null)
214 {
215 throw new IllegalArgumentException("function must not be null");
216 }
217
218 forEach(new BinaryProcedure<Long, E>()
219 {
220 public void run(final Long index, final E e)
221 {
222 setQuick(index, function.evaluate(e));
223 }
224 });
225
226 return this;
227 }
228
229
230 public Matrix1D<E> assign(final Matrix1D<? extends E> other)
231 {
232 if (other == null)
233 {
234 throw new IllegalArgumentException("other must not be null");
235 }
236 if (!(size == other.size()))
237 {
238 throw new IllegalArgumentException("this and other must be the same size");
239 }
240
241 forEach(new BinaryProcedure<Long, E>()
242 {
243 public void run(final Long index, final E ignore)
244 {
245 E e = other.getQuick(index);
246 setQuick(index, e);
247 }
248 });
249
250 return this;
251 }
252
253
254 public Matrix1D<E> assign(final Matrix1D<? extends E> other,
255 final BinaryFunction<E, E, E> function)
256 {
257 if (other == null)
258 {
259 throw new IllegalArgumentException("other must not be null");
260 }
261 if (size != other.size())
262 {
263 throw new IllegalArgumentException("this and other must be the same size");
264 }
265 if (function == null)
266 {
267 throw new IllegalArgumentException("function must not be null");
268 }
269
270 forEach(new BinaryProcedure<Long, E>()
271 {
272 public void run(final Long index, final E e)
273 {
274 E result = function.evaluate(e, other.getQuick(index));
275 setQuick(index, result);
276 }
277 });
278
279 return this;
280 }
281
282
283 public E aggregate(final BinaryFunction<E, E, E> aggr, final UnaryFunction<E, E> function)
284 {
285 if (aggr == null)
286 {
287 throw new IllegalArgumentException("aggr must not be null");
288 }
289 if (function == null)
290 {
291 throw new IllegalArgumentException("function must not be null");
292 }
293 if (size == 0)
294 {
295 return null;
296 }
297 long last = (size - 1L);
298 E a = function.evaluate(getQuick(last));
299 for (long index = last; --index >= 0;)
300 {
301 a = aggr.evaluate(a, function.evaluate(getQuick(index)));
302 }
303 return a;
304 }
305
306
307 public E aggregate(final Matrix1D<? extends E> other,
308 final BinaryFunction<E, E, E> aggr,
309 final BinaryFunction<E, E, E> function)
310 {
311 if (other == null)
312 {
313 throw new IllegalArgumentException("other must not be null");
314 }
315 if (!(size == other.size()))
316 {
317 throw new IllegalArgumentException("this and other must be the same size");
318 }
319 if (aggr == null)
320 {
321 throw new IllegalArgumentException("aggr must not be null");
322 }
323 if (function == null)
324 {
325 throw new IllegalArgumentException("function must not be null");
326 }
327
328 if (size == 0)
329 {
330 return null;
331 }
332
333 long last = (size - 1L);
334 E a = function.evaluate(getQuick(last), other.getQuick(last));
335 for (long index = last; --index >= 0;)
336 {
337 a = aggr.evaluate(a, function.evaluate(getQuick(index), other.getQuick(index)));
338 }
339 return a;
340 }
341
342
343
344
345
346
347 protected AbstractMatrix1D<E> view()
348 {
349 try
350 {
351 AbstractMatrix1D<E> m = (AbstractMatrix1D<E>) clone();
352 return m;
353 }
354 catch (CloneNotSupportedException e)
355 {
356 throw new RuntimeException(e);
357 }
358 }
359
360
361
362
363
364
365 protected AbstractMatrix1D<E> vFlip()
366 {
367 if (size > 0)
368 {
369 zero += (size - 1) * stride;
370 stride = -stride;
371 isView = true;
372 }
373
374 return this;
375 }
376
377
378 public Matrix1D<E> viewFlip()
379 {
380 return view().vFlip();
381 }
382
383
384
385
386
387
388
389
390 protected AbstractMatrix1D<E> vPart(final long index, final long width)
391 {
392 if (size > 0)
393 {
394 zero += (stride * index);
395 size = width;
396 isView = true;
397 }
398
399 return this;
400 }
401
402
403 public Matrix1D<E> viewPart(final long index, final long width)
404 {
405 return view().vPart(index, width);
406 }
407
408
409 public Matrix1D<E> viewSelection(final long[] indices)
410 {
411 return null;
412 }
413
414
415 public Matrix1D<E> viewSelection(final UnaryPredicate<E> predicate)
416 {
417 return null;
418 }
419
420
421 public Matrix1D<E> viewSelection(final BitMatrix1D mask)
422 {
423 return null;
424 }
425
426
427
428
429
430
431
432 protected AbstractMatrix1D<E> vStrides(final long stride)
433 {
434 this.stride *= stride;
435
436 if (size != 0)
437 {
438 size = ((size - 1) / stride) + 1L;
439 }
440 isView = true;
441
442 return this;
443 }
444
445
446 public Matrix1D<E> viewStrides(final long stride)
447 {
448 return view().vStrides(stride);
449 }
450
451
452 public void forEach(final UnaryProcedure<? super E> procedure)
453 {
454 if (procedure == null)
455 {
456 throw new IllegalArgumentException("procedure must not be null");
457 }
458
459 for (long index = 0; index < size; index++)
460 {
461 E e = getQuick(index);
462 procedure.run(e);
463 }
464 }
465
466
467 public void forEach(final UnaryPredicate<? super E> predicate,
468 final UnaryProcedure<? super E> procedure)
469 {
470 if (predicate == null)
471 {
472 throw new IllegalArgumentException("predicate must not be null");
473 }
474 if (procedure == null)
475 {
476 throw new IllegalArgumentException("procedure must not be null");
477 }
478
479 for (long index = 0; index < size; index++)
480 {
481 E e = getQuick(index);
482 if (predicate.test(e))
483 {
484 procedure.run(e);
485 }
486 }
487 }
488
489
490 public void forEachNonNull(final UnaryProcedure<? super E> procedure)
491 {
492 forEach(new UnaryPredicate<E>()
493 {
494 public boolean test(final E e)
495 {
496 return (e != null);
497 }
498 }, procedure);
499 }
500
501
502 public void forEach(final BinaryProcedure<Long, ? super E> procedure)
503 {
504 if (procedure == null)
505 {
506 throw new IllegalArgumentException("procedure must not be null");
507 }
508
509 for (long index = 0; index < size; index++)
510 {
511 E e = getQuick(index);
512 procedure.run(index, e);
513 }
514 }
515
516
517 public void forEach(final BinaryPredicate<Long, ? super E> predicate,
518 final BinaryProcedure<Long, ? super E> procedure)
519 {
520 if (predicate == null)
521 {
522 throw new IllegalArgumentException("predicate must not be null");
523 }
524 if (procedure == null)
525 {
526 throw new IllegalArgumentException("procedure must not be null");
527 }
528
529 for (long index = 0; index < size; index++)
530 {
531 E e = getQuick(index);
532 if (predicate.test(index, e))
533 {
534 procedure.run(index, e);
535 }
536 }
537 }
538
539
540
541
542
543
544 protected long zero()
545 {
546 return zero;
547 }
548
549
550
551
552
553
554 protected long stride()
555 {
556 return stride;
557 }
558
559
560
561
562
563
564 protected boolean isView()
565 {
566 return isView;
567 }
568
569
570 public String toString()
571 {
572 final StringBuffer sb = new StringBuffer();
573 sb.append(size);
574 sb.append(" matrix\n");
575
576 forEach(new BinaryProcedure<Long, E>()
577 {
578 public void run(final Long index, final E e)
579 {
580 sb.append((e == null) ? "null" : e.toString());
581 if (index != (size() - 1))
582 {
583 sb.append(" ");
584 }
585 }
586 });
587
588 return sb.toString();
589 }
590
591
592
593
594 private class ObjectMatrix1DIterator
595 implements Iterator<E>
596 {
597
598 private long index = 0L;
599
600
601
602 public boolean hasNext()
603 {
604 return (index < size);
605 }
606
607
608 public E next()
609 {
610 if (index < size)
611 {
612 E e = getQuick(index);
613 index++;
614 return e;
615 }
616 else
617 {
618 throw new NoSuchElementException("index=" + index);
619 }
620 }
621
622
623 public void remove()
624 {
625 throw new UnsupportedOperationException();
626 }
627 }
628 }