Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
midpath_check.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//include/bertini2/nag_algorithms/midpath_check.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//include/bertini2/nag_algorithms/midpath_check.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with include/bertini2/nag_algorithms/midpath_check.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) 2015 - 2021 by Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
22// individual authors of this file include:
23// James Collins, West Texas A&M University
24// silviana amethyst, university of wisconsin-eau claire
25
26
34
35
36#pragma once
37
38#include "bertini2/nag_algorithms/common/config.hpp"
40
41namespace bertini{
42 namespace algorithm{
43
44
45 template<typename RealType, typename ComplexType, typename MetaDataType>
46 struct MidpathChecker : public detail::Configured<MidPathConfig>
47 {
48 using MidPathConfT = MidPathConfig;
49 using AlgConf = detail::Configured<MidPathConfig>;
50 using BoundaryData = SolnCont< MetaDataType >;
51 using PathIndT = unsigned long long;
52
53
54 MidpathChecker() = default;
55
61 template<typename ...T>
62 MidpathChecker( T const& ...config) : AlgConf(config...)
63 {
64 passed_ = true;
65 }
66
67
74 struct CrossedPath{
75
76 CrossedPath(PathIndT index, PathIndT crossed_with, bool same_start)
77 {
78 index_ = index;
79 crossed_with_.push_back( std::make_pair(crossed_with, same_start) );
80 rerun_ = !same_start;
81 }
82
83
84 PathIndT index() const
85 {
86 return index_;
87 }
88
89 void crossed_with(std::pair<PathIndT, bool> crossed)
90 {
91 crossed_with_.push_back(crossed);
92 }
93
94 void rerun(bool same_start)
95 {
96 rerun_ = rerun_ || !same_start;
97 }
98
99 bool rerun() const
100 {
101 return rerun_;
102 }
103
104
105 private:
106 PathIndT index_;
107 std::vector< std::pair<PathIndT, bool> > crossed_with_; // first is index of path crossed with, second is bool = true if had same starting point as crossed path
108 bool rerun_;
109
110
111 }; //re: struct CrossedPath
112
113
114
115 bool Passed() const
116 {
117 return passed_;
118 }
119
120
121 const auto& SamePointTol() const
122 {
123 return this->template Get<MidPathConfT>().same_point_tolerance;
124 }
125
134 template <typename StartSystemT>
135 bool Check(BoundaryData const& boundary_data, StartSystemT const& start_system)
136 {
137 for (PathIndT ii = 0; ii < boundary_data.size(); ++ii)
138 {
139 if ( boundary_data[ii].success_code != SuccessCode::Success)
140 continue;
141
142 const Vec<ComplexType>& solution_ii = boundary_data[ii].path_point;
143 const auto start_ii = start_system.template StartPoint<ComplexType>(ii);
144
145 for (PathIndT jj = ii+1; jj < boundary_data.size(); ++jj)
146 {
147 if ( boundary_data[jj].success_code != SuccessCode::Success)
148 continue;
149
150 const Vec<ComplexType>& solution_jj = boundary_data[jj].path_point;
151 const Vec<ComplexType> diff_sol = solution_ii - solution_jj;
152
153 if ((diff_sol.template lpNorm<Eigen::Infinity>()/solution_ii.template lpNorm<Eigen::Infinity>()) < SamePointTol())
154 {
155 bool i_already_stored = false;
156 bool j_already_stored = false;
157 // Check if start points are the same
158
159 const auto start_jj = start_system.template StartPoint<ComplexType>(jj);
160 auto diff_start = start_ii - start_jj;
161 bool same_start = (diff_start.template lpNorm<Eigen::Infinity>() > SamePointTol());
162
163
164 // Check if path has already been stored in crossed_paths_
165 for(auto& v : crossed_paths_)
166 {
167 if(v.index() == ii)
168 {
169 v.crossed_with(std::make_pair(jj,same_start));
170 i_already_stored = true;
171 v.rerun(same_start);
172 }
173 if(v.index() == jj)
174 {
175 v.crossed_with(std::make_pair(ii,same_start));
176 j_already_stored = true;
177 v.rerun(same_start);
178 }
179 }
180
181 // If not already stored, create CrossedPath object and add to crossed_paths_
182 if(!i_already_stored)
183 {
184 CrossedPath tempPath(ii, jj, same_start);
185 crossed_paths_.push_back(tempPath);
186 }
187 if(!j_already_stored)
188 {
189 CrossedPath tempPath(jj, ii, same_start);
190 crossed_paths_.push_back(tempPath);
191 }
192
193 passed_ = false;
194
195 }
196 }
197 }
198 return passed_;
199 };
200
201
202 const std::vector<CrossedPath> GetCrossedPaths() const
203 {
204 return crossed_paths_;
205 }
206
207
208
209 private:
210
211 std::vector<CrossedPath> crossed_paths_; // Data for all paths that crossed on last check
212 bool passed_; // Did the check pass?
213
214
215 }; //re: struct MidpathChecker
216
217 } // re: namespace algorithm
218}// re: namespace bertini
Contains the detail/configured helper type, for templated getting/setting/storage of config structs.