Skip to content

Commit b1c8457

Browse files
committed
ImgMath: implemented IF, EQ, NEQ, LT, GT
Equal (EQ), NotEqual (NEQ), LessThan (LT), and GreaterThan (GT) all set the output to 1 when true, to zero when false. IF is a TrinaryFunction that conditionally executes either the 2nd ("then") or the 3rd ("else") argument depending on whether the 1st is true or false. Performance tests show a considerable cost, perhaps 3X over low-level math.
1 parent 214c806 commit b1c8457

File tree

2 files changed

+434
-11
lines changed

2 files changed

+434
-11
lines changed

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

Lines changed: 236 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ else if ( op instanceof IUnaryFunction )
137137
if ( op instanceof IBinaryFunction )
138138
{
139139
ops.addLast( ( ( IBinaryFunction )op ).getSecond() );
140+
141+
if ( op instanceof ITrinaryFunction )
142+
{
143+
ops.addLast( ( ( ITrinaryFunction )op ).getThird() );
144+
}
140145
}
141146
}
142147
else if ( op instanceof Var )
@@ -296,6 +301,31 @@ static public final Var var( final String name )
296301
return new Var( name );
297302
}
298303

304+
static public final Equal EQ( final Object o1, final Object o2 )
305+
{
306+
return new Equal( o1, o2 );
307+
}
308+
309+
static public final NotEqual NEQ( final Object o1, final Object o2 )
310+
{
311+
return new NotEqual( o1, o2 );
312+
}
313+
314+
static public final LessThan LT( final Object o1, final Object o2 )
315+
{
316+
return new LessThan( o1, o2 );
317+
}
318+
319+
static public final GreaterThan GT( final Object o1, final Object o2 )
320+
{
321+
return new GreaterThan( o1, o2 );
322+
}
323+
324+
static public final If IF( final Object o1, final Object o2, final Object o3 )
325+
{
326+
return new If( o1, o2, o3 );
327+
}
328+
299329

300330
static public interface IFunction
301331
{
@@ -318,6 +348,11 @@ static public interface IBinaryFunction extends IUnaryFunction
318348
public IFunction getSecond();
319349
}
320350

351+
static public interface ITrinaryFunction extends IBinaryFunction
352+
{
353+
public IFunction getThird();
354+
}
355+
321356
static private final class IterableImgSource< I extends RealType< I > > implements IFunction
322357
{
323358
private final RandomAccessibleInterval< I > rai;
@@ -491,6 +526,44 @@ public void setScrap( final RealType< ? > output )
491526
}
492527
}
493528

529+
static abstract public class TrinaryFunction extends Function implements ITrinaryFunction
530+
{
531+
protected final IFunction a, b ,c;
532+
533+
protected RealType< ? > scrap;
534+
535+
public TrinaryFunction( final Object o1, final Object o2, final Object o3 )
536+
{
537+
this.a = wrap( o1 );
538+
this.b = wrap( o2 );
539+
this.c = wrap( o3 );
540+
}
541+
542+
public final IFunction getFirst()
543+
{
544+
return this.a;
545+
}
546+
547+
public final IFunction getSecond()
548+
{
549+
return this.b;
550+
}
551+
552+
public final IFunction getThird()
553+
{
554+
return this.c;
555+
}
556+
557+
public void setScrap( final RealType< ? > output )
558+
{
559+
if ( null == output ) return;
560+
this.scrap = output.copy();
561+
this.a.setScrap( output );
562+
this.b.setScrap( output );
563+
this.c.setScrap( output );
564+
}
565+
}
566+
494567
static private final class Mul extends BinaryFunction
495568
{
496569
public Mul( final Object o1, final Object o2 )
@@ -803,6 +876,24 @@ private final void setupVars( final IFunction o, final boolean[] used )
803876
{
804877
setupVars( bf.getSecond(), used );
805878
}
879+
880+
if ( o instanceof ITrinaryFunction )
881+
{
882+
final TrinaryFunction tf = ( TrinaryFunction )o;
883+
884+
if ( tf.getThird() instanceof Var )
885+
{
886+
final Var var = ( Var )tf.getThird();
887+
if ( var.name == this.varName )
888+
{
889+
var.setScrap( this.scrap );
890+
used[0] = true;
891+
}
892+
} else
893+
{
894+
setupVars( tf.getThird(), used );
895+
}
896+
}
806897
}
807898
}
808899
}
@@ -887,19 +978,157 @@ public void setScrap( final RealType< ? > output ) {
887978
}
888979
}
889980

