Skip to content

Commit 650fb05

Browse files
dietzcctrueden
authored andcommitted
WIP
1 parent d342151 commit 650fb05

6 files changed

Lines changed: 63 additions & 85 deletions

File tree

ops-examples/src/main/java/org/scijava/ops/examples/SumOfArrays.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import java.util.function.BiFunction;
55
import java.util.function.BinaryOperator;
66

7-
import org.scijava.collection.DoubleArray;
8-
import org.scijava.collection.IntArray;
9-
import org.scijava.ops.TreeReduceOp;
7+
import org.scijava.ops.AggregateOp;
8+
import org.scijava.util.DoubleArray;
9+
import org.scijava.util.IntArray;
1010

1111
/**
1212
* Takes a list of DoubleArray as inputs; produces the sum of the values.
@@ -15,7 +15,7 @@
1515
* into a tree of operations, which are combined toward the root of the tree.
1616
* </p>
1717
*/
18-
public class SumOfArrays implements TreeReduceOp<IntArray, DoubleArray> {
18+
public class SumOfArrays implements AggregateOp<IntArray, DoubleArray> {
1919

2020
@Override
2121
public BiFunction<DoubleArray, IntArray, DoubleArray> accumulator() {
@@ -49,7 +49,7 @@ public DoubleArray apply(final DoubleArray in1, final DoubleArray in2) {
4949
}
5050

5151
@Override
52-
public DoubleArray createZero(final IntArray in) {
52+
public DoubleArray createMemo(final IntArray in) {
5353
return new DoubleArray(in.size());
5454
}
5555

ops-examples/src/main/java/org/scijava/ops/examples/SumOfIntegers.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import java.util.function.BiFunction;
55
import java.util.function.BinaryOperator;
66

7-
import org.scijava.ops.TreeReduceOp;
7+
import org.scijava.ops.AggregateOp;
88

99
/**
1010
* Takes a list of doubles as inputs; produces the sum of the values.
@@ -13,7 +13,7 @@
1313
* into a tree of operations, which are combined toward the root of the tree.
1414
* </p>
1515
*/
16-
public class SumOfIntegers implements TreeReduceOp<Integer, Long> {
16+
public class SumOfIntegers implements AggregateOp<Integer, Long> {
1717

1818
@Override
1919
public BiFunction<Long, Integer, Long> accumulator() {
@@ -39,7 +39,7 @@ public Long apply(final Long t, final Long u) {
3939
}
4040

4141
@Override
42-
public Long createZero(final Integer in) {
42+
public Long createMemo(final Integer in) {
4343
return 0L;
4444
}
4545

ops/src/main/java/org/scijava/ops/TreeReduceOp.java renamed to ops/src/main/java/org/scijava/ops/AggregateOp.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import java.util.function.BinaryOperator;
55

66
// tree-reduce N->M -- Aggregator composes (not extends):
7-
// -- BiFunction<I, O (memo), O>
7+
// -- BiFunction<O (memo), I, O>
88
// -- BinaryOperator<O>
9-
// -- O createIdentity(I in)
9+
// -- O createMemo(I in)
1010
/** See: https://stackoverflow.com/a/38949457/1207769 */
11-
public interface TreeReduceOp<I, O> {
11+
public interface AggregateOp<I, O> {
1212

1313
/**
1414
* NB: The infrastructure that executes the tree reduce must guarantee that
@@ -18,5 +18,5 @@ public interface TreeReduceOp<I, O> {
1818
*/
1919
BiFunction<O, I, O> accumulator();
2020
BinaryOperator<O> combiner();
21-
O createZero(I in);
21+
O createMemo(I in);
2222
}

ops/src/main/java/org/scijava/ops/MapOp.java renamed to ops/src/main/java/org/scijava/ops/FlatMapOp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66

77
/** (flat)map -- 1->N */
88
@FunctionalInterface
9-
public interface MapOp<I, O> extends BiConsumer<I, Consumer<O>> {}
9+
public interface FlatMapOp<I, O> extends BiConsumer<I, Consumer<O>> {}

ops/src/main/java/org/scijava/ops/Ops.java

Lines changed: 49 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,31 @@
33

44
import java.util.ArrayList;
55
import java.util.Collection;
6-
import java.util.List;
76
import java.util.function.BiConsumer;
8-
import java.util.function.BiFunction;
97
import java.util.function.Function;
108
import java.util.stream.Collectors;
119

1210
public final class Ops {
1311

14-
private Ops() {}
12+
private Ops() {
13+
}
1514

16-
public static <I, O> ComputerOp<I, O> asComputer(final Function<I, O> op,
17-
final BiConsumer<O, O> copy)
18-
{
15+
public static <I, O> ComputerOp<I, O> asComputer(final Function<I, O> op, final BiConsumer<O, O> copy) {
1916
return (in, out) -> {
2017
final O temp = op.apply(in);
2118
copy.accept(temp, out);
2219
};
2320
}
24-
public <IO> ComputerOp<IO, IO> asComputer(final InplaceOp<IO> op,
25-
final BiConsumer<IO, IO> copy)
26-
{
21+
22+
public <IO> ComputerOp<IO, IO> asComputer(final InplaceOp<IO> op, final BiConsumer<IO, IO> copy) {
2723
return (in, out) -> {
2824
copy.accept(in, out);
2925
op.accept(out);
3026
};
3127
}
32-
// TODO: add more adapters! Yay!
33-
34-
// TODO: consider whether (some of?) these should be service methods,
35-
// for extensibility. Or better: plugins of type OpAdapter. Later!
36-
// E.g.: expressing tree-reduce as a function may depend on type details.
37-
// net.imagej.ops.map ops are a special case for e.g. IterableInterval.
38-
39-
public static <I, O> Function<Collection<I>, O> asFunction(
40-
final TreeReduceOp<I, O> op)
41-
{
42-
return in -> {
43-
final BiFunction<O, I, O> acc = op.accumulator();
44-
final O zero = op.createZero(in.iterator().next());
45-
// TODO: use spliterator for multi-threading and use combiner
46-
in.stream().forEach(e -> acc.apply(zero, e));
47-
return zero;
48-
};
49-
}
5028

51-
public <IO, F extends InplaceOp<IO> & OutputAware<IO, IO>> Function<IO, IO>
52-
asFunction(final F op, final BiConsumer<IO, IO> copy)
53-
{
29+
public <IO, F extends InplaceOp<IO> & OutputAware<IO, IO>> Function<IO, IO> asFunction(final F op,
30+
final BiConsumer<IO, IO> copy) {
5431
return in -> {
5532
IO o = op.createOutput(in);
5633
copy.accept(in, o);
@@ -59,64 +36,65 @@ public static <I, O> Function<Collection<I>, O> asFunction(
5936
};
6037
}
6138

62-
// FIXME: lame.
63-
public static <I, O> Function<I, O> asFunction(final MapOp<I, O> op) {
64-
return new Function<I, O>() {
65-
private List<O> out = new ArrayList<>(1);
66-
67-
@Override
68-
public O apply(final I in) {
69-
op.accept(in, in1 -> out.set(0, in1));
70-
return out.get(0);
71-
}};
39+
public static <I, O> Function<I, Collection<O>> asFunction(final FlatMapOp<I, O> op) {
40+
return in -> {
41+
final ArrayList<O> out = new ArrayList<>();
42+
op.accept(in, (o) -> out.add(o));
43+
return out;
44+
};
7245
}
7346

74-
public static <I, O, OP extends ComputerOp<I, O> & OutputAware<I, O>>
75-
Function<I, O> asFunction(final OP op)
76-
{
47+
public static <I, O, OP extends ComputerOp<I, O> & OutputAware<I, O>> Function<I, O> asFunction(final OP op) {
7748
return in -> {
7849
final O out = op.createOutput(in);
7950
op.accept(in, out);
8051
return out;
8152
};
8253
}
8354

84-
public static <I, O> MapOp<I, O> asMap(final Function<I, O> op) {
55+
public static <I, O> FlatMapOp<I, O> asFlatMap(final Function<I, O> op) {
8556
return (in, out) -> out.accept(op.apply(in));
8657
}
8758

88-
// TODO: add more adapters! Yay!
59+
public static <I> InplaceOp<I> asInplace(Function<I, I> func, final BiConsumer<I, I> copy) {
60+
return (in) -> {
61+
final I res = func.apply(in);
62+
copy.accept(res, in);
63+
};
64+
}
65+
66+
public static <I> InplaceOp<I> asInplace(ComputerOp<I, I> func) {
67+
return (in) -> func.accept(in, in);
68+
}
8969

90-
public static <I, O> Function<Collection<I>, Collection<O>> lift(
91-
final Function<I, O> op)
92-
{
70+
public static <I, C extends OutputAware<I, I> & ComputerOp<I, I>> InplaceOp<I> asInplace(C func,
71+
final BiConsumer<I, I> copy) {
72+
return (in) -> {
73+
I out = func.createOutput(in);
74+
func.accept(in, out);
75+
copy.accept(out, in);
76+
};
77+
}
78+
79+
public static <I, O> Function<Collection<I>, O> asFunction(final AggregateOp<I, O> op) {
80+
return in -> {
81+
final O memo = op.createMemo(in.iterator().next());
82+
return in.parallelStream().reduce(memo, op.accumulator(), op.combiner());
83+
};
84+
}
85+
86+
public static <I, O> Function<Collection<I>, Collection<O>> lift(final Function<I, O> op) {
9387
// START HERE: need to make this an explicit subclass a la Views
9488
// maybe LiftedFunctionOp or something. It implements SelfAware,
95-
// which defines OpInfo info(), allowing this guy to define how it works.
89+
// which defines OpInfo info(), allowing this guy to define how it
90+
// works.
9691
// That way, the wrapped op's extra parameters can be propagated into
9792
// the wrapped guy here.
9893
return in -> in.parallelStream().map(op).collect(Collectors.toList());
9994
}
10095

101-
// TODO: consider whether (some of?) these should be service methods,
102-
// for extensibility. Or better: plugins of type OpAdapter. Later!
103-
// E.g.: expressing tree-reduce as a function may depend on type details.
104-
// net.imagej.ops.map ops are a special case for e.g. IterableInterval.
105-
106-
107-
108-
////////////////////
109-
// Possibly problematic
110-
// Consider whether to have these, can throw exception if incompatible
111-
112-
// use function as inplace --------- only allowed if Function<T, T> and structures match
113-
// mutate(arg):
114-
// o = f(arg)
115-
// copy(o -> arg)
116-
117-
// use computer as inplace ---------
118-
// mutate(arg):
119-
// o = create(arg)
120-
// compute(arg, o)
121-
// copy(o -> arg)
122-
}
96+
public static <I, O> Function<Collection<I>, Collection<O>> lift(final FlatMapOp<I, O> op) {
97+
return (in) -> in.parallelStream().flatMap((i) -> asFunction(op).apply(i).parallelStream())
98+
.collect(Collectors.toList());
99+
}
100+
}

ops/src/main/java/org/scijava/ops/SimpleTreeReduceOp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import java.util.function.BinaryOperator;
44

55
/**
6-
* Special case of {@link TreeReduceOp} where the aggreagtor and the combiner do
6+
* Special case of {@link AggregateOp} where the aggreagtor and the combiner do
77
* the same thing, producing outputs the same type as the input, with no need
88
* for an initial zero value.
99
*/

0 commit comments

Comments
 (0)