diff --git a/bounds.patch b/bounds.patch new file mode 100644 index 00000000..461d9ec4 --- /dev/null +++ b/bounds.patch @@ -0,0 +1,79 @@ +diff --git a/src/main/java/net/imglib2/roi/Bounds.java b/src/main/java/net/imglib2/roi/Bounds.java +index 3f9e1ab..7c5145b 100644 +--- a/src/main/java/net/imglib2/roi/Bounds.java ++++ b/src/main/java/net/imglib2/roi/Bounds.java +@@ -535,40 +535,60 @@ public abstract class Bounds< I extends RealInterval, B extends Bounds< I, B > > + + private final RealInterval i2; + ++ private final double[] min; ++ ++ private final double[] max; ++ + public UnionRealInterval( final RealInterval i1, final RealInterval i2 ) + { + super( i1.numDimensions() ); + this.i1 = i1; + this.i2 = i2; + assert ( i1.numDimensions() == i2.numDimensions() ); ++ min = new double[ i1.numDimensions() ]; ++ max = new double[ i1.numDimensions() ]; ++ Arrays.fill( min, Double.NaN ); ++ Arrays.fill( max, Double.NaN ); + } + + @Override + public double realMin( final int d ) + { +- if ( Intervals.isEmpty( i1 ) ) ++ if ( Double.isNaN( min[ d ] ) ) + { +- if ( Intervals.isEmpty( i2 ) ) +- return Double.POSITIVE_INFINITY; +- return i2.realMin( d ); ++ if ( Intervals.isEmpty( i1 ) ) ++ { ++ if ( Intervals.isEmpty( i2 ) ) ++ min[ d ] = Double.POSITIVE_INFINITY; ++ else ++ min[ d ] = i2.realMin( d ); ++ } ++ else if ( Intervals.isEmpty( i2 ) ) ++ min[ d] = i1.realMin( d ); ++ else ++ min[ d ] = Math.min( i1.realMin( d ), i2.realMin( d ) ); + } +- if ( Intervals.isEmpty( i2 ) ) +- return i1.realMin( d ); +- return Math.min( i1.realMin( d ), i2.realMin( d ) ); ++ return min[ d ]; + } + + @Override + public double realMax( final int d ) + { +- if ( Intervals.isEmpty( i1 ) ) ++ if ( Double.isNaN( max[d] ) + { +- if ( Intervals.isEmpty( i2 ) ) +- return Double.NEGATIVE_INFINITY; +- return i2.realMax( d ); ++ if ( Intervals.isEmpty( i1 ) ) ++ { ++ if ( Intervals.isEmpty( i2 ) ) ++ max[ d ] = Double.NEGATIVE_INFINITY; ++ else ++ max[ d ] = i2.realMax( d ); ++ } ++ else if ( Intervals.isEmpty( i2 ) ) ++ max[ d ] = i1.realMax( d ); ++ else ++ max[ d ] = Math.max( i1.realMax( d ), i2.realMax( d ) ); + } +- if ( Intervals.isEmpty( i2 ) ) +- return i1.realMax( d ); +- return Math.max( i1.realMax( d ), i2.realMax( d ) ); ++ return max[ d ]; + } + } + diff --git a/src/main/java/net/imglib2/roi/Bounds.java b/src/main/java/net/imglib2/roi/Bounds.java index 3f9e1abb..869a8aa9 100644 --- a/src/main/java/net/imglib2/roi/Bounds.java +++ b/src/main/java/net/imglib2/roi/Bounds.java @@ -535,40 +535,60 @@ public static class UnionRealInterval extends AbstractAdaptingRealInterval private final RealInterval i2; + private final double[] min; + + private final double[] max; + public UnionRealInterval( final RealInterval i1, final RealInterval i2 ) { super( i1.numDimensions() ); this.i1 = i1; this.i2 = i2; assert ( i1.numDimensions() == i2.numDimensions() ); + min = new double[ i1.numDimensions() ]; + max = new double[ i1.numDimensions() ]; + Arrays.fill( min, Double.NaN ); + Arrays.fill( max, Double.NaN ); } @Override public double realMin( final int d ) { - if ( Intervals.isEmpty( i1 ) ) + if ( Double.isNaN( min[ d ] ) ) { - if ( Intervals.isEmpty( i2 ) ) - return Double.POSITIVE_INFINITY; - return i2.realMin( d ); + if ( Intervals.isEmpty( i1 ) ) + { + if ( Intervals.isEmpty( i2 ) ) + min[ d ] = Double.POSITIVE_INFINITY; + else + min[ d ] = i2.realMin( d ); + } + else if ( Intervals.isEmpty( i2 ) ) + min[ d] = i1.realMin( d ); + else + min[ d ] = Math.min( i1.realMin( d ), i2.realMin( d ) ); } - if ( Intervals.isEmpty( i2 ) ) - return i1.realMin( d ); - return Math.min( i1.realMin( d ), i2.realMin( d ) ); + return min[ d ]; } @Override public double realMax( final int d ) { - if ( Intervals.isEmpty( i1 ) ) + if ( Double.isNaN( max[d] ) ) { - if ( Intervals.isEmpty( i2 ) ) - return Double.NEGATIVE_INFINITY; - return i2.realMax( d ); + if ( Intervals.isEmpty( i1 ) ) + { + if ( Intervals.isEmpty( i2 ) ) + max[ d ] = Double.NEGATIVE_INFINITY; + else + max[ d ] = i2.realMax( d ); + } + else if ( Intervals.isEmpty( i2 ) ) + max[ d ] = i1.realMax( d ); + else + max[ d ] = Math.max( i1.realMax( d ), i2.realMax( d ) ); } - if ( Intervals.isEmpty( i2 ) ) - return i1.realMax( d ); - return Math.max( i1.realMax( d ), i2.realMax( d ) ); + return max[ d ]; } } diff --git a/src/test/java/net/imglib2/roi/GeomMaskMultipleORTest.java b/src/test/java/net/imglib2/roi/GeomMaskMultipleORTest.java index 17ddbb2c..fb061ce2 100644 --- a/src/test/java/net/imglib2/roi/GeomMaskMultipleORTest.java +++ b/src/test/java/net/imglib2/roi/GeomMaskMultipleORTest.java @@ -3,6 +3,8 @@ import net.imglib2.roi.geom.GeomMasks; import org.junit.Test; +import static org.junit.Assert.assertTrue; + public class GeomMaskMultipleORTest { @Test @@ -11,13 +13,16 @@ public void multipleOr() final RealMaskRealInterval mask = GeomMasks.closedBox( new double[]{ 0, 0, 0 }, new double[]{ 1, 1, 1 } ); RealMaskRealInterval test = mask; long start = System.currentTimeMillis(); + long duration = 0; for ( int i = 0; i < 20; i++ ) { test = test.or( mask ); System.out.println( "RealMin: " + test.realMin( 0 )); System.out.println( "NumOr: " + i ); - System.out.println( "Duration [ms]:" + ( System.currentTimeMillis() - start ) ); + duration = System.currentTimeMillis() - start; + System.out.println( "Duration [ms]: " + duration ); start = System.currentTimeMillis(); } + assertTrue( duration < 10 ); } }