def solve_biquadratic(f, g, opt):
 G = groebner([f, g])
 if ((len(G) == 1) and G[0].is_ground):
  return None
 if (len(G) != 2):
  raise SolveFailed
 (p, q) = G
 (x, y) = opt.gens
 p = Poly(p, x, expand=False)
 q = q.ltrim((-1))
 p_roots = [rcollect(expr, y) for expr in roots(p).keys()]
 q_roots = list(roots(q).keys())
 solutions = []
 for q_root in q_roots:
  for p_root in p_roots:
   solution = (p_root.subs(y, q_root), q_root)
   solutions.append(solution)
 return sorted(solutions, key=default_sort_key)

def solve_biquadratic ( f , g , opt ) : G = groebner ( [ f , g ] ) if ( ( len ( G ) == 1 ) and G [ 0 ] . is_ground ) : return None if ( len ( G ) != 2 ) : raise SolveFailed ( p , q ) = G ( x , y ) = opt . gens p = Poly ( p , x , expand = False ) q = q . ltrim ( ( - 1 ) ) p_roots = [ rcollect ( expr , y ) for expr in roots ( p ) . keys ( ) ] q_roots = list ( roots ( q ) . keys ( ) ) solutions = [ ] for q_root in q_roots : for p_root in p_roots : solution = ( p_root . subs ( y , q_root ) , q_root ) solutions . append ( solution ) return sorted ( solutions , key = default_sort_key )
solve a system of two bivariate quadratic polynomial equations .