gnu-octave / symbolic

A Symbolic Package for Octave using SymPy
https://octave.sourceforge.io/symbolic/
GNU General Public License v3.0
160 stars 37 forks source link

piecewise: matlab compatibility issue for certain interval forms #1277

Open NRJank opened 1 year ago

NRJank commented 1 year ago

the following is matlab compatible but produces an error in Octave 8.3.0 with symbolic package 3.1.1:

>> pkg load symbolic
>> syms x
>> y = piecewise(-2<x<0, 2*x +1);
error: Python exception: TypeError: Can only compare inequalities with Expr
    occurred at line 14 of the Python code block:
    return _op(*_ins)
error: called from
    pycall_sympy__ at line 179 column 7
    elementwise_op at line 102 column 5
    ineq_helper at line 32 column 5
    lt at line 71 column 5
cbm755 commented 1 year ago

The real trouble here is -2 < x < 0, which gives the same error on its own.

I know Python allows these sorts of constructions. But does Octave?

Ignoring Symbolic, I get this:

x = 10
-2 < x < 8
ans = 1

I think what its done there is -2 < x is true. true is 1. 1 is less than 8.

Perhaps that doesn't exactly preclude overloading @sym/lt.m to somehow allow -2 < x < 0 to DTRT, but I'm a bit skeptical.

cbm755 commented 1 year ago

references:

https://github.com/sympy/sympy/issues/8541

https://docs.sympy.org/latest/modules/core.html#r137

(technically, it being impossible to support -2 < x < 0 directly in SymPy does not preclude us from doing it)


Workaround:

>> y = piecewise(and(-2 < x, x < 0), 2*x + 1)
y = (sym) {2⋅x + 1  for x > -2 ∧ x < 0
NRJank commented 1 year ago

not surprised that that's what happens in Octave. in Matlab you get the following for the lines that fail above:

>> syms x
>> y = piecewise(-2<x<0, 2*x +1)

y = 
piecewise(x in Dom::Interval(-2, 0), 2*x +1)

and for your interval test, i think your interpretation for non-symbolic is correct. I get the following if i play with the numbers:

>> x = 10;
>> class(x)
ans = 
     'double'
>> -2<x<8
ans = 
    logical
      1

>> x = -1;

>> -2<x<8
ans = 
    logical
      1

>> -2<x<0
ans = 
    logical
      0

not sure how, but it seems overloading the different equality operators may be necessary to enable that sort of interval notation.