890-
/*
891-
static public interface BooleanFunction< O extends RealType< O > >
981+
static private abstract class Compare extends BinaryFunction
982+
{
983+
public Compare( final Object o1, final Object o2) {
984+
super( o1, o2 );
985+
}
986+
987+
abstract protected boolean compare( final RealType<?> t1, final RealType<?> t2 );
988+
989+
@SuppressWarnings("rawtypes")
990+
@Override
991+
public void eval( final RealType output ) {
992+
this.a.eval( this.scrap );
993+
this.b.eval( output );
994+
if ( this.compare( this.scrap, output ) )
995+
output.setOne();
996+
else
997+
output.setZero();
998+
}
999+
1000+
@SuppressWarnings("rawtypes")
1001+
@Override
1002+
public void eval( final RealType output, final Localizable loc) {
1003+
this.a.eval( this.scrap, loc );
1004+
this.b.eval( output, loc );
1005+
if ( this.compare( this.scrap, output ) )
1006+
output.setOne();
1007+
else
1008+
output.setZero();
1009+
}
1010+
}
1011+
1012+
static private final class Equal extends Compare
8921013
{
893-
public boolean eval( final O output );
1014+
public Equal( final Object o1, final Object o2) {
1015+
super( o1, o2 );
1016+
}
8941017

895-
public boolean eval( final O output, final Localizable loc );
1018+
@SuppressWarnings({ "rawtypes", "unchecked" })
1019+
public final boolean compare( final RealType t1, final RealType t2 )
1020+
{
1021+
return 0 == t1.compareTo( t2 );
1022+
}
1023+
1024+
@Override
1025+
public Equal copy() {
1026+
final Equal copy = new Equal( this.a.copy(), this.b.copy() );
1027+
copy.setScrap( this.scrap );
1028+
return copy;
1029+
}
8961030
}
8971031

898-
static public class Equals< O extends RealType O > extends BooleanFunction< O >
1032+
static private final class NotEqual extends Compare
8991033
{
1034+
public NotEqual( final Object o1, final Object o2) {
1035+
super( o1, o2 );
1036+
}
9001037

1038+
@SuppressWarnings({ "rawtypes", "unchecked" })
1039+
public final boolean compare( final RealType t1, final RealType t2 )
1040+
{
1041+
return 0 != t1.compareTo( t2 );
1042+
}
1043+
1044+
@Override
1045+
public NotEqual copy() {
1046+
final NotEqual copy = new NotEqual( this.a.copy(), this.b.copy() );
1047+
copy.setScrap( this.scrap );
1048+
return copy;
1049+
}
1050+
}
1051+
1052+
static private final class LessThan extends Compare
1053+
{
1054+
public LessThan( final Object o1, final Object o2) {
1055+
super( o1, o2 );
1056+
}
9011057

902-
... TODO Equals, LessThan, GreaterThan
1058+
@SuppressWarnings({ "rawtypes", "unchecked" })
1059+
public final boolean compare( final RealType t1, final RealType t2 )
1060+
{
1061+
return -1 == t1.compareTo( t2 );
1062+
}
1063+
1064+
@Override
1065+
public LessThan copy() {
1066+
final LessThan copy = new LessThan( this.a.copy(), this.b.copy() );
1067+
copy.setScrap( this.scrap );
1068+
return copy;
1069+
}
1070+
}
1071+
1072+
static private final class GreaterThan extends Compare
1073+
{
1074+
public GreaterThan( final Object o1, final Object o2) {
1075+
super(o1, o2);
1076+
}
1077+
1078+
@SuppressWarnings({ "rawtypes", "unchecked" })
1079+
public final boolean compare( final RealType t1, final RealType t2 )
1080+
{
1081+
return 1 == t1.compareTo( t2 );
1082+
}
1083+
1084+
@Override
1085+
public GreaterThan copy() {
1086+
final GreaterThan copy = new GreaterThan( this.a.copy(), this.b.copy() );
1087+
copy.setScrap( this.scrap );
1088+
return copy;
1089+
}
1090+
}
1091+
1092+
static private final class If extends TrinaryFunction
1093+
{
1094+
public If( final Object o1, final Object o2, final Object o3 )
1095+
{
1096+
super( o1, o2, o3 );
1097+
}
1098+
1099+
@Override
1100+
public final void eval( final RealType<?> output ) {
1101+
this.a.eval( this.scrap );
1102+
if ( 0.0f != this.scrap.getRealFloat() )
1103+
{
1104+
// Then
1105+
this.b.eval( output );
1106+
} else
1107+
{
1108+
// Else
1109+
this.c.eval( output );
1110+
}
1111+
}
1112+
1113+
@Override
1114+
public final void eval( final RealType<?> output, final Localizable loc ) {
1115+
this.a.eval( this.scrap, loc );
1116+
if ( 0.0f != this.scrap.getRealFloat() )
1117+
{
1118+
// Then
1119+
this.b.eval( output, loc );
1120+
} else
1121+
{
1122+
// Else
1123+
this.c.eval( output, loc );
1124+
}
1125+
}
1126+
1127+
@Override
1128+
public If copy() {
1129+
final If copy = new If( this.a.copy(), this.b.copy(), this.c.copy() );
1130+
copy.setScrap( this.scrap );
1131+
return copy;
1132+
}
9031133
}
904-
*/
9051134
}

0 commit comments

Comments
 (0)