ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/forkjoin/ParallelDoubleArray.java
Revision: 1.14
Committed: Tue Jan 6 14:34:59 2009 UTC (15 years, 5 months ago) by dl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +0 -0 lines
State: FILE REMOVED
Log Message:
Repackaging

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