changeset 8982:dc6bda6f9994

implement compound logical ops
author Jaroslav Hajek <highegg@gmail.com>
date Sat, 14 Mar 2009 23:08:08 +0100
parents ed5055b0a476
children e781ab1aee39
files liboctave/ChangeLog liboctave/mx-op-decl.h liboctave/mx-op-defs.h src/ChangeLog src/OPERATORS/op-b-bm.cc src/OPERATORS/op-bm-b.cc src/OPERATORS/op-bm-bm.cc src/OPERATORS/op-fm-fm.cc src/OPERATORS/op-int.h src/OPERATORS/op-m-m.cc src/ov.cc src/ov.h src/pt-cbinop.cc
diffstat 13 files changed, 211 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Sat Mar 14 19:42:50 2009 +0100
+++ b/liboctave/ChangeLog	Sat Mar 14 23:08:08 2009 +0100
@@ -1,3 +1,8 @@
+2009-03-14  Jaroslav Hajek  <highegg@gmail.com>
+
+	* mx-op-decl.h (*BOOL_OP_DECLS): Support compound binary ops.
+	* mx-op-defs.h (*BOOL_OP): Ditto. Optimize.
+
 2009-03-14  Jaroslav Hajek  <highegg@gmail.com>
 
 	* fNDArray.h (FloatMatrix::matrix_value): Fix return type.
--- a/liboctave/mx-op-decl.h	Sat Mar 14 19:42:50 2009 +0100
+++ b/liboctave/mx-op-decl.h	Sat Mar 14 23:08:08 2009 +0100
@@ -171,7 +171,9 @@
 
 #define NDS_BOOL_OP_DECLS(ND, S, API) \
   NDBOOL_OP_DECL (mx_el_and, ND, S, API); \
-  NDBOOL_OP_DECL (mx_el_or,  ND, S, API);
+  NDBOOL_OP_DECL (mx_el_or,  ND, S, API); \
+  NDBOOL_OP_DECL (mx_el_not_and, ND, S, API); \
+  NDBOOL_OP_DECL (mx_el_not_or,  ND, S, API);
 
 #define NDS_OP_DECLS(R, ND, S, API) \
   NDS_BIN_OP_DECLS (R, ND, S, API) \
@@ -196,7 +198,9 @@
 
 #define SND_BOOL_OP_DECLS(S, ND, API) \
   NDBOOL_OP_DECL (mx_el_and, S, ND, API); \
-  NDBOOL_OP_DECL (mx_el_or,  S, ND, API);
+  NDBOOL_OP_DECL (mx_el_or,  S, ND, API); \
+  NDBOOL_OP_DECL (mx_el_and_not, S, ND, API); \
+  NDBOOL_OP_DECL (mx_el_or_not,  S, ND, API);
 
 #define SND_OP_DECLS(R, S, ND, API) \
   SND_BIN_OP_DECLS (R, S, ND, API) \
@@ -221,7 +225,11 @@
 
 #define NDND_BOOL_OP_DECLS(ND1, ND2, API) \
   NDBOOL_OP_DECL (mx_el_and, ND1, ND2, API); \
-  NDBOOL_OP_DECL (mx_el_or,  ND1, ND2, API);
+  NDBOOL_OP_DECL (mx_el_or,  ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_and_not, ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_or_not,  ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_not_and, ND1, ND2, API); \
+  NDBOOL_OP_DECL (mx_el_not_or,  ND1, ND2, API);
 
 #define NDND_OP_DECLS(R, ND1, ND2, API) \
   NDND_BIN_OP_DECLS (R, ND1, ND2, API) \
--- a/liboctave/mx-op-defs.h	Sat Mar 14 19:42:50 2009 +0100
+++ b/liboctave/mx-op-defs.h	Sat Mar 14 23:08:08 2009 +0100
@@ -492,18 +492,16 @@
   NDS_CMP_OP2 (mx_el_eq, ==, ND,    , S,   , SPEC1, SPEC2) \
   NDS_CMP_OP2 (mx_el_ne, !=, ND,    , S,   , SPEC1, SPEC2)
 
