diff --git a/src/main/java/net/imglib2/algorithm/math/Compute.java b/src/main/java/net/imglib2/algorithm/math/Compute.java index c3b8bb4d7..d5107f9c0 100644 --- a/src/main/java/net/imglib2/algorithm/math/Compute.java +++ b/src/main/java/net/imglib2/algorithm/math/Compute.java @@ -6,6 +6,7 @@ import java.util.LinkedList; import net.imglib2.Cursor; +import net.imglib2.RandomAccess; import net.imglib2.RandomAccessibleInterval; import net.imglib2.algorithm.math.abstractions.IBinaryFunction; import net.imglib2.algorithm.math.abstractions.IFunction; @@ -13,6 +14,9 @@ import net.imglib2.algorithm.math.abstractions.IUnaryFunction; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.algorithm.math.abstractions.Util; +import net.imglib2.algorithm.math.execution.FunctionCursor; +import net.imglib2.algorithm.math.execution.FunctionCursorIncompatibleOrder; +import net.imglib2.algorithm.math.execution.FunctionRandomAccess; import net.imglib2.converter.Converter; import net.imglib2.type.numeric.RealType; import net.imglib2.view.Views; @@ -21,7 +25,7 @@ public class Compute { private final IFunction operation; private final boolean compatible_iteration_order; - + /** * Validate the {code operation}. * @@ -71,14 +75,7 @@ public < O extends RealType< O > > RandomAccessibleInterval< O > into( ) { if ( null == converter ) - converter = new Converter< RealType< ? >, O >() - { - @Override - public final void convert( final RealType< ? > input, final O output) - { - output.setReal( input.getRealDouble() ); - } - }; + converter = Util.genericRealTypeConverter(); // Recursive copy: initializes interval iterators and sets temporary computation holder final OFunction< O > f = this.operation.reInit( @@ -115,6 +112,7 @@ private boolean validate( final IFunction f ) // child-parent map final HashMap< IFunction, IFunction > cp = new HashMap<>(); + cp.put( f, null ); // Collect images to later check their iteration order final LinkedList< RandomAccessibleInterval< ? > > images = new LinkedList<>(); @@ -125,26 +123,26 @@ private boolean validate( final IFunction f ) // Collect Let instances to check that their declared variables are used final HashSet< Let > lets = new HashSet<>(); - IFunction parent = null; - - // Iterate into the nested operations + // Iterate into the nested operations, depth-first while ( ! ops.isEmpty() ) { final IFunction op = ops.removeFirst(); - cp.put( op, parent ); - parent = op; if ( op instanceof ImgSource ) { - images.addLast( ( ( ImgSource< ? > )op ).getRandomAccessibleInterval() ); + images.addFirst( ( ( ImgSource< ? > )op ).getRandomAccessibleInterval() ); } else if ( op instanceof IUnaryFunction ) { - ops.addLast( ( ( IUnaryFunction )op ).getFirst() ); + final IFunction first = ( ( IUnaryFunction )op ).getFirst(); + ops.addFirst( first ); + cp.put( first, op ); if ( op instanceof IBinaryFunction ) { - ops.addLast( ( ( IBinaryFunction )op ).getSecond() ); + final IFunction second = ( ( IBinaryFunction )op ).getSecond(); + ops.add( 1, second ); + cp.put( second, op ); if ( op instanceof Let ) { @@ -153,7 +151,9 @@ else if ( op instanceof IUnaryFunction ) if ( op instanceof ITrinaryFunction ) { - ops.addLast( ( ( ITrinaryFunction )op ).getThird() ); + final IFunction third = ( ( ITrinaryFunction )op ).getThird(); + ops.add( 2, third ); + cp.put( third, op ); } } } @@ -168,16 +168,16 @@ else if ( op instanceof Var ) final HashSet< Let > used = new HashSet<>(); all: for ( final Var var : vars ) { - parent = var; + IFunction parent = var; while ( null != ( parent = cp.get( parent ) ) ) { if ( parent instanceof Let ) { - Let let = ( Let )parent; + final Let let = ( Let )parent; if ( let.getVarName() != var.getName() ) continue; // Else, found: Var is in use - used.add( let ); + used.add( let ); // might already be in used continue all; } } @@ -200,4 +200,43 @@ else if ( op instanceof Var ) return Util.compatibleIterationOrder( images ); } + + public < O extends RealType< O > > RandomAccess< O > randomAccess( final O outputType, final Converter< RealType< ? >, O > converter ) + { + return new FunctionRandomAccess< O >( this.operation, outputType, converter ); + } + + public < O extends RealType< O > > RandomAccess< O > randomAccess( final O outputType ) + { + return new FunctionRandomAccess< O >( this.operation, outputType, Util.genericRealTypeConverter() ); + } + + /** Returns a {@link RandomAccess} with the same type as the first input image found. */ + public < O extends RealType< O > > RandomAccess< O > randomAccess() + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval< O > img = ( RandomAccessibleInterval< O > )Util.findFirstImg( operation ); + final O outputType = img.randomAccess().get().createVariable(); + return new FunctionRandomAccess< O >( this.operation, outputType, Util.genericRealTypeConverter() ); + } + + public < O extends RealType< O > > Cursor< O > cursor( final O outputType, final Converter< RealType< ? >, O > converter ) + { + if ( this.compatible_iteration_order ) + return new FunctionCursor< O >( this.operation, outputType, converter ); + return new FunctionCursorIncompatibleOrder< O >( this.operation, outputType, converter ); + } + + public < O extends RealType< O > > Cursor< O > cursor( final O outputType ) + { + return this.cursor( outputType, Util.genericRealTypeConverter() ); + } + + /** Returns a {@link Cursor} with the same type as the first input image found. */ + public < O extends RealType< O > > Cursor< O > cursor() + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval< O > img = ( RandomAccessibleInterval< O > )Util.findFirstImg( operation ); + return this.cursor( img.randomAccess().get().createVariable() ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/If.java b/src/main/java/net/imglib2/algorithm/math/If.java index d9521f7dc..74c3f8e7d 100644 --- a/src/main/java/net/imglib2/algorithm/math/If.java +++ b/src/main/java/net/imglib2/algorithm/math/If.java @@ -4,6 +4,7 @@ import java.util.Map; import net.imglib2.algorithm.math.abstractions.ATrinaryFunction; +import net.imglib2.algorithm.math.abstractions.Compare; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.algorithm.math.execution.Comparison; import net.imglib2.algorithm.math.execution.IfStatement; @@ -41,7 +42,7 @@ public < O extends RealType< O > > OFunction< O > reInit( // and then having to read it out and compare it to zero to make a boolean, // instead returning a boolean directly. final OFunction< O > instance; - if ( this.a instanceof Comparison ) + if ( this.a instanceof Compare ) instance = new IfStatementBoolean< O >( ( Comparison< O > ) this.a.reInit( tmp, bindings, converter, imgS ), this.b.reInit( tmp, bindings, converter, imgS ), this.c.reInit( tmp, bindings, converter, imgS ) ); else diff --git a/src/main/java/net/imglib2/algorithm/math/ImgSource.java b/src/main/java/net/imglib2/algorithm/math/ImgSource.java index a93713ca6..cd138091d 100644 --- a/src/main/java/net/imglib2/algorithm/math/ImgSource.java +++ b/src/main/java/net/imglib2/algorithm/math/ImgSource.java @@ -5,13 +5,14 @@ import net.imglib2.RandomAccessibleInterval; import net.imglib2.algorithm.math.abstractions.IFunction; import net.imglib2.algorithm.math.abstractions.OFunction; +import net.imglib2.algorithm.math.abstractions.ViewableFunction; import net.imglib2.algorithm.math.execution.ImgSourceIterable; import net.imglib2.algorithm.math.execution.ImgSourceIterableDirect; import net.imglib2.algorithm.math.execution.Variable; import net.imglib2.converter.Converter; import net.imglib2.type.numeric.RealType; -public class ImgSource< I extends RealType< I > > implements IFunction +public class ImgSource< I extends RealType< I > > extends ViewableFunction implements IFunction { private final RandomAccessibleInterval< I > rai; diff --git a/src/main/java/net/imglib2/algorithm/math/Let.java b/src/main/java/net/imglib2/algorithm/math/Let.java index c9be4ec97..f5a84a4f4 100644 --- a/src/main/java/net/imglib2/algorithm/math/Let.java +++ b/src/main/java/net/imglib2/algorithm/math/Let.java @@ -7,12 +7,13 @@ import net.imglib2.algorithm.math.abstractions.IFunction; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.algorithm.math.abstractions.Util; +import net.imglib2.algorithm.math.abstractions.ViewableFunction; import net.imglib2.algorithm.math.execution.LetBinding; import net.imglib2.algorithm.math.execution.Variable; import net.imglib2.converter.Converter; import net.imglib2.type.numeric.RealType; -public final class Let implements IFunction, IBinaryFunction +public final class Let extends ViewableFunction implements IFunction, IBinaryFunction { private final String varName; private final IFunction varValue; diff --git a/src/main/java/net/imglib2/algorithm/math/NumberSource.java b/src/main/java/net/imglib2/algorithm/math/NumberSource.java index 4e5764a07..b6abc8b45 100644 --- a/src/main/java/net/imglib2/algorithm/math/NumberSource.java +++ b/src/main/java/net/imglib2/algorithm/math/NumberSource.java @@ -4,6 +4,7 @@ import net.imglib2.algorithm.math.abstractions.IFunction; import net.imglib2.algorithm.math.abstractions.OFunction; +import net.imglib2.algorithm.math.execution.IterableRandomAccessibleFunction; import net.imglib2.algorithm.math.execution.NumericSource; import net.imglib2.algorithm.math.execution.Variable; import net.imglib2.converter.Converter; @@ -26,4 +27,22 @@ public < O extends RealType< O > > NumericSource< O > reInit( { return new NumericSource< O >( tmp.copy(), this.number ); } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view() + { + throw new UnsupportedOperationException(); + } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType ) + { + throw new UnsupportedOperationException(); + } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType, final Converter< RealType< ? >, O > converter ) + { + throw new UnsupportedOperationException(); + } } \ No newline at end of file diff --git a/src/main/java/net/imglib2/algorithm/math/Var.java b/src/main/java/net/imglib2/algorithm/math/Var.java index c03ef1616..b344a4a1e 100644 --- a/src/main/java/net/imglib2/algorithm/math/Var.java +++ b/src/main/java/net/imglib2/algorithm/math/Var.java @@ -4,6 +4,7 @@ import net.imglib2.algorithm.math.abstractions.IVar; import net.imglib2.algorithm.math.abstractions.OFunction; +import net.imglib2.algorithm.math.execution.IterableRandomAccessibleFunction; import net.imglib2.algorithm.math.execution.Variable; import net.imglib2.converter.Converter; import net.imglib2.type.numeric.RealType; @@ -32,4 +33,22 @@ public < O extends RealType< O > > Variable< O > reInit( { return new Variable< O >( this.name, bindings.get( this.name ) ); } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view() + { + throw new UnsupportedOperationException(); + } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType ) + { + throw new UnsupportedOperationException(); + } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType, final Converter< RealType< ? >, O > converter ) + { + throw new UnsupportedOperationException(); + } } \ No newline at end of file diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/ABinaryFunction.java b/src/main/java/net/imglib2/algorithm/math/abstractions/ABinaryFunction.java index 76ba134f1..c37afbabc 100644 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/ABinaryFunction.java +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/ABinaryFunction.java @@ -1,6 +1,6 @@ package net.imglib2.algorithm.math.abstractions; -abstract public class ABinaryFunction extends VarargsFunction implements IBinaryFunction +abstract public class ABinaryFunction extends ViewableFunction implements IBinaryFunction { protected final IFunction a, b; @@ -12,7 +12,7 @@ public ABinaryFunction( final Object o1, final Object o2 ) public ABinaryFunction( final Object... obs ) { - final IFunction[] p = this.wrapMap( obs ); + final IFunction[] p = Util.wrapMap( this, obs ); this.a = p[ 0 ]; this.b = p[ 1 ]; } diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/ATrinaryFunction.java b/src/main/java/net/imglib2/algorithm/math/abstractions/ATrinaryFunction.java index 2cd1572cb..9877ec55e 100644 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/ATrinaryFunction.java +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/ATrinaryFunction.java @@ -1,27 +1,14 @@ package net.imglib2.algorithm.math.abstractions; -import net.imglib2.type.numeric.RealType; - -abstract public class ATrinaryFunction extends VarargsFunction implements ITrinaryFunction +abstract public class ATrinaryFunction extends ViewableFunction implements ITrinaryFunction { protected final IFunction a, b ,c; - - protected final RealType< ? > scrap; public ATrinaryFunction( final Object o1, final Object o2, final Object o3 ) { this.a = Util.wrap( o1 ); this.b = Util.wrap( o2 ); this.c = Util.wrap( o3 ); - this.scrap = null; - } - - protected ATrinaryFunction( final RealType< ? > scrap, final IFunction f1, final IFunction f2, final IFunction f3 ) - { - this.scrap = scrap; - this.a = f1; - this.b = f2; - this.c = f3; } public final IFunction getFirst() diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/AUnaryFunction.java b/src/main/java/net/imglib2/algorithm/math/abstractions/AUnaryFunction.java index 32f09d952..e875a0eae 100644 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/AUnaryFunction.java +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/AUnaryFunction.java @@ -2,7 +2,7 @@ import net.imglib2.type.numeric.RealType; -abstract public class AUnaryFunction implements IUnaryFunction +abstract public class AUnaryFunction extends ViewableFunction implements IUnaryFunction { protected final IFunction a; diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/IFunction.java b/src/main/java/net/imglib2/algorithm/math/abstractions/IFunction.java index e3bddfa04..bce3c564f 100644 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/IFunction.java +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/IFunction.java @@ -2,6 +2,7 @@ import java.util.Map; +import net.imglib2.algorithm.math.execution.IterableRandomAccessibleFunction; import net.imglib2.algorithm.math.execution.Variable; import net.imglib2.converter.Converter; import net.imglib2.type.numeric.RealType; @@ -14,4 +15,10 @@ public < O extends RealType< O > > OFunction< O > reInit( final Converter< RealType< ? >, O > converter, final Map< Variable< O >, OFunction< O > > imgSources ); + + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view(); + + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType ); + + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType, final Converter< RealType< ? >, O > converter ); } \ No newline at end of file diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/IImgSourceIterable.java b/src/main/java/net/imglib2/algorithm/math/abstractions/IImgSourceIterable.java new file mode 100644 index 000000000..562b78a6f --- /dev/null +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/IImgSourceIterable.java @@ -0,0 +1,12 @@ +package net.imglib2.algorithm.math.abstractions; + +import net.imglib2.Localizable; + +public interface IImgSourceIterable +{ + public boolean hasNext(); + + public Localizable localizable(); + + public void localize( final long[] position ); +} diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/IVar.java b/src/main/java/net/imglib2/algorithm/math/abstractions/IVar.java index 8dd8104a5..557276ae5 100644 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/IVar.java +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/IVar.java @@ -1,7 +1,5 @@ package net.imglib2.algorithm.math.abstractions; -import net.imglib2.type.numeric.RealType; - public interface IVar extends IFunction { public String getName(); diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/OFunction.java b/src/main/java/net/imglib2/algorithm/math/abstractions/OFunction.java index b3c30b8d3..2558b0bd8 100644 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/OFunction.java +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/OFunction.java @@ -1,5 +1,7 @@ package net.imglib2.algorithm.math.abstractions; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.type.numeric.RealType; @@ -8,4 +10,6 @@ public interface OFunction< O extends RealType< O > > public O eval(); public O eval( final Localizable loc ); + + public List< OFunction< O > > children(); } diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/Util.java b/src/main/java/net/imglib2/algorithm/math/abstractions/Util.java index 3b65e09b8..7e5ad9358 100644 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/Util.java +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/Util.java @@ -1,13 +1,20 @@ package net.imglib2.algorithm.math.abstractions; +import java.lang.reflect.Constructor; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import java.util.Set; import net.imglib2.RandomAccessibleInterval; import net.imglib2.algorithm.math.ImgSource; +import net.imglib2.algorithm.math.Let; import net.imglib2.algorithm.math.NumberSource; +import net.imglib2.algorithm.math.Var; +import net.imglib2.converter.Converter; +import net.imglib2.type.numeric.RealType; import net.imglib2.view.Views; public class Util @@ -74,6 +81,10 @@ else if ( o instanceof IFunction ) { return ( (IFunction) o ); } + else if ( o instanceof String ) + { + return new Var( (String)o ); + } // Make it fail return null; @@ -110,4 +121,166 @@ else if ( op instanceof IUnaryFunction ) return images; } + + static public final RandomAccessibleInterval< ? > findFirstImg ( final IFunction f ) + { + final LinkedList< IFunction > ops = new LinkedList<>(); + ops.add( f ); + + // Iterate into the nested operations + while ( ! ops.isEmpty() ) + { + final IFunction op = ops.removeFirst(); + + if ( op instanceof ImgSource ) + return ( ( ImgSource< ? > )op ).getRandomAccessibleInterval(); + else if ( op instanceof IUnaryFunction ) + { + ops.addLast( ( ( IUnaryFunction )op ).getFirst() ); + + if ( op instanceof IBinaryFunction ) + { + ops.addLast( ( ( IBinaryFunction )op ).getSecond() ); + + if ( op instanceof ITrinaryFunction ) + { + ops.addLast( ( ( ITrinaryFunction )op ).getThird() ); + } + } + } + } + + return null; + } + + static final public IFunction[] wrapMap( final Object caller, final Object[] obs ) + { + try { + if ( 2 == obs.length ) + return new IFunction[]{ Util.wrap( obs[ 0 ] ), Util.wrap( obs[ 1 ]) }; + + final Constructor< ? > constructor = caller.getClass().getConstructor( new Class[]{ Object.class, Object.class } ); + ABinaryFunction a = ( ABinaryFunction )constructor.newInstance( obs[0], obs[1] ); + ABinaryFunction b; + + for ( int i = 2; i < obs.length -1; ++i ) + { + b = ( ABinaryFunction )constructor.newInstance( a, obs[i] ); + a = b; + } + + return new IFunction[]{ a, Util.wrap( obs[ obs.length - 1 ] ) }; + } catch (Exception e) + { + throw new RuntimeException( "Error with the constructor for class " + caller.getClass(), e ); + } + } + + static public final < O extends RealType< O > > Converter< RealType< ? >, O > genericRealTypeConverter() + { + return new Converter< RealType< ? >, O >() + { + @Override + public final void convert( final RealType< ? > input, final O output) + { + output.setReal( input.getRealDouble() ); + } + }; + } + + public static final < O extends RealType< O > > IImgSourceIterable findFirstIterableImgSource( final OFunction< O > f ) + { + final LinkedList< OFunction< O > > ops = new LinkedList<>(); + ops.addLast( f ); + + // Iterate into the nested operations + while ( ! ops.isEmpty() ) + { + final OFunction< O > op = ops.removeFirst(); + for ( final OFunction< O > cf : op.children() ) + { + if ( cf instanceof IImgSourceIterable ) + return ( IImgSourceIterable ) cf; + ops.addLast( cf ); + } + } + + return null; + } + + public static final < O extends RealType< O > > List< IImgSourceIterable > findAllIterableImgSource( final OFunction< O > f ) + { + final LinkedList< OFunction< O > > ops = new LinkedList<>(); + ops.addLast( f ); + + final List< IImgSourceIterable > iis = new ArrayList<>(); + + // Iterate into the nested operations + while ( ! ops.isEmpty() ) + { + final OFunction< O > op = ops.removeFirst(); + for ( final OFunction< O > cf : op.children() ) + { + if ( cf instanceof IImgSourceIterable ) + iis.add( ( IImgSourceIterable ) cf ); + else + ops.addLast( cf ); + } + } + + return iis; + } + + /** Generate a printable, indented {@link String} with the nested hierarchy + * of operations under {@link IFunction} {@code f}. */ + public static final String hierarchy( final IFunction f ) + { + final LinkedList< IFunction > ops = new LinkedList<>(); + ops.add( f ); + + final StringBuilder hierarchy = new StringBuilder(); + final LinkedList< String > indents = new LinkedList<>(); + indents.add(""); + + // Iterate into the nested operations, depth-first + while ( ! ops.isEmpty() ) + { + final IFunction op = ops.removeFirst(); + + String indent = indents.removeFirst(); + String pre = ""; + String post = ""; + + if ( op instanceof IUnaryFunction ) + { + ops.addFirst( ( ( IUnaryFunction )op ).getFirst() ); + indents.addFirst( indent + " " ); + + if ( op instanceof IBinaryFunction ) + { + if ( op instanceof Let ) + { + post = " \"" + ( ( Let )op ).getVarName() + "\" -> "; + } + ops.add( 1, ( ( IBinaryFunction )op ).getSecond() ); + indents.add( 1, indent + " " ); + + if ( op instanceof ITrinaryFunction ) + { + ops.add( 2, ( ( ITrinaryFunction )op ).getThird() ); + indents.add( 2, indent + " " ); + } + } + } + else if ( op instanceof Var ) + { + pre = "\"" + ( ( Var )op ).getName() + "\" "; + } + + + hierarchy.append( indent + pre + op.getClass().getSimpleName() + post + "\n"); + } + + return hierarchy.toString(); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/VarargsFunction.java b/src/main/java/net/imglib2/algorithm/math/abstractions/VarargsFunction.java deleted file mode 100644 index e29d8d6a4..000000000 --- a/src/main/java/net/imglib2/algorithm/math/abstractions/VarargsFunction.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.imglib2.algorithm.math.abstractions; - -import java.lang.reflect.Constructor; - -abstract public class VarargsFunction -{ - final public IFunction[] wrapMap( final Object[] obs ) - { - try { - if ( 2 == obs.length ) - return new IFunction[]{ Util.wrap( obs[ 0 ] ), Util.wrap( obs[ 1 ]) }; - - final Constructor< ? > constructor = this.getClass().getConstructor( new Class[]{ Object.class, Object.class } ); - ABinaryFunction a = ( ABinaryFunction )constructor.newInstance( obs[0], obs[1] ); - ABinaryFunction b; - - for ( int i = 2; i < obs.length -1; ++i ) - { - b = ( ABinaryFunction )constructor.newInstance( a, obs[i] ); - a = b; - } - - return new IFunction[]{ a, Util.wrap( obs[ obs.length - 1 ] ) }; - } catch (Exception e) - { - throw new RuntimeException( "Error with the constructor for class " + this.getClass(), e ); - } - } -} \ No newline at end of file diff --git a/src/main/java/net/imglib2/algorithm/math/abstractions/ViewableFunction.java b/src/main/java/net/imglib2/algorithm/math/abstractions/ViewableFunction.java new file mode 100644 index 000000000..eb733a658 --- /dev/null +++ b/src/main/java/net/imglib2/algorithm/math/abstractions/ViewableFunction.java @@ -0,0 +1,26 @@ +package net.imglib2.algorithm.math.abstractions; + +import net.imglib2.algorithm.math.execution.IterableRandomAccessibleFunction; +import net.imglib2.converter.Converter; +import net.imglib2.type.numeric.RealType; + +public abstract class ViewableFunction implements IFunction +{ + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view() + { + return new IterableRandomAccessibleFunction< O >( this ); + } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType ) + { + return new IterableRandomAccessibleFunction< O >( this, outputType ); + } + + @Override + public < O extends RealType< O > > IterableRandomAccessibleFunction< O > view( final O outputType, final Converter< RealType< ? >, O > converter ) + { + return new IterableRandomAccessibleFunction< O >( this, outputType, converter ); + } +} \ No newline at end of file diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Addition.java b/src/main/java/net/imglib2/algorithm/math/execution/Addition.java index ee27cf404..2bc681ec7 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Addition.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Addition.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -29,4 +32,10 @@ public final O eval( final Localizable loc ) this.scrap.add( this.b.eval( loc ) ); return this.scrap; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Comparison.java b/src/main/java/net/imglib2/algorithm/math/execution/Comparison.java index cbe8d3533..13d851fd3 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Comparison.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Comparison.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.IBooleanFunction; import net.imglib2.algorithm.math.abstractions.OFunction; @@ -44,4 +47,10 @@ public final boolean evalBoolean( final Localizable loc ) { return this.compare( this.a.eval( loc ), this.b.eval( loc ) ); } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b ); + } } \ No newline at end of file diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Division.java b/src/main/java/net/imglib2/algorithm/math/execution/Division.java index 2ab0bb8b0..785be4c72 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Division.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Division.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -29,4 +32,10 @@ public final O eval( final Localizable loc ) this.scrap.div( this.b.eval( loc ) ); return this.scrap; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/FunctionCursor.java b/src/main/java/net/imglib2/algorithm/math/execution/FunctionCursor.java new file mode 100644 index 000000000..7de65f4ea --- /dev/null +++ b/src/main/java/net/imglib2/algorithm/math/execution/FunctionCursor.java @@ -0,0 +1,82 @@ +package net.imglib2.algorithm.math.execution; + +import java.util.HashMap; +import java.util.List; + +import net.imglib2.AbstractCursor; +import net.imglib2.algorithm.math.abstractions.IFunction; +import net.imglib2.algorithm.math.abstractions.IImgSourceIterable; +import net.imglib2.algorithm.math.abstractions.OFunction; +import net.imglib2.algorithm.math.abstractions.Util; +import net.imglib2.converter.Converter; +import net.imglib2.type.numeric.RealType; + +public class FunctionCursor< O extends RealType< O > > extends AbstractCursor< O > +{ + private final O outputType; + private final IFunction operation; + private final Converter< RealType< ? >, O > converter; + + protected OFunction< O > f; + protected O scrap; + protected IImgSourceIterable ii; + protected List< IImgSourceIterable > all_ii; + + public FunctionCursor( final IFunction operation, final O outputType, final Converter< RealType< ? >, O > converter ) { + super( Util.findFirstImg( operation ).numDimensions() ); + this.operation = operation; + this.outputType = outputType; + this.converter = null == converter ? Util.genericRealTypeConverter() : converter; + this.reset(); + } + + @Override + public O get() + { + return this.scrap; + } + + @Override + public void fwd() + { + this.scrap = this.f.eval(); + } + + @Override + public boolean hasNext() + { + return this.ii.hasNext(); + } + + @Override + public void reset() { + this.f = this.operation.reInit( this.outputType.createVariable() , new HashMap< String, O >(), this.converter, null ); + this.ii = Util.findFirstIterableImgSource( this.f ); + this.all_ii = Util.findAllIterableImgSource( this.f ); + } + + @Override + public long getLongPosition( final int d ) + { + return this.ii.localizable().getLongPosition( d ); + } + + @Override + public void localize( final long[] position ) { + for ( final IImgSourceIterable ii : this.all_ii ) + ii.localize( position ); + } + + @Override + public AbstractCursor< O > copy() + { + return new FunctionCursor< O >( this.operation, this.outputType, this.converter ); + } + + @Override + public AbstractCursor< O > copyCursor() + { + return this.copy(); + } + +} diff --git a/src/main/java/net/imglib2/algorithm/math/execution/FunctionCursorIncompatibleOrder.java b/src/main/java/net/imglib2/algorithm/math/execution/FunctionCursorIncompatibleOrder.java new file mode 100644 index 000000000..52f56aac4 --- /dev/null +++ b/src/main/java/net/imglib2/algorithm/math/execution/FunctionCursorIncompatibleOrder.java @@ -0,0 +1,20 @@ +package net.imglib2.algorithm.math.execution; + +import net.imglib2.Cursor; +import net.imglib2.algorithm.math.abstractions.IFunction; +import net.imglib2.converter.Converter; +import net.imglib2.type.numeric.RealType; + +public class FunctionCursorIncompatibleOrder< O extends RealType< O > > extends FunctionCursor< O > implements Cursor< O > +{ + public FunctionCursorIncompatibleOrder( final IFunction operation, final O outputType, final Converter< RealType< ? >, O > converter ) + { + super( operation, outputType, converter ); + } + + @Override + public void fwd() + { + this.scrap = this.f.eval( this.ii.localizable() ); + } +} diff --git a/src/main/java/net/imglib2/algorithm/math/execution/FunctionRandomAccess.java b/src/main/java/net/imglib2/algorithm/math/execution/FunctionRandomAccess.java new file mode 100644 index 000000000..45cb76487 --- /dev/null +++ b/src/main/java/net/imglib2/algorithm/math/execution/FunctionRandomAccess.java @@ -0,0 +1,75 @@ +package net.imglib2.algorithm.math.execution; + +import java.util.HashMap; + +import net.imglib2.Point; +import net.imglib2.RandomAccess; +import net.imglib2.Sampler; +import net.imglib2.algorithm.math.abstractions.IFunction; +import net.imglib2.algorithm.math.abstractions.OFunction; +import net.imglib2.algorithm.math.abstractions.Util; +import net.imglib2.converter.Converter; +import net.imglib2.type.numeric.RealType; + +public class FunctionRandomAccess< O extends RealType< O > > extends Point implements RandomAccess< O > +{ + private final FunctionSampler sampler; + + public FunctionRandomAccess( final IFunction operation, final O outputType, final Converter< RealType< ? >, O > converter ) + { + super( Util.findFirstImg( operation ).numDimensions() ); + this.sampler = new FunctionSampler( this, operation, outputType, converter ); + } + + private final class FunctionSampler implements Sampler< O > + { + private final Point point; + private final IFunction operation; + private final O outputType; + private final Converter< RealType< ? >, O > converter; + private final OFunction< O > f; + + FunctionSampler( final Point point, final IFunction operation, final O outputType, final Converter< RealType< ? >, O > converter ) + { + this.point = point; + this.operation = operation; + this.outputType = outputType.createVariable(); + this.converter = converter; + this.f = operation.reInit( + outputType.copy(), + new HashMap< String, O >(), + null == converter ? Util.genericRealTypeConverter() : converter, + null ); + } + + @Override + public final Sampler< O > copy() + { + return new FunctionSampler( this.point, this.operation, this.outputType, this.converter ); + } + + @Override + public final O get() + { + return this.f.eval( this.point ); + } + } + + @Override + public Sampler< O > copy() + { + return this.sampler.copy(); + } + + @Override + public O get() + { + return this.sampler.get(); + } + + @Override + public RandomAccess< O > copyRandomAccess() + { + return new FunctionRandomAccess< O >( this.sampler.operation, this.sampler.outputType, this.sampler.converter ); + } +} diff --git a/src/main/java/net/imglib2/algorithm/math/execution/IfStatement.java b/src/main/java/net/imglib2/algorithm/math/execution/IfStatement.java index a5a498ef6..aca4b8da1 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/IfStatement.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/IfStatement.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -34,4 +37,10 @@ public final O eval( final Localizable loc ) // Else : this.c.eval(); } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b, this.c ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/IfStatementBoolean.java b/src/main/java/net/imglib2/algorithm/math/execution/IfStatementBoolean.java index 80e4250fa..a3c1b6d26 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/IfStatementBoolean.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/IfStatementBoolean.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -31,4 +34,10 @@ public final O eval( final Localizable loc ) this.b.eval( loc ) : this.c.eval( loc ); } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.abool, this.b, this.c ); + } } \ No newline at end of file diff --git a/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterable.java b/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterable.java index 25f903c17..222a73978 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterable.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterable.java @@ -1,19 +1,22 @@ package net.imglib2.algorithm.math.execution; -import java.util.Iterator; +import java.util.Arrays; +import java.util.List; +import net.imglib2.Cursor; import net.imglib2.Localizable; import net.imglib2.RandomAccess; import net.imglib2.RandomAccessibleInterval; +import net.imglib2.algorithm.math.abstractions.IImgSourceIterable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.converter.Converter; import net.imglib2.type.numeric.RealType; import net.imglib2.view.Views; -public class ImgSourceIterable< I extends RealType< I >, O extends RealType< O > > implements OFunction< O > +public class ImgSourceIterable< I extends RealType< I >, O extends RealType< O > > implements OFunction< O >, IImgSourceIterable { private final RandomAccessibleInterval< I > rai; - private final Iterator< I > it; + private final Cursor< I > it; private final RandomAccess< I > ra; private Converter< I, O > converter; private final O scrap; @@ -21,7 +24,7 @@ public class ImgSourceIterable< I extends RealType< I >, O extends RealType< O > public ImgSourceIterable( final O scrap, final Converter< I, O > converter, final RandomAccessibleInterval< I > rai ) { this.rai = rai; - this.it = Views.iterable( rai ).iterator(); + this.it = Views.iterable( rai ).cursor(); this.ra = rai.randomAccess(); this.converter = converter; this.scrap = scrap; @@ -46,4 +49,28 @@ public RandomAccessibleInterval< I > getRandomAccessibleInterval() { return this.rai; } + + @Override + public boolean hasNext() + { + return this.it.hasNext(); + } + + @Override + public Localizable localizable() + { + return this.it; + } + + @Override + public void localize(long[] position) + { + this.it.localize( position ); + } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList(); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterableDirect.java b/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterableDirect.java index ce71a49ca..37e9d29f4 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterableDirect.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/ImgSourceIterableDirect.java @@ -1,24 +1,27 @@ package net.imglib2.algorithm.math.execution; -import java.util.Iterator; +import java.util.Arrays; +import java.util.List; +import net.imglib2.Cursor; import net.imglib2.Localizable; import net.imglib2.RandomAccess; import net.imglib2.RandomAccessibleInterval; +import net.imglib2.algorithm.math.abstractions.IImgSourceIterable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; import net.imglib2.view.Views; -public class ImgSourceIterableDirect< O extends RealType< O > > implements OFunction< O > +public class ImgSourceIterableDirect< O extends RealType< O > > implements OFunction< O >, IImgSourceIterable { private final RandomAccessibleInterval< O > rai; - private final Iterator< O > it; + private final Cursor< O > it; private final RandomAccess< O > ra; public ImgSourceIterableDirect( final RandomAccessibleInterval< O > rai ) { this.rai = rai; - this.it = Views.iterable( rai ).iterator(); + this.it = Views.iterable( rai ).cursor(); this.ra = rai.randomAccess(); } @@ -39,4 +42,28 @@ public RandomAccessibleInterval< O > getRandomAccessibleInterval() { return this.rai; } + + @Override + public boolean hasNext() + { + return this.it.hasNext(); + } + + @Override + public Localizable localizable() + { + return this.it; + } + + @Override + public void localize(long[] position) + { + this.it.localize( position ); + } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList(); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/IterableRandomAccessibleFunction.java b/src/main/java/net/imglib2/algorithm/math/execution/IterableRandomAccessibleFunction.java new file mode 100644 index 000000000..0fd4291c4 --- /dev/null +++ b/src/main/java/net/imglib2/algorithm/math/execution/IterableRandomAccessibleFunction.java @@ -0,0 +1,119 @@ +package net.imglib2.algorithm.math.execution; + +import java.util.Iterator; + +import net.imglib2.AbstractInterval; +import net.imglib2.Cursor; +import net.imglib2.Interval; +import net.imglib2.IterableInterval; +import net.imglib2.RandomAccess; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.View; +import net.imglib2.algorithm.math.Compute; +import net.imglib2.algorithm.math.abstractions.IFunction; +import net.imglib2.algorithm.math.abstractions.Util; +import net.imglib2.converter.Converter; +import net.imglib2.type.numeric.RealType; +import net.imglib2.util.Intervals; +import net.imglib2.view.Views; + +/** + * A {@link View} of the computation defined by an {@link IFunction}. + * + * The dimensions are those of the first input {@link RandomAccessibleInterval} found. + * (the computation will fail if images do not have the same dimensions.) + * + * If an output type is not defined, then the {@link RealType} of the first {@link RandomAccessibleInterval} found is used. + * + * @author Albert Cardona + * + * @param The {@link RealType}. + */ +public class IterableRandomAccessibleFunction< O extends RealType< O > > +extends AbstractInterval +implements RandomAccessibleInterval< O >, IterableInterval< O >, View +{ + private final IFunction operation; + private final RandomAccessibleInterval< ? > firstImg; + private final O outputType; + private final Converter< RealType< ? >, O > converter; + + public IterableRandomAccessibleFunction( final IFunction operation, final O outputType, final Converter< RealType< ? >, O > converter ) + { + super( Util.findFirstImg( operation ) ); + this.operation = operation; + this.firstImg = Util.findFirstImg( operation ); // Twice: unavoidable + this.outputType = outputType; + this.converter = converter; + } + + /** + * Use a default {@link Converter} as defined by {@link Util#genericRealTypeConverter()}. + */ + public IterableRandomAccessibleFunction( final IFunction operation, final O outputType ) + { + this( operation, outputType, null ); + } + + /** + * Use a the same {@link RealType} as the first input {@link RandomAccessibleInterval} found, + * and a default {@link Converter} as defined by {@link Util#genericRealTypeConverter()}. + */ + @SuppressWarnings("unchecked") + public IterableRandomAccessibleFunction( final IFunction operation ) + { + super( Util.findFirstImg( operation ) ); + this.operation = operation; + this.firstImg = Util.findFirstImg( operation ); // Twice: unavoidable + this.outputType = ( ( O ) this.firstImg.randomAccess().get() ).createVariable(); + this.converter = null; + } + + @Override + public RandomAccess< O > randomAccess() + { + return new Compute( this.operation ).randomAccess( this.outputType, this.converter ); + } + + @Override + public RandomAccess< O > randomAccess( final Interval interval ) + { + return this.randomAccess(); + } + + @Override + public O firstElement() + { + return this.randomAccess().get(); + } + + @Override + public Object iterationOrder() + { + return Views.iterable( this.firstImg ).iterationOrder(); + } + + @Override + public long size() + { + return Intervals.numElements( this.firstImg ); + } + + @Override + public Iterator< O > iterator() + { + return this.cursor(); + } + + @Override + public Cursor< O > cursor() + { + return new Compute( this.operation ).cursor( this.outputType, this.converter ); + } + + @Override + public Cursor< O > localizingCursor() + { + return this.cursor(); + } +} diff --git a/src/main/java/net/imglib2/algorithm/math/execution/LetBinding.java b/src/main/java/net/imglib2/algorithm/math/execution/LetBinding.java index 5a46c24f3..3852730e7 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/LetBinding.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/LetBinding.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -41,4 +44,10 @@ public final String getVarName() { return this.varName; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.varValue, this.body ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Maximum.java b/src/main/java/net/imglib2/algorithm/math/execution/Maximum.java index 2be9a7aef..8e74ef9e4 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Maximum.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Maximum.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -14,6 +17,7 @@ public Maximum( final OFunction< O > a, final OFunction< O > b ) this.b = b; } + @Override public final O eval() { final O x = this.a.eval(); @@ -21,10 +25,17 @@ public final O eval() return x.compareTo( y ) > 0 ? x : y; } + @Override public final O eval( final Localizable loc ) { final O x = this.a.eval( loc ); final O y = this.b.eval( loc ); return x.compareTo( y ) > 0 ? x : y; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Minimum.java b/src/main/java/net/imglib2/algorithm/math/execution/Minimum.java index f15bd263b..4176d412d 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Minimum.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Minimum.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -14,6 +17,7 @@ public Minimum( final OFunction< O > a, final OFunction< O > b ) this.b = b; } + @Override public final O eval() { final O x = this.a.eval(); @@ -21,10 +25,17 @@ public final O eval() return x.compareTo( y ) < 0 ? x : y; } + @Override public final O eval( final Localizable loc ) { final O x = this.a.eval( loc ); final O y = this.b.eval( loc ); return x.compareTo( y ) < 0 ? x : y; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Multiplication.java b/src/main/java/net/imglib2/algorithm/math/execution/Multiplication.java index 267a831a2..a5d0c28c0 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Multiplication.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Multiplication.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -16,6 +19,7 @@ public Multiplication( final O scrap, final OFunction< O > a, final OFunction< O this.b = b; } + @Override public final O eval() { this.scrap.set( this.a.eval() ); @@ -23,10 +27,17 @@ public final O eval() return this.scrap; } + @Override public final O eval( final Localizable loc ) { this.scrap.set( this.a.eval( loc ) ); this.scrap.mul( this.b.eval( loc ) ); return this.scrap; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/NumericSource.java b/src/main/java/net/imglib2/algorithm/math/execution/NumericSource.java index 9bbb2b139..ff0dd1536 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/NumericSource.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/NumericSource.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -28,4 +31,10 @@ public final O eval( final Localizable loc ) { return this.value; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList(); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Printing.java b/src/main/java/net/imglib2/algorithm/math/execution/Printing.java index 14ac2de2b..0860a89df 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Printing.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Printing.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -30,4 +33,10 @@ public final O eval( final Localizable loc) System.out.println( this.title + " :: " + result ); return result; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Subtraction.java b/src/main/java/net/imglib2/algorithm/math/execution/Subtraction.java index 1ca903e8f..853b55222 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Subtraction.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Subtraction.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -16,6 +19,7 @@ public Subtraction( final O scrap, final OFunction< O > a, final OFunction< O > this.b = b; } + @Override public final O eval() { this.scrap.set( this.a.eval() ); @@ -23,10 +27,17 @@ public final O eval() return this.scrap; } + @Override public final O eval( final Localizable loc ) { this.scrap.set( this.a.eval( loc ) ); this.scrap.sub( this.b.eval( loc ) ); return this.scrap; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList( this.a, this.b ); + } } diff --git a/src/main/java/net/imglib2/algorithm/math/execution/Variable.java b/src/main/java/net/imglib2/algorithm/math/execution/Variable.java index 993fddf04..3a29f68bf 100644 --- a/src/main/java/net/imglib2/algorithm/math/execution/Variable.java +++ b/src/main/java/net/imglib2/algorithm/math/execution/Variable.java @@ -1,5 +1,8 @@ package net.imglib2.algorithm.math.execution; +import java.util.Arrays; +import java.util.List; + import net.imglib2.Localizable; import net.imglib2.algorithm.math.abstractions.OFunction; import net.imglib2.type.numeric.RealType; @@ -36,4 +39,10 @@ public final String getName() { return this.name; } + + @Override + public List< OFunction< O > > children() + { + return Arrays.asList(); + } } diff --git a/src/test/java/net/imglib2/algorithm/math/ImgMathTest.java b/src/test/java/net/imglib2/algorithm/math/ImgMathTest.java index d5c4b3b17..29c0e7fd0 100644 --- a/src/test/java/net/imglib2/algorithm/math/ImgMathTest.java +++ b/src/test/java/net/imglib2/algorithm/math/ImgMathTest.java @@ -35,6 +35,8 @@ import net.imglib2.IterableInterval; import net.imglib2.RandomAccess; import net.imglib2.RandomAccessibleInterval; +import net.imglib2.algorithm.math.abstractions.IFunction; +import net.imglib2.algorithm.math.abstractions.Util; import net.imglib2.converter.Converters; import net.imglib2.img.array.ArrayImg; import net.imglib2.img.array.ArrayImgFactory; @@ -310,7 +312,7 @@ protected boolean testIfThenElse() { final ArrayImg< FloatType, ? > saturation = new ArrayImgFactory< FloatType >( new FloatType() ).create( dims ); // Compute saturation - compute( let( "red", red, + final IFunction f = let( "red", red, "green", green, "blue", blue, "max", max( var( "red" ), var( "green" ), var( "blue" ) ), @@ -318,8 +320,9 @@ protected boolean testIfThenElse() { IF ( EQ( 0, var( "max" ) ), 0, div( sub( var( "max" ), var( "min" ) ), - var( "max" ) ) ) ) ) - .into( saturation ); + var( "max" ) ) ) ); + System.out.println("=== Hierarchy ===\n" + Util.hierarchy( f ) ); + compute( f ).into( saturation ); final long sum = sumAsInts( saturation, 255.0 ); @@ -661,11 +664,13 @@ protected boolean testGT() @Test public void test1() { + System.out.println("test1"); assertTrue( testImgMath1() ); } @Test public void test2() { + System.out.println("test2"); assertTrue( testIterationOrder() ); } @@ -677,31 +682,37 @@ public void test3() { @Test public void test4() { + System.out.println("test4"); assertTrue( testVarags() ); } @Test public void testLet1Simple() { + System.out.println("testLet1Simple"); assertTrue( testLetOneLevel() ); } @Test public void testLet2Advanced() { + System.out.println("testLet2Advanced"); assertTrue( testLetTwoLets() ); } @Test public void testLet3MultiVar() { + System.out.println("testLet3MultiVar"); assertTrue ( testMultiLet() ); } @Test public void testLet4NestedMultiLet() { + System.out.println("testLet4NestedMultiLet"); assertTrue ( testNestedMultiLet() ); } @Test public void test1IfThenElse() { + System.out.println("test1IfThenElse"); assertTrue ( testIfThenElse() ); } @@ -713,11 +724,13 @@ public void test1IfThenElsePerformance() { @Test public void test5LT() { + System.out.println("test5LT"); assertTrue( testLT() ); } @Test public void test6GT() { + System.out.println("test6GT"); assertTrue( testGT() ); }