59 class LinearProduct :
public virtual Symbol,
public virtual EnableSharedFromThisVirtual<LinearProduct>
62 BERTINI_DEFAULT_VISITABLE()
64 virtual ~LinearProduct() =
default;
67 template<
typename... Ts>
69 std::shared_ptr<LinearProduct> Make(Ts&& ...ts){
70 return std::shared_ptr<LinearProduct>(
new LinearProduct(ts...) );
82 LinearProduct(VariableGroup variables,
int num_factors,
bool is_hom_vars =
false) :
83 variables_(variables), num_factors_(num_factors), is_hom_vars_(is_hom_vars)
88 Mat<dbl>& coeffs_dbl_ref = std::get<Mat<dbl>>(coeffs_);
90 Mat<mpfr_complex>& coeffs_mpfr_ref = std::get<Mat<mpfr_complex>>(coeffs_);
98 SetupVariables(num_factors, variables);
99 coeffs_rat_real_.resize(num_factors_, num_variables_+1);
100 coeffs_rat_imag_.resize(num_factors_, num_variables_+1);
103 for (
int ii = 0; ii < num_factors_; ++ii)
105 for (
int jj = 0; jj < num_variables_+1; ++jj)
111 coeffs_dbl_ref(ii,jj).real(
static_cast<double>(coeffs_rat_real_(ii,jj)) );
112 coeffs_dbl_ref(ii,jj).imag(
static_cast<double>(coeffs_rat_imag_(ii,jj)) );
113 coeffs_mpfr_ref(ii,jj).real(
static_cast<mpfr_float
>(coeffs_rat_real_(ii,jj)) );
114 coeffs_mpfr_ref(ii,jj).imag(
static_cast<mpfr_float
>(coeffs_rat_imag_(ii,jj)) );
118 is_rational_coeffs_ =
true;
124 is_homogenized_ =
true;
125 hom_variable_ = Integer::Make(0);
126 for(
int ii = 0; ii < coeffs_mpfr_ref.rows(); ++ii)
128 coeffs_rat_real_(ii,num_variables_) = mpq_rational(0);
129 coeffs_rat_imag_(ii,num_variables_) = mpq_rational(0);
130 coeffs_dbl_ref(ii,num_variables_) = dbl(0);
131 coeffs_mpfr_ref(ii,num_variables_) = mpfr_complex(0);
149 LinearProduct(VariableGroup
const& variables, Mat<mpfr_complex>
const& coeffs_mpfr,
bool is_hom_vars =
false)
150 : variables_(variables), num_factors_(coeffs_mpfr.rows()), is_hom_vars_(is_hom_vars)
152 if(variables.size()+1 != coeffs_mpfr.cols())
153 throw std::runtime_error(
"attempting to construct a linear product manually, not enough columns for the number of variables in the variable group");
157 Mat<dbl>& coeffs_dbl_ref = std::get<Mat<dbl>>(coeffs_);
158 Mat<mpfr_complex>& coeffs_mpfr_ref = std::get<Mat<mpfr_complex>>(coeffs_);
160 SetupVariables(num_factors_, variables);
162 coeffs_mpfr_ref = coeffs_mpfr;
168 is_homogenized_ =
true;
169 hom_variable_ = Integer::Make(0);
170 for(
int ii = 0; ii < coeffs_mpfr_ref.rows(); ++ii)
172 coeffs_mpfr_ref(ii,num_variables_) = mpfr_complex(0);
178 for(
int ii = 0; ii < num_factors_; ++ii)
180 for(
int jj = 0; jj < coeffs_mpfr.cols(); ++jj)
182 coeffs_dbl_ref(ii,jj) =
static_cast<dbl
>(coeffs_mpfr_ref(ii,jj));
187 is_rational_coeffs_ =
false;
224 for(
auto& v : variables_)
234 void print(std::ostream & target)
const override;
242 std::shared_ptr<Node>
Differentiate(std::shared_ptr<Variable>
const& v =
nullptr)
const override ;
253 int Degree(std::shared_ptr<Variable>
const& v =
nullptr)
const override;
266 int Degree(VariableGroup
const& vars)
const override;
275 std::vector<int>
MultiDegree(VariableGroup
const& vars)
const override;
289 void Homogenize(VariableGroup
const& vars, std::shared_ptr<Variable>
const& homvar)
override;
301 bool IsHomogeneous(std::shared_ptr<Variable>
const& v =
nullptr)
const override;
310 bool IsHomogeneous(VariableGroup
const& vars)
const override;
319 virtual void precision(
unsigned int prec)
const override
321 auto& val_pair = std::get< std::pair<mpfr_complex,bool> >(current_value_);
322 val_pair.first.precision(prec);
324 this->PrecisionChangeSpecific(prec);
326 for (
auto iter : variables_)
327 iter->precision(prec);
370 hom_var = hom_variable_;
378 void GetRatCoeffs(Mat<mpq_rational>& coeffs_real, Mat<mpq_rational>& coeffs_imag)
const
380 coeffs_real = coeffs_rat_real_;
381 coeffs_imag = coeffs_rat_imag_;
389 auto& coeffs_mpfr_ref = std::get<Mat<mpfr_complex>>(coeffs_);
390 coeffs = coeffs_mpfr_ref;
398 return is_rational_coeffs_;
410 template<
typename CType>
413 Vec<CType> coeff_ret(num_variables_ + 1);
414 Mat<CType>& coeff_ref = std::get<Mat<CType>>(coeffs_);
416 for(
int jj = 0; jj < num_variables_ + 1; ++jj)
418 coeff_ret(jj) = coeff_ref(index,jj);
445 dbl
FreshEval_d(std::shared_ptr<Variable>
const& diff_variable)
const override
459 void FreshEval_d(dbl& evaluation_value, std::shared_ptr<Variable>
const& diff_variable)
const override
461 evaluation_value = dbl(1);
462 const Mat<dbl>& coeffs_ref = std::get< Mat<dbl> >(coeffs_);
466 for (
int jj = 0; jj < num_variables_; ++jj)
468 variables_[jj]->EvalInPlace<dbl>(temp_var_d_[jj], diff_variable);
471 hom_variable_->EvalInPlace<dbl>(temp_var_d_[num_variables_], diff_variable);
479 for (
int ii = 0; ii < num_factors_; ++ii)
482 temp_sum_d_ = dbl(0);
483 for (
int jj = 0; jj < num_variables_ + 1; ++jj)
485 temp_sum_d_ += coeffs_ref(ii,jj)*temp_var_d_[jj];
490 evaluation_value *= temp_sum_d_;
500 mpfr_complex
FreshEval_mp(std::shared_ptr<Variable>
const& diff_variable)
const override
502 mpfr_complex eval_value;
515 void FreshEval_mp(mpfr_complex& evaluation_value, std::shared_ptr<Variable>
const& diff_variable)
const override
517 evaluation_value = mpfr_complex(1);
518 const Mat<mpfr_complex>& coeffs_ref = std::get< Mat<mpfr_complex> >(coeffs_);
521 for (
int jj = 0; jj < num_variables_; ++jj)
523 variables_[jj]->EvalInPlace<mpfr_complex>(temp_var_mp_[jj], diff_variable);
525 hom_variable_->EvalInPlace<mpfr_complex>(temp_var_mp_[num_variables_], diff_variable);
531 for (
int ii = 0; ii < num_factors_; ++ii)
534 temp_sum_mp_ = mpfr_complex(0);
535 for (
int jj = 0; jj < num_variables_ + 1; ++jj)
537 temp_sum_mp_ += coeffs_ref(ii,jj)*temp_var_mp_[jj];
542 evaluation_value *= temp_sum_mp_;
567 Mat<mpq_rational> coeffs_rat_real_;
569 Mat<mpq_rational> coeffs_rat_imag_;
571 std::tuple< Mat<dbl>, Mat<mpfr_complex> > coeffs_;
573 VariableGroup variables_;
575 std::shared_ptr<Node> hom_variable_;
579 size_t num_variables_;
580 bool is_rational_coeffs_;
581 bool is_homogenized_ =
false;
582 bool is_hom_vars_ =
false;
585 mutable std::vector<dbl> temp_var_d_;
586 mutable std::vector<mpfr_complex> temp_var_mp_;
587 mutable mpfr_complex temp_sum_mp_;
588 mutable dbl temp_sum_d_;
600 LinearProduct(VariableGroup
const& variables, std::shared_ptr<Node>
const& hom_var,
601 Mat<mpq_rational>
const& coeffs_real, Mat<mpq_rational>
const& coeffs_imag,
bool is_hom_vars) :
602 variables_(variables), num_factors_(coeffs_real.rows()), hom_variable_(hom_var), is_hom_vars_(is_hom_vars)
604 num_variables_ = variables.size();
607 Mat<dbl>& coeffs_dbl_ref = std::get<Mat<dbl>>(coeffs_);
608 coeffs_dbl_ref.resize(num_factors_, num_variables_+1);
609 Mat<mpfr_complex>& coeffs_mpfr_ref = std::get<Mat<mpfr_complex>>(coeffs_);
610 coeffs_mpfr_ref.resize(num_factors_, num_variables_+1);
613 temp_var_d_.resize(num_variables_ + 1);
614 temp_var_d_[num_variables_] = dbl(1);
615 temp_var_mp_.resize(num_variables_ + 1);
616 temp_var_mp_[num_variables_] = mpfr_complex(1);
619 coeffs_rat_real_ = coeffs_real;
620 coeffs_rat_imag_ = coeffs_imag;
622 for (
int ii = 0; ii < num_factors_; ++ii)
624 for (
int jj = 0; jj < num_variables_+1; ++jj)
626 coeffs_dbl_ref(ii,jj).real(
static_cast<double>(coeffs_rat_real_(ii,jj)) );
627 coeffs_dbl_ref(ii,jj).imag(
static_cast<double>(coeffs_rat_imag_(ii,jj)) );
628 coeffs_mpfr_ref(ii,jj).real(
static_cast<mpfr_float
>(coeffs_rat_real_(ii,jj)) );
629 coeffs_mpfr_ref(ii,jj).imag(
static_cast<mpfr_float
>(coeffs_rat_imag_(ii,jj)) );
633 is_rational_coeffs_ =
true;
637 is_homogenized_ =
true;
638 hom_variable_ = Integer::Make(0);
645 LinearProduct(VariableGroup
const& variables, std::shared_ptr<Node>
const& hom_var, Mat<mpfr_complex>
const& coeffs,
bool is_hom_vars) :
646 variables_(variables), num_factors_(coeffs.rows()), hom_variable_(hom_var), is_hom_vars_(is_hom_vars)
648 num_variables_ = variables.size();
651 Mat<dbl>& coeffs_dbl_ref = std::get<Mat<dbl>>(coeffs_);
652 coeffs_dbl_ref.resize(num_factors_, num_variables_+1);
653 Mat<mpfr_complex>& coeffs_mpfr_ref = std::get<Mat<mpfr_complex>>(coeffs_);
654 coeffs_mpfr_ref.resize(num_factors_, num_variables_+1);
657 temp_var_d_.resize(num_variables_ + 1);
658 temp_var_d_[num_variables_] = dbl(1);
659 temp_var_mp_.resize(num_variables_ + 1);
660 temp_var_mp_[num_variables_] = mpfr_complex(1);
662 coeffs_mpfr_ref = coeffs;
664 for (
int ii = 0; ii < num_factors_; ++ii)
666 for (
int jj = 0; jj < num_variables_+1; ++jj)
668 coeffs_dbl_ref(ii,jj) =
static_cast<dbl
>(coeffs_mpfr_ref(ii,jj));
672 is_rational_coeffs_ =
false;
676 is_homogenized_ =
true;
677 hom_variable_ = Integer::Make(0);
690 std::shared_ptr<LinearProduct> GetLinears(
size_t index)
const;
701 std::shared_ptr<LinearProduct> GetLinears(std::vector<size_t> indices)
const;
705 void SetupVariables(
size_t num_factors, VariableGroup
const& variables)
707 num_variables_ = variables.size();
710 Mat<dbl>& coeffs_dbl_ref = std::get<Mat<dbl>>(coeffs_);
711 coeffs_dbl_ref.resize(num_factors_, num_variables_+1);
712 Mat<mpfr_complex>& coeffs_mpfr_ref = std::get<Mat<mpfr_complex>>(coeffs_);
713 coeffs_mpfr_ref.resize(num_factors_, num_variables_+1);
716 temp_var_d_.resize(num_variables_ + 1);
717 temp_var_d_[num_variables_] = dbl(1);
718 temp_var_mp_.resize(num_variables_ + 1);
719 temp_var_mp_[num_variables_] = mpfr_complex(1);
721 hom_variable_ = Integer::Make(1);
727 friend class boost::serialization::access;
729 template <
typename Archive>
730 void serialize(Archive& ar,
const unsigned version) {
731 ar & boost::serialization::base_object<Symbol>(*
this);
735 void PrecisionChangeSpecific(
unsigned prec)
const
737 temp_sum_mp_.precision(prec);
738 for(
auto& v : temp_var_mp_)
743 Mat<mpfr_complex> coeffs_ref = std::get<Mat<mpfr_complex>>(coeffs_);
744 for(
int ii = 0; ii < coeffs_ref.rows(); ++ii)
746 for(
int jj = 0; jj < coeffs_ref.cols(); ++jj)
748 coeffs_ref(ii,jj).precision(prec);
749 coeffs_ref(ii,jj).real(
static_cast<mpfr_float
>(coeffs_rat_real_(ii,jj)) );
750 coeffs_ref(ii,jj).imag(
static_cast<mpfr_float
>(coeffs_rat_imag_(ii,jj)) );