Reputation: 13
I am trying to solve a set of linear simultaneous equations using linsolve in Sympy over a range of values. For simplicity I am showing below what I have been trying to do using simple equations.
from sympy import symbols, linsolve, IndexedBase
m = 2
n = symbols('n', integer=True)
x, y = symbols('x, y', cls=IndexedBase)
for n in range (0, m+1):
E1 = 2*x[n] + 5*y[n] - 33 + 2*n
E2 = x[n] + 3*y[n] - 19 + 4*n
sol = linsolve([E1, E2], [x[n], y[n]])
(x[n], y[n]) = tuple(*sol)
This returns an error "'IndexedBase' object does not support item assignment". How can I map the solution values to the indexed symbols so that I will be able to use them later in the code (e.g., take the sum of all x values (x[0] + x[1] + x[2])? I am looking for a robust solution as for the real equations the value of m can be around 500.
Upvotes: 1
Views: 397
Reputation:
SymPy objects are immutable; one cannot attach numeric data to them. "x" is always just that, a symbol "x"; and "x[2]" is an indexed symbol "x[2]". They do not get associated with any numeric values. To store solutions, use a list of tuples or a dictionary (or list of dictionaries), whichever is more convenient.
solutions = {}
for n in range(0, m+1):
E1 = 2*x[n] + 5*y[n] - 33 + 2*n
E2 = x[n] + 3*y[n] - 19 + 4*n
sol = linsolve([E1, E2], [x[n], y[n]])
solutions.update(dict(zip([x[n], y[n]], *sol)))
print(solutions)
This prints {x[0]: 4, y[0]: 5, x[1]: 18, y[1]: -1, x[2]: 32, y[2]: -7}
. You can then use this dictionary in subs
:
expr = x[0] + 3*y[2]
print(expr.subs(solutions)) # -17
Upvotes: 1