/** \brief in the setup of this object, make a new system randomizer. \param solve_options the current state of the solver. \param W input witness set, witn numbers of linears, patches, and variables. */ void make_randomizer(const SolverConfiguration & solve_options, const WitnessSet & W) { randomizer_ = std::make_shared<SystemRandomizer>(*(new SystemRandomizer)); randomizer_->setup(W.num_variables()-W.num_linears()-W.num_patches(), solve_options.PPD.num_funcs); }
void WitnessSet::merge(const WitnessSet & W_in, tracker_config_t * T) { //error checking first if ( (num_vars_==0) && (W_in.num_vars_!=0) && (num_points()==0)) { num_vars_ = W_in.num_vars_; num_natty_vars_ = W_in.num_natty_vars_; } if (W_in.num_natty_vars_ != this->num_natty_vars_) { std::stringstream ss; ss << "merging two witness sets with differing numbers of natural variables. "<< W_in.num_natural_variables() <<" merging set, "<< this->num_natural_variables() << " existing\n", throw std::logic_error(ss.str()); } //just mindlessly add the linears. up to user to ensure linears get merged correctly. no way to know what they want... for (unsigned int ii = 0; ii<W_in.num_linears(); ii++) { WitnessSet::add_linear(W_in.linear(ii)); } for (unsigned int ii = 0; ii<W_in.num_points(); ii++) { int is_new = 1; vec_mp & in_point = W_in.point(ii); for (unsigned int jj = 0; jj<num_points(); jj++){ vec_mp & curr_point = this->point(jj); //cache the sizes int in_size = in_point->size; int curr_size = curr_point->size; in_point->size = this->num_natural_variables(); curr_point->size = this->num_natural_variables(); if (isSamePoint_homogeneous_input(curr_point, in_point, T->final_tol_times_mult)) { is_new = 0; in_point->size = in_size; curr_point->size = curr_size; break; } // restore the sizes in_point->size = in_size; curr_point->size = curr_size; } if (is_new==1) WitnessSet::add_point( (in_point) ); } for (unsigned int ii = 0; ii<W_in.num_patches(); ii++) { int is_new = 1; for (unsigned int jj = 0; jj<this->num_patches(); jj++){ if ( this->patch(jj)->size == W_in.patch(ii)->size) { if (isSamePoint_inhomogeneous_input(patch(jj), W_in.patch(ii), T->final_tol_times_mult)) { is_new = 0; break; } } } if (is_new==1) WitnessSet::add_patch(W_in.patch(ii)); } return; }//re: merge_witness_sets
int compute_crit_nullspace_right(SolverOutput & solve_out, // the returned value const WitnessSet & W, std::shared_ptr<SystemRandomizer> randomizer, vec_mp *pi, // an array of projections, the number of which is the target dimensions int ambient_dim, BertiniRealConfig & program_options, SolverConfiguration & solve_options, NullspaceConfiguration *ns_config) { //many of the 1's here should be replaced by the number of patch equations, or the number of variable_groups // get the max degree of the derivative functions. this is unique to the left nullspace formulation, as the functions become mixed together int max_degree; nullspace_config_setup_right(ns_config, pi, ambient_dim, &max_degree, randomizer, W, solve_options); if (max_degree==0) { // this will probably need tweaking when the dimension is higher than 1. but who really is going to decompose a linear surface? solve_out.copy_patches(W); ns_concluding_modifications(solve_out, W, ns_config); std::cout << "the highest degree of any derivative equation is 0. Returning empty SolverOutput." << std::endl; //then there cannot possibly be any critical points, with respect to ANY projection. simply return an empty but complete set. return 0; } // /// ///// end setup //////// ////////////// /////////////////////////// int offset; WitnessSet Wtemp, Wtemp2; // 2. Do a bunch of homotopies in $x$, each set of which will be followed by a single linear solve in $v$. if (program_options.verbose_level()>=3) { std::cout << "building up linprod start system for left nullspace" << std::endl; } // setup for the multilin moves // these are for feeding into the multilin solver -- and that's it. the majority will be overridden in the while loop as the start x linears vec_mp *multilin_linears = (vec_mp *) br_malloc(W.num_linears()*sizeof(vec_mp)); // target dim is the number of linears in the input witness set for (unsigned int ii=0; ii<W.num_linears(); ii++) { init_vec_mp2(multilin_linears[ii],W.num_variables(), solve_options.T.AMP_max_prec); multilin_linears[ii]->size = W.num_variables(); vec_cp_mp(multilin_linears[ii], W.linear(ii)); } MultilinConfiguration ml_config(solve_options,randomizer); // this is for performing the matrix inversion to get ahold of the $v$ values corresponding to $x$ mat_mp tempmat; init_mat_mp2(tempmat, ns_config->num_v_vars, ns_config->num_v_vars,solve_options.T.AMP_max_prec); tempmat->rows = tempmat->cols = ns_config->num_v_vars; offset = ns_config->num_v_vars-1; for (int jj=0; jj<ns_config->num_v_vars; jj++) set_mp(&tempmat->entry[offset][jj], &ns_config->v_patch->coord[jj]); // for holding the result of the matrix inversion vec_mp result; init_vec_mp2(result,ns_config->num_v_vars,solve_options.T.AMP_max_prec); result->size = ns_config->num_v_vars; // use this for the matrix inversion vec_mp invert_wrt_me; init_vec_mp2(invert_wrt_me,ns_config->num_v_vars,solve_options.T.AMP_max_prec); invert_wrt_me->size = ns_config->num_v_vars; for (int ii=0; ii<ns_config->num_v_vars-1; ii++) set_zero_mp(&invert_wrt_me->coord[ii]); // set zero set_one_mp(&invert_wrt_me->coord[ns_config->num_v_vars-1]); // the last entry is set to 1 for the patch equation vec_mp temppoint; init_vec_mp2(temppoint, ns_config->num_natural_vars +ns_config->num_synth_vars + ns_config->num_v_vars,solve_options.T.AMP_max_prec); temppoint->size = ns_config->num_natural_vars + ns_config->num_synth_vars + ns_config->num_v_vars; WitnessSet W_step_one; W_step_one.set_num_variables(W.num_variables()); W_step_one.set_num_natural_variables(W.num_natural_variables()); W_step_one.copy_patches(W); W_step_one.copy_names(W); WitnessSet W_linprod; W_linprod.set_num_variables(ns_config->num_natural_vars + ns_config->num_v_vars + ns_config->num_synth_vars); W_linprod.set_num_natural_variables(W.num_natural_variables()); if (program_options.quick_run()<=1) solve_options.robust = true; else solve_options.robust = false; for (int ii=0; ii<randomizer->num_rand_funcs(); ii++) { int differentiated_degree = randomizer->randomized_degree(ii)-1; // the -1 is for differentiating. this could be 0. if (differentiated_degree==0) { continue; } else{ for (int jj=0; jj<differentiated_degree; jj++) { //copy in the linear for the solve vec_cp_mp(multilin_linears[0], ns_config->starting_linears[ii][jj]); // the remainder of the linears are left alone (stay stationary). if (program_options.verbose_level()>=6) { std::cout << "moving FROM this set:\n"; for (unsigned int ii=0; ii<W.num_linears(); ii++) { print_point_to_screen_matlab(W.linear(ii),"L"); } std::cout << "\nTO this set:\n"; for (unsigned int ii=0; ii<W.num_linears(); ii++) { print_point_to_screen_matlab(multilin_linears[ii],"ELL"); } } // actually solve WRT the linears SolverOutput fillme; multilin_solver_master_entry_point(W, // WitnessSet fillme, // the new data is put here! multilin_linears, ml_config, solve_options); WitnessSet Wtemp; fillme.get_noninfinite_w_mult_full(Wtemp); // should be ordered W_step_one.merge(Wtemp, &solve_options.T); Wtemp.reset(); } int curr_index = 0; for (int kk=0; kk<ns_config->num_v_vars; kk++) { // subtract one from upper limit because of the patch equation if (kk!=ii) { for (int mm=0; mm<ns_config->num_v_vars; mm++){ set_mp(&tempmat->entry[curr_index][mm], &ns_config->v_linears[kk]->coord[mm]);} curr_index++; } } // invert the matrix for the v variables. matrixSolve_mp(result, tempmat, invert_wrt_me); //set the bottom part of the temppoint, which will be a startpoint for the nullspace call later. offset = ns_config->num_natural_vars+ns_config->num_synth_vars; for (int mm=0; mm<ns_config->num_v_vars; mm++) set_mp(&temppoint->coord[mm+offset], &result->coord[mm]); //set the top part, x, of the start point, and copy it in. for (unsigned int kk=0; kk<W_step_one.num_points(); kk++) { for (int mm=0; mm<ns_config->num_natural_vars+ns_config->num_synth_vars; mm++) { set_mp(&temppoint->coord[mm], & W_step_one.point(kk)->coord[mm]); } W_linprod.add_point(temppoint); } W_step_one.reset(); W_step_one.set_num_variables(W.num_variables()); W_step_one.set_num_natural_variables(W.num_natural_variables()); W_step_one.copy_patches(W); // necessary? W_step_one.copy_names(W); // necessary? } } for (int ii=0; ii<1; ii++) clear_vec_mp(multilin_linears[ii]); free(multilin_linears); clear_vec_mp(temppoint); int num_before = W_linprod.num_points(); W_linprod.sort_for_unique(&solve_options.T); if (num_before - W_linprod.num_points()>0) { std::cout << "there were non-unique start points" << std::endl; mypause(); } W_linprod.set_num_natural_variables(ns_config->num_v_vars+ns_config->num_synth_vars); W_linprod.copy_patches(W); W_linprod.copy_names(W); //set some solver options if (program_options.quick_run()<=0) solve_options.robust = true; else solve_options.robust = false; solve_options.use_midpoint_checker = 0; if (program_options.verbose_level()>=6) ns_config->print(); if (program_options.verbose_level()>=3) { std::cout << "running nullspace right method" << std::endl; } nullspacejac_solver_master_entry_point(solve_options.T.MPType, W_linprod, // carries with it the start points, but not the linears. solve_out, // the created data goes in here. ns_config, solve_options); ns_concluding_modifications(solve_out, W, ns_config); clear_mat_mp(tempmat); clear_vec_mp(invert_wrt_me); clear_vec_mp(result); return SUCCESSFUL; }
int sphere_solver_master_entry_point(const WitnessSet &W, // carries with it the start points, and the linears. SolverOutput &solve_out, // new data goes in here SphereConfiguration & config, SolverConfiguration & solve_options) { if (solve_options.use_parallel()) { solve_options.call_for_help(SPHERE_SOLVER); } sphere_eval_data_d *ED_d = NULL; sphere_eval_data_mp *ED_mp = NULL; switch (solve_options.T.MPType) { case 0: ED_d = new sphere_eval_data_d(0); ED_d->setup(config, W, solve_options); break; case 1: ED_mp = new sphere_eval_data_mp(1); ED_mp->setup(config, W, solve_options); // // initialize latest_newton_residual_mp // mpf_init(solve_options.T.latest_newton_residual_mp); // <------ THIS LINE IS ABSOLUTELY CRITICAL TO CALL break; case 2: ED_d = new sphere_eval_data_d(2); ED_mp = ED_d->BED_mp; ED_d->setup(config, W, solve_options); adjust_tracker_AMP(& (solve_options.T), W.num_variables()); break; default: break; } master_solver(solve_out, W, ED_d, ED_mp, solve_options); switch (solve_options.T.MPType) { case 0: delete ED_d; break; case 1: delete ED_mp; break; case 2: delete ED_d; break; default: { std::stringstream printme; printme << "trying to use an MPType which is not 0, 1, or 2. yours is " << solve_options.T.MPType << std::endl; throw std::logic_error(printme.str()); break; } } for (unsigned int jj=0; jj<W.num_linears(); jj++) { solve_out.add_linear(W.linear(jj)); } return SUCCESSFUL; }
int sphere_eval_data_d::setup(SphereConfiguration & config, const WitnessSet & W, SolverConfiguration & solve_options) { SLP_memory = config.SLP_memory; // set up the vectors to hold the two linears. mp_to_d(radius, config.radius); vec_mp_to_d(center, config.center); if (this->center->size < W.num_variables()) { int old_size = this->center->size; increase_size_vec_d(this->center, W.num_variables()); this->center->size = W.num_variables(); for (int ii=old_size; ii<W.num_variables(); ii++) { set_zero_d(&this->center->coord[ii]); } } if (this->num_static_linears==0) { static_linear = (vec_d *) br_malloc(W.num_linears()*sizeof(vec_d)); } else { static_linear = (vec_d *) br_realloc(static_linear, W.num_linears()*sizeof(vec_d)); } for (unsigned int ii=0; ii<W.num_linears(); ii++) { init_vec_d(static_linear[ii],0); vec_mp_to_d(static_linear[ii],W.linear(ii)); } num_static_linears = W.num_linears(); num_natural_vars = W.num_natural_variables(); num_variables = W.num_variables(); for (int ii=0; ii<2; ii++) { vec_mp_to_d(starting_linear[ii],config.starting_linear[ii]); } verbose_level(solve_options.verbose_level()); SolverDoublePrecision::setup(config.SLP, config.randomizer()); generic_setup_patch(&patch,W); if (solve_options.use_gamma_trick==1) get_comp_rand_d(this->gamma); // set gamma to be random complex value else set_one_d(this->gamma); if (this->MPType==2) { this->BED_mp->setup(config, W, solve_options); rat_to_d(this->gamma, this->BED_mp->gamma_rat); } return 0; }
int sphere_eval_data_mp::setup(SphereConfiguration & config, const WitnessSet & W, SolverConfiguration & solve_options) { if (config.randomizer().use_count()==0) { std::cout << "don't have randomizer set up!" << std::endl; br_exit(-97621); } if (!config.have_mem) { std::cout << "don't have memory!" << std::endl; br_exit(-3231); } this->SLP_memory = config.SLP_memory; num_natural_vars = W.num_natural_variables(); num_variables = W.num_variables(); // set up the vectors to hold the linears. if (this->num_static_linears==0) { static_linear = (vec_mp *) br_malloc(W.num_linears()*sizeof(vec_mp)); } else { static_linear = (vec_mp *) br_realloc(static_linear, W.num_linears()*sizeof(vec_mp)); } for (unsigned int ii=0; ii<W.num_linears(); ii++) { init_vec_mp(static_linear[ii],0); vec_cp_mp(static_linear[ii],W.linear(ii)); } set_mp(this->radius, config.radius); vec_cp_mp(this->center, config.center); if (this->center->size < W.num_variables()) { int old_size = this->center->size; increase_size_vec_mp(this->center, W.num_variables()); this->center->size = W.num_variables(); for (int ii=old_size; ii<W.num_variables(); ii++) { set_zero_mp(&this->center->coord[ii]); } } if (this->MPType==2) { set_mp(this->radius_full_prec, config.radius); vec_cp_mp(this->center_full_prec, config.center); if (this->center_full_prec->size < W.num_variables()) { int old_size = this->center_full_prec->size; increase_size_vec_mp(this->center_full_prec, W.num_variables()); this->center_full_prec->size = W.num_variables(); for (int ii=old_size; ii<W.num_variables(); ii++) { set_zero_mp(&this->center_full_prec->coord[ii]); } } if (this->num_static_linears==0) { static_linear_full_prec = (vec_mp *) br_malloc(W.num_linears()*sizeof(vec_mp)); } else { static_linear_full_prec = (vec_mp *) br_realloc(static_linear_full_prec, W.num_linears()*sizeof(vec_mp)); } for (unsigned int ii=0; ii<W.num_linears(); ii++) { init_vec_mp2(static_linear_full_prec[ii],0,1024); vec_cp_mp(static_linear_full_prec[ii], W.linear(ii)); } } this->num_static_linears = W.num_linears(); for (int ii=0; ii<2; ii++) { vec_cp_mp( this->starting_linear[ii], config.starting_linear[ii]); if (MPType==2) { vec_cp_mp(this->starting_linear_full_prec[ii], config.starting_linear[ii]); } } // the usual verbose_level(solve_options.verbose_level()); SolverMultiplePrecision::setup(config.SLP, config.randomizer()); generic_setup_patch(&patch,W); if (solve_options.use_gamma_trick==1) get_comp_rand_mp(this->gamma); // set gamma to be random complex value else{ set_one_mp(this->gamma); } comp_d temp; if (this->MPType==2) { if (solve_options.use_gamma_trick==1){ get_comp_rand_rat(temp, this->gamma, this->gamma_rat, 64, solve_options.T.AMP_max_prec, 0, 0); } else{ set_one_mp(this->gamma); set_one_rat(this->gamma_rat); } } return 0; }