简体   繁体   中英

sympy: How to solve this system of transcendental equations?

I'm trying to solve a system of transcendental equations using sympy:

from sympy import *
A, Z, phi, d, a, tau, t, R, u, v = symbols('A Z phi d a tau t R u v', real=True)

system = [
    Eq(A, sqrt(R**2*cos(u)**2 + 2*R*d*cos(a)*cos(u) + d**2 + 2*d*(v*sin(tau) - (R*sin(u) + t)*cos(tau))*sin(a) + (v*sin(tau) - (R*sin(u) + t)*cos(tau))**2)),
    Eq(Z, v*cos(tau) + (R*sin(u) + t)*sin(tau)),
    Eq(phi, (R*sin(a)*cos(u) - (v*sin(tau) - (R*sin(u) + t)*cos(tau))*cos(a))/A),
]

or in euclidian coordinates:

system = [
     Eq(A, sqrt(d**2 + 2*d*x*cos(a) + 2*d*(z*sin(tau) - (t + y)*cos(tau))*sin(a) + x**2 + (z*sin(tau) - (t + y)*cos(tau))**2)),
     Eq(Z, z*cos(tau) + (t + y)*sin(tau)),
     Eq(phi, (x*sin(a) - (z*sin(tau) - (t + y)*cos(tau))*cos(a))/A),
     Eq(R**2, x**2+y**2),
]

Essentially this is an intersection of a circle (radius A) with a skewed (angle τ) cylinder (radius R) rotating (angle a) around an eccentric axis (d). I'm interested in the function φ(A, Z) as I need to evaluate it for several hundred combinations of A and Z for a few combinations of the other parameters (R, A, d, t, τ).

Here is what I tried:

  • Directly using solve(system, [u, v, phi]) : Needs too much time to complete.
  • Reducing it to one equation using first and then using solveset() .
  • Inserting numbers for all parameters (example: R, A, d, t, tao = 25, 150, 125, 2, 5/180*pi ) then using any combination of the N() and solve() or solveset() .
  • I was able to get solutions for the simplified problem of the unskewed cylinder ( t, tao = 0, 0 ) with d = sqrt(A**2 - R**2) .

How can I solve this system of equations? Failing that: How can I get numeric values for φ for a few dozen combinations of the parameters and a few hundred points (A, Z) each?


If you are interested. Here is the code leading up to the equation:

A, Z, phi, d, a, tau, t, R, u, v = symbols('A Z phi d a tau t R u v', real=True)

r10, z10, phi10 = symbols('r10 z10 phi_10', real=True)
system10 = [Eq(A, r10), Eq(Z, z10), Eq(phi, phi10)]

x9, x8, y8, z8 = symbols('x9 x8 y8 z8', real=True)
system8 = [e.subs(r10, sqrt(x9**2+y8**2)).subs(z10, z8).subs(phi10, y8/A).subs(x9, x8+d) for e in system10]

r6, phi7, phi6, z6 = symbols('r6 phi_7 phi_6 z6', real=True)
system6 = [e.subs(x8, r6*cos(phi7)).subs(y8, r6*sin(phi7)).subs(z8, z6).subs(phi7, phi6+a) for e in system8]

x6, y6 = symbols('x_6 y_6', real=True)
system6xy = [simplify(expand_trig(e).subs(cos(phi6), x6/r6).subs(sin(phi6), y6/r6)) for e in system6]

# solve([simplify(e.subs(phi6, u).subs(r6, R).subs(z6, v).subs(d, sqrt(A**2-R**2))) for e in system6], [u, v, phi]) -> phi = acos(+-R/A)

r5, phi5, x5 = symbols('r_5 phi_5 x_5', real=True)
system5 = [e.subs(x6, x5).subs(y6, r5*cos(phi5)).subs(z6, r5*sin(phi5)) for e in system6xy]

r4, phi4, x4 = symbols('r_4 phi_4 x_4', real=True)
system4 = [e.subs(phi5, phi4 + tau).subs(r5, r4).subs(x5, x4) for e in system5]

x3, y3, z3 = symbols('x_3 y_3 z_3', real=True)
system3 = [expand_trig(e).subs(cos(phi4), y3/r4).subs(sin(phi4), z3/r4).subs(r4, sqrt(y3**2+z3**2)).subs(x4, x3) for e in system4]

x2, y2, z2 = symbols('x_2 y_2 z_2', real=True)
system2 = [e.subs(x3, x2).subs(y3, y2+t).subs(z3, z2) for e in system3]

system = [simplify(e.subs(x2, R*cos(u)).subs(y2, R*sin(u)).subs(z2, v)) for e in system2]

# solve([simplify(e.subs(tau, 0).subs(t, 0).subs(d, sqrt(A**2-R**2))) for e in system], [u, v, phi]) -> phi = acos(+-R/A)

Your first two equations must be solved for u and v; the 3rd then gives the corresponding value of phi. You can easily solve the 2nd for v.

Approach:

Solve the 2nd equation for v and substitute that into the 1st to obtain a function of only u and other variables, the values of which you will define (solving this high order symbolic expression will not be effective). You can't easily solve that equation for u, but you can get a reasonable solution for sin(u) in terms of cos(u) to give two roots: sin(u) = f1(cos(u)) and f2(cos(u)). I get

(Z*sin(tau) + d*sin(a)*cos(tau) - t - sqrt(A**2 - R**2*cos(u)**2 -
2*R*d*cos(a)*cos(u) - d**2*cos(a)**2)*cos(tau))/R

and

(Z*sin(tau) + d*sin(a)*cos(tau) - t + sqrt(A**2 - R**2*cos(u)**2 -
2*R*d*cos(a)*cos(u) - d**2*cos(a)**2)*cos(tau))/R

If we let x = cos(u) we know that f1(x)**2 + x**2 - 1 = 0 (which we call z1(x) and similarly z2(x) for the other root) AND we know that x is constrained to the range of [-1, 1]. So we can bisect zi(x) for x in the range of [-1, 1] to find the value of x; u = asin(x) can be substituted into the second equation to find v; finally, u and v can be substituted into the 3rd to find phi.

eg for {tau: 3, R: 7, A: 7, t: 4, a: 3, Z: 3, d: 2} I get x = sin(u) = {-.704, 0.9886} which gives v = {-1.47, -3.16} and phi = {1.52, -.093}

Of course, those values may be meaningless if the input is meaningless, but with the right values hopefully this approach might prove worthwhile.

/c

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM