George
George

Reputation: 5691

map each element to expression

I have this code:

import sympy
import numpy as np
from sympy.utilities.lambdify import lambdify
from collections import OrderedDict

arr = [np.array([ 1, 2]), np.array([ 5, 6])]
a,b = sympy.symbols('a b')
var = [a,b]
expr = ['a+cos(b)', 'a+cos(b)*2']

f = lambdify( var, expr, 'numpy')

vals = OrderedDict(zip(var, arr)).values()
f(*vals)

and I am receiving:

[array([ 1.28366219,  2.96017029]), array([ 1.56732437,  3.92034057])]

I want to receive:

[array([ 1.28366219,  3.92034057])]

hence :

1+np.cos(5) = 1.28366219

2 +np.cos(6)*2 = 3.92034057

Upvotes: 3

Views: 254

Answers (1)

Cleb
Cleb

Reputation: 26027

Given the way you implemented f, I think the only way to get your desired output is to access the desired elements directly. When you pass values for a and b, both expressions in f will be evaluated and returned in a list (as you defined it). You can check f.func_doc

f.func_doc
"Created with lambdify. Signature:\n\nfunc(a, b)\n\nExpression:\n\n['a+cos(b)', 'a+cos(b)*2']"

Then

f(1, np.pi)

returns

[0.0, -1.0]

as expected, where 0.0 corresponds to a+cos(b) and -1.0 to a+cos(b)*2.

In your example you could simply do:

[vali[i] for i, vali in enumerate(f(*vals))]

which gives you the desired output:

[1.2836621854632262, 3.9203405733007317]

I guess it would be easier to define the expressions separately rather than in a list as you currently do it but I don't know the reason for the structure you chose:

from sympy import cos

f1 = lambdify((a, b), a+cos(b))
f2 = lambdify((a, b), a+cos(b)*2)

res = [np.array([f1(1, 5), f2(2, 6)])]

which gives

[array([ 1.28366219,  3.92034057])]

Upvotes: 2

Related Questions