|
|
[Up to jsr166y.forkjoin Examples]
There are several ways to modify the contents of a Parallel Array. You can replace values with a running accumulated value, you can replace values with a generated value, or you can replace values by mapping existing values or by combining the existing value with another array or Parallel Array. In addition, you can sequentially set individual items (but doing so outside the concurrent FJ framework). This is useful if only a small percent of values require intitialization.
The examples below use ParallelDoubleArray, but analogous operation exist for ParallelArray<T> and ParallelLongArray. We will assume you are familiar with Creating arrays and Initializing arrays and have a ParallelDoubleArray reference, pda.
This example initializes a Parallel Array with all 1.0 values, then uses the cumulateSum to compute a running sum {1.0, 2.0, 3.0, 4.0, ...}
pda.replaceWithValue(1.0);
pda.cumulateSum();
Once that value has been computing, running cumulateSum() again yields {1.0, 3.0, 6.0, 10.0, ...}
pda.cumulateSum();
Generators are object which generate values without accepting input arguments or prior values. Ops.DoubleGenerator is defined with the method double op(). You can use generators to populate Parallel Arrays. There are several variations of random number generators, such as CommonOps.doubleRandom(), CommonOps.doubleRandom(double bound) and CommonOps.doubleRandom(double least, double bound)
// put random values into a Parallel Array
pda.replaceWithGeneratedValue(CommonOps.doubleRandom(0, 100.0));
A Mapping is an operation which consumes one value and outputs another value that is normally derived from the input. Thus, by applying a mapping to a Parallel Array, you can modify the contents. For example, to add a number to all elements of a Parallel Array. Given our ParallelDoubleArray pda with the values {1.0, 3.0, 6.0, 10.0, ...}, the following will replace the contents with {101.5, 103.5, 106.5, 110.5, ...}
static class Adder implements
Ops.DoubleOp{
// See also Using jsr166y.forkjoin Mappings and Predicates for tips on using mappers and predicates effectively.
private final double addend;
Adder(final double addend) {
this.addend = addend;
}
@Override
public double op(final double a) {
return a + addend;
}
}double x = 100.5;
pda.replaceWithMapping(new Adder(x));
There are also mappings which take two arguments: the element index and the current value. The following replaces each elementi with the value f(i) + elementi
double f(int i) { ... }
...
pda.
replaceWithMappedIndex(new Ops.IntAndDoubleToDouble() {
@Override
public double op(final int i, final double element_i) {
return f(i) + element_i;
}
});
Like basic arrays, you can individually assign values to a Parallel Array. Doing so runs outside the concurrent FJ framework, meaning the work is not done concurrently. This is useful if only a small percent of values require intitialization, or if the values being assigned are not in existing arrays or Parallel Arrays.
David Biesackpda.set(0, x);
pda.set(1, y);...
// Copy some values from some non-parallel source into
// a Parallel Array
Map<Integer, Double> values = // ... some Map
for(Map.Entry<Integer, Double> e : values) {
pda.set(e.getKey(), e.getValue());