Skip to content

Commit eb89070

Browse files
committed
ImgMath: refactor to make all member variables final.
The IFunction copy method was renamed to reInit, which is more accurate. The performance of Var improved a lot.
1 parent ff9c814 commit eb89070

File tree

24 files changed

+283
-224
lines changed

24 files changed

+283
-224
lines changed
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package net.imglib2.algorithm.math;
22

3+
import java.util.Map;
4+
35
import net.imglib2.Localizable;
46
import net.imglib2.algorithm.math.abstractions.ABinaryFunction;
7+
import net.imglib2.algorithm.math.abstractions.IFunction;
8+
import net.imglib2.converter.Converter;
59
import net.imglib2.type.numeric.RealType;
610

711
public final class Add extends ABinaryFunction
@@ -15,27 +19,33 @@ public Add( final Object... obs )
1519
{
1620
super( obs );
1721
}
22+
23+
private Add( final RealType< ? > scrap, final IFunction f1, final IFunction f2 )
24+
{
25+
super( scrap, f1, f2 );
26+
}
1827

1928
@SuppressWarnings({ "rawtypes", "unchecked" })
2029
@Override
21-
public final void eval( final RealType output ) {
30+
public final void eval( final RealType output )
31+
{
2232
this.a.eval( output );
2333
this.b.eval( this.scrap );
2434
output.add( this.scrap );
2535
}
2636

2737
@SuppressWarnings({ "rawtypes", "unchecked" })
2838
@Override
29-
public final void eval( final RealType output, final Localizable loc ) {
39+
public final void eval( final RealType output, final Localizable loc )
40+
{
3041
this.a.eval( output, loc );
3142
this.b.eval( this.scrap, loc );
3243
output.add( this.scrap );
3344
}
3445

3546
@Override
36-
public Add copy() {
37-
final Add f = new Add( this.a.copy(), this.b.copy() );
38-
f.setScrap( this.scrap );
39-
return f;
47+
public Add reInit( final RealType<?> tmp, final Map<String, RealType<?>> bindings, final Converter<RealType<?>, RealType<?>> converter )
48+
{
49+
return new Add( tmp.copy(), this.a.reInit( tmp, bindings, converter ), this.b.reInit( tmp, bindings, converter ) );
4050
}
4151
}

src/main/java/net/imglib2/algorithm/math/Compute.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.ArrayList;
44
import java.util.HashMap;
5+
import java.util.HashSet;
56
import java.util.LinkedList;
67

78
import net.imglib2.Cursor;
@@ -43,13 +44,13 @@ public Compute(
4344

4445
public < O extends RealType< O > > RandomAccessibleInterval< O > into( final RandomAccessibleInterval< O > target )
4546
{
46-
// Recursive copy: initializes interval iterators
47-
final IFunction f = this.operation.copy();
48-
// Set temporary computation holders
49-
final O scrap = target.randomAccess().get().createVariable();
50-
f.setScrap( scrap );
47+
// Recursive copy: initializes interval iterators and sets temporary computation holder
48+
final IFunction f = this.operation.reInit(
49+
target.randomAccess().get().createVariable(),
50+
new HashMap< String, RealType< ? > >(),
51+
converter );
5152

52-
final boolean compatible_iteration_order = this.setup( f, converter );
53+
final boolean compatible_iteration_order = this.setup( f );
5354

5455
// Check compatible iteration order and dimensions
5556
if ( compatible_iteration_order )
@@ -74,7 +75,7 @@ public < O extends RealType< O > > RandomAccessibleInterval< O > into( final Ran
7475
}
7576

7677
@SuppressWarnings({ "rawtypes", "unchecked" })
77-
private boolean setup( final IFunction f, final Converter< ?, ? > converter )
78+
private boolean setup( final IFunction f )
7879
{
7980
final LinkedList< IFunction > ops = new LinkedList<>();
8081
ops.add( f );
@@ -88,6 +89,9 @@ private boolean setup( final IFunction f, final Converter< ?, ? > converter )
8889
// Collect Var instances to check that each corresponds to an upstream Let
8990
final ArrayList< Var > vars = new ArrayList<>();
9091

92+
// Collect Let instances to check that their declared variables are used
93+
final HashSet< Let > lets = new HashSet<>();
94+
9195
IFunction parent = null;
9296

9397
// Iterate into the nested operations
@@ -100,8 +104,6 @@ private boolean setup( final IFunction f, final Converter< ?, ? > converter )
100104
if ( op instanceof IterableImgSource )
101105
{
102106
final IterableImgSource iis = ( IterableImgSource )op;
103-
// Side effect: set the converter from input to output types
104-
iis.setConverter( converter );
105107
images.addLast( iis.rai );
106108
}
107109
else if ( op instanceof IUnaryFunction )
@@ -112,6 +114,11 @@ else if ( op instanceof IUnaryFunction )
112114
{
113115
ops.addLast( ( ( IBinaryFunction )op ).getSecond() );
114116

117+
if ( op instanceof Let )
118+
{
119+
lets.add( ( Let )op );
120+
}
121+
115122
if ( op instanceof ITrinaryFunction )
116123
{
117124
ops.addLast( ( ( ITrinaryFunction )op ).getThird() );
@@ -126,6 +133,7 @@ else if ( op instanceof Var )
126133
}
127134

128135
// Check Vars: are they all using names declared in upstream Lets
136+
final HashSet< Let > used = new HashSet<>();
129137
all: for ( final Var var : vars )
130138
{
131139
parent = var;
@@ -134,15 +142,27 @@ else if ( op instanceof Var )
134142
if ( parent instanceof Let )
135143
{
136144
Let let = ( Let )parent;
137-
if ( let.varName != var.name )
145+
if ( let.getVarName() != var.getName() )
138146
continue;
139147
// Else, found: Var is in use
148+
used.add( let );
140149
continue all;
141150
}
142151
}
143152
// No upstream Let found
144-
throw new RuntimeException( "The Var(\"" + var.name + "\") does not read from any upstream Let. " );
145-
}
153+
throw new RuntimeException( "The Var(\"" + var.getName() + "\") does not read from any upstream Let. " );
154+
}
155+
156+
// Check Lets: are their declared variables used in downstream Vars?
157+
if ( lets.size() != used.size() )
158+
{
159+
lets.removeAll( used );
160+
String msg = "The Let-declared variable" + ( 1 == lets.size() ? "" : "s" );
161+
for ( final Let let : lets )
162+
msg += " \"" + let.getVarName() + "\"";
163+
msg += " " + ( 1 == lets.size() ? "is" : "are") + " not used by any downstream Var.";
164+
throw new RuntimeException( msg );
165+
}
146166

147167
return Util.compatibleIterationOrder( images );
148168
}

src/main/java/net/imglib2/algorithm/math/Div.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package net.imglib2.algorithm.math;
22

3+
import java.util.Map;
4+
35
import net.imglib2.Localizable;
46
import net.imglib2.algorithm.math.abstractions.ABinaryFunction;
57
import net.imglib2.algorithm.math.abstractions.IFunction;
8+
import net.imglib2.converter.Converter;
69
import net.imglib2.type.numeric.RealType;
710

811
public final class Div extends ABinaryFunction implements IFunction
@@ -17,27 +20,33 @@ public Div( final Object... obs )
1720
{
1821
super( obs );
1922
}
23+
24+
private Div( final RealType< ? > scrap, final IFunction f1, final IFunction f2 )
25+
{
26+
super( scrap, f1, f2 );
27+
}
2028

2129
@SuppressWarnings({ "rawtypes", "unchecked" })
2230
@Override
23-
public final void eval( final RealType output ) {
31+
public final void eval( final RealType output )
32+
{
2433
this.a.eval( output );
2534
this.b.eval( this.scrap );
2635
output.div( this.scrap );
2736
}
2837

2938
@SuppressWarnings({ "rawtypes", "unchecked" })
3039
@Override
31-
public final void eval( final RealType output, final Localizable loc) {
40+
public final void eval( final RealType output, final Localizable loc)
41+
{
3242
this.a.eval( output, loc );
3343
this.b.eval( this.scrap, loc );
3444
output.div( this.scrap );
3545
}
3646

3747
@Override
38-
public Div copy() {
39-
final Div f = new Div( this.a.copy(), this.b.copy() );
40-
f.setScrap( this.scrap );
41-
return f;
48+
public Div reInit( final RealType<?> tmp, final Map<String, RealType<?>> bindings, final Converter<RealType<?>, RealType<?>> converter )
49+
{
50+
return new Div( tmp.copy(), this.a.reInit( tmp, bindings, converter ), this.b.reInit( tmp, bindings, converter ) );
4251
}
4352
}
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package net.imglib2.algorithm.math;
22

3+
import java.util.Map;
4+
35
import net.imglib2.algorithm.math.abstractions.Compare;
6+
import net.imglib2.algorithm.math.abstractions.IFunction;
7+
import net.imglib2.converter.Converter;
48
import net.imglib2.type.numeric.RealType;
59

610
public final class Equal extends Compare
@@ -9,16 +13,20 @@ public Equal( final Object o1, final Object o2) {
913
super( o1, o2 );
1014
}
1115

16+
private Equal( final RealType< ? > scrap, final IFunction f1, final IFunction f2 )
17+
{
18+
super( scrap, f1, f2 );
19+
}
20+
1221
@SuppressWarnings({ "rawtypes", "unchecked" })
1322
public final boolean compare( final RealType t1, final RealType t2 )
1423
{
1524
return 0 == t1.compareTo( t2 );
1625
}
1726

1827
@Override
19-
public Equal copy() {
20-
final Equal copy = new Equal( this.a.copy(), this.b.copy() );
21-
copy.setScrap( this.scrap );
22-
return copy;
28+
public Equal reInit( final RealType<?> tmp, final Map<String, RealType<?>> bindings, final Converter<RealType<?>, RealType<?>> converter )
29+
{
30+
return new Equal( tmp.copy(), this.a.reInit( tmp, bindings, converter ), this.b.reInit( tmp, bindings, converter ) );
2331
}
2432
}
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package net.imglib2.algorithm.math;
22

3+
import java.util.Map;
4+
35
import net.imglib2.algorithm.math.abstractions.Compare;
6+
import net.imglib2.algorithm.math.abstractions.IFunction;
7+
import net.imglib2.converter.Converter;
48
import net.imglib2.type.numeric.RealType;
59

610
public final class GreaterThan extends Compare
@@ -9,16 +13,20 @@ public GreaterThan( final Object o1, final Object o2) {
913
super(o1, o2);
1014
}
1115

16+
private GreaterThan( final RealType< ? > scrap, final IFunction f1, final IFunction f2 )
17+
{
18+
super( scrap, f1, f2 );
19+
}
20+
1221
@SuppressWarnings({ "rawtypes", "unchecked" })
1322
public final boolean compare( final RealType t1, final RealType t2 )
1423
{
1524
return 1 == t1.compareTo( t2 );
1625
}
1726

1827
@Override
19-
public GreaterThan copy() {
20-
final GreaterThan copy = new GreaterThan( this.a.copy(), this.b.copy() );
21-
copy.setScrap( this.scrap );
22-
return copy;
28+
public GreaterThan reInit( final RealType<?> tmp, final Map<String, RealType<?>> bindings, final Converter<RealType<?>, RealType<?>> converter )
29+
{
30+
return new GreaterThan( tmp.copy(), this.a.reInit( tmp, bindings, converter ), this.b.reInit( tmp, bindings, converter ) );
2331
}
2432
}

src/main/java/net/imglib2/algorithm/math/If.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package net.imglib2.algorithm.math;
22

3+
import java.util.Map;
4+
35
import net.imglib2.Localizable;
46
import net.imglib2.algorithm.math.abstractions.ATrinaryFunction;
7+
import net.imglib2.algorithm.math.abstractions.IFunction;
8+
import net.imglib2.converter.Converter;
59
import net.imglib2.type.numeric.RealType;
610

711
public final class If extends ATrinaryFunction
@@ -10,9 +14,15 @@ public If( final Object o1, final Object o2, final Object o3 )
1014
{
1115
super( o1, o2, o3 );
1216
}
17+
18+
private If( final RealType< ? > scrap, final IFunction f1, final IFunction f2, final IFunction f3 )
19+
{
20+
super ( scrap, f1, f2, f3 );
21+
}
1322

1423
@Override
15-
public final void eval( final RealType<?> output ) {
24+
public final void eval( final RealType<?> output )
25+
{
1626
this.a.eval( this.scrap );
1727
if ( 0.0f != this.scrap.getRealFloat() )
1828
{
@@ -26,7 +36,8 @@ public final void eval( final RealType<?> output ) {
2636
}
2737

2838
@Override
29-
public final void eval( final RealType<?> output, final Localizable loc ) {
39+
public final void eval( final RealType<?> output, final Localizable loc )
40+
{
3041
this.a.eval( this.scrap, loc );
3142
if ( 0.0f != this.scrap.getRealFloat() )
3243
{
@@ -40,9 +51,8 @@ public final void eval( final RealType<?> output, final Localizable loc ) {
4051
}
4152

4253
@Override
43-
public If copy() {
44-
final If copy = new If( this.a.copy(), this.b.copy(), this.c.copy() );
45-
copy.setScrap( this.scrap );
46-
return copy;
54+
public If reInit( final RealType<?> tmp, final Map<String, RealType<?>> bindings, final Converter<RealType<?>, RealType<?>> converter )
55+
{
56+
return new If( tmp.copy(), this.a.reInit( tmp, bindings, converter ), this.b.reInit( tmp, bindings, converter ), this.c.reInit( tmp, bindings, converter ) );
4757
}
4858
}

src/main/java/net/imglib2/algorithm/math/ImgMath.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,9 @@
11
package net.imglib2.algorithm.math;
22

3-
import java.util.ArrayList;
4-
import java.util.HashMap;
5-
import java.util.Iterator;
6-
import java.util.LinkedList;
7-
8-
import net.imglib2.Cursor;
93
import net.imglib2.RandomAccessibleInterval;
10-
import net.imglib2.algorithm.math.abstractions.IBinaryFunction;
114
import net.imglib2.algorithm.math.abstractions.IFunction;
12-
import net.imglib2.algorithm.math.abstractions.ITrinaryFunction;
13-
import net.imglib2.algorithm.math.abstractions.IUnaryFunction;
14-
import net.imglib2.algorithm.math.abstractions.Util;
155
import net.imglib2.converter.Converter;
166
import net.imglib2.type.numeric.RealType;
17-
import net.imglib2.view.Views;
187

198
/**
209
* An easy yet relatively high performance way to perform pixel-wise math

0 commit comments

Comments
 (0)