-#define NDS_BOOL_OP(F, OP, ND, S, LHS_ZERO, RHS_ZERO) \
+#define NDS_BOOL_OP(F, EQ, OP, ND, S, LHS_ZERO, RHS_ZERO) \
   boolNDArray \
   F (const ND& m, const S& s) \
   { \
-    boolNDArray r; \
+    boolNDArray r (m.dims ()); \
  \
     octave_idx_type len = m.length (); \
  \
     if (len > 0) \
       { \
-        r.resize (m.dims ()); \
- \
 	if (xisnan (s)) \
 	  gripe_nan_to_logical_conversion (); \
 	else \
@@ -515,7 +513,7 @@
 		  return r; \
 		} \
 	      else \
-		r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \
+		r.xelem(i) = (m.elem(i) EQ LHS_ZERO) OP (s != RHS_ZERO); \
 	  } \
       } \
  \
@@ -523,8 +521,10 @@
   }
 
 #define NDS_BOOL_OPS2(ND, S, LHS_ZERO, RHS_ZERO) \
-  NDS_BOOL_OP (mx_el_and, &&, ND, S, LHS_ZERO, RHS_ZERO) \
-  NDS_BOOL_OP (mx_el_or,  ||, ND, S, LHS_ZERO, RHS_ZERO)
+  NDS_BOOL_OP (mx_el_and, !=, &&, ND, S, LHS_ZERO, RHS_ZERO) \
+  NDS_BOOL_OP (mx_el_or,  !=, ||, ND, S, LHS_ZERO, RHS_ZERO) \
+  NDS_BOOL_OP (mx_el_not_and, ==, &&, ND, S, LHS_ZERO, RHS_ZERO) \
+  NDS_BOOL_OP (mx_el_not_or,  ==, ||, ND, S, LHS_ZERO, RHS_ZERO)
 
 #define NDS_BOOL_OPS(ND, S, ZERO) \
   NDS_BOOL_OPS2(ND, S, ZERO, ZERO)
@@ -623,18 +623,16 @@
   SND_CMP_OP2 (mx_el_eq, ==, S,   , ND,    , SPEC1, SPEC2) \
   SND_CMP_OP2 (mx_el_ne, !=, S,   , ND,    , SPEC1, SPEC2)
 
-#define SND_BOOL_OP(F, OP, S, ND, LHS_ZERO, RHS_ZERO) \
+#define SND_BOOL_OP(F, OP, EQ, S, ND, LHS_ZERO, RHS_ZERO) \
   boolNDArray \
   F (const S& s, const ND& m) \
   { \
-    boolNDArray r; \
+    boolNDArray r (m.dims ()); \
  \
     octave_idx_type len = m.length (); \
  \
     if (len > 0) \
       { \
-        r.resize (m.dims ()); \
- \
 	if (xisnan (s)) \
 	  gripe_nan_to_logical_conversion (); \
 	else \
@@ -646,7 +644,7 @@
 		  return r; \
 		} \
 	      else \
-		r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \
+		r.xelem(i) = (s != LHS_ZERO) OP (m.elem(i) EQ RHS_ZERO); \
 	    } \
       } \
  \
@@ -654,8 +652,10 @@
   }
 
 #define SND_BOOL_OPS2(S, ND, LHS_ZERO, RHS_ZERO) \
-  SND_BOOL_OP (mx_el_and, &&, S, ND, LHS_ZERO, RHS_ZERO) \
-  SND_BOOL_OP (mx_el_or,  ||, S, ND, LHS_ZERO, RHS_ZERO)
+  SND_BOOL_OP (mx_el_and, &&, !=, S, ND, LHS_ZERO, RHS_ZERO) \
+  SND_BOOL_OP (mx_el_or,  ||, !=, S, ND, LHS_ZERO, RHS_ZERO) \
+  SND_BOOL_OP (mx_el_and_not, &&, ==, S, ND, LHS_ZERO, RHS_ZERO) \
+  SND_BOOL_OP (mx_el_or_not,  ||, ==, S, ND, LHS_ZERO, RHS_ZERO)
 
 #define SND_BOOL_OPS(S, ND, ZERO) \
   SND_BOOL_OPS2(S, ND, ZERO, ZERO)
@@ -722,7 +722,7 @@
   NDND_CMP_OP (mx_el_eq, ==, ND1,   , ND2,   ) \
   NDND_CMP_OP (mx_el_ne, !=, ND1,   , ND2,   )
 
