I'm looking for a way to easily manipulate the results given by the solveset
method in the SymPy package. In particular, I have a function omega(x,n,p,gamma)
and I want to compute its roots while keeping gamma
as a symbolic variable:
def omega(x,n,p,gamma):
#do stuff
gamma, x=var('gamma x')
roots=solveset(omega_complete(x,30,1,gamma), x)
omega
returns a non-linear combination of x
and gamma
, so other methods in the same library such as linsolve
or solve
do not work. Currently I am stuck with an output of type FiniteSet
after calling solveset
: the result is printed in LaTeX and looks like this.
The naive conversion list(roots)
gives the error TypeError: did not evaluate to a bool: None
. The alternative way that I found in this answer using roots.args[0], roots.args[1]
is also not what I'm looking for. Can anyone help?
The full code (note that are actually two functions, omega_complete
and omega_cycle
, that are similarly defined):
import numpy as np
import cmath as cm
from sympy import *
def target(n,p):
w=[]
for j in range(n):
if j==p:
w.append(1)
else: w.append(0)
return np.array(w)
###---complete---####
def change_basis_complete(N):
matrix=np.zeros((N,N),dtype=complex)
for n in range(0,N):
for m in range(0,N):
matrix[n,m]=(1/cm.sqrt(N))*cm.exp(2*np.pi*1j*(n+1)*(m+1)/N)
return matrix
def new_target_complete(N,p):
return np.dot(change_basis_complete(N),target(N,p))
def omega_complete(x,N,p,gamma):
w=new_target_complete(N,p)
old_spectrum=np.zeros(N)
for i in range(N-1):
old_spectrum[i]=N
old_spectrum[N-1]=0
sigma=0
for i in range(N):
sigma+=(abs(w[i])**2)/(gamma*old_spectrum[i]-x)
return 1-sigma
###---cycle---####
def change_basis_cycle(N):
matrix=np.zeros((N,N),dtype=complex)
for n in range(0,N):
for m in range(0,N):
matrix[n,m]=(1/cm.sqrt(N))*cm.exp(-2*np.pi*1j*(n+1)*(m+1)/N)
return matrix
def new_target_cycle(N,p):
return np.dot(change_basis_cycle(N),target(N,p))
def omega_cycle(x,N,p,gamma):
w=new_target_cycle(N,p)
old_spectrum=np.zeros(N)
for n in range(N):
old_spectrum[n]=2-2*cm.cos((2*cm.pi*n)/N)
sigma=0
for i in range(N):
sigma+=(abs(w[i])**2)/(gamma*old_spectrum[i]-x)
return 1-sigma