简体   繁体   中英

How to declare relations between SymPy symbols

I have the following code that's supposed to order a NumPy "matrix" based on the order of the elements of the first "row". I am dealing with SymPy variables, which do not have a straightforward ordering to them.

import sympy as sym
import numpy as np

a = sym.symbols("a", positive=True)
b = sym.symbols("b")

arr_num = np.array([[1.5, 3, 0], [.5, .4, .1]])
arr_sym_a = np.array([[a, 2*a, 0],[.5, .4, .1]])
arr_sym_b = np.array([[a, b, 0],[.5, .4, .1]])

def order(array):
    return array[:, np.argsort(array)][:, 0]


print(order(arr_num))
print(order(arr_sym_a))
print(order(arr_sym_b))

For arr_num, I get the expected output:

[[0.  1.5  3. ]
[0.1 0.5 0.4]]

As seen above, I already know how to declare a variable positive so that the np.argsort knows to order 0<a<2*a , and I do get the expected output for order(arr_sym_a) :

[[0 a 2*a]
 [0.1 0.5 0.4]]

The question is whether there is a similar way to notify SymPy that b>a and then get

[[0 a b]
 [0.1 0.5 0.4]]

So far I have been getting the error message " TypeError: cannot determine truth value of Relational ", which is not surprising since there is no way for np.argsort to tell that a>b .

Thanks

With symbols, the array is object dtype:

In [117]: arr_sym_a
Out[117]: 
array([[a, 2*a, 0],
       [0.5, 0.4, 0.1]], dtype=object)


In [119]: np.argsort(arr_sym_a)
Out[119]: 
array([[2, 0, 1],
       [2, 1, 0]])

So a row of the array can be sorted:

In [121]: np.sort(arr_sym_a[0])
Out[121]: array([0, a, 2*a], dtype=object)

Individual terms can be ordered:

In [122]: arr_sym_a[0,0]>arr_sym_a[0,1]
Out[122]: False

In [123]: arr_sym_a[0,1]>arr_sym_a[0,2]
Out[123]: True

In [124]: a>2*a
Out[124]: False

In [125]: 0>a
Out[125]: False

But:

In [126]: arr_sym_b[0,0]>arr_sym_b[0,1]
Out[126]: a > b

this is a sympy.Relational , which does not have a simple True/False value

In [127]: bool(arr_sym_b[0,0]>arr_sym_b[0,1])
TypeError: cannot determine truth value of Relational

This is analogous to the array ambiguity error:

In [128]: bool(np.array([1,2])>0)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Off hand I don't see anything in https://docs.sympy.org/latest/modules/core.html#module-sympy.core.relational

to help, but there might be a way of declaring this relational to be True or False.

So while symbols can be used in numpy arrays, the result is an object dtype array. Operations on such an array occur as list-comprehension speed, and are highly dependent on what methods are defined to the individual elements.

sympy.lambdify is the best way to create a numpy compatible function from a sympy expression. But even that is not foolproof.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM