涉及角度约束的方程

时间:2019-05-26 16:23:10

标签: python sympy equation-solving

我正在尝试使用sympy求解方程组。

from sympy import *
def get_angles(a, b, c, d):
    theta, phi, lamb = symbols('\\theta \\phi \\lambda', real=True)
    a_eq = Eq(cos(theta / 2), a)
    b_eq = Eq(exp(I * phi) * sin(theta / 2), b)
    c_eq = Eq(-exp(I * lamb) * sin(theta / 2), c)
    d_eq = Eq(exp(I * (phi + lamb)) * cos(theta / 2), d)
    # theta_constr1 = Eq(theta >= 0)
    # theta_constr2 = Eq(theta <= pi)
    # phi_constr1 = Eq(phi >= 0)
    # phi_constr2 = Eq(phi < 2 * pi)
    res = solve([
        a_eq, b_eq, c_eq, d_eq,
        #theta_constr1, theta_constr2, phi_constr1, phi_constr2,
    ],
        theta,
        phi,
        lamb,
        check=False,
        dict=True)
    return res

该函数按原样返回正确的结果,但是如果我尝试将约束置于方程组(注释的部分)内部的角度上,该函数将不起作用。有什么办法可以拥有它们?

目前,我正在使用一种简单的解决方案来克服此限制:我将上一个函数的结果传递给下一个函数,以过滤掉不需要的结果

def _final_constraint(result):
    res = []
    for sol in result:
        to_add = True
        for k, v in sol.items():
            if str(k) == '\\theta' and (v < 0 or v > pi):
                to_add = False
                break
            elif str(k) == '\\phi' and (v < 0 or v >= 2 * pi):
                to_add = False
                break
        if to_add:
            res.append(simplify(sol))
    return res

1 个答案:

答案 0 :(得分:1)

Eq代表Equality,而不是等式(尽管有讨论将此类对象添加到SymPy中)。因此,未注释的Eq会按您的预期进行解释,而注释的注释则不会。您可以尝试将theta_constr1 = Eq(theta >= 0)替换为theta_constr1 = theta >= 0,但是您将遇到不平等求解器的问题-它抱怨不平等中存在多个兴趣符号。那么,如何将x >= 0这样的不等式重写为Eq(x + eps, 0),其中eps是非负Symbol

def get_angles(a, b, c, d):
    theta, phi, lamb = symbols('\\theta \\phi \\lambda', real=True)
    eps = Symbol('eps', nonnegative=True)
    a_eq = Eq(cos(theta / 2), a)
    b_eq = Eq(exp(I * phi) * sin(theta / 2), b)
    c_eq = Eq(-exp(I * lamb) * sin(theta / 2), c)
    d_eq = Eq(exp(I * (phi + lamb)) * cos(theta / 2), d)
    theta_constr1 = theta + eps
    theta_constr2 = pi - theta + eps
    phi_constr1 = phi  + eps
    phi_constr2 = 2 * pi - phi + eps
    res = solve([
        a_eq, b_eq, c_eq, d_eq,
        theta_constr1, theta_constr2, phi_constr1, phi_constr2,
        ],
        theta,
        phi,
        lamb,
        check=False,
        set=True)
    return res

>>> print(filldedent(get_angles(11,2,3,4)))

([\lambda, \phi, \theta], {(pi, 0, 4*pi - 2*acos(11)), (0, pi,
2*acos(11)), (0, pi, 4*pi - 2*acos(11)), (0, 0, 4*pi - 2*acos(11)),
(0, 0, 2*acos(11)), (pi, pi, 4*pi - 2*acos(11)), (pi, pi, 2*acos(11)),
(pi, 0, 2*acos(11))})

您必须确定thetaphi的哪一侧(如果有)满足您的方程式。