Omar
Omar

Reputation: 13

Map linsolve solutions to indexed symbols in Sympy

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

Answers (1)

user6655984
user6655984

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

Related Questions