[docs]classCodingSOS(CodingTypeZ):N_parameters=2p_c1=0p_c2=0# none means don't enforce mirroring, True false means mirror to respective sideunstable=None
[docs]deftransfer(self):# second order sections (2x roots either real or complex conj)c1,c2=self.effective_params()Xn=self.sys.Xzn_gridXnsq=self.sys.Xzn_grid_sqreturnc2*Xnsq+Xn*c1+1
[docs]defupdate_roots(self,r1,r2=None):""" r2, may be unspecified, in which case it is assumed to be nothing, if r1 is real, or otherwise the conjugate of r1 """ifself.unstableisnotNone:ifabs(r1)>=1:self.unstable=Trueelse:self.unstable=Falseifr2isNone:ifr1.imag!=0:self.p_c2=r1.real**2+r1.imag**2self.p_c1=-2*r1.realelse:self.p_c2=0self.p_c1=-r1.realelse:ifr1.imag!=0:# TODO check conjugatesself.p_c2=r1.real**2+r1.imag**2self.p_c1=-2*r1.realelse:self.p_c2=r1*r2self.p_c1=-(r1+r2)return
[docs]defroots(self):# second order sections (2x roots either real or complex conj)c1,c2=self.effective_params()# a = c2, b = c1, c = 1disc=c1*c1-4*c2ifdisc>=0:sqrt_disc=disc**0.5ifc1<0:r1=(-c1+sqrt_disc)/2else:r1=(-c1-sqrt_disc)/2r2=c2/r1return[r1,r2]else:sqrt_disc=(-disc)**0.5r1=(-c1+sqrt_disc*1j)/2return[r1,r1.conjugate()]
[docs]defroots_r(self):# second order sections (2x roots either real or complex conj)c1,c2=self.effective_params()# a = c2, b = c1, c = 1disc=c1*c1-4*c2ifdisc>=0:sqrt_disc=disc**0.5ifc1<0:r1=(-c1+sqrt_disc)/2else:r1=(-c1-sqrt_disc)/2r2=c2/r1return[r1,r2]else:return[]
[docs]defroots_c(self):# second order sections (2x roots either real or complex conj)# complex form is always numerically stablec1,c2=self.effective_params()# a = c2, b = c1, c = 1disc=c1*c1-4*c2ifdisc>=0:sqrt_disc=disc**0.5return[]else:sqrt_disc=(-disc)**0.5r1=(-c1+sqrt_disc*1j)/2return[r1]