Python/Sympy: solve equations with different values

1.6k Views Asked by At

I'm trying to solve these three equations:

a1 + a2 = b1
a2 + a3 = b2
b1 + b2 = c1

I generate values for three variables that are chosen randomly (disallowing the combination b1, b2, and c1), so I might have a1 = 5, a3 = 10, and c1 = 100, so I can solve that equation with sympy.

My problem is that I can't seem to transfer the random input to the sympy part of the code and loop over it.

a1, a2, a3, b1, b2, c1 = symbols('a1 a2 a3 b1 b2 c1')
solve([a1.subs(a1, 5) + a2 - b1, a2 + a3.subs (a3, 10) - b2, b1 + b2 - c1.subs (c1, 100)], (a1, a2, a3, b1, b2, c1))

This works when I assume a1, a3 and c1 as I mentioned in my example, but I choose those variables randomly beforehand. I've tried to create for-loops depending on which variables were chosen, but there are too many possible combinations of three variables, so I gave up.

2

There are 2 best solutions below

2
On BEST ANSWER

If I've correctly understood what you're asking, you can use Sympy's linsolve function to solve the equations symbolically first, then substitute in numbers afterwards. The key step is to tell linsolve which variables you want to solve for. I suggest using sets to separate the variables you're solving for from the ones you want to plug in values for. You might declare your variables like this:

all_vars = symbols('a1 a2 a3 b1 b2 c1')
# randomly choose which variables will have values
plug_in_for_vars = ...
solve_for_vars = tuple(set(all_vars) - set(plug_in_for_vars))

Then you can define your equations

equations = [a1 + a2 - b1, a2 + a3 - b2, b1 + b2 - c1]

and pass them and the chosen variables to linsolve

solution = linsolve(equations, solve_for_vars)

Then you can plug in the chosen values.

solution.subs({variable: value(variable) for variable in plug_in_for_vars})

Of course value(variable) is a proxy for whatever you do to determine the numeric values you want to plug in.

0
On

There are only 19 different ways to do this, so it's not too bad to just do this symbolically to see all possibilities:

from sympy import symbols, subsets, solve, Dict
v = a1, a2, a3, b1, b2, c1 = symbols('a1 a2 a3 b1 b2 c1')
eqs = (a1 + a2 - b1, a2 + a3 - b2, b1 + b2 - c1)
# we will not assign b1,b2,c1 so we will never solve for a1,a2,a3
ignore = set(v[:3])
for i in subsets(v, 3):
    if set(i) != ignore:
        subs = set(v)-set(i)
        sol = solve(eqs,i,dict=True)[0]
        print('replace',subs,'solve for',set(sol),':\n\t', sol)

The output is

replace {b2, c1, a3} solve for {a2, a1, b1} :
    {a1: a3 - 2*b2 + c1, a2: -a3 + b2, b1: -b2 + c1}
replace {c1, a3, b1} solve for {a2, b2, a1} :
    {a1: a3 + 2*b1 - c1, a2: -a3 - b1 + c1, b2: -b1 + c1}
replace {b2, a3, b1} solve for {a2, c1, a1} :
    {a1: a3 + b1 - b2, a2: -a3 + b2, c1: b1 + b2}
replace {a2, b2, c1} solve for {a1, a3, b1} :
    {a1: -a2 - b2 + c1, b1: -b2 + c1, a3: -a2 + b2}
replace {a2, c1, b1} solve for {b2, a1, a3} :
    {a1: -a2 + b1, a3: -a2 - b1 + c1, b2: -b1 + c1}
replace {a2, b2, b1} solve for {c1, a1, a3} :
    {a1: -a2 + b1, a3: -a2 + b2, c1: b1 + b2}
replace {a2, c1, a3} solve for {b2, a1, b1} :
    {a1: -2*a2 - a3 + c1, b1: -a2 - a3 + c1, b2: a2 + a3}
replace {a2, b2, a3} solve for {a1, b1} :
    {a1: -a2 - b2 + c1, b1: -b2 + c1}
replace {a2, a3, b1} solve for {b2, a1, c1} :
    {a1: -a2 + b1, b2: a2 + a3, c1: a2 + a3 + b1}
replace {a1, b2, c1} solve for {a2, a3, b1} :
    {a2: -a1 - b2 + c1, a3: a1 + 2*b2 - c1, b1: -b2 + c1}
replace {a1, c1, b1} solve for {a2, b2, a3} :
    {a2: -a1 + b1, a3: a1 - 2*b1 + c1, b2: -b1 + c1}
replace {b2, a1, b1} solve for {a2, c1, a3} :
    {a2: -a1 + b1, a3: a1 - b1 + b2, c1: b1 + b2}
replace {a1, c1, a3} solve for {a2, b2, b1} :
    {a2: -a1/2 - a3/2 + c1/2, b1: a1/2 - a3/2 + c1/2, b2: -a1/2 + a3/2 + c1/2}
replace {b2, a1, a3} solve for {a2, c1, b1} :
    {a2: -a3 + b2, b1: a1 - a3 + b2, c1: a1 - a3 + 2*b2}
replace {a1, a3, b1} solve for {a2, b2, c1} :
    {a2: -a1 + b1, b2: -a1 + a3 + b1, c1: -a1 + a3 + 2*b1}
replace {a1, c1, a2} solve for {b2, a3, b1} :
    {a3: -a1 - 2*a2 + c1, b1: a1 + a2, b2: -a1 - a2 + c1}
replace {a2, b2, a1} solve for {c1, a3, b1} :
    {b1: a1 + a2, c1: a1 + a2 + b2, a3: -a2 + b2}
replace {a2, a1, b1} solve for {b2, a3} :
    {a3: -a2 - b1 + c1, b2: -b1 + c1}
replace {a2, a1, a3} solve for {b2, c1, b1} :
    {b1: a1 + a2, b2: a2 + a3, c1: a1 + 2*a2 + a3}

If you want to see values, you can do Dict(sol).subs(dict(zip(subs, (1,2,3)))) where 1,2,3 are the values you want to use:

Dict(sol).subs(dict(zip(subs, (1,2,3))))
{b1: 3, b2: 4, c1: 7}