def double_double_cascade_step(dim, embsys, esols, tasks=0): r""" Given in *embsys* an embedded polynomial system and solutions with nonzero slack variables in *esols*, does one step in the homotopy cascade, with double double precision arithmetic. The dimension of the solution set represented by *embsys* and *esols* is the value of *dim*. The number of tasks in multithreaded path tracking is given by *tasks*. The default zero value of *tasks* indicates no multithreading. The list on return contains witness points on lower dimensional solution components. """ from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_start_system from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_start_solutions from phcpy.phcpy2c2 import py2c_dobldobl_cascade_homotopy from phcpy.phcpy2c2 import py2c_solve_by_dobldobl_homotopy_continuation from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_copy_dobldobl_target_solutions_to_container from phcpy.interface import store_dobldobl_witness_set from phcpy.interface import load_dobldobl_solutions store_dobldobl_witness_set(len(embsys), dim, embsys, esols) py2c_copy_dobldobl_container_to_start_system() py2c_copy_dobldobl_container_to_start_solutions() py2c_dobldobl_cascade_homotopy() py2c_solve_by_dobldobl_homotopy_continuation(tasks) py2c_solcon_clear_dobldobl_solutions() py2c_copy_dobldobl_target_solutions_to_container() return load_dobldobl_solutions()
def dobldobl_start_diagonal_cascade(gamma=0, tasks=0): r""" Does the path tracking to start a diagonal cascade in double double precision. For this to work, the functions dobldobl_diagonal_homotopy and dobldobl_diagonal_cascade_solutions must be executed successfully. If *gamma* equals 0 on input, then a random *gamma* constant is generated, otherwise, the given complex *gamma* will be used in the homotopy. Multitasking is available, and activated by the *tasks* parameter. Returns the target (system and its corresponding) solutions. """ from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy_with_gamma from phcpy.phcpy2c2 import py2c_solve_by_dobldobl_homotopy_continuation from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_syscon_clear_dobldobl_system from phcpy.phcpy2c2 import py2c_copy_dobldobl_target_solutions_to_container from phcpy.phcpy2c2 import py2c_copy_dobldobl_target_system_to_container from phcpy.interface import load_dobldobl_solutions from phcpy.interface import load_dobldobl_system if (gamma == 0): py2c_create_dobldobl_homotopy() else: py2c_create_dobldobl_homotopy_with_gamma(gamma.real, gamma.imag) py2c_solve_by_dobldobl_homotopy_continuation(tasks) py2c_solcon_clear_dobldobl_solutions() py2c_syscon_clear_dobldobl_system() py2c_copy_dobldobl_target_solutions_to_container() # from phcpy.phcpy2c2 import py2c_write_dobldobl_target_system # print 'the dobldobl target system :' # py2c_write_dobldobl_target_system() py2c_copy_dobldobl_target_system_to_container() tsys = load_dobldobl_system() sols = load_dobldobl_solutions() return (tsys, sols)
def dobldobl_start_diagonal_cascade(gamma=0, tasks=0): r""" Does the path tracking to start a diagonal cascade in double double precision. For this to work, the functions dobldobl_diagonal_homotopy and dobldobl_diagonal_cascade_solutions must be executed successfully. If *gamma* equals 0 on input, then a random *gamma* constant is generated, otherwise, the given complex *gamma* will be used in the homotopy. Multitasking is available, and activated by the *tasks* parameter. Returns the target (system and its corresponding) solutions. """ from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy_with_gamma from phcpy.phcpy2c2 import py2c_solve_by_dobldobl_homotopy_continuation from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_syscon_clear_dobldobl_system from phcpy.phcpy2c2 import py2c_copy_dobldobl_target_solutions_to_container from phcpy.phcpy2c2 import py2c_copy_dobldobl_target_system_to_container from phcpy.interface import load_dobldobl_solutions from phcpy.interface import load_dobldobl_system if(gamma == 0): py2c_create_dobldobl_homotopy() else: py2c_create_dobldobl_homotopy_with_gamma(gamma.real, gamma.imag) py2c_solve_by_dobldobl_homotopy_continuation(tasks) py2c_solcon_clear_dobldobl_solutions() py2c_syscon_clear_dobldobl_system() py2c_copy_dobldobl_target_solutions_to_container() # from phcpy.phcpy2c2 import py2c_write_dobldobl_target_system # print 'the dobldobl target system :' # py2c_write_dobldobl_target_system() py2c_copy_dobldobl_target_system_to_container() tsys = load_dobldobl_system() sols = load_dobldobl_solutions() return (tsys, sols)
def dobldobl_solve(pols, silent=False, tasks=0): """ Calls the blackbox solver. On input in pols is a list of strings. By default, the solver will print to screen the computed root counts. To make the solver silent, set the flag silent to True. The number of tasks for multithreading is given by tasks. The solving happens in double double precision arithmetic. """ from phcpy.phcpy2c2 import py2c_syscon_clear_dobldobl_Laurent_system from phcpy.phcpy2c2 \ import py2c_syscon_initialize_number_of_dobldobl_Laurentials from phcpy.phcpy2c2 import py2c_syscon_store_dobldobl_Laurential from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_solve_dobldobl_Laurent_system from phcpy.interface import load_dobldobl_solutions py2c_syscon_clear_dobldobl_Laurent_system() py2c_solcon_clear_dobldobl_solutions() dim = len(pols) py2c_syscon_initialize_number_of_dobldobl_Laurentials(dim) for ind in range(0, dim): pol = pols[ind] nchar = len(pol) py2c_syscon_store_dobldobl_Laurential(nchar, dim, ind+1, pol) py2c_solve_dobldobl_Laurent_system(silent, tasks) return load_dobldobl_solutions()
def dobldobl_littlewood_richardson_homotopies( ndim, kdim, brackets, verbose=True, vrfcnd=False, minrep=True, tosqr=False, outputfilename="" ): r""" In n-dimensional space we consider k-dimensional planes, subject to intersection conditions represented by brackets. The parameters *ndim* and *kdim* give values for n and k respectively. The parameter *brackets* is a list of brackets. A bracket is a list of as many natural numbers (in the range 1..*ndim*) as *kdim*. The Littlewood-Richardson homotopies compute k-planes that meet the flags at spaces of dimensions prescribed by the brackets, in double double precision. Four options are passed as Booleans: *verbose*: for adding extra output during computations, *vrfcnd*: for extra diagnostic verification of Schubert conditions, *minrep*: for a minimial representation of the problem formulation, *tosqr*: to square the overdetermined systems. On return is a 4-tuple. The first item of the tuple is the formal root count, sharp for general flags, then as second item the coordinates of the flags. The coordinates of the flags are stored row wise in a list of real and imaginary parts. The third and fourth item of the tuple on return are respectively the polynomial system that has been solved and its solutions. The length of the list of solution should match the root count. """ from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_schubert_dobldobl_littlewood_richardson_homotopies as ddlrhom from phcpy.interface import load_dobldobl_solutions, load_dobldobl_system py2c_solcon_clear_dobldobl_solutions() nbc = len(brackets) cds = "" for bracket in brackets: for num in bracket: cds = cds + " " + str(num) # print 'the condition string :', cds (roco, sflags) = ddlrhom( ndim, kdim, nbc, len(cds), cds, int(verbose), int(vrfcnd), int(minrep), int(tosqr), len(outputfilename), outputfilename, ) rflags = eval(sflags) flgs = [] for k in range(len(rflags) / 4): flgs.append(complex(rflags[2 * k], rflags[2 * k + 2])) fsys = load_dobldobl_system() sols = load_dobldobl_solutions() return (roco, flgs, fsys, sols)
def dobldobl_littlewood_richardson_homotopies(ndim, kdim, brackets, \ verbose=True, vrfcnd=False, minrep=True, tosqr=False, outputfilename=''): r""" In n-dimensional space we consider k-dimensional planes, subject to intersection conditions represented by brackets. The parameters *ndim* and *kdim* give values for n and k respectively. The parameter *brackets* is a list of brackets. A bracket is a list of as many natural numbers (in the range 1..*ndim*) as *kdim*. The Littlewood-Richardson homotopies compute k-planes that meet the flags at spaces of dimensions prescribed by the brackets, in double double precision. Four options are passed as Booleans: *verbose*: for adding extra output during computations, *vrfcnd*: for extra diagnostic verification of Schubert conditions, *minrep*: for a minimial representation of the problem formulation, *tosqr*: to square the overdetermined systems. On return is a 4-tuple. The first item of the tuple is the formal root count, sharp for general flags, then as second item the coordinates of the flags. The coordinates of the flags are stored row wise in a list of real and imaginary parts. The third and fourth item of the tuple on return are respectively the polynomial system that has been solved and its solutions. The length of the list of solution should match the root count. """ from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 \ import py2c_schubert_dobldobl_littlewood_richardson_homotopies \ as ddlrhom from phcpy.interface import load_dobldobl_solutions, load_dobldobl_system py2c_solcon_clear_dobldobl_solutions() nbc = len(brackets) cds = '' for bracket in brackets: for num in bracket: cds = cds + ' ' + str(num) # print 'the condition string :', cds (roco, sflags) = ddlrhom(ndim, kdim, nbc, len(cds), cds, \ int(verbose), int(vrfcnd), int(minrep), int(tosqr), \ len(outputfilename), outputfilename) rflags = eval(sflags) flgs = [] for k in range(len(rflags) / 4): flgs.append(complex(rflags[2 * k], rflags[2 * k + 2])) fsys = load_dobldobl_system() sols = load_dobldobl_solutions() return (roco, flgs, fsys, sols)
def store_dobldobl_solutions(nvar, sols): """ Stores the solutions in the list sols, represented as strings in PHCpack format into the solution container for processing with complex double double arithmetic. The number nvar equals the number of variables. """ from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_solcon_append_dobldobl_solution_string py2c_solcon_clear_dobldobl_solutions() for ind in range(0, len(sols)): fail = py2c_solcon_append_dobldobl_solution_string\ (nvar, len(sols[ind]), sols[ind]) if(fail != 0): break return fail
def double_double_track(target, start, sols, gamma=0, tasks=0): r""" Does path tracking in double double precision. On input are a target system, a start system with solutions, optionally a (random) gamma constant and the number of tasks. The default value zero for *tasks* indicates no multithreading. The number of tasks in the multithreading is given by *tasks*. The *target* is a list of strings representing the polynomials of the target system (which has to be solved). The *start* is a list of strings representing the polynomials of the start system with known solutions in *sols*. The *sols* is a list of strings representing start solutions. By default, a random *gamma* constant is generated, otherwise *gamma* must be a nonzero complex constant. On return are the string representations of the solutions computed at the end of the paths. """ from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_target_system from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_start_system from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_start_solutions from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy_with_gamma from phcpy.phcpy2c2 import py2c_solve_by_dobldobl_homotopy_continuation from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_copy_dobldobl_target_solutions_to_container from phcpy.interface import store_dobldobl_system from phcpy.interface import store_dobldobl_solutions from phcpy.interface import load_dobldobl_solutions from phcpy.solver import number_of_symbols dim = number_of_symbols(start) store_dobldobl_system(target, nbvar=dim) py2c_copy_dobldobl_container_to_target_system() store_dobldobl_system(start, nbvar=dim) py2c_copy_dobldobl_container_to_start_system() # py2c_clear_dobldobl_homotopy() if(gamma == 0): py2c_create_dobldobl_homotopy() else: py2c_create_dobldobl_homotopy_with_gamma(gamma.real, gamma.imag) store_dobldobl_solutions(dim, sols) py2c_copy_dobldobl_container_to_start_solutions() py2c_solve_by_dobldobl_homotopy_continuation(tasks) py2c_solcon_clear_dobldobl_solutions() py2c_copy_dobldobl_target_solutions_to_container() return load_dobldobl_solutions()
def store_dobldobl_solutions(nvar, sols): r""" Stores the solutions in the list *sols*, represented as strings in PHCpack format into the solution container for processing with complex double double arithmetic. The number *nvar* equals the number of variables. """ from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_solcon_append_dobldobl_solution_string py2c_solcon_clear_dobldobl_solutions() fail = 0 for ind in range(0, len(sols)): fail = py2c_solcon_append_dobldobl_solution_string\ (nvar, len(sols[ind]), sols[ind]) if (fail != 0): # break print 'Solution at position', ind, 'is not appended.' return fail
def store_dobldobl_solutions(nvar, sols): r""" Stores the solutions in the list *sols*, represented as strings in PHCpack format into the solution container for processing with complex double double arithmetic. The number *nvar* equals the number of variables. """ from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_solcon_append_dobldobl_solution_string py2c_solcon_clear_dobldobl_solutions() fail = 0 for ind in range(0, len(sols)): fail = py2c_solcon_append_dobldobl_solution_string\ (nvar, len(sols[ind]), sols[ind]) if(fail != 0): # break print 'Solution at position', ind, 'is not appended.' return fail
def double_double_track(target, start, sols, gamma=0, tasks=0): """ Does path tracking in double double precision. On input are a target system, a start system with solutions, optionally a (random) gamma constant and the number of tasks. The target is a list of strings representing the polynomials of the target system (which has to be solved). The start is a list of strings representing the polynomials of the start system with known solutions in sols. The sols is a list of strings representing start solutions. By default, a random gamma constant is generated, otherwise gamma must be a nonzero complex constant. On return are the string representations of the solutions computed at the end of the paths. """ from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_target_system from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_start_system from phcpy.phcpy2c2 import py2c_copy_dobldobl_container_to_start_solutions from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy from phcpy.phcpy2c2 import py2c_create_dobldobl_homotopy_with_gamma from phcpy.phcpy2c2 import py2c_solve_by_dobldobl_homotopy_continuation from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_copy_dobldobl_target_solutions_to_container from phcpy.interface import store_dobldobl_system from phcpy.interface import store_dobldobl_solutions from phcpy.interface import load_dobldobl_solutions from phcpy.solver import number_of_symbols dim = number_of_symbols(start) store_dobldobl_system(target, nbvar=dim) py2c_copy_dobldobl_container_to_target_system() store_dobldobl_system(start, nbvar=dim) py2c_copy_dobldobl_container_to_start_system() # py2c_clear_dobldobl_homotopy() if(gamma == 0): py2c_create_dobldobl_homotopy() else: py2c_create_dobldobl_homotopy_with_gamma(gamma.real, gamma.imag) store_dobldobl_solutions(dim, sols) py2c_copy_dobldobl_container_to_start_solutions() py2c_solve_by_dobldobl_homotopy_continuation(tasks) py2c_solcon_clear_dobldobl_solutions() py2c_copy_dobldobl_target_solutions_to_container() return load_dobldobl_solutions()
def dobldobl_littlewood_richardson_homotopies(ndim, kdim, brackets, \ verbose=True, vrfcnd=False, outputfilename='/tmp/output'): """ In n-dimensional space we consider k-dimensional planes, subject to intersection conditions represented by brackets. The parameters ndim and kdim give values for n and k respectively. The parameter brackets is a list of brackets. A bracket is a list of as many natural numbers (in the range 1..ndim) as kdim. The Littlewood-Richardson homotopies compute k-planes that meet the flags at spaces of dimensions prescribed by the brackets, in double double precision. On return is a 4-tuple. The first item of the tuple is the formal root count, sharp for general flags, then as second item the coordinates of the flags. The coordinates of the flags are stored row wise in a list of real and imaginary parts. The third and fourth item of the tuple on return are respectively the polynomial system that has been solved and its solutions. The length of the list of solution should match the root count. """ from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 \ import py2c_schubert_dobldobl_littlewood_richardson_homotopies \ as ddlrhom from phcpy.interface import load_dobldobl_solutions, load_dobldobl_system py2c_solcon_clear_dobldobl_solutions() nbc = len(brackets) cds = '' for bracket in brackets: for num in bracket: cds = cds + ' ' + str(num) # print 'the condition string :', cds (roco, sflags) = ddlrhom(ndim, kdim, nbc, len(cds), cds, int(verbose), \ int(vrfcnd), len(outputfilename), outputfilename) rflags = eval(sflags) flgs = [] for k in range(len(rflags)/4): flgs.append(complex(rflags[2*k], rflags[2*k+2])) fsys = load_dobldobl_system() sols = load_dobldobl_solutions() return (roco, flgs, fsys, sols)
def dobldobl_random_coefficient_system(silent=False): """ Runs the polyhedral homotopies and returns a random coefficient system based on the contents of the cell container, in double double precision arithmetic. For this to work, the mixed_volume function must be called first. """ from phcpy.phcpy2c2 import py2c_celcon_dobldobl_random_coefficient_system from phcpy.phcpy2c2 import py2c_celcon_copy_into_dobldobl_systems_container from phcpy.phcpy2c2 import py2c_celcon_dobldobl_polyhedral_homotopy from phcpy.phcpy2c2 import py2c_celcon_number_of_cells from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.phcpy2c2 import py2c_celcon_solve_dobldobl_start_system from phcpy.phcpy2c2 import py2c_celcon_track_dobldobl_solution_path from phcpy.phcpy2c2 \ import py2c_celcon_copy_target_dobldobl_solution_to_container from phcpy.interface import load_dobldobl_system, load_dobldobl_solutions py2c_celcon_dobldobl_random_coefficient_system() py2c_celcon_copy_into_dobldobl_systems_container() # py2c_syscon_write_dobldobl_system() result = load_dobldobl_system() # print result py2c_celcon_dobldobl_polyhedral_homotopy() nbcells = py2c_celcon_number_of_cells() py2c_solcon_clear_dobldobl_solutions() for cell in range(1, nbcells+1): mixvol = py2c_celcon_solve_dobldobl_start_system(cell) if not silent: print 'system %d has %d solutions' % (cell, mixvol) for j in range(1, mixvol+1): if not silent: print '-> tracking path %d out of %d' % (j, mixvol) py2c_celcon_track_dobldobl_solution_path(cell, j, 0) py2c_celcon_copy_target_dobldobl_solution_to_container(cell, j) sols = load_dobldobl_solutions() # print sols # newton_step(result, sols) return (result, sols)
def dobldobl_monodromy_breakup(embsys, esols, dim, \ islaurent=0, verbose=True, nbloops=0): r""" Applies the monodromy breakup algorithm in double double precision to factor the *dim*-dimensional algebraic set represented by the embedded system *embsys* and its solutions *esols*. If the embedded polynomial system is a Laurent system, then islaurent must equal one, the default is zero. If *verbose* is False, then no output is written. If *nbloops* equals zero, then the user is prompted to give the maximum number of loops. """ from phcpy.phcpy2c2 import py2c_factor_set_dobldobl_to_mute from phcpy.phcpy2c2 import py2c_factor_set_dobldobl_to_verbose from phcpy.phcpy2c2 import py2c_factor_dobldobl_assign_labels from phcpy.phcpy2c2 import py2c_factor_initialize_dobldobl_monodromy from phcpy.phcpy2c2 import py2c_factor_initialize_dobldobl_sampler from phcpy.phcpy2c2 import py2c_factor_initialize_dobldobl_Laurent_sampler from phcpy.phcpy2c2 import py2c_factor_dobldobl_trace_grid_diagnostics from phcpy.phcpy2c2 import py2c_factor_set_dobldobl_trace_slice from phcpy.phcpy2c2 import py2c_factor_store_dobldobl_gammas from phcpy.phcpy2c2 import py2c_factor_dobldobl_track_paths from phcpy.phcpy2c2 import py2c_factor_store_dobldobl_solutions from phcpy.phcpy2c2 import py2c_factor_restore_dobldobl_solutions from phcpy.phcpy2c2 import py2c_factor_new_dobldobl_slices from phcpy.phcpy2c2 import py2c_factor_swap_dobldobl_slices from phcpy.phcpy2c2 import py2c_factor_permutation_after_dobldobl_loop from phcpy.phcpy2c2 import py2c_factor_number_of_dobldobl_components from phcpy.phcpy2c2 import py2c_factor_update_dobldobl_decomposition from phcpy.phcpy2c2 import py2c_solcon_write_dobldobl_solutions from phcpy.phcpy2c2 import py2c_solcon_clear_dobldobl_solutions from phcpy.interface import store_dobldobl_solutions from phcpy.interface import store_dobldobl_system from phcpy.interface import store_dobldobl_laurent_system if(verbose): print('... applying monodromy factorization with double doubles ...') py2c_factor_set_dobldobl_to_verbose() else: py2c_factor_set_dobldobl_to_mute() deg = len(esols) nvar = len(embsys) if(verbose): print('nvar =', nvar, 'dim =', dim, 'deg =', deg) if(islaurent == 1): store_dobldobl_laurent_system(embsys) py2c_factor_dobldobl_assign_labels(nvar, deg) py2c_factor_initialize_dobldobl_Laurent_sampler(dim) else: store_dobldobl_system(embsys) py2c_factor_dobldobl_assign_labels(nvar, deg) py2c_factor_initialize_dobldobl_sampler(dim) if(verbose): py2c_solcon_write_dobldobl_solutions() if(nbloops == 0): strnbloops = input('give the maximum number of loops : ') nbloops = int(strnbloops) py2c_factor_initialize_dobldobl_monodromy(nbloops, deg, dim) py2c_factor_store_dobldobl_solutions() if(verbose): print('... initializing the grid ...') for i in range(1, 3): py2c_factor_set_dobldobl_trace_slice(i) py2c_factor_store_dobldobl_gammas(nvar) py2c_factor_dobldobl_track_paths(islaurent) py2c_factor_store_dobldobl_solutions() py2c_factor_restore_dobldobl_solutions() py2c_factor_swap_dobldobl_slices() (err, dis) = py2c_factor_dobldobl_trace_grid_diagnostics() if(verbose): print('The diagnostics of the trace grid :') print(' largest error on the samples :', err) print(' smallest distance between the samples :', dis) for i in range(1, nbloops+1): if(verbose): print('... starting loop %d ...' % i) py2c_factor_new_dobldobl_slices(dim, nvar) py2c_factor_store_dobldobl_gammas(nvar) py2c_factor_dobldobl_track_paths(islaurent) py2c_solcon_clear_dobldobl_solutions() py2c_factor_store_dobldobl_gammas(nvar) py2c_factor_dobldobl_track_paths(islaurent) py2c_factor_store_dobldobl_solutions() sprm = py2c_factor_permutation_after_dobldobl_loop(deg) if(verbose): perm = eval(sprm) print('the permutation :', perm) nb0 = py2c_factor_number_of_dobldobl_components() done = py2c_factor_update_dobldobl_decomposition(deg, len(sprm), sprm) nb1 = py2c_factor_number_of_dobldobl_components() if(verbose): print('number of factors : %d -> %d' % (nb0, nb1)) deco = decomposition(deg, 'dd') print('decomposition :', deco) if(done == 1): break py2c_factor_restore_dobldobl_solutions()