user10648668
user10648668

Reputation:

Restricting domain of solution set when using SymPy solve in the multiple variables case

Say, I'm trying to solve the system of equations:

enter image description here

for θ, λ and ɸ , where a, b, c and d are complex numbers and the matrix on the LHS is a unitary matrix.

The SymPy code I have at hand does successfully do the job but there are a few edge cases it misses.

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)
    res = solve([a_eq, b_eq, c_eq, d_eq],
                theta,
                phi,
                lamb,
                check=False,
                set=True)
    return res

For instance, it doesn't restrict the range of the solutions. I did notice this answer but it only works for single variable cases. So any idea how to add the domain restrictions for the solution set, when dealing with multiple variables?

Upvotes: 1

Views: 1871

Answers (1)

Oscar Benjamin
Oscar Benjamin

Reputation: 14530

You can declare assumptions on the symbols and solve should check them e.g.:

In [12]: solve(x*(1-x))                                                                                                           
Out[12]: [0, 1]

In [13]: x = Symbol('x', positive=True)                                                                                           

In [14]: solve(x*(1-x))                                                                                                           
Out[14]: [1]

That works for some restrictions but won't work for a restriction like x<y. You can however post-process the output from solve:

In [6]: sol = [{x:1, y:2, z:3}, {x:1, y:0, z:4}, {x:3, y:2, z:1}]                                                                 

In [7]: sol                                                                                                                       
Out[7]: [{x: 1, y: 2, z: 3}, {x: 1, y: 0, z: 4}, {x: 3, y: 2, z: 1}]

In [8]: cond = And(0 < x, x < z, 0 < y)                                                                                           

In [9]: cond                                                                                                                      
Out[9]: x > 0 ∧ y > 0 ∧ x < z

In [10]: cond.subs(sol[0])                                                                                                        
Out[10]: True

In [11]: [s for s in sol if cond.subs(s)]                                                                                         
Out[11]: [{x: 1, y: 2, z: 3}]

Upvotes: 1

Related Questions