Problem
I am working with an arbitrary MxN numpy matrix where each element is a sympy expression, potentially with differing symbols. For the purposes of visualization, let's work with the following matrix test
import sympy as sp
import numpy as np
a,b,c=sp.symbols('a b c');
test=np.array([[a**2,a+b],[a*c+b,b/c]]);When run, test will look like:
In [25]: test
Out[25]:
array([[a**2, a + b], [a*c + b, b/c]], dtype=object)I would like to be able to replace one variable in this array with a number and return a new array that has the same dimensions as test but has replaced the specified variable with it's new value. For example, if I wanted to replace b with 2, the new array should look like:
array([[a**2, a + 2], [a*c + 2, 2/c]], dtype=object)Attempt at a Solution
I first tried to use the sympy function subs but I received the following error:
test.subs({b:2})
Traceback (most recent call last): File "<ipython-input-29-a9a04d63af37>", line 1, in <module> test.subs({b:2})
AttributeError: 'numpy.ndarray' object has no attribute 'subs'I looked at using lambdify but I believe that it returns a numeric lambda expression which isn't what I want. I need a new symbolic expression, just one that doesn't depend on b anymore. I found some literature in the Wolfram Mathematica documentation under pattern matching that seems to be what I need but I can't figure out how to implement this in Python, or if it's even possible to do so. Any help would be greatly appreciated.
2 Answers
Just use sympy. No need for numpy, at least not for the substitution:
In [117]: import sympy
In [118]: a,b,c=sympy.symbols('a b c')
In [120]: M=sympy.Matrix([[a**2, a+b],[a*c+b, b/c]])
In [121]: M
Out[121]:
Matrix([
[ a**2, a + b],
[a*c + b, b/c]])
In [123]: M.subs({b:2})
Out[123]:
Matrix([
[ a**2, a + 2],
[a*c + 2, 2/c]]) 1 array is not an expression, therefore it has not the method subs
1