11

I'm trying to code various optimisation methods, as a way of revising. I want to be able to use SymPy to evaluate a function with an arbitrary number of variables at a given point, where the co-ordinates of the point are stored in an array.

For example, I'd like to evaluate f(x,y) = 3*x**2 - 2*x*y + y**2 + 4*x + 3*y at the point b = [1,2]. But I'd really like a general way of doing it, that can handle a function with any number of variables and an appropriate length array as the point to be evaluated as, so sympy.evalf(f, subs = {foo}) isn't really very useful.

Lemur
  • 2,659
  • 4
  • 26
  • 41
Tam Coton
  • 786
  • 1
  • 9
  • 20
  • Could you just use map() ? http://docs.python.org/2/library/functions.html#map – Samizdis Mar 18 '13 at 14:00
  • http://Whathaveyoutried.com – Snakes and Coffee Mar 18 '13 at 14:05
  • Welcome to SO! Posting code and some specifics of what you have tried is recommended here, please read the FAQ and hopefully you can get better answers! – span Mar 18 '13 at 14:15
  • Map looks promising initially, but I don't think it's relevant, sadly - it evaluates a function for several specific values of the arguments. What I want to do is evaluate a SymPy expression at one general multivariate point. Thanks for linking it though, I'd not come across it before and I'm sure it'll be useful in future. I've had a look through the SymPy documentation, mostly the numerical evaluation and algebra sections, but not found anything useful. This surprises me somewhat, as I feel it's the kind of thing that would be wanted quite often. – Tam Coton Mar 18 '13 at 14:25
  • If all your expressions are polynomials, you can also try Poly. – asmeurer Mar 19 '13 at 14:20

3 Answers3

5

You are working with SymPy expression trees, not functions. On any expression you can do:

>>> vars = sorted(expression.free_symbols)
>>> evaluated = expression.subs(*zip(vars, your_values))
Krastanov
  • 6,479
  • 3
  • 29
  • 42
  • 1
    Thanks very much - where can I find the documentation on those commands? I'd rather understand what they do rather than just copy verbatim without understanding! – Tam Coton Mar 18 '13 at 17:42
  • 1
    https://docs.sympy.org/latest/tutorials/intro-tutorial/basic_operations.html – Benjamin Smus Aug 15 '23 at 23:08
1

I would also expect this to be easier to do, but here's a good workaround:

If you know the symbol names ('x','y', e.g.), you can create a dict on the fly using zip:

fvars = sympy.symbols('x, y') #these probably already exist, use: fvars = [x,y]

b = [1,2]
sympy.evalf(f, subs = dict(zip(fvars,b)))
askewchan
  • 45,161
  • 17
  • 118
  • 134
1

lambdify is a good option to generate a Python-callable function.

An example, assuming you have a function f and the symbols x and y:

from sympy import lambdify
import numpy as np

callable_fct = lambdify((x, y), f)
xn = np.arange(0, 2, 0.1)
yn = 3
print(callable_fct(xn, yn))
Marine Galantin
  • 1,634
  • 1
  • 17
  • 28
user3021380
  • 146
  • 3