-#define NDND_BOOL_OP(F, OP, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+#define NDND_BOOL_OP(F, EQ1, OP, EQ2, ND1, ND2, LHS_ZERO, RHS_ZERO) \
   boolNDArray \
   F (const ND1& m1, const ND2& m2) \
   { \
@@ -735,7 +735,7 @@
       { \
 	if (! m1_dims.all_zero ()) \
 	  { \
-	    r.resize (m1_dims); \
+	    r = boolNDArray (m1_dims); \
  \
 	    for (octave_idx_type i = 0; i < m1.length (); i++) \
 	      if (xisnan (m1.elem(i)) || xisnan (m2.elem(i))) \
@@ -744,7 +744,7 @@
 		  return r; \
 		} \
 	      else \
-		r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != RHS_ZERO); \
+		r.xelem(i) = (m1.elem(i) EQ1 LHS_ZERO) OP (m2.elem(i) EQ2 RHS_ZERO); \
 	  } \
       } \
     else \
@@ -754,8 +754,12 @@
   }
 
 #define NDND_BOOL_OPS2(ND1, ND2, LHS_ZERO, RHS_ZERO) \
-  NDND_BOOL_OP (mx_el_and, &&, ND1, ND2, LHS_ZERO, RHS_ZERO) \
-  NDND_BOOL_OP (mx_el_or,  ||, ND1, ND2, LHS_ZERO, RHS_ZERO)
+  NDND_BOOL_OP (mx_el_and, !=, &&, !=, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_or,  !=, ||, !=, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_and_not, != , &&, ==, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_or_not, !=, ||, ==, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_not_and, ==, &&, !=, ND1, ND2, LHS_ZERO, RHS_ZERO) \
+  NDND_BOOL_OP (mx_el_not_or,  ==, ||, !=, ND1, ND2, LHS_ZERO, RHS_ZERO)
 
 #define NDND_BOOL_OPS(ND1, ND2, ZERO) \
   NDND_BOOL_OPS2(ND1, ND2, ZERO, ZERO)
--- a/src/ChangeLog	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/ChangeLog	Sat Mar 14 23:08:08 2009 +0100
@@ -1,3 +1,17 @@
+2009-03-13  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov.h (octave_value::compound_binary_op): Support bool compound ops.
+	* ov.cc (do_binary_op, decompose_binary_op, binary_op_fcn_name):
+	Ditto.
+	* pt-cbinop.cc (strip_not, simplify_and_or_op): New funcs.
+	(maybe_compound_binary_expression): Support bool compound ops.
+	* OPERATORS/op-int.h: Support bool compound ops.
+	* OPERATORS/op-b-bm.cc: Ditto.
+	* OPERATORS/op-bm-b.cc: Ditto.
+	* OPERATORS/op-bm-bm.cc: Ditto.
+	* OPERATORS/op-fm-fm.cc: Ditto.
+	* OPERATORS/op-m-m.cc: Ditto.
+
 2009-03-13  Jaroslav Hajek  <highegg@gmail.com>
 
 	* xpow.cc (xpow (const NDArray&, double), xpow (const ComplexNDArray&, double),
--- a/src/OPERATORS/op-b-bm.cc	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/OPERATORS/op-b-bm.cc	Sat Mar 14 23:08:08 2009 +0100
@@ -43,6 +43,9 @@
 DEFNDBINOP_FN (el_and, bool, bool_matrix, bool, bool_array, mx_el_and)
 DEFNDBINOP_FN (el_or, bool, bool_matrix, bool, bool_array, mx_el_or)
 
+DEFNDBINOP_FN (el_and_not, bool, bool_matrix, bool, bool_array, mx_el_and_not)
+DEFNDBINOP_FN (el_or_not, bool, bool_matrix, bool, bool_array, mx_el_or_not)
+
 DEFNDCATOP_FN (b_bm, bool, bool_matrix, bool_array, bool_array, concat)
 DEFNDCATOP_FN (b_m, bool, matrix, array, array, concat)
 DEFNDCATOP_FN (s_bm, scalar, bool_matrix, array, array, concat)
--- a/src/OPERATORS/op-bm-b.cc	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/OPERATORS/op-bm-b.cc	Sat Mar 14 23:08:08 2009 +0100
@@ -52,6 +52,9 @@
 DEFNDBINOP_FN (el_and, bool_matrix, bool, bool_array, bool, mx_el_and)
 DEFNDBINOP_FN (el_or, bool_matrix, bool, bool_array, bool, mx_el_or)
 
+DEFNDBINOP_FN (el_not_and, bool_matrix, bool, bool_array, bool, mx_el_not_and)
+DEFNDBINOP_FN (el_not_or, bool_matrix, bool, bool_array, bool, mx_el_not_or)
+
 DEFNDCATOP_FN (bm_b, bool_matrix, bool, bool_array, bool_array, concat)
 DEFNDCATOP_FN (bm_s, bool_matrix, scalar, array, array, concat)
 DEFNDCATOP_FN (m_b, matrix, bool, array, array, concat)
--- a/src/OPERATORS/op-bm-bm.cc	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/OPERATORS/op-bm-bm.cc	Sat Mar 14 23:08:08 2009 +0100
@@ -79,6 +79,18 @@
 DEFNDBINOP_FN (el_or,  bool_matrix, bool_matrix, bool_array, bool_array,
 	       mx_el_or)
 
+DEFNDBINOP_FN (el_not_and, bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_not_and)
+
+DEFNDBINOP_FN (el_not_or,  bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_not_or)
+
+DEFNDBINOP_FN (el_and_not, bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_and_not)
+
+DEFNDBINOP_FN (el_or_not,  bool_matrix, bool_matrix, bool_array, bool_array,
+	       mx_el_or_not)
+
 DEFNDCATOP_FN (bm_bm, bool_matrix, bool_matrix, bool_array, bool_array, concat)
 DEFNDCATOP_FN (bm_m, bool_matrix, matrix, array, array, concat)
 DEFNDCATOP_FN (m_bm, matrix, bool_matrix, array, array, concat)
@@ -124,6 +136,10 @@
 
   INSTALL_BINOP (op_el_and, octave_bool_matrix, octave_bool_matrix, el_and);
   INSTALL_BINOP (op_el_or, octave_bool_matrix, octave_bool_matrix, el_or);
+  INSTALL_BINOP (op_el_not_and, octave_bool_matrix, octave_bool_matrix, el_not_and);
+  INSTALL_BINOP (op_el_not_or, octave_bool_matrix, octave_bool_matrix, el_not_or);
+  INSTALL_BINOP (op_el_and_not, octave_bool_matrix, octave_bool_matrix, el_and_not);
+  INSTALL_BINOP (op_el_or_not, octave_bool_matrix, octave_bool_matrix, el_or_not);
 
   INSTALL_CATOP (octave_bool_matrix, octave_bool_matrix, bm_bm);
   INSTALL_CATOP (octave_bool_matrix, octave_matrix, bm_m);
--- a/src/OPERATORS/op-fm-fm.cc	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/OPERATORS/op-fm-fm.cc	Sat Mar 14 23:08:08 2009 +0100
@@ -141,6 +141,16 @@
 	       float_array, mx_el_and)
 DEFNDBINOP_FN (el_or,  float_matrix, float_matrix, float_array, 
 	       float_array, mx_el_or)
