[docs]defroots_bin_type(roots,policy="auto",F_nyquist_Hz=None,strict=True,simple_output=False,real_tol=1e-6,conj_tol=1e-4,):""" roots_r are the real roots roots_c are just the positive complex roots roots_u are any unsorted roots """assertpolicyin["auto","pos","strict","drop_pos","drop_neg"]defare_same(r1,r2):ifabs(r1)<0.8:returnabs(r1-r2)<conj_tolelse:returnabs((r1/r2)-1)<conj_tol@np.vectorizedefare_real(r1):ifabs(r1.real)<0.8:returnabs(np.imag(r1))<real_tolelse:returnabs(np.imag(r1)/np.real(r1))<real_tolroots_r=[]roots_u=[]seen_cplx_pos=Falseseen_cplx_neg=Falseroots_u=[]forrootinroots:ifare_real(root):roots_r.append(np.real(root))elifnp.imag(root)>0:seen_cplx_pos|=Trueroots_u.append(root)else:seen_cplx_neg|=Trueroots_u.append(root)ifpolicy=="auto":ifseen_cplx_negandseen_cplx_pos:policy="strict"else:policy="pos"roots_c=[]ifpolicy=="strict":roots_u=np.asarray(roots_u)pos_select=roots_u.imag>0roots_neg=roots_u[~pos_select]roots_pos=roots_u[pos_select]rB=roots_matching.nearest_unique_pairs(roots_pos,roots_neg.conjugate())roots_u=list(rB.l1_remain)+[r.conjugate()forrinrB.l2_remain]forr1,r2inrB.r12_list:ifnotstrictorare_same(r1,r2):# roots_c.append((r1 + r2) / 2)# TODO, this seems to work better, not clear why..roots_c.append(r1)else:roots_u.append(r1)roots_u.append(r2.conjugate())elifpolicy=="pos":forrootinroots_u:ifnp.imag(root)>0:roots_c.append(root)else:roots_c.append(root.conjugate())roots_u=[]elifpolicy=="drop_neg":forrootinroots_u:ifnp.imag(root)>0:roots_c.append(root)roots_u=[]elifpolicy=="drop_pos":forrootinroots_u:ifnp.imag(root)<0:roots_c.append(root.conjugate())roots_u=[]ifnotsimple_output:return(np.asarray(roots_r),np.asarray(roots_c),np.asarray(roots_u),policy)else:ifroots_u:raiseRuntimeError("Unbalanced or unpairable roots!")returnroots_r,roots_c