ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/ParallelDoubleArray.java
Revision: 1.1
Committed: Tue Jan 6 14:30:58 2009 UTC (15 years, 3 months ago) by dl
Branch: MAIN
Log Message:
Repackaged parallel collection classes

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 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 /** Return the number of elements */
141 public int size();
142 /** Return the minimum element, or Double.MAX_VALUE if empty */
143 public double min();
144 /** Return the maximum element, or -Double.MAX_VALUE if empty */
145 public double max();
146 /** Return the index of the minimum element, or -1 if empty */
147 public int indexOfMin();
148 /** Return the index of the maximum element, or -1 if empty */
149 public int indexOfMax();
150 /** Return the sum of all elements */
151 public double sum();
152 /** Return the arithmetic average of all elements */
153 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 public ParallelDoubleArray replaceWithMapping(DoubleOp op) {
195 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 * Make len slots available at index
926 */
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