+DEFNDBINOP_FN (el_not_and, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_not_and)
+DEFNDBINOP_FN (el_not_or,  float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_not_or)
+DEFNDBINOP_FN (el_and_not, float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_and_not)
+DEFNDBINOP_FN (el_or_not,  float_matrix, float_matrix, float_array, 
+	       float_array, mx_el_or_not)
+
+
 
 DEFNDCATOP_FN (fm_fm, float_matrix, float_matrix, float_array, 
 	       float_array, concat)
--- a/src/OPERATORS/op-int.h	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/OPERATORS/op-int.h	Sat Mar 14 23:08:08 2009 +0100
@@ -407,7 +407,9 @@
 
 #define OCTAVE_SM_INT_BOOL_OPS(PFX, TS, TM) \
   DEFNDBINOP_FN (PFX ## _el_and, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_and) \
-  DEFNDBINOP_FN (PFX ## _el_or,  TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_or)
+  DEFNDBINOP_FN (PFX ## _el_or,  TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_or) \
+  DEFNDBINOP_FN (PFX ## _el_and_not, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_and_not) \
+  DEFNDBINOP_FN (PFX ## _el_or_not,  TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, mx_el_or_not)
 
 #define OCTAVE_SM_POW_OPS(T1, T2) \
   octave_value \
@@ -575,7 +577,9 @@
 
 #define OCTAVE_MS_INT_BOOL_OPS(PFX, TM, TS) \
   DEFNDBINOP_FN (PFX ## _el_and, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_and) \
-  DEFNDBINOP_FN (PFX ## _el_or, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_or)
+  DEFNDBINOP_FN (PFX ## _el_or, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_or) \
+  DEFNDBINOP_FN (PFX ## _el_not_and, TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_not_and) \
+  DEFNDBINOP_FN (PFX ## _el_not_or,  TM ## matrix, TS ## scalar, TM ## array, TS ## scalar, mx_el_not_or)
 
 #define OCTAVE_MS_INT_ASSIGN_OPS(PFX, TM, TS, TE) \
   DEFNDASSIGNOP_FN (PFX ## _assign, TM ## matrix, TS ## scalar, TM ## scalar, assign)
@@ -734,7 +738,11 @@
 
 #define OCTAVE_MM_INT_BOOL_OPS(PFX, T1, T2) \
   DEFNDBINOP_FN (PFX ## _el_and, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_and) \
-  DEFNDBINOP_FN (PFX ## _el_or,  T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_or)
+  DEFNDBINOP_FN (PFX ## _el_or,  T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_or) \
+  DEFNDBINOP_FN (PFX ## _el_not_and, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_not_and) \
+  DEFNDBINOP_FN (PFX ## _el_not_or,  T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_not_or) \
+  DEFNDBINOP_FN (PFX ## _el_and_not, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_and_not) \
+  DEFNDBINOP_FN (PFX ## _el_or_not,  T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## array, mx_el_or_not)
 
 #define OCTAVE_MM_INT_ASSIGN_OPS(PFX, TLHS, TRHS, TE) \
   DEFNDASSIGNOP_FN (PFX ## _assign, TLHS ## matrix, TRHS ## matrix, TLHS ## array, assign)
@@ -978,7 +986,9 @@
 
 #define OCTAVE_INSTALL_SM_INT_BOOL_OPS(PFX, T1, T2) \
   INSTALL_BINOP (op_el_and, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_and); \
-  INSTALL_BINOP (op_el_or, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_or);
+  INSTALL_BINOP (op_el_or, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_or); \
+  INSTALL_BINOP (op_el_and_not, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_and_not); \
+  INSTALL_BINOP (op_el_or_not, octave_ ## T1 ## scalar, octave_ ## T2 ## matrix, PFX ## _el_or_not);
 
 #define OCTAVE_INSTALL_SM_INT_OPS(TYPE) \
   OCTAVE_INSTALL_SM_INT_ARITH_OPS (sm, TYPE ## _, TYPE ## _) \
@@ -1028,7 +1038,9 @@
 
 #define OCTAVE_INSTALL_MS_INT_BOOL_OPS(PFX, T1, T2) \
   INSTALL_BINOP (op_el_and, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_and); \
-  INSTALL_BINOP (op_el_or, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_or);
+  INSTALL_BINOP (op_el_or, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_or); \
+  INSTALL_BINOP (op_el_not_and, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_not_and); \
+  INSTALL_BINOP (op_el_not_or, octave_ ## T1 ## matrix, octave_ ## T2 ## scalar, PFX ## _el_not_or);
 
 #define OCTAVE_INSTALL_MS_INT_ASSIGN_OPS(PFX, TLHS, TRHS) \
   INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## scalar, PFX ## _assign)
@@ -1087,7 +1099,11 @@
 
 #define OCTAVE_INSTALL_MM_INT_BOOL_OPS(PFX, T1, T2) \
   INSTALL_BINOP (op_el_and, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_and); \
-  INSTALL_BINOP (op_el_or, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_or);
+  INSTALL_BINOP (op_el_or, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_or); \
+  INSTALL_BINOP (op_el_not_and, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_not_and); \
+  INSTALL_BINOP (op_el_not_or, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_not_or); \
+  INSTALL_BINOP (op_el_and_not, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_and_not); \
+  INSTALL_BINOP (op_el_or_not, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _el_or_not);
 
 #define OCTAVE_INSTALL_MM_INT_ASSIGN_OPS(PFX, TLHS, TRHS) \
   INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## matrix, PFX ## _assign)
--- a/src/OPERATORS/op-m-m.cc	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/OPERATORS/op-m-m.cc	Sat Mar 14 23:08:08 2009 +0100
@@ -125,6 +125,11 @@
 
 DEFNDBINOP_FN (el_and, matrix, matrix, array, array, mx_el_and)
 DEFNDBINOP_FN (el_or,  matrix, matrix, array, array, mx_el_or)
+DEFNDBINOP_FN (el_not_and, matrix, matrix, array, array, mx_el_not_and)
+DEFNDBINOP_FN (el_not_or,  matrix, matrix, array, array, mx_el_not_or)
+DEFNDBINOP_FN (el_and_not, matrix, matrix, array, array, mx_el_and_not)
+DEFNDBINOP_FN (el_or_not,  matrix, matrix, array, array, mx_el_or_not)
+
 
 DEFNDCATOP_FN (m_m, matrix, matrix, array, array, concat)
 
--- a/src/ov.cc	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/ov.cc	Sat Mar 14 23:08:08 2009 +0100
@@ -377,6 +377,22 @@
       retval = "timesherm";
       break;
 
+    case op_el_and_not:
+      retval = "andnot";
+      break;
+
+    case op_el_or_not:
+      retval = "ornot";
+      break;
+
+    case op_el_not_and:
+      retval = "notand";
+      break;
+
+    case op_el_not_or:
+      retval = "notor";
+      break;
+
     default:
       break;
     }
@@ -1903,6 +1919,26 @@
                              v1,
                              do_unary_op (octave_value::op_hermitian, v2));
       break;
+    case octave_value::op_el_not_and:
+      retval = do_binary_op (octave_value::op_el_and,
+                             do_unary_op (octave_value::op_not, v1),
+                             v2);
+      break;
+    case octave_value::op_el_not_or:
+      retval = do_binary_op (octave_value::op_el_or,
+                             do_unary_op (octave_value::op_not, v1),
+                             v2);
+      break;
+    case octave_value::op_el_and_not:
+      retval = do_binary_op (octave_value::op_el_and,
+                             v1,
+                             do_unary_op (octave_value::op_not, v2));
+      break;
+    case octave_value::op_el_or_not:
+      retval = do_binary_op (octave_value::op_el_or,
+                             v1,
+                             do_unary_op (octave_value::op_not, v2));
+      break;
     default:
       error ("invalid compound operator");
       break;
--- a/src/ov.h	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/ov.h	Sat Mar 14 23:08:08 2009 +0100
@@ -112,6 +112,10 @@
     op_mul_trans,
     op_herm_mul,      
     op_mul_herm,
+    op_el_not_and,
+    op_el_not_or,
+    op_el_and_not,
+    op_el_or_not,
     num_compound_binary_ops,
     unknown_compound_binary_op
   };
--- a/src/pt-cbinop.cc	Sat Mar 14 19:42:50 2009 +0100
+++ b/src/pt-cbinop.cc	Sat Mar 14 23:08:08 2009 +0100
@@ -57,6 +57,27 @@
     return octave_value::unknown_unary_op;
 }
 
+static octave_value::unary_op 
+strip_not (tree_expression *&exp)
+{
+  if (exp->is_unary_expression ())
+    {
+      tree_unary_expression *uexp = 
+        dynamic_cast<tree_unary_expression *> (exp);
+
+      octave_value::unary_op op = uexp->op_type ();
+
+      if (op == octave_value::op_not)
+	exp = uexp->operand ();
+      else
+	op = octave_value::unknown_unary_op;
+
+      return op;
+    }
+  else
+    return octave_value::unknown_unary_op;
+}
+
 // Possibly convert multiplication to trans_mul, mul_trans, herm_mul,
 // or mul_herm.
 
@@ -85,6 +106,39 @@
   return retop;
 }
 
+// Possibly contract and/or with negation.
+
+static octave_value::compound_binary_op
+simplify_and_or_op (tree_expression *&a, tree_expression *&b, octave_value::binary_op op)
+{
+  octave_value::compound_binary_op retop;
+  octave_value::unary_op opa = strip_not (a);
+
+  if (opa == octave_value::op_not)
+    {
+      if (op == octave_value::op_el_and)
+        retop = octave_value::op_el_not_and;
+      else if (op == octave_value::op_el_or)
+        retop = octave_value::op_el_not_or;
+    }
+  else
+    {
+      octave_value::unary_op opb = strip_not (b);
+
+      if (opb == octave_value::op_not)
+        {
+          if (op == octave_value::op_el_and)
+            retop = octave_value::op_el_and_not;
+          else if (op == octave_value::op_el_or)
+            retop = octave_value::op_el_or_not;
+        }
+      else
+        retop = octave_value::unknown_compound_binary_op;
+    }
+
+  return retop;
+}
+
 tree_binary_expression *
 maybe_compound_binary_expression (tree_expression *a, tree_expression *b,
                                   int l, int c, octave_value::binary_op t)
@@ -98,6 +152,11 @@
       ct = simplify_mul_op (ca, cb);
       break;
 
+    case octave_value::op_el_and:
+    case octave_value::op_el_or:
+      ct = simplify_and_or_op (ca, cb, t);
+      break;
+
     default:
       ct = octave_value::unknown_compound_binary_op;
       break;