Minor MATLAB/Octave logical incompatibility

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Minor MATLAB/Octave logical incompatibility

Randy Gober
Minor MATLAB/Octave logical incompatibility

Looking at the online MATLAB documentation for the logical command, I noticed this tidbit:


"Most arithmetic operations remove the logicalness from an array. For example, adding zero to a logical array removes its logical characteristic. A = +A is the easiest way to convert a logical array, A, to a numeric double array."

(From http://www.mathworks.com/access/helpdesk/help/techdoc/ref/logical.html)

However, Octave keeps the type as bool in this case, in the just realest 2.1.58, we have:

octave:1> A=logical(eye(3));
octave:2> islogical(A)
ans = 1
octave:3> A=+A;
octave:4> islogical(A)
ans = 1
octave:5> islogical(eye(3))
ans = 0

(also verified using 'whos')

I am not sure if this is a bug or a feature, but it is different from the way MATLAB does it.




Reply | Threaded
Open this post in threaded view
|

Minor MATLAB/Octave logical incompatibility

John W. Eaton-6
On  5-Sep-2004, Randy Gober <[hidden email]> wrote:

| Looking at the online MATLAB documentation for the logical command, I
| noticed this tidbit:
|
|
| "Most arithmetic operations remove the logicalness from an array. For
| example, adding zero to a logical array removes its logical characteristic.
| A = +A is the easiest way to convert a logical array, A, to a numeric double
| array."
| (From
| http://www.mathworks.com/access/helpdesk/help/techdoc/ref/logical.html)
|
| However, Octave keeps the type as bool in this case, in the just realest
| 2.1.58, we have:
|
| octave:1> A=logical(eye(3));
| octave:2> islogical(A)
| ans = 1
| octave:3> A=+A;
| octave:4> islogical(A)
| ans = 1
| octave:5> islogical(eye(3))
| ans = 0
|
| (also verified using 'whos')
|
| I am not sure if this is a bug or a feature, but it is different from the
| way MATLAB does it.

Currently, Octave treats unary plus as a no-op in the parser.  Should
we change this?  It would mean that instead of having the parser
convert the unary plus to a no-op, a function to handle the unary plus
operation would have to be defined for every octave_value class that
needs unary plus.  Hmm.  I guess this may be needed anyway if we want
to support classes at the scripting language level which can overload
unary plus.

jwe


Reply | Threaded
Open this post in threaded view
|

Minor MATLAB/Octave logical incompatibility

John W. Eaton-6
On  6-Sep-2004, John W. Eaton <[hidden email]> wrote:

| Currently, Octave treats unary plus as a no-op in the parser.  Should
| we change this?  It would mean that instead of having the parser
| convert the unary plus to a no-op, a function to handle the unary plus
| operation would have to be defined for every octave_value class that
| needs unary plus.  Hmm.  I guess this may be needed anyway if we want
| to support classes at the scripting language level which can overload
| unary plus.

Here are the changes required to make unary + work as you expect.
Note that this means unary + will no longer work for other
user-defined data types until they are similarly updated.

jwe



src/ChangeLog:

2004-09-06  John W. Eaton  <[hidden email]>

        * version.h (OCTAVE_API_VERSION): Now api-v10.

        * OPERATORS/op-b-b.cc, OPERATORS/op-bm-bm.cc: Define and install
        unary plus and unary minus operators.

        * OPERATORS/op-int.h, OPERATORS/op-cm-cm.cc,
        OPERATORS/op-cs-cs.cc, OPERATORS/op-m-m.cc, OPERATORS/op-range.cc:
        Define and install unary plus operator.

        * ov.cc (unary_op_as_string): Handle op_uplus too.

        * parse.y (prefix_expr): Build unary plus op here instead of
        converting to no-op.
        (make_prefix_op): Accept op_uplus.


Index: src/ov.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/ov.cc,v
retrieving revision 1.113
diff -u -r1.113 ov.cc
--- a/src/ov.cc 31 Aug 2004 05:30:47 -0000 1.113
+++ b/src/ov.cc 6 Sep 2004 15:42:50 -0000
@@ -134,6 +134,10 @@
       retval = "!";
       break;
 
+    case op_uplus:
+      retval = "+";
+      break;
+
     case op_uminus:
       retval = "-";
       break;
Index: src/ov.h
===================================================================
RCS file: /usr/local/cvsroot/octave/src/ov.h,v
retrieving revision 1.110
diff -u -r1.110 ov.h
--- a/src/ov.h 1 Sep 2004 21:24:54 -0000 1.110
+++ b/src/ov.h 6 Sep 2004 15:42:50 -0000
@@ -100,6 +100,7 @@
   enum unary_op
   {
     op_not,
+    op_uplus,
     op_uminus,
     op_transpose,
     op_hermitian,
Index: src/parse.y
===================================================================
RCS file: /usr/local/cvsroot/octave/src/parse.y,v
retrieving revision 1.221
diff -u -r1.221 parse.y
--- a/src/parse.y 6 Aug 2004 03:17:13 -0000 1.221
+++ b/src/parse.y 6 Sep 2004 15:42:50 -0000
@@ -804,7 +804,7 @@
  | EXPR_NOT prefix_expr %prec UNARY
   { $$ = make_prefix_op (EXPR_NOT, $2, $1); }
  | '+' prefix_expr %prec UNARY
-  { $$ = $2; }
+  { $$ = make_prefix_op ('+', $2, $1); }
  | '-' prefix_expr %prec UNARY
   { $$ = make_prefix_op ('-', $2, $1); }
  ;
@@ -2217,6 +2217,10 @@
       t = octave_value::op_not;
       break;
 
+    case '+':
+      t = octave_value::op_uplus;
+      break;
+
     case '-':
       t = octave_value::op_uminus;
       break;
Index: src/version.h
===================================================================
RCS file: /usr/local/cvsroot/octave/src/version.h,v
retrieving revision 1.70
diff -u -r1.70 version.h
--- a/src/version.h 2 Sep 2004 01:28:09 -0000 1.70
+++ b/src/version.h 6 Sep 2004 15:42:50 -0000
@@ -25,7 +25,7 @@
 
 #define OCTAVE_VERSION "2.1.58"
 
-#define OCTAVE_API_VERSION "api-v9"
+#define OCTAVE_API_VERSION "api-v10"
 
 #define OCTAVE_COPYRIGHT \
   "Copyright (C) 2004 John W. Eaton."
Index: src/OPERATORS/op-b-b.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-b-b.cc,v
retrieving revision 1.11
diff -u -r1.11 op-b-b.cc
--- a/src/OPERATORS/op-b-b.cc 4 Sep 2004 01:16:28 -0000 1.11
+++ b/src/OPERATORS/op-b-b.cc 6 Sep 2004 15:42:51 -0000
@@ -45,6 +45,19 @@
 // scalar unary ops.
 
 DEFUNOP_OP (not, bool, !)
+
+UNOPDECL (uplus, a)
+{
+  CAST_UNOP_ARG (const octave_bool&);
+  return octave_value (v.double_value ());
+}
+
+UNOPDECL (uminus, a)
+{
+  CAST_UNOP_ARG (const octave_bool&);
+  return octave_value (- v.double_value ());
+}
+
 DEFUNOP_OP (transpose, bool, /* no-op */)
 DEFUNOP_OP (hermitian, bool, /* no-op */)
 
@@ -63,6 +76,8 @@
 install_b_b_ops (void)
 {
   INSTALL_UNOP (op_not, octave_bool, not);
+  INSTALL_UNOP (op_uplus, octave_bool, uplus);
+  INSTALL_UNOP (op_uminus, octave_bool, uminus);
   INSTALL_UNOP (op_transpose, octave_bool, transpose);
   INSTALL_UNOP (op_hermitian, octave_bool, hermitian);
 
Index: src/OPERATORS/op-bm-bm.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-bm-bm.cc,v
retrieving revision 1.15
diff -u -r1.15 op-bm-bm.cc
--- a/src/OPERATORS/op-bm-bm.cc 4 Sep 2004 01:16:28 -0000 1.15
+++ b/src/OPERATORS/op-bm-bm.cc 6 Sep 2004 15:42:51 -0000
@@ -41,6 +41,8 @@
 // unary bool matrix ops.
 
 DEFNDUNOP_OP (not, bool_matrix, bool_array, !)
+DEFNDUNOP_OP (uplus, bool_matrix, array, +)
+DEFNDUNOP_OP (uminus, bool_matrix, array, -)
 
 DEFUNOP (transpose, bool_matrix)
 {
@@ -76,6 +78,8 @@
 install_bm_bm_ops (void)
 {
   INSTALL_UNOP (op_not, octave_bool_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_bool_matrix, uplus);
+  INSTALL_UNOP (op_uminus, octave_bool_matrix, uminus);
   INSTALL_UNOP (op_transpose, octave_bool_matrix, transpose);
   INSTALL_UNOP (op_hermitian, octave_bool_matrix, transpose);
 
Index: src/OPERATORS/op-cm-cm.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-cm-cm.cc,v
retrieving revision 1.12
diff -u -r1.12 op-cm-cm.cc
--- a/src/OPERATORS/op-cm-cm.cc 23 Jul 2004 19:01:23 -0000 1.12
+++ b/src/OPERATORS/op-cm-cm.cc 6 Sep 2004 15:42:51 -0000
@@ -40,6 +40,7 @@
 // unary complex matrix ops.
 
 DEFNDUNOP_OP (not, complex_matrix, complex_array, !)
+DEFNDUNOP_OP (uplus, complex_matrix, complex_array, /* no-op */)
 DEFNDUNOP_OP (uminus, complex_matrix, complex_array, -)
 
 DEFUNOP (transpose, complex_matrix)
@@ -116,6 +117,7 @@
 install_cm_cm_ops (void)
 {
   INSTALL_UNOP (op_not, octave_complex_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_complex_matrix, uplus);
   INSTALL_UNOP (op_uminus, octave_complex_matrix, uminus);
   INSTALL_UNOP (op_transpose, octave_complex_matrix, transpose);
   INSTALL_UNOP (op_hermitian, octave_complex_matrix, hermitian);
Index: src/OPERATORS/op-cs-cs.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-cs-cs.cc,v
retrieving revision 1.10
diff -u -r1.10 op-cs-cs.cc
--- a/src/OPERATORS/op-cs-cs.cc 23 Jul 2004 19:01:23 -0000 1.10
+++ b/src/OPERATORS/op-cs-cs.cc 6 Sep 2004 15:42:51 -0000
@@ -47,6 +47,7 @@
   return octave_value (v.complex_value () == 0.0);
 }
 
+DEFUNOP_OP (uplus, complex, /* no-op */)
 DEFUNOP_OP (uminus, complex, -)
 DEFUNOP_OP (transpose, complex, /* no-op */)
 
@@ -182,6 +183,7 @@
 install_cs_cs_ops (void)
 {
   INSTALL_UNOP (op_not, octave_complex, not);
+  INSTALL_UNOP (op_uplus, octave_complex, uplus);
   INSTALL_UNOP (op_uminus, octave_complex, uminus);
   INSTALL_UNOP (op_transpose, octave_complex, transpose);
   INSTALL_UNOP (op_hermitian, octave_complex, hermitian);
Index: src/OPERATORS/op-int.h
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-int.h,v
retrieving revision 1.6
diff -u -r1.6 op-int.h
--- a/src/OPERATORS/op-int.h 4 Sep 2004 01:16:28 -0000 1.6
+++ b/src/OPERATORS/op-int.h 6 Sep 2004 15:42:51 -0000
@@ -38,6 +38,7 @@
   /* scalar unary ops. */  \
  \
   DEFUNOP_OP (s_not, TYPE ## _scalar, !) \
+  DEFUNOP_OP (s_uplus, TYPE ## _scalar, /* no-op */) \
   DEFUNOP_OP (s_uminus, TYPE ## _scalar, -) \
   DEFUNOP_OP (s_transpose, TYPE ## _scalar, /* no-op */) \
   DEFUNOP_OP (s_hermitian, TYPE ## _scalar, /* no-op */) \
@@ -346,6 +347,7 @@
   /* matrix unary ops. */ \
  \
   DEFNDUNOP_OP (m_not, TYPE ## _matrix, TYPE ## _array, !) \
+  DEFNDUNOP_OP (m_uplus, TYPE ## _matrix, TYPE ## _array, /* no-op */) \
   DEFNDUNOP_OP (m_uminus, TYPE ## _matrix, TYPE ## _array, -) \
  \
   DEFUNOP (m_transpose, TYPE ## _matrix) \
@@ -473,6 +475,7 @@
 
 #define OCTAVE_INSTALL_S_INT_UNOPS(TYPE) \
   INSTALL_UNOP (op_not, octave_ ## TYPE ## _scalar, s_not); \
+  INSTALL_UNOP (op_uplus, octave_ ## TYPE ## _scalar, s_uplus); \
   INSTALL_UNOP (op_uminus, octave_ ## TYPE ## _scalar, s_uminus); \
   INSTALL_UNOP (op_transpose, octave_ ## TYPE ## _scalar, s_transpose); \
   INSTALL_UNOP (op_hermitian, octave_ ## TYPE ## _scalar, s_hermitian); \
@@ -616,6 +619,7 @@
 
 #define OCTAVE_INSTALL_M_INT_UNOPS(TYPE) \
   INSTALL_UNOP (op_not, octave_ ## TYPE ## _matrix, m_not); \
+  INSTALL_UNOP (op_uplus, octave_ ## TYPE ## _matrix, m_uplus); \
   INSTALL_UNOP (op_uminus, octave_ ## TYPE ## _matrix, m_uminus); \
   INSTALL_UNOP (op_transpose, octave_ ## TYPE ## _matrix, m_transpose); \
   INSTALL_UNOP (op_hermitian, octave_ ## TYPE ## _matrix, m_transpose); \
Index: src/OPERATORS/op-m-m.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-m-m.cc,v
retrieving revision 1.16
diff -u -r1.16 op-m-m.cc
--- a/src/OPERATORS/op-m-m.cc 23 Jul 2004 19:01:23 -0000 1.16
+++ b/src/OPERATORS/op-m-m.cc 6 Sep 2004 15:42:51 -0000
@@ -40,6 +40,7 @@
 // matrix unary ops.
 
 DEFNDUNOP_OP (not, matrix, array, !)
+DEFNDUNOP_OP (uplus, matrix, array, /* no-op */)
 DEFNDUNOP_OP (uminus, matrix, array, -)
 
 DEFUNOP (transpose, matrix)
@@ -103,6 +104,7 @@
 install_m_m_ops (void)
 {
   INSTALL_UNOP (op_not, octave_matrix, not);
+  INSTALL_UNOP (op_uplus, octave_matrix, uplus);
   INSTALL_UNOP (op_uminus, octave_matrix, uminus);
   INSTALL_UNOP (op_transpose, octave_matrix, transpose);
   INSTALL_UNOP (op_hermitian, octave_matrix, transpose);
Index: src/OPERATORS/op-range.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-range.cc,v
retrieving revision 1.7
diff -u -r1.7 op-range.cc
--- a/src/OPERATORS/op-range.cc 23 Jul 2004 19:01:23 -0000 1.7
+++ b/src/OPERATORS/op-range.cc 6 Sep 2004 15:42:51 -0000
@@ -51,6 +51,7 @@
   return octave_value (! v.matrix_value());
 }
 
+DEFUNOP_OP (uplus, range, /* no-op */)
 DEFUNOP_OP (uminus, range, -)
 
 DEFUNOP (transpose, range)
@@ -80,6 +81,7 @@
 install_range_ops (void)
 {
   INSTALL_UNOP (op_not, octave_range, not);
+  INSTALL_UNOP (op_uplus, octave_range, uplus);
   INSTALL_UNOP (op_uminus, octave_range, uminus);
   INSTALL_UNOP (op_transpose, octave_range, transpose);
   INSTALL_UNOP (op_hermitian, octave_range, transpose);
Index: src/OPERATORS/op-s-s.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/OPERATORS/op-s-s.cc,v
retrieving revision 1.11
diff -u -r1.11 op-s-s.cc
--- a/src/OPERATORS/op-s-s.cc 23 Jul 2004 19:01:23 -0000 1.11
+++ b/src/OPERATORS/op-s-s.cc 6 Sep 2004 15:42:51 -0000
@@ -41,6 +41,7 @@
 // scalar unary ops.
 
 DEFUNOP_OP (not, scalar, !)
+DEFUNOP_OP (uplus, scalar, /* no-op */)
 DEFUNOP_OP (uminus, scalar, -)
 DEFUNOP_OP (transpose, scalar, /* no-op */)
 DEFUNOP_OP (hermitian, scalar, /* no-op */)