Home > Software engineering >  Is there a way to pass an equation symbolically into a function for sympy?
Is there a way to pass an equation symbolically into a function for sympy?

Time:01-01

From this

import sympy as sp

x,y,z = sp.symbols("x y z")
sp.Ep(x,y/z)

To this

#varibles = array
#equation = ????
def solver(variables,equation):
    #Looping through variables array and converting variables to sympy objects 
    for var in variables:
        var = sp.symbols(var)
    
    #Generate sympy Equation
    equation = sp.Ep(equation)

variables = [x,y,z]
equation = x,y/z #invalid code

solver(variables,equation)

I'm creating a function that is able to take in an equation with x amount of variables and x-1 number of values then solve for the missing variable symbolically then return a numerical answer using the values provided.

I only included a small portion of code where I'm having trouble understanding how to pass through an equation. Any solutions or pointers would be greatly appericated. Thanks.

CodePudding user response:

There are several layers of potential confusion here concerning Python variables and SymPy objects (Symbols) used for variables.

Here is an example of what you are saying:

# 3 variables
syms = x, y, z = var('x:z')
# 2 values
vals = {x:1, y:2}
# an equations
eq = Eq(x, y/z)

# solve for the missing value symbolically
missing = set(syms) - set(vals)  # == {z}
solve(eq, missing)
[y/x]

# solve for the missing value after substituting in the known values
solve(eq.subs(vals))
[2]

You could make a solver to accept an equation and then specified values and figure out the missing one and return that value by doing something like this:

>>> def solver(eq, **vals):
...     from sympy.core.containers import Dict
...     from sympy.solvers.solvers import solve
...     free = eq.free_symbols
...     vals = Dict(vals)
...     x = free - set(vals)
...     if len(x) != 1:
...         raise ValueError('specify all but one of the values for %s' % free)
...     x = x.pop()
...     return solve(eq.subs(vals), x, dict=True)
...
>>> solver(eq, x=1, z=2)
[{y: 2}]

Does that give you some ideas of how to continue?

  • Related