ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/ParallelDoubleArray.java
Revision: 1.4
Committed: Tue Feb 21 01:54:03 2012 UTC (12 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.3: +8 -8 lines
Log Message:
use third person in javadoc first sentence

File Contents

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