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.