@@ -355,9 +355,9 @@ public static < T extends RealType< T >, U extends RealType< U >, V extends Real
355355 final int nTasks ,
356356 final double ... weights ) throws InterruptedException , ExecutionException
357357 {
358-
359358 final boolean isIsotropic = weights .length <= 1 ;
360- final double [] w = weights .length == source .numDimensions () ? weights : DoubleStream .generate ( () -> weights .length == 0 ? 1.0 : weights [ 0 ] ).limit ( source .numDimensions () ).toArray ();
359+ final double [] w = weights .length == source .numDimensions () ? weights
360+ : DoubleStream .generate (() -> weights .length == 0 ? 1.0 : weights [0 ]).limit (source .numDimensions ()).toArray ();
361361
362362 switch ( distanceType )
363363 {
@@ -1105,6 +1105,19 @@ private static < T extends RealType< T >, U extends RealType< U > > void transfo
11051105 final RandomAccessibleInterval < U > target ,
11061106 final Distance d ,
11071107 final int dim )
1108+ {
1109+ final long size = target .dimension ( dim );
1110+ if ( size > Integer .MAX_VALUE )
1111+ transformAlongDimensionComposite (source , target , d , dim );
1112+ else
1113+ transformAlongDimensionPrimitive (source , target , d , dim );
1114+ }
1115+
1116+ private static < T extends RealType < T >, U extends RealType < U > > void transformAlongDimensionComposite (
1117+ final RandomAccessible < T > source ,
1118+ final RandomAccessibleInterval < U > target ,
1119+ final Distance d ,
1120+ final int dim )
11081121 {
11091122 final int lastDim = target .numDimensions () - 1 ;
11101123 final long size = target .dimension ( dim );
@@ -1129,6 +1142,35 @@ private static < T extends RealType< T >, U extends RealType< U > > void transfo
11291142 }
11301143 }
11311144
1145+ private static < T extends RealType < T >, U extends RealType < U > > void transformAlongDimensionPrimitive (
1146+ final RandomAccessible < T > source ,
1147+ final RandomAccessibleInterval < U > target ,
1148+ final Distance d ,
1149+ final int dim )
1150+ {
1151+ final int lastDim = target .numDimensions () - 1 ;
1152+ final long size = target .dimension ( dim );
1153+ final RealComposite < DoubleType > tmp = Views .collapseReal ( createAppropriateOneDimensionalImage ( size , new DoubleType () ) ).randomAccess ().get ();
1154+
1155+ // do not permute if we already work on last dimension
1156+ final Cursor < RealComposite < T > > s = Views .flatIterable ( Views .collapseReal ( dim == lastDim ? Views .interval ( source , target ) : Views .permute ( Views .interval ( source , target ), dim , lastDim ) ) ).cursor ();
1157+ final Cursor < RealComposite < U > > t = Views .flatIterable ( Views .collapseReal ( dim == lastDim ? target : Views .permute ( target , dim , lastDim ) ) ).cursor ();
1158+
1159+ final long [] lowerBoundDistanceIndex = new long [(int )size ];
1160+ final double [] envelopeIntersectLocation = new double [(int )size + 1 ];
1161+
1162+ while ( s .hasNext () )
1163+ {
1164+ final RealComposite < T > sourceComp = s .next ();
1165+ final RealComposite < U > targetComp = t .next ();
1166+ for ( long i = 0 ; i < size ; ++i )
1167+ {
1168+ tmp .get ( i ).set ( sourceComp .get ( i ).getRealDouble () );
1169+ }
1170+ transformSingleColumnPrimitive ( tmp , targetComp , lowerBoundDistanceIndex , envelopeIntersectLocation , d , dim , size );
1171+ }
1172+ }
1173+
11321174 private static < T extends RealType < T >, U extends RealType < U > > void transformAlongDimensionParallel (
11331175 final RandomAccessible < T > source ,
11341176 final RandomAccessibleInterval < U > target ,
@@ -1167,6 +1209,53 @@ private static < T extends RealType< T >, U extends RealType< U > > void transfo
11671209 invokeAllAndWait ( es , tasks );
11681210 }
11691211
1212+ private static < T extends RealType < T >, U extends RealType < U > > void transformSingleColumnPrimitive (
1213+ final RealComposite < T > source ,
1214+ final RealComposite < U > target ,
1215+ final long [] lowerBoundDistanceIndex ,
1216+ final double [] envelopeIntersectLocation ,
1217+ final Distance d ,
1218+ final int dim ,
1219+ final long size )
1220+ {
1221+ int k = 0 ;
1222+
1223+ lowerBoundDistanceIndex [0 ] = 0 ;
1224+ envelopeIntersectLocation [0 ] = Double .NEGATIVE_INFINITY ;
1225+ envelopeIntersectLocation [1 ] = Double .POSITIVE_INFINITY ;
1226+ for ( long position = 1 ; position < size ; ++position )
1227+ {
1228+ long envelopeIndexAtK = lowerBoundDistanceIndex [k ];
1229+ final double sourceAtPosition = source .get ( position ).getRealDouble ();
1230+ double s = d .intersect ( envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), position , sourceAtPosition , dim );
1231+
1232+ for ( double envelopeValueAtK = envelopeIntersectLocation [k ]; s <= envelopeValueAtK && k >= 1 ; envelopeValueAtK = envelopeIntersectLocation [k ] )
1233+ {
1234+ --k ;
1235+ envelopeIndexAtK = lowerBoundDistanceIndex [k ];
1236+ s = d .intersect ( envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), position , sourceAtPosition , dim );
1237+ }
1238+ ++k ;
1239+ lowerBoundDistanceIndex [k ] = position ;
1240+ envelopeIntersectLocation [k ] = s ;
1241+ envelopeIntersectLocation [k + 1 ] = Double .POSITIVE_INFINITY ;
1242+ }
1243+
1244+ k = 0 ;
1245+
1246+ for ( long position = 0 ; position < size ; ++position )
1247+ {
1248+ while ( envelopeIntersectLocation [ k + 1 ] < position )
1249+ {
1250+ ++k ;
1251+ }
1252+ final long envelopeIndexAtK = lowerBoundDistanceIndex [k ];
1253+ // copy necessary because of the following line, access to source
1254+ // after write to source -> source and target cannot be the same
1255+ target .get ( position ).setReal ( d .evaluate ( position , envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), dim ) );
1256+ }
1257+ }
1258+
11701259 private static < T extends RealType < T >, U extends RealType < U > > void transformSingleColumn (
11711260 final RealComposite < T > source ,
11721261 final RealComposite < U > target ,
@@ -1187,7 +1276,7 @@ private static < T extends RealType< T >, U extends RealType< U > > void transfo
11871276 final double sourceAtPosition = source .get ( position ).getRealDouble ();
11881277 double s = d .intersect ( envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), position , sourceAtPosition , dim );
11891278
1190- for ( double envelopeValueAtK = envelopeIntersectLocation .get ( k ).get (); s <= envelopeValueAtK ; envelopeValueAtK = envelopeIntersectLocation .get ( k ).get () )
1279+ for ( double envelopeValueAtK = envelopeIntersectLocation .get ( k ).get (); s <= envelopeValueAtK && k >= 1 ; envelopeValueAtK = envelopeIntersectLocation .get ( k ).get () )
11911280 {
11921281 --k ;
11931282 envelopeIndexAtK = lowerBoundDistanceIndex .get ( k ).get ();
@@ -1212,7 +1301,6 @@ private static < T extends RealType< T >, U extends RealType< U > > void transfo
12121301 // after write to source -> source and target cannot be the same
12131302 target .get ( position ).setReal ( d .evaluate ( position , envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), dim ) );
12141303 }
1215-
12161304 }
12171305
12181306 private static < T extends RealType < T >, U extends RealType < U > > void transformL1AlongDimension (
@@ -1725,6 +1813,21 @@ private static < T extends RealType< T >, U extends RealType< U >, L extends Int
17251813 final RandomAccessible < M > labelTarget ,
17261814 final Distance d ,
17271815 final int dim )
1816+ {
1817+ final long size = target .dimension ( dim );
1818+ if ( size > Integer .MAX_VALUE )
1819+ transformAlongDimensionPropagateLabelsComposite (source , target , labelSource , labelTarget , d , dim );
1820+ else
1821+ transformAlongDimensionPropagateLabelsPrimitive (source , target , labelSource , labelTarget , d , dim );
1822+ }
1823+
1824+ private static < T extends RealType < T >, U extends RealType < U >, L extends IntegerType < L >, M extends IntegerType < M > > void transformAlongDimensionPropagateLabelsComposite (
1825+ final RandomAccessible < T > source ,
1826+ final RandomAccessibleInterval < U > target ,
1827+ final RandomAccessible < L > labelSource ,
1828+ final RandomAccessible < M > labelTarget ,
1829+ final Distance d ,
1830+ final int dim )
17281831 {
17291832 final int lastDim = target .numDimensions () - 1 ;
17301833 final long size = target .dimension ( dim );
@@ -1759,11 +1862,11 @@ private static < T extends RealType< T >, U extends RealType< U >, L extends Int
17591862 tmp .get ( i ).set ( sourceComp .get ( i ).getRealDouble () );
17601863 tmpLabel .get ( i ).setInteger ( labelComp .get ( i ).getIntegerLong () );
17611864 }
1762- transformSingleColumnPropagateLabels ( tmp , targetComp , tmpLabel , labelTargetComp , lowerBoundDistanceIndex , envelopeIntersectLocation , d , dim , size );
1865+ transformSingleColumnPropagateLabelsComposite ( tmp , targetComp , tmpLabel , labelTargetComp , lowerBoundDistanceIndex , envelopeIntersectLocation , d , dim , size );
17631866 }
17641867 }
17651868
1766- private static < T extends RealType < T >, U extends RealType < U >, L extends IntegerType <L >, M extends IntegerType <M > > void transformSingleColumnPropagateLabels (
1869+ private static < T extends RealType < T >, U extends RealType < U >, L extends IntegerType <L >, M extends IntegerType <M > > void transformSingleColumnPropagateLabelsComposite (
17671870 final RealComposite < T > source ,
17681871 final RealComposite < U > target ,
17691872 final RealComposite < L > labelsSource ,
@@ -1785,7 +1888,7 @@ private static < T extends RealType< T >, U extends RealType< U >, L extends Int
17851888 final double sourceAtPosition = source .get ( position ).getRealDouble ();
17861889 double s = d .intersect ( envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), position , sourceAtPosition , dim );
17871890
1788- for ( double envelopeValueAtK = envelopeIntersectLocation .get ( k ).get (); s <= envelopeValueAtK ; envelopeValueAtK = envelopeIntersectLocation .get ( k ).get () )
1891+ for ( double envelopeValueAtK = envelopeIntersectLocation .get ( k ).get (); s <= envelopeValueAtK && k >= 1 ; envelopeValueAtK = envelopeIntersectLocation .get ( k ).get () )
17891892 {
17901893 --k ;
17911894 envelopeIndexAtK = lowerBoundDistanceIndex .get ( k ).get ();
@@ -1813,6 +1916,100 @@ private static < T extends RealType< T >, U extends RealType< U >, L extends Int
18131916
18141917 }
18151918
1919+ private static < T extends RealType < T >, U extends RealType < U >, L extends IntegerType < L >, M extends IntegerType < M > > void transformAlongDimensionPropagateLabelsPrimitive (
1920+ final RandomAccessible < T > source ,
1921+ final RandomAccessibleInterval < U > target ,
1922+ final RandomAccessible < L > labelSource ,
1923+ final RandomAccessible < M > labelTarget ,
1924+ final Distance d ,
1925+ final int dim )
1926+ {
1927+ final int lastDim = target .numDimensions () - 1 ;
1928+ final int size = (int )target .dimension ( dim );
1929+
1930+ final Img < DoubleType > tmpImg = createAppropriateOneDimensionalImage ( size , new DoubleType () );
1931+ final RealComposite < DoubleType > tmp = Views .collapseReal ( tmpImg ).randomAccess ().get ();
1932+
1933+ final Img < L > tmpLabelImg = Util .getSuitableImgFactory ( tmpImg , labelSource .getType () ).create ( tmpImg );
1934+ final RealComposite < L > tmpLabel = Views .collapseReal ( tmpLabelImg ).randomAccess ().get ();
1935+
1936+ // do not permute if we already work on last dimension
1937+ final Cursor < RealComposite < T > > s = Views .flatIterable ( Views .collapseReal ( dim == lastDim ? Views .interval ( source , target ) : Views .permute ( Views .interval ( source , target ), dim , lastDim ) ) ).cursor ();
1938+ final Cursor < RealComposite < U > > t = Views .flatIterable ( Views .collapseReal ( dim == lastDim ? target : Views .permute ( target , dim , lastDim ) ) ).cursor ();
1939+
1940+ final Cursor < RealComposite < L > > ls = Views .flatIterable (
1941+ Views .collapseReal ( dim == lastDim ? Views .interval ( labelSource , target ) : Views .permute ( Views .interval ( labelSource , target ), dim , lastDim ) ) ).cursor ();
1942+
1943+ final Cursor < RealComposite < M > > lt = Views .flatIterable (
1944+ Views .collapseReal ( dim == lastDim ? Views .interval ( labelTarget , target ) : Views .permute ( Views .interval ( labelTarget , target ), dim , lastDim ) ) ).cursor ();
1945+
1946+ final long [] lowerBoundDistanceIndex = new long [size ];
1947+ final double [] envelopeIntersectLocation = new double [size +1 ];
1948+
1949+ while ( s .hasNext () )
1950+ {
1951+ final RealComposite < T > sourceComp = s .next ();
1952+ final RealComposite < U > targetComp = t .next ();
1953+ final RealComposite < L > labelComp = ls .next ();
1954+ final RealComposite < M > labelTargetComp = lt .next ();
1955+ for ( long i = 0 ; i < size ; ++i )
1956+ {
1957+ tmp .get ( i ).set ( sourceComp .get ( i ).getRealDouble () );
1958+ tmpLabel .get ( i ).setInteger ( labelComp .get ( i ).getIntegerLong () );
1959+ }
1960+ transformSingleColumnPropagateLabelsPrimitive ( tmp , targetComp , tmpLabel , labelTargetComp , lowerBoundDistanceIndex , envelopeIntersectLocation , d , dim , size );
1961+ }
1962+ }
1963+
1964+ private static < T extends RealType < T >, U extends RealType < U >, L extends IntegerType <L >, M extends IntegerType <M > > void transformSingleColumnPropagateLabelsPrimitive (
1965+ final RealComposite < T > source ,
1966+ final RealComposite < U > target ,
1967+ final RealComposite < L > labelsSource ,
1968+ final RealComposite < M > labelsResult ,
1969+ final long [] lowerBoundDistanceIndex ,
1970+ final double [] envelopeIntersectLocation ,
1971+ final Distance d ,
1972+ final int dim ,
1973+ final long size )
1974+ {
1975+ int k = 0 ;
1976+
1977+ lowerBoundDistanceIndex [0 ] = 0 ;
1978+ envelopeIntersectLocation [0 ] = Double .NEGATIVE_INFINITY ;
1979+ envelopeIntersectLocation [1 ] = Double .POSITIVE_INFINITY ;
1980+ for ( long position = 1 ; position < size ; ++position )
1981+ {
1982+ long envelopeIndexAtK = lowerBoundDistanceIndex [k ];
1983+ final double sourceAtPosition = source .get ( position ).getRealDouble ();
1984+ double s = d .intersect ( envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), position , sourceAtPosition , dim );
1985+
1986+ for ( double envelopeValueAtK = envelopeIntersectLocation [k ]; s <= envelopeValueAtK && k >= 1 ; envelopeValueAtK = envelopeIntersectLocation [k ] )
1987+ {
1988+ --k ;
1989+ envelopeIndexAtK = lowerBoundDistanceIndex [k ];
1990+ s = d .intersect ( envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), position , sourceAtPosition , dim );
1991+ }
1992+ ++k ;
1993+ lowerBoundDistanceIndex [k ] = position ;
1994+ envelopeIntersectLocation [k ] = s ;
1995+ envelopeIntersectLocation [k + 1 ] = Double .POSITIVE_INFINITY ;
1996+ }
1997+
1998+ k = 0 ;
1999+ for ( long position = 0 ; position < size ; ++position )
2000+ {
2001+ while ( envelopeIntersectLocation [ k + 1 ] < position )
2002+ {
2003+ ++k ;
2004+ }
2005+ final long envelopeIndexAtK = lowerBoundDistanceIndex [k ];
2006+ // copy necessary because of the following line, access to source
2007+ // after write to source -> source and target cannot be the same
2008+ target .get ( position ).setReal ( d .evaluate ( position , envelopeIndexAtK , source .get ( envelopeIndexAtK ).getRealDouble (), dim ) );
2009+ labelsResult .get ( position ).setInteger ( labelsSource .get ( envelopeIndexAtK ).getIntegerLong () );
2010+ }
2011+ }
2012+
18162013 private static < T extends RealType < T >, U extends RealType < U >, L extends IntegerType < L >, M extends IntegerType < M > > void transformAlongDimensionPropagateLabelsParallel (
18172014 final RandomAccessible < T > source ,
18182015 final RandomAccessibleInterval < U > target ,
0 commit comments