243 public virtual AnyZeroDim,
245 public SystemManagementP<SystemType, StartSystemType>,
247 typename AlgoTraits< ZeroDim<TrackerType, EndgameType, SystemType, StartSystemType, SystemManagementP>>::NeededConfigs>
250 using TrackerT = TrackerType;
251 using EndgameT = EndgameType;
252 using SystemT = SystemType;
253 using StartSystemT = StartSystemType;
259 using BaseComplexType =
typename tracking::TrackerTraits<TrackerType>::BaseComplexType;
260 using BaseRealType =
typename tracking::TrackerTraits<TrackerType>::BaseRealType;
262 using PrecisionConfig =
typename tracking::TrackerTraits<TrackerType>::PrecisionConfig;
264 using SolnIndT =
typename SolnCont<BaseComplexType>::size_type;
266 using SystemManagementPolicy = SystemManagementP<SystemType, StartSystemType>;
268 using StoredSystemT =
typename SystemManagementPolicy::StoredSystemT;
269 using StoredStartSystemT =
typename SystemManagementPolicy::StoredStartSystemT;
273 typename AlgoTraits<ZeroDim<TrackerType, EndgameType, SystemType, StartSystemType, SystemManagementP>>::NeededConfigs>;
277 using Tolerances = TolerancesConfig;
278 using PostProcessing = PostProcessingConfig;
279 using ZeroDimConf = ZeroDimConfig<BaseComplexType>;
280 using AutoRetrack = AutoRetrackConfig;
283 using EGBoundaryMetaDataT = EGBoundaryMetaData<BaseComplexType>;
284 using SolutionMetaDataT = SolutionMetaData<BaseComplexType>;
289 using MidpathType = MidpathChecker<BaseRealType, BaseComplexType, EGBoundaryMetaData<BaseComplexType>>;
291 using SystemManagementPolicy::TargetSystem;
292 using SystemManagementPolicy::StartSystem;
293 using SystemManagementPolicy::Homotopy;
306 template<
typename ... SysTs>
307 ZeroDim(SysTs
const& ...sys) : SystemManagementPolicy(sys...), tracker_(TargetSystem()), endgame_(tracker_)
329 if (TargetSystem().HavePathVariable())
330 throw std::runtime_error(
"unable to perform zero dim solve on target system -- has path variable, use user homotopy instead.");
332 if (TargetSystem().NumVariables() > TargetSystem().NumTotalFunctions())
333 throw std::runtime_error(
"unable to perform zero dim solve on target system -- underconstrained, so has no zero dimensional solutions.");
335 if (!TargetSystem().IsPolynomial())
336 throw std::runtime_error(
"unable to perform zero dim solve on target system -- system is non-polynomial, use user homotopy instead.");
344 DefaultSystemSetup();
352 void DefaultSystemSetup()
354 SystemManagementPolicy::SystemSetup(this->
template Get<ZeroDimConf>().path_variable_name);
355 num_start_points_ = StartSystem().NumStartPoints();
372 this->
template Set<Tolerances>(Tolerances());
373 this->
template Set<PostProcessing>(PostProcessing());
374 this->
template Set<ZeroDimConf>(ZeroDimConf());
375 this->
template Set<AutoRetrack>(AutoRetrack());
378 void SetMidpathRetrackTol(NumErrorT
const& rt)
380 midpath_retrack_tolerance_ = rt;
383 const auto& MidpathRetrackTol()
const
385 return midpath_retrack_tolerance_;
394 midpath_ = MidpathType(MidPathConfig());
398 void SetMidpath(MidPathConfig
const& mp)
410 tracker_.SetSystem(Homotopy());
412 this->
template Get<Tolerances>().newton_before_endgame,
413 this->
template Get<Tolerances>().path_truncation_threshold,
414 tracking::SteppingConfig(), tracking::NewtonConfig());
416 tracker_.PrecisionSetup(PrecisionConfig(Homotopy()));
431 tracker_ = new_tracker;
432 endgame_.SetTracker(tracker_);
466 endgame_ = new_endgame;
491 const T & GetFromEndgame()
const
493 return endgame_.template Get<T>();
497 void SetToEndgame(T
const& t)
542 return solutions_post_endgame_;
550 return solution_final_metadata_;
558 return solutions_at_endgame_boundary_;
566 void PreSolveChecks()
const
568 if (num_start_points_ > solutions_at_endgame_boundary_.max_size())
569 throw std::runtime_error(
"start system has more solutions than container for results. I refuse to continue until this has been addressed.");
575 auto num_as_size_t =
static_cast<SolnIndT
>(num_start_points_);
577 solution_final_metadata_.resize(num_as_size_t);
578 solutions_at_endgame_boundary_.resize(num_as_size_t);
579 solutions_post_endgame_.resize(num_as_size_t);
581 SetMidpathRetrackTol(this->
template Get<Tolerances>().newton_before_endgame);
593 DefaultPrecision(this->
template Get<ZeroDimConf>().initial_ambient_precision);
595 GetTracker().SetTrackingTolerance(this->
template Get<Tolerances>().newton_before_endgame);
597 auto t_start = this->
template Get<ZeroDimConf>().start_time;
598 auto t_endgame_boundary = this->
template Get<ZeroDimConf>().endgame_boundary;
600 for (
decltype(num_start_points_) ii{0}; ii < num_start_points_; ++ii)
602 TrackSinglePathBeforeEG(
static_cast<SolnIndT
>(ii));
611 void TrackSinglePathBeforeEG(SolnIndT soln_ind)
614 if (tracking::TrackerTraits<TrackerType>::IsAdaptivePrec)
620 auto& smd = solution_final_metadata_[soln_ind];
622 smd.path_index = soln_ind;
623 smd.solution_index = soln_ind;
625 DefaultPrecision(this->
template Get<ZeroDimConf>().initial_ambient_precision);
626 auto t_start = this->
template Get<ZeroDimConf>().start_time;
627 auto t_endgame_boundary = this->
template Get<ZeroDimConf>().endgame_boundary;
628 auto start_point = StartSystem().template StartPoint<BaseComplexType>(soln_ind);
630 Vec<BaseComplexType> result;
631 auto tracking_success =
GetTracker().TrackPath(result, t_start, t_endgame_boundary, start_point);
633 solutions_at_endgame_boundary_[soln_ind] = EGBoundaryMetaDataT({ result, tracking_success,
GetTracker().CurrentStepsize() });
635 smd.pre_endgame_success = tracking_success;
638 if (tracking::TrackerTraits<TrackerType>::IsAdaptivePrec)
640 if (first_prec_rec_.DidPrecisionIncrease())
642 smd.precision_changed =
true;
643 smd.time_of_first_prec_increase = first_prec_rec_.TimeOfIncrease();
649 smd.max_precision_used =
650 max(smd.max_precision_used, min_max_prec_.MaxPrecision());
656 void EGBoundaryAction()
658 auto midcheckpassed = midpath_.Check(solutions_at_endgame_boundary_, StartSystem());
660 unsigned num_resolve_attempts = 0;
661 while (!midcheckpassed && num_resolve_attempts < this->
template Get<ZeroDimConf>().max_num_crossed_path_resolve_attempts)
664 midcheckpassed = midpath_.Check(solutions_at_endgame_boundary_, StartSystem());
665 num_resolve_attempts++;
670 void MidpathResolve()
672 ShrinkMidpathTolerance();
674 for(
auto const& v : midpath_.GetCrossedPaths())
678 unsigned long long index = v.index();
679 auto soln_ind =
static_cast<SolnIndT
>(index);
680 TrackSinglePathBeforeEG(soln_ind);
687 void ShrinkMidpathTolerance()
689 midpath_retrack_tolerance_ *= this->
template Get<AutoRetrack>().midpath_decrease_tolerance_factor;
690 GetTracker().SetTrackingTolerance(midpath_retrack_tolerance_);
698 GetTracker().SetTrackingTolerance(this->
template Get<Tolerances>().newton_during_endgame);
700 for (
decltype(num_start_points_) ii{0}; ii < num_start_points_; ++ii)
702 auto soln_ind =
static_cast<SolnIndT
>(ii);
704 if (solution_final_metadata_[soln_ind].pre_endgame_success != SuccessCode::Success)
707 TrackSinglePathDuringEG(soln_ind);
712 void TrackSinglePathDuringEG(SolnIndT soln_ind)
715 auto& smd = solution_final_metadata_[soln_ind];
717 if (tracking::TrackerTraits<TrackerType>::IsAdaptivePrec)
719 if (!smd.precision_changed)
724 const auto& bdry_point = solutions_at_endgame_boundary_[soln_ind].path_point;
727 GetTracker().SetStepSize(solutions_at_endgame_boundary_[soln_ind].last_used_stepsize);
728 GetTracker().ReinitializeInitialStepSize(
false);
733 BaseComplexType t_endgame_boundary = this->
template Get<ZeroDimConf>().endgame_boundary;
735 auto eg_success =
GetEndgame().Run(t_endgame_boundary, bdry_point, t_end);
737 solutions_post_endgame_[soln_ind] =
GetEndgame().template FinalApproximation<BaseComplexType>();
741 smd.endgame_success = eg_success;
743 if (tracking::TrackerTraits<TrackerType>::IsAdaptivePrec)
745 if (!smd.precision_changed)
747 if (first_prec_rec_.DidPrecisionIncrease())
749 smd.precision_changed =
true;
750 smd.time_of_first_prec_increase = first_prec_rec_.TimeOfIncrease();
756 smd.max_precision_used =
757 max(smd.max_precision_used, min_max_prec_.MaxPrecision());
759 if (tracking::TrackerTraits<TrackerType>::IsAdaptivePrec)
762 DefaultPrecision(
Precision(solutions_post_endgame_[soln_ind]));
763 TargetSystem().precision(
Precision(solutions_post_endgame_[soln_ind]));
765 smd.function_residual =
static_cast<NumErrorT
>(TargetSystem().Eval(solutions_post_endgame_[soln_ind]).template lpNorm<Eigen::Infinity>());
766 smd.final_time_used =
GetEndgame().LatestTime();
767 smd.condition_number =
GetTracker().LatestConditionNumber();
768 smd.newton_residual =
GetTracker().LatestNormOfStep();
770 smd.accuracy_estimate =
GetEndgame().ApproximateError();
771 smd.accuracy_estimate_user_coords =
772 static_cast<NumErrorT
>( (TargetSystem().DehomogenizePoint(solutions_post_endgame_[soln_ind]) -
773 TargetSystem().DehomogenizePoint(
GetEndgame().
template PreviousApproximation<BaseComplexType>())).template lpNorm<Eigen::Infinity>() );
782 ComputePostTrackMetadata();
792 void ComputePostTrackMetadata()
794 ComputeMultiplicities();
797 void ComputeMultiplicities()
799 std::vector<std::vector<int>> multiplicity_indices(num_start_points_);
801 for (
decltype(num_start_points_) ii{0}; ii < num_start_points_; ++ii)
803 if (solution_final_metadata_[ii].endgame_success!=SuccessCode::Success)
806 for (
decltype(num_start_points_) jj{ii+1}; jj < num_start_points_; ++jj)
808 if (solution_final_metadata_[jj].endgame_success!=SuccessCode::Success)
811 if ( (solutions_post_endgame_[ii] - solutions_post_endgame_[jj]).norm() < this->
template Get<PostProcessing>().same_point_tolerance)
813 multiplicity_indices[ii].push_back(jj);
814 multiplicity_indices[jj].push_back(ii);
815 ++solution_final_metadata_[ii].multiplicity;
816 ++solution_final_metadata_[jj].multiplicity;
828 unsigned long long num_start_points_;
829 NumErrorT midpath_retrack_tolerance_;
834 tracking::FirstPrecisionRecorder<TrackerType> first_prec_rec_;
835 tracking::MinMaxPrecisionRecorder<TrackerType> min_max_prec_;
839 TrackerType tracker_;
840 EndgameType endgame_;
841 MidpathType midpath_;
846 SolnCont< EGBoundaryMetaDataT > solutions_at_endgame_boundary_;
847 SolnCont<Vec<BaseComplexType> > solutions_post_endgame_;
848 SolnCont<SolutionMetaDataT> solution_final_metadata_;