Search code examples
pythonnumpysympysolver

Possible use of lambdify() with Sympy to take advantage of numerical solvers for three equations and three unknowns


I've three real, multivariate equations (three variables) that need to be solved, simultaneously, for numerical results (not symbolic, in this case.) In the past, I've just used SymPy's solve() function which works great for much of what I work on (linear symbolic equations.)

But these three are non-linear. Assume three symbolic expressions e1, e2, and e3 with real, positive variables c1, c2, and c3:

c1, c2, c3 = symbols( 'c1,c2,c3', real=True, positive=True )
e1 = f(c1, c2, c3)               # f() is actually too long to write out
e2 = g(c1, c2, c3)               # g() is actually too long to write out
e3 = h(c1, c2, c3)               # h() is actually too long to write out
                                 # .. but see at-bottom for f() for clarity

I do not get any errors when attempting the following:

solve( [ Eq(e1, -1), Eq(e2, -0.5), Eq(e3, -sqrt(3)/2) ], [ c1, c2, c3 ] )

And I happen to know the vicinity of the right answers: c1=3.5472, c2=1.39199, and c3=0.20238 (roughly.)

However, I terminated the solution attempt after waiting a few hours.

I am not sure how to "help" the above solver with the nearby values. (I am a casual user and therefore likely sufficiently ignorant to not know how to find the right documentation, readily, if such exists. I did try and considered asking for help only after a few hours spent there, as well. I won't document all my failed attempts here.)

So I decided that if I were to lambdify the above equations then perhaps I could take advantage of other solvers.

My first inclination was to set up lambdified functions to result in zero, as I imagined the possibility of a reduced set of options, otherwise. So, as follows:

f1 = lambdify( (c1,c2,c3), e1 + 1 )
f2 = lambdify( (c1,c2,c3), e2 + 0.5 )
f3 = lambdify( (c1,c2,c3), e3 + sqrt(3)/2 )

And when I plug in my approximate values for c1, c2, and c3, I do get near-zero outputs from f1, f2, and f3. Which is good. It means I did at least manage to use lambdify (for the first time) in a way that worked as I expected it might.

However, now I'm stuck with which way to head from here.

I do have a lot of failed results I could document. But, looking back over them, they are entirely about my ignorance and probably not particularly helpful here. Noise and very little signal in there, I think.

There is one and only one possible solution and all three will converge on zero at the same time. So this isn't exactly a simulated annealing kind of problem (though amenable to it, I suppose.) I had fully expected SymPy's solve() to deal with this rather quickly, but now I suspect that it is spinning its wheels taking symbolic derivatives. (Of course, I'm not sure.) But this is why I was thinking about porting over these expressions into a more numerical side of things in hopes of a solver that will work with numerical differences rather than symbolic derivatives.

What's the right approach here? I'm lost. I think the answer should be more about me learning something new about syntax that I'm lacking, for now. But bear in mind that e1, e2, and e3 are not linear combinations of c1, c2, and c3. They involve a variety of integer powers, square roots, cube roots, and combinations of various products of any two or three of them, as well.

That's it. I'm hoping for a nudge in the right direction if not an outright "here's how" answer.

Note: e1, e2, and e3 are below on separate lines for anyone caring what these things look like:

-(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))/(3*(sqrt(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**(1/3)) - (sqrt(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**(1/3)/3 - (2*c1*c3 + 2*c2*c3)/(3*c1*c2*c3)
((c2 + 3*c3)/(c1*c2*c3) - (2*c1*c3 + 2*c2*c3)**2/(3*c1**2*c2**2*c3**2))*re(1/((-1/2 + sqrt(3)*I/2)*(sqrt(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**(1/3))) + sqrt(3)*((cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2 + sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)**2*Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/4)**(1/6)*sin(atan2(sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2, cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))/3)/6 + ((cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2 + sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)**2*Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/4)**(1/6)*cos(atan2(sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2, cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))/3)/6 - (2*c1*c3 + 2*c2*c3)/(3*c1*c2*c3)
((c2 + 3*c3)/(c1*c2*c3) - (2*c1*c3 + 2*c2*c3)**2/(3*c1**2*c2**2*c3**2))*im(1/((-1/2 + sqrt(3)*I/2)*(sqrt(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**(1/3))) + ((cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2 + sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)**2*Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/4)**(1/6)*sin(atan2(sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2, cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))/3)/6 - sqrt(3)*((cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2 + sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)**2*Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/4)**(1/6)*cos(atan2(sin(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2, cos(atan2(0, -4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2)/2)*sqrt(Abs(-4*(-3*(c2 + 3*c3)/(c1*c2*c3) + (2*c1*c3 + 2*c2*c3)**2/(c1**2*c2**2*c3**2))**3 + (27/(c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(c1**2*c2**2*c3**2) + 2*(2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))**2))/2 + 27/(2*c1*c2*c3) - 9*(c2 + 3*c3)*(2*c1*c3 + 2*c2*c3)/(2*c1**2*c2**2*c3**2) + (2*c1*c3 + 2*c2*c3)**3/(c1**3*c2**3*c3**3))/3)/6

Solution

  • Sympy also exposes nsolve, which can be used to numerically solve a system of linear (or nonlinear) equation. All you have to do is:

    nsolve([e1, e2, e3], [c1, c2, c3], [3.5472, 1.39199, 0.20238])
    

    This function lambdifies the expressions and uses mpmath's findroot. It's very handy if you happen to know a good initial guess.

    Since you have 3 equations, you could also use SymPy Plotting Backend's plot3d_implicit to find a good initial guess:

    from spb import *
    plot3d_implicit(e1, e2, e3, (c1, -5, 5), (c2, -5, 5), (c3, -5, 5), backend=KB, n=150)
    

    Anyway, without knowing the exact expressions for e2, e3, this is all I can suggest.