ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/ParallelDoubleArray.java
Revision: 1.14
Committed: Sun Jan 18 20:17:32 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.13: +1 -0 lines
Log Message:
exactly one blank line before and after package statements

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package extra166y;
8
9 import jsr166y.*;
10 import static extra166y.Ops.*;
11 import java.util.*;
12 import java.util.concurrent.atomic.*;
13 import java.lang.reflect.Array;
14
15 /**
16 * An array of doubles supporting parallel operations. This class
17 * provides methods supporting the same operations as {@link
18 * ParallelArray}, but specialized for scalar doubles. It additionally
19 * provides a few methods specific to numerical values.
20 */
21 public class ParallelDoubleArray extends AbstractParallelAnyArray.DUPap {
22 // Same internals as ParallelArray, but specialized for doubles
23 AsList listView; // lazily constructed
24
25 /**
26 * Returns a common default executor for use in ParallelArrays.
27 * This executor arranges enough parallelism to use most, but not
28 * necessarily all, of the available processors on this system.
29 * @return the executor
30 */
31 public static ForkJoinPool defaultExecutor() {
32 return PAS.defaultExecutor();
33 }
34
35 /**
36 * Constructor for use by subclasses to create a new ParallelDoubleArray
37 * using the given executor, and initially using the supplied
38 * array, with effective size bound by the given limit. This
39 * constructor is designed to enable extensions via
40 * subclassing. To create a ParallelDoubleArray, use {@link #create},
41 * {@link #createEmpty}, {@link #createUsingHandoff} or {@link
42 * #createFromCopy}.
43 * @param executor the executor
44 * @param array the array
45 * @param limit the upper bound limit
46 */
47 protected ParallelDoubleArray(ForkJoinPool executor, double[] array,
48 int limit) {
49 super(executor, 0, limit, array);
50 if (executor == null || array == null)
51 throw new NullPointerException();
52 if (limit < 0 || limit > array.length)
53 throw new IllegalArgumentException();
54 }
55
56 /**
57 * Trusted internal version of protected constructor.
58 */
59 ParallelDoubleArray(ForkJoinPool executor, double[] array) {
60 super(executor, 0, array.length, array);
61 }
62
63 /**
64 * Creates a new ParallelDoubleArray using the given executor and
65 * an array of the given size.
66 * @param size the array size
67 * @param executor the executor
68 */
69 public static ParallelDoubleArray create
70 (int size, ForkJoinPool executor) {
71 double[] array = new double[size];
72 return new ParallelDoubleArray(executor, array, size);
73 }
74
75 /**
76 * Creates a new ParallelDoubleArray initially using the given array and
77 * executor. In general, the handed off array should not be used
78 * for other purposes once constructing this ParallelDoubleArray. The
79 * given array may be internally replaced by another array in the
80 * course of methods that add or remove elements.
81 * @param handoff the array
82 * @param executor the executor
83 */
84 public static ParallelDoubleArray createUsingHandoff
85 (double[] handoff, ForkJoinPool executor) {
86 return new ParallelDoubleArray(executor, handoff, handoff.length);
87 }
88
89 /**
90 * Creates a new ParallelDoubleArray using the given executor and
91 * initially holding copies of the given
92 * source elements.
93 * @param source the source of initial elements
94 * @param executor the executor
95 */
96 public static ParallelDoubleArray createFromCopy
97 (double[] source, ForkJoinPool executor) {
98 // For now, avoid copyOf so people can compile with Java5
99 int size = source.length;
100 double[] array = new double[size];
101 System.arraycopy(source, 0, array, 0, size);
102 return new ParallelDoubleArray(executor, array, size);
103 }
104
105 /**
106 * Creates a new ParallelDoubleArray using an array of the given size,
107 * initially holding copies of the given source truncated or
108 * padded with zeros to obtain the specified length.
109 * @param source the source of initial elements
110 * @param size the array size
111 * @param executor the executor
112 */
113 public static ParallelDoubleArray createFromCopy
114 (int size, double[] source, ForkJoinPool executor) {
115 // For now, avoid copyOf so people can compile with Java5
116 double[] array = new double[size];
117 System.arraycopy(source, 0, array, 0,
118 Math.min(source.length, size));
119 return new ParallelDoubleArray(executor, array, size);
120 }
121
122 /**
123 * Creates a new ParallelDoubleArray using the given executor and
124 * an array of the given size, but with an initial effective size
125 * of zero, enabling incremental insertion via {@link
126 * ParallelDoubleArray#asList} operations.
127 * @param size the array size
128 * @param executor the executor
129 */
130 public static ParallelDoubleArray createEmpty
131 (int size, ForkJoinPool executor) {
132 double[] array = new double[size];
133 return new ParallelDoubleArray(executor, array, 0);
134 }
135
136 /**
137 * Summary statistics for a possibly bounded, filtered, and/or
138 * mapped ParallelDoubleArray.
139 */
140 public static interface SummaryStatistics {
141 /** Returns the number of elements */
142 public int size();
143 /** Returns the minimum element, or Double.MAX_VALUE if empty */
144 public double min();
145 /** Returns the maximum element, or -Double.MAX_VALUE if empty */
146 public double max();
147 /** Returns the index of the minimum element, or -1 if empty */
148 public int indexOfMin();
149 /** Returns the index of the maximum element, or -1 if empty */
150 public int indexOfMax();
151 /** Returns the sum of all elements */
152 public double sum();
153 /** Returns the arithmetic average of all elements */
154 public double average();
155 }
156
157 /**
158 * Returns the executor used for computations.
159 * @return the executor
160 */
161 public ForkJoinPool getExecutor() { return ex; }
162
163 /**
164 * Applies the given procedure to elements.
165 * @param procedure the procedure
166 */
167 public void apply(DoubleProcedure procedure) {
168 super.apply(procedure);
169 }
170
171 /**
172 * Returns reduction of elements.
173 * @param reducer the reducer
174 * @param base the result for an empty array
175 * @return reduction
176 */
177 public double reduce(DoubleReducer reducer, double base) {
178 return super.reduce(reducer, base);
179 }
180
181 /**
182 * Returns a new ParallelDoubleArray holding all elements.
183 * @return a new ParallelDoubleArray holding all elements
184 */
185 public ParallelDoubleArray all() {
186 return super.all();
187 }
188
189 /**
190 * Replaces elements with the results of applying the given op
191 * to their current values.
192 * @param op the op
193 * @return this (to simplify use in expressions)
194 */
195 public ParallelDoubleArray replaceWithMapping(DoubleOp op) {
196 super.replaceWithMapping(op);
197 return this;
198 }
199
200 /**
201 * Replaces elements with the results of applying the given
202 * op to their indices.
203 * @param op the op
204 * @return this (to simplify use in expressions)
205 */
206 public ParallelDoubleArray replaceWithMappedIndex(IntToDouble op) {
207 super.replaceWithMappedIndex(op);
208 return this;
209 }
210
211 /**
212 * Replaces elements with the results of applying the given
213 * mapping to each index and current element value.
214 * @param op the op
215 * @return this (to simplify use in expressions)
216 */
217 public ParallelDoubleArray replaceWithMappedIndex(IntAndDoubleToDouble op) {
218 super.replaceWithMappedIndex(op);
219 return this;
220 }
221
222 /**
223 * Replaces elements with the results of applying the given
224 * generator. For example, to fill the array with uniform random
225 * values, use
226 * {@code replaceWithGeneratedValue(Ops.doubleRandom())}.
227 * @param generator the generator
228 * @return this (to simplify use in expressions)
229 */
230 public ParallelDoubleArray replaceWithGeneratedValue(DoubleGenerator generator) {
231 super.replaceWithGeneratedValue(generator);
232 return this;
233 }
234
235 /**
236 * Replaces elements with the given value.
237 * @param value the value
238 * @return this (to simplify use in expressions)
239 */
240 public ParallelDoubleArray replaceWithValue(double value) {
241 super.replaceWithValue(value);
242 return this;
243 }
244
245 /**
246 * Replaces elements with results of applying
247 * {@code op(thisElement, otherElement)}.
248 * @param other the other array
249 * @param combiner the combiner
250 * @return this (to simplify use in expressions)
251 * @throws ArrayIndexOutOfBoundsException if other array has
252 * fewer elements than this array
253 */
254 public ParallelDoubleArray replaceWithMapping
255 (BinaryDoubleOp combiner, ParallelDoubleArrayWithDoubleMapping other) {
256 super.replaceWithMapping(combiner, other);
257 return this;
258 }
259
260 /**
261 * Replaces elements with results of applying
262 * {@code op(thisElement, otherElement)}.
263 * @param other the other array
264 * @param combiner the combiner
265 * @return this (to simplify use in expressions)
266 * @throws ArrayIndexOutOfBoundsException if other array has
267 * fewer elements than this array
268 */
269 public ParallelDoubleArray replaceWithMapping(BinaryDoubleOp combiner,
270 double[] other) {
271 super.replaceWithMapping(combiner, other);
272 return this;
273 }
274
275 /**
276 * Returns the index of some element equal to given target, or -1
277 * if not present.
278 * @param target the element to search for
279 * @return the index or -1 if not present
280 */
281 public int indexOf(double target) {
282 return super.indexOf(target);
283 }
284
285 /**
286 * Assuming this array is sorted, returns the index of an element
287 * equal to given target, or -1 if not present. If the array
288 * is not sorted, the results are undefined.
289 * @param target the element to search for
290 * @return the index or -1 if not present
291 */
292 public int binarySearch(double target) {
293 return super.binarySearch(target);
294 }
295
296 /**
297 * Assuming this array is sorted with respect to the given
298 * comparator, returns the index of an element equal to given
299 * target, or -1 if not present. If the array is not sorted, the
300 * results are undefined.
301 * @param target the element to search for
302 * @param comparator the comparator
303 * @return the index or -1 if not present
304 */
305 public int binarySearch(double target, DoubleComparator comparator) {
306 return super.binarySearch(target, comparator);
307 }
308
309 /**
310 * Returns summary statistics, using the given comparator
311 * to locate minimum and maximum elements.
312 * @param comparator the comparator to use for
313 * locating minimum and maximum elements
314 * @return the summary
315 */
316 public ParallelDoubleArray.SummaryStatistics summary
317 (DoubleComparator comparator) {
318 return super.summary(comparator);
319 }
320
321 /**
322 * Returns summary statistics, using natural comparator.
323 * @return the summary
324 */
325 public ParallelDoubleArray.SummaryStatistics summary() {
326 return super.summary();
327 }
328
329 /**
330 * Returns the minimum element, or Double.MAX_VALUE if empty.
331 * @param comparator the comparator
332 * @return minimum element, or Double.MAX_VALUE if empty
333 */
334 public double min(DoubleComparator comparator) {
335 return super.min(comparator);
336 }
337
338 /**
339 * Returns the minimum element, or Double.MAX_VALUE if empty.
340 * @return minimum element, or Double.MAX_VALUE if empty
341 */
342 public double min() {
343 return super.min();
344 }
345
346 /**
347 * Returns the maximum element, or -Double.MAX_VALUE if empty.
348 * @param comparator the comparator
349 * @return maximum element, or -Double.MAX_VALUE if empty
350 */
351 public double max(DoubleComparator comparator) {
352 return super.max(comparator);
353 }
354
355 /**
356 * Returns the maximum element, or -Double.MAX_VALUE if empty.
357 * @return maximum element, or -Double.MAX_VALUE if empty
358 */
359 public double max() {
360 return super.max();
361 }
362
363 /**
364 * Replaces each element with the running cumulation of applying
365 * the given reducer. For example, if the contents are the numbers
366 * {@code 1, 2, 3}, and the reducer operation adds numbers, then
367 * after invocation of this method, the contents would be {@code 1,
368 * 3, 6} (that is, {@code 1, 1+2, 1+2+3}).
369 * @param reducer the reducer
370 * @param base the result for an empty array
371 * @return this (to simplify use in expressions)
372 */
373 public ParallelDoubleArray cumulate(DoubleReducer reducer, double base) {
374 super.cumulate(reducer, base);
375 return this;
376 }
377
378 /**
379 * Replaces each element with the cumulation of applying the given
380 * reducer to all previous values, and returns the total
381 * reduction. For example, if the contents are the numbers {@code 1,
382 * 2, 3}, and the reducer operation adds numbers, then after
383 * invocation of this method, the contents would be {@code 0, 1,
384 * 3} (that is, {@code 0, 0+1, 0+1+2}, and the return value
385 * would be 6 (that is, {@code 1+2+3}).
386 * @param reducer the reducer
387 * @param base the result for an empty array
388 * @return the total reduction
389 */
390 public double precumulate(DoubleReducer reducer, double base) {
391 return super.precumulate(reducer, base);
392 }
393
394 /**
395 * Sorts the array. Unlike Arrays.sort, this sort does
396 * not guarantee that elements with equal keys maintain their
397 * relative position in the array.
398 * @param comparator the comparator to use
399 * @return this (to simplify use in expressions)
400 */
401 public ParallelDoubleArray sort(DoubleComparator comparator) {
402 super.sort(comparator);
403 return this;
404 }
405
406 /**
407 * Sorts the array, assuming all elements are Comparable. Unlike
408 * Arrays.sort, this sort does not guarantee that elements
409 * with equal keys maintain their relative position in the array.
410 * @return this (to simplify use in expressions)
411 * @throws ClassCastException if any element is not Comparable
412 */
413 public ParallelDoubleArray sort() {
414 super.sort();
415 return this;
416 }
417
418 /**
419 * Removes consecutive elements that are equal,
420 * shifting others leftward, and possibly decreasing size. This
421 * method may be used after sorting to ensure that this
422 * ParallelDoubleArray contains a set of unique elements.
423 * @return this (to simplify use in expressions)
424 */
425 public ParallelDoubleArray removeConsecutiveDuplicates() {
426 // Sequential implementation for now
427 int k = 0;
428 int n = fence;
429 if (k < n) {
430 double[] arr = this.array;
431 double last = arr[k++];
432 for (int i = k; i < n; ++i) {
433 double x = arr[i];
434 if (last != x)
435 arr[k++] = last = x;
436 }
437 removeSlotsAt(k, n);
438 }
439 return this;
440 }
441
442 /**
443 * Equivalent to {@code asList().addAll} but specialized for
444 * array arguments and likely to be more efficient.
445 * @param other the elements to add
446 * @return this (to simplify use in expressions)
447 */
448 public ParallelDoubleArray addAll(double[] other) {
449 int csize = other.length;
450 int end = fence;
451 insertSlotsAt(end, csize);
452 System.arraycopy(other, 0, array, end, csize);
453 return this;
454 }
455
456 /**
457 * Appends all (possibly bounded, filtered, or mapped) elements of
458 * the given ParallelDoubleArray, resizing and/or reallocating this
459 * array if necessary.
460 * @param other the elements to add
461 * @return this (to simplify use in expressions)
462 */
463 public ParallelDoubleArray addAll(ParallelDoubleArrayWithDoubleMapping other) {
464 int end = fence;
465 if (other.hasFilter()) {
466 PAS.FJDAppendAllDriver r = new PAS.FJDAppendAllDriver
467 (other, end, array);
468 ex.invoke(r);
469 array = r.results;
470 fence = end + r.resultSize;
471 }
472 else {
473 int csize = other.size();
474 insertSlotsAt(end, csize);
475 if (other.hasMap())
476 ex.invoke(new PAS.FJDMap(other, other.origin, other.fence,
477 null, array, end - other.origin));
478 else
479 System.arraycopy(other.array, 0, array, end, csize);
480 }
481 return this;
482 }
483
484 /**
485 * Returns a new ParallelDoubleArray containing only the unique
486 * elements of this array (that is, without any duplicates).
487 * @return the new ParallelDoubleArray
488 */
489 public ParallelDoubleArray allUniqueElements() {
490 return super.allUniqueElements();
491 }
492
493 /**
494 * Removes from the array all elements for which the given
495 * selector holds.
496 * @param selector the selector
497 * @return this (to simplify use in expressions)
498 */
499 public ParallelDoubleArray removeAll(DoublePredicate selector) {
500 DFPap v = new DFPap(ex, 0, fence, array, selector);
501 PAS.FJRemoveAllDriver f = new PAS.FJRemoveAllDriver(v, 0, fence);
502 ex.invoke(f);
503 removeSlotsAt(f.offset, fence);
504 return this;
505 }
506
507 /**
508 * Returns true if all elements at the same relative positions
509 * of this and other array are equal.
510 * @param other the other array
511 * @return true if equal
512 */
513 public boolean hasAllEqualElements
514 (ParallelDoubleArrayWithDoubleMapping other) {
515 return super.hasAllEqualElements(other);
516 }
517
518 /**
519 * Returns the sum of elements.
520 * @return the sum of elements
521 */
522 public double sum() {
523 return super.sum();
524 }
525
526 /**
527 * Replaces each element with the running sum.
528 * @return this (to simplify use in expressions)
529 */
530 public ParallelDoubleArray cumulateSum() {
531 super.cumulateSum();
532 return this;
533 }
534
535 /**
536 * Replaces each element with its prefix sum.
537 * @return the total sum
538 */
539 public double precumulateSum() {
540 return super.precumulateSum();
541 }
542
543 /**
544 * Returns an operation prefix that causes a method to
545 * operate only on the elements of the array between
546 * firstIndex (inclusive) and upperBound (exclusive).
547 * @param firstIndex the lower bound (inclusive)
548 * @param upperBound the upper bound (exclusive)
549 * @return operation prefix
550 */
551 public ParallelDoubleArrayWithBounds withBounds(int firstIndex,
552 int upperBound) {
553 return super.withBounds(firstIndex, upperBound);
554 }
555
556 /**
557 * Returns an operation prefix that causes a method to operate
558 * only on the elements of the array for which the given selector
559 * returns true.
560 * @param selector the selector
561 * @return operation prefix
562 */
563 public ParallelDoubleArrayWithFilter withFilter(DoublePredicate selector) {
564 return super.withFilter(selector);
565 }
566
567 /**
568 * Returns an operation prefix that causes a method to operate
569 * only on elements for which the given binary selector returns
570 * true.
571 * @param selector the selector
572 * @return operation prefix
573 */
574 public ParallelDoubleArrayWithFilter withFilter
575 (BinaryDoublePredicate selector,
576 ParallelDoubleArrayWithDoubleMapping other) {
577 return super.withFilter(selector, other);
578 }
579
580 /**
581 * Returns an operation prefix that causes a method to operate
582 * only on elements for which the given indexed selector returns
583 * true.
584 * @param selector the selector
585 * @return operation prefix
586 */
587 public ParallelDoubleArrayWithFilter withIndexedFilter
588 (IntAndDoublePredicate selector) {
589 return super.withIndexedFilter(selector);
590 }
591
592 /**
593 * Returns an operation prefix that causes a method to operate
594 * on mapped elements of the array using the given op.
595 * @param op the op
596 * @return operation prefix
597 */
598 public <U> ParallelDoubleArrayWithMapping<U> withMapping
599 (DoubleToObject<? extends U> op) {
600 return super.withMapping(op);
601 }
602
603 /**
604 * Returns an operation prefix that causes a method to operate
605 * on mapped elements of the array using the given op.
606 * @param op the op
607 * @return operation prefix
608 */
609 public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
610 return super.withMapping(op);
611 }
612
613 /**
614 * Returns an operation prefix that causes a method to operate
615 * on mapped elements of the array using the given op.
616 * @param op the op
617 * @return operation prefix
618 */
619 public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
620 return super.withMapping(op);
621 }
622
623 /**
624 * Returns an operation prefix that causes a method to operate
625 * on binary mappings of this array and the other array.
626 * @param combiner the combiner
627 * @param other the other array
628 * @return operation prefix
629 * @throws IllegalArgumentException if other array is a
630 * filtered view (all filters must precede all mappings)
631 */
632 public <V,W,X> ParallelDoubleArrayWithMapping<W> withMapping
633 (DoubleAndObjectToObject<? super V, ? extends W> combiner,
634 ParallelArrayWithMapping<X,V> other) {
635 return super.withMapping(combiner, other);
636 }
637
638 /**
639 * Returns an operation prefix that causes a method to operate
640 * on binary mappings of this array and the other array.
641 * @param combiner the combiner
642 * @param other the other array
643 * @return operation prefix
644 * @throws IllegalArgumentException if other array is a
645 * filtered view (all filters must precede all mappings)
646 */
647 public <V> ParallelDoubleArrayWithMapping<V> withMapping
648 (DoubleAndDoubleToObject<? extends V> combiner,
649 ParallelDoubleArrayWithDoubleMapping other) {
650 return super.withMapping(combiner, other);
651 }
652
653 /**
654 * Returns an operation prefix that causes a method to operate
655 * on binary mappings of this array and the other array.
656 * @param combiner the combiner
657 * @param other the other array
658 * @return operation prefix
659 * @throws IllegalArgumentException if other array is a
660 * filtered view (all filters must precede all mappings)
661 */
662 public <V> ParallelDoubleArrayWithMapping<V> withMapping
663 (DoubleAndLongToObject<? extends V> combiner,
664 ParallelLongArrayWithLongMapping other) {
665 return super.withMapping(combiner, other);
666 }
667
668 /**
669 * Returns an operation prefix that causes a method to operate
670 * on binary mappings of this array and the other array.
671 * @param combiner the combiner
672 * @param other the other array
673 * @return operation prefix
674 * @throws IllegalArgumentException if other array is a
675 * filtered view (all filters must precede all mappings)
676 */
677 public <V,W> ParallelDoubleArrayWithDoubleMapping withMapping
678 (DoubleAndObjectToDouble<? super V> combiner,
679 ParallelArrayWithMapping<W,V> other) {
680 return super.withMapping(combiner, other);
681 }
682
683 /**
684 * Returns an operation prefix that causes a method to operate
685 * on binary mappings of this array and the other array.
686 * @param combiner the combiner
687 * @param other the other array
688 * @return operation prefix
689 * @throws IllegalArgumentException if other array is a
690 * filtered view (all filters must precede all mappings)
691 */
692 public ParallelDoubleArrayWithDoubleMapping withMapping
693 (BinaryDoubleOp combiner,
694 ParallelDoubleArrayWithDoubleMapping other) {
695 return super.withMapping(combiner, other);
696 }
697
698 /**
699 * Returns an operation prefix that causes a method to operate
700 * on binary mappings of this array and the other array.
701 * @param combiner the combiner
702 * @param other the other array
703 * @return operation prefix
704 * @throws IllegalArgumentException if other array is a
705 * filtered view (all filters must precede all mappings)
706 */
707 public ParallelDoubleArrayWithDoubleMapping withMapping
708 (DoubleAndLongToDouble combiner,
709 ParallelLongArrayWithLongMapping other) {
710 return super.withMapping(combiner, other);
711 }
712
713 /**
714 * Returns an operation prefix that causes a method to operate
715 * on binary mappings of this array and the other array.
716 * @param combiner the combiner
717 * @param other the other array
718 * @return operation prefix
719 * @throws IllegalArgumentException if other array is a
720 * filtered view (all filters must precede all mappings)
721 */
722 public <V,W> ParallelDoubleArrayWithLongMapping withMapping
723 (DoubleAndObjectToLong<? super V> combiner,
724 ParallelArrayWithMapping<W,V> other) {
725 return super.withMapping(combiner, other);
726 }
727
728 /**
729 * Returns an operation prefix that causes a method to operate
730 * on binary mappings of this array and the other array.
731 * @param combiner the combiner
732 * @param other the other array
733 * @return operation prefix
734 * @throws IllegalArgumentException if other array is a
735 * filtered view (all filters must precede all mappings)
736 */
737 public ParallelDoubleArrayWithLongMapping withMapping
738 (DoubleAndDoubleToLong combiner,
739 ParallelDoubleArrayWithDoubleMapping other) {
740 return super.withMapping(combiner, other);
741 }
742
743 /**
744 * Returns an operation prefix that causes a method to operate
745 * on binary mappings of this array and the other array.
746 * @param combiner the combiner
747 * @param other the other array
748 * @return operation prefix
749 * @throws IllegalArgumentException if other array is a
750 * filtered view (all filters must precede all mappings)
751 */
752 public ParallelDoubleArrayWithLongMapping withMapping
753 (DoubleAndLongToLong combiner,
754 ParallelLongArrayWithLongMapping other) {
755 return super.withMapping(combiner, other);
756 }
757
758 /**
759 * Returns an operation prefix that causes a method to operate on
760 * mappings of this array using the given mapper that accepts as
761 * arguments an element's current index and value, and produces a
762 * new value.
763 * @param mapper the mapper
764 * @return operation prefix
765 */
766 public <U> ParallelDoubleArrayWithMapping<U> withIndexedMapping
767 (IntAndDoubleToObject<? extends U> mapper) {
768 return super.withIndexedMapping(mapper);
769 }
770
771 /**
772 * Returns an operation prefix that causes a method to operate on
773 * mappings of this array using the given mapper that accepts as
774 * arguments an element's current index and value, and produces a
775 * new value.
776 * @param mapper the mapper
777 * @return operation prefix
778 */
779 public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
780 (IntAndDoubleToDouble mapper) {
781 return super.withIndexedMapping(mapper);
782 }
783
784 /**
785 * Returns an operation prefix that causes a method to operate on
786 * mappings of this array using the given mapper that accepts as
787 * arguments an element's current index and value, and produces a
788 * new value.
789 * @param mapper the mapper
790 * @return operation prefix
791 */
792 public ParallelDoubleArrayWithLongMapping withIndexedMapping
793 (IntAndDoubleToLong mapper) {
794 return super.withIndexedMapping(mapper);
795 }
796
797 /**
798 * Returns an iterator stepping through each element of the array
799 * up to the current limit. This iterator does <em>not</em>
800 * support the remove operation. However, a full
801 * {@code ListIterator} supporting add, remove, and set
802 * operations is available via {@link #asList}.
803 * @return an iterator stepping through each element
804 */
805 public Iterator<Double> iterator() {
806 return new ParallelDoubleArrayIterator(array, fence);
807 }
808
809 static final class ParallelDoubleArrayIterator
810 implements Iterator<Double> {
811 int cursor;
812 final double[] arr;
813 final int hi;
814 ParallelDoubleArrayIterator(double[] a, int limit) { arr = a; hi = limit; }
815 public boolean hasNext() { return cursor < hi; }
816 public Double next() {
817 if (cursor >= hi)
818 throw new NoSuchElementException();
819 return Double.valueOf(arr[cursor++]);
820 }
821 public void remove() {
822 throw new UnsupportedOperationException();
823 }
824 }
825
826 // List support
827
828 /**
829 * Returns a view of this ParallelDoubleArray as a List. This List
830 * has the same structural and performance characteristics as
831 * {@link ArrayList}, and may be used to modify, replace or extend
832 * the bounds of the array underlying this ParallelDoubleArray.
833 * The methods supported by this list view are <em>not</em> in
834 * general implemented as parallel operations. This list is also
835 * not itself thread-safe. In particular, performing list updates
836 * while other parallel operations are in progress has undefined
837 * (and surely undesired) effects.
838 * @return a list view
839 */
840 public List<Double> asList() {
841 AsList lv = listView;
842 if (lv == null)
843 listView = lv = new AsList();
844 return lv;
845 }
846
847 /**
848 * Returns the effective size of the underlying array. The
849 * effective size is the current limit, if used (see {@link
850 * #setLimit}), or the length of the array otherwise.
851 * @return the effective size of array
852 */
853 public int size() { return fence; }
854
855 /**
856 * Returns the underlying array used for computations.
857 * @return the array
858 */
859 public double[] getArray() { return array; }
860
861 /**
862 * Returns the element of the array at the given index.
863 * @param i the index
864 * @return the element of the array at the given index
865 */
866 public double get(int i) { return array[i]; }
867
868 /**
869 * Sets the element of the array at the given index to the given value.
870 * @param i the index
871 * @param x the value
872 */
873 public void set(int i, double x) { array[i] = x; }
874
875 /**
876 * Equivalent to {@code asList().toString()}.
877 * @return a string representation
878 */
879 public String toString() {
880 return asList().toString();
881 }
882
883 /**
884 * Ensures that the underlying array can be accessed up to the
885 * given upper bound, reallocating and copying the underlying
886 * array to expand if necessary. Or, if the given limit is less
887 * than the length of the underlying array, causes computations to
888 * ignore elements past the given limit.
889 * @param newLimit the new upper bound
890 * @throws IllegalArgumentException if newLimit less than zero
891 */
892 public final void setLimit(int newLimit) {
893 if (newLimit < 0)
894 throw new IllegalArgumentException();
895 int cap = array.length;
896 if (newLimit > cap)
897 resizeArray(newLimit);
898 fence = newLimit;
899 }
900
901 final void resizeArray(int newCap) {
902 int cap = array.length;
903 if (newCap > cap) {
904 double[] a = new double[newCap];
905 System.arraycopy(array, 0, a, 0, cap);
906 array = a;
907 }
908 }
909
910 final void insertElementAt(int index, double e) {
911 int hi = fence++;
912 if (hi >= array.length)
913 resizeArray((hi * 3)/2 + 1);
914 if (hi > index)
915 System.arraycopy(array, index, array, index+1, hi - index);
916 array[index] = e;
917 }
918
919 final void appendElement(double e) {
920 int hi = fence++;
921 if (hi >= array.length)
922 resizeArray((hi * 3)/2 + 1);
923 array[hi] = e;
924 }
925
926 /**
927 * Makes len slots available at index.
928 */
929 final void insertSlotsAt(int index, int len) {
930 if (len <= 0)
931 return;
932 int cap = array.length;
933 int newSize = fence + len;
934 if (cap < newSize) {
935 cap = (cap * 3)/2 + 1;
936 if (cap < newSize)
937 cap = newSize;
938 resizeArray(cap);
939 }
940 if (index < fence)
941 System.arraycopy(array, index, array, index + len, fence - index);
942 fence = newSize;
943 }
944
945 final void removeSlotAt(int index) {
946 System.arraycopy(array, index + 1, array, index, fence - index - 1);
947 --fence;
948 }
949
950 final void removeSlotsAt(int fromIndex, int toIndex) {
951 if (fromIndex < toIndex) {
952 int size = fence;
953 System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
954 int newSize = size - (toIndex - fromIndex);
955 fence = newSize;
956 }
957 }
958
959 final int seqIndexOf(double target) {
960 double[] arr = array;
961 int end = fence;
962 for (int i = 0; i < end; i++)
963 if (target == arr[i])
964 return i;
965 return -1;
966 }
967
968 final int seqLastIndexOf(double target) {
969 double[] arr = array;
970 for (int i = fence - 1; i >= 0; i--)
971 if (target == arr[i])
972 return i;
973 return -1;
974 }
975
976 final class ListIter implements ListIterator<Double> {
977 int cursor;
978 int lastRet;
979 double[] arr; // cache array and bound
980 int hi;
981 ListIter(int lo) {
982 this.cursor = lo;
983 this.lastRet = -1;
984 this.arr = ParallelDoubleArray.this.array;
985 this.hi = ParallelDoubleArray.this.fence;
986 }
987
988 public boolean hasNext() {
989 return cursor < hi;
990 }
991
992 public Double next() {
993 int i = cursor;
994 if (i < 0 || i >= hi)
995 throw new NoSuchElementException();
996 double next = arr[i];
997 lastRet = i;
998 cursor = i + 1;
999 return Double.valueOf(next);
1000 }
1001
1002 public void remove() {
1003 int k = lastRet;
1004 if (k < 0)
1005 throw new IllegalStateException();
1006 ParallelDoubleArray.this.removeSlotAt(k);
1007 hi = ParallelDoubleArray.this.fence;
1008 if (lastRet < cursor)
1009 cursor--;
1010 lastRet = -1;
1011 }
1012
1013 public boolean hasPrevious() {
1014 return cursor > 0;
1015 }
1016
1017 public Double previous() {
1018 int i = cursor - 1;
1019 if (i < 0 || i >= hi)
1020 throw new NoSuchElementException();
1021 double previous = arr[i];
1022 lastRet = cursor = i;
1023 return Double.valueOf(previous);
1024 }
1025
1026 public int nextIndex() {
1027 return cursor;
1028 }
1029
1030 public int previousIndex() {
1031 return cursor - 1;
1032 }
1033
1034 public void set(Double e) {
1035 int i = lastRet;
1036 if (i < 0 || i >= hi)
1037 throw new NoSuchElementException();
1038 arr[i] = e.doubleValue();
1039 }
1040
1041 public void add(Double e) {
1042 int i = cursor;
1043 ParallelDoubleArray.this.insertElementAt(i, e.doubleValue());
1044 arr = ParallelDoubleArray.this.array;
1045 hi = ParallelDoubleArray.this.fence;
1046 lastRet = -1;
1047 cursor = i + 1;
1048 }
1049 }
1050
1051 final class AsList extends AbstractList<Double> implements RandomAccess {
1052 public Double get(int i) {
1053 if (i >= fence)
1054 throw new IndexOutOfBoundsException();
1055 return Double.valueOf(array[i]);
1056 }
1057
1058 public Double set(int i, Double x) {
1059 if (i >= fence)
1060 throw new IndexOutOfBoundsException();
1061 double[] arr = array;
1062 Double t = Double.valueOf(arr[i]);
1063 arr[i] = x.doubleValue();
1064 return t;
1065 }
1066
1067 public boolean isEmpty() {
1068 return fence == 0;
1069 }
1070
1071 public int size() {
1072 return fence;
1073 }
1074
1075 public Iterator<Double> iterator() {
1076 return new ListIter(0);
1077 }
1078
1079 public ListIterator<Double> listIterator() {
1080 return new ListIter(0);
1081 }
1082
1083 public ListIterator<Double> listIterator(int index) {
1084 if (index < 0 || index > fence)
1085 throw new IndexOutOfBoundsException();
1086 return new ListIter(index);
1087 }
1088
1089 public boolean add(Double e) {
1090 appendElement(e.doubleValue());
1091 return true;
1092 }
1093
1094 public void add(int index, Double e) {
1095 if (index < 0 || index > fence)
1096 throw new IndexOutOfBoundsException();
1097 insertElementAt(index, e.doubleValue());
1098 }
1099
1100 public boolean addAll(Collection<? extends Double> c) {
1101 int csize = c.size();
1102 if (csize == 0)
1103 return false;
1104 int hi = fence;
1105 setLimit(hi + csize);
1106 double[] arr = array;
1107 for (Double e : c)
1108 arr[hi++] = e.doubleValue();
1109 return true;
1110 }
1111
1112 public boolean addAll(int index, Collection<? extends Double> c) {
1113 if (index < 0 || index > fence)
1114 throw new IndexOutOfBoundsException();
1115 int csize = c.size();
1116 if (csize == 0)
1117 return false;
1118 insertSlotsAt(index, csize);
1119 double[] arr = array;
1120 for (Double e : c)
1121 arr[index++] = e.doubleValue();
1122 return true;
1123 }
1124
1125 public void clear() {
1126 fence = 0;
1127 }
1128
1129 public boolean remove(Object o) {
1130 if (!(o instanceof Double))
1131 return false;
1132 int idx = seqIndexOf(((Double)o).doubleValue());
1133 if (idx < 0)
1134 return false;
1135 removeSlotAt(idx);
1136 return true;
1137 }
1138
1139 public Double remove(int index) {
1140 Double oldValue = get(index);
1141 removeSlotAt(index);
1142 return oldValue;
1143 }
1144
1145 public void removeRange(int fromIndex, int toIndex) {
1146 removeSlotsAt(fromIndex, toIndex);
1147 }
1148
1149 public boolean contains(Object o) {
1150 if (!(o instanceof Double))
1151 return false;
1152 return seqIndexOf(((Double)o).doubleValue()) >= 0;
1153 }
1154
1155 public int indexOf(Object o) {
1156 if (!(o instanceof Double))
1157 return -1;
1158 return seqIndexOf(((Double)o).doubleValue());
1159 }
1160
1161 public int lastIndexOf(Object o) {
1162 if (!(o instanceof Double))
1163 return -1;
1164 return seqLastIndexOf(((Double)o).doubleValue());
1165 }
1166 }
1167
1168 }