#NEWLINE# def matrix_fglm( F , ring , O_to ) : #NEWLINE# #INDENT# '\n    Converts the reduced Groebner basis ``F`` of a zero-dimensional\n    ideal w.r.t. ``O_from`` to a reduced Groebner basis\n    w.r.t. ``O_to``.\n\n    References\n    ==========\n\n    J.C. Faugere, P. Gianni, D. Lazard, T. Mora (1994). Efficient\n    Computation of Zero-dimensional Groebner Bases by Change of\n    Ordering\n    ' #NEWLINE# domain = ring . domain #NEWLINE# ngens = ring . ngens #NEWLINE# ring_to = ring . clone ( order = O_to ) #NEWLINE# old_basis = _basis ( F , ring ) #NEWLINE# M = _representing_matrices ( old_basis , F , ring ) #NEWLINE# S = [ ring . zero_monom ] #NEWLINE# V = [ ( [ domain . one ] + ( [ domain . zero ] * ( len ( old_basis ) - 1 ) ) ) ] #NEWLINE# G = [ ] #NEWLINE# L = [ ( i , 0 ) for i in range ( ngens ) ] #NEWLINE# L . sort ( key = ( lambda k_l : O_to ( _incr_k ( S [ k_l [ 1 ] ] , k_l [ 0 ] ) ) ) , reverse = True ) #NEWLINE# t = L . pop ( ) #NEWLINE# P = _identity_matrix ( len ( old_basis ) , domain ) #NEWLINE# while True : #NEWLINE# #INDENT# s = len ( S ) #NEWLINE# v = _matrix_mul ( M [ t [ 0 ] ] , V [ t [ 1 ] ] ) #NEWLINE# _lambda = _matrix_mul ( P , v ) #NEWLINE# if all ( ( ( _lambda [ i ] == domain . zero ) for i in range ( s , len ( old_basis ) ) ) ) : #NEWLINE# #INDENT# lt = ring . term_new ( _incr_k ( S [ t [ 1 ] ] , t [ 0 ] ) , domain . one ) #NEWLINE# rest = ring . from_dict ( { S [ i ] : _lambda [ i ] for i in range ( s ) } ) #NEWLINE# g = ( lt - rest ) . set_ring ( ring_to ) #NEWLINE# if g : #NEWLINE# #INDENT# G . append ( g ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# P = _update ( s , _lambda , P ) #NEWLINE# S . append ( _incr_k ( S [ t [ 1 ] ] , t [ 0 ] ) ) #NEWLINE# V . append ( v ) #NEWLINE# L . extend ( [ ( i , s ) for i in range ( ngens ) ] ) #NEWLINE# L = list ( set ( L ) ) #NEWLINE# L . sort ( key = ( lambda k_l : O_to ( _incr_k ( S [ k_l [ 1 ] ] , k_l [ 0 ] ) ) ) , reverse = True ) #NEWLINE# #UNINDENT# L = [ ( k , l ) for ( k , l ) in L if all ( ( ( monomial_div ( _incr_k ( S [ l ] , k ) , g . LM ) is None ) for g in G ) ) ] #NEWLINE# if ( not L ) : #NEWLINE# #INDENT# G = [ g . monic ( ) for g in G ] #NEWLINE# return sorted ( G , key = ( lambda g : O_to ( g . LM ) ) , reverse = True ) #NEWLINE# #UNINDENT# t = L . pop ( )