00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __MMX_HOMOTOPY_POST_CERTIFY_HPP
00016 #define __MMX_HOMOTOPY_POST_CERTIFY_HPP
00017 #include <continewz/homotopy_ball.hpp>
00018 #include <continewz/homotopy_floating.hpp>
00019 #include <basix/vector_sort.hpp>
00020
00021 namespace mmx {
00022 #define Function slp_tangent<ball<C> >
00023
00024 template<typename V= homotopy_euler, typename W= homotopy_ball>
00025 struct homotopy_post_certify {};
00026
00027 template<typename C>
00028 struct homotopy_variant_helper<ball<C> > {
00029 typedef Homotopy_variant(C) V;
00030 typedef homotopy_post_certify<V> HV; };
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template<typename R> vector<vector<nat> >
00051 separate_balls (const vector<ball<R> >& v2) {
00052 typedef ball<R> B;
00053 nat n= N(v2);
00054 if (n == 0) return vector<vector<nat> > ();
00055 vector<B> v= copy (v2);
00056 vector<nat> sigma;
00057 sort (v, sigma);
00058
00059
00060 vector<R> lo= lower (v);
00061 vector<R> up= upper (v);
00062
00063
00064 for (nat i=1 ; i<n; i++) up[i] = max (up[i-1], up[i]);
00065 for (nat i=n-1; i>0; i--) lo[i-1]= min (lo[i-1], lo[i]);
00066
00067
00068 vector<vector<nat> > r;
00069 vector<nat> current;
00070 current << sigma[0];
00071 for (nat i=1; i<n; i++) {
00072 if (up[i-1] < lo[i]) {
00073 r << current;
00074 current= vector<nat> ();
00075 }
00076 current << sigma[i];
00077 }
00078 r << current;
00079
00080 return r;
00081 }
00082
00083 template<typename C> vector<vector<nat> >
00084 separate_balls (const vector<ball<C> >& v, const vector<vector<nat> >& in) {
00085 vector<vector<nat> > out;
00086 for (nat i=0; i<N(in); i++) {
00087 nat n= N(in[i]);
00088 if (n <= 1) { out << in[i]; continue; }
00089 vector<ball<C> > w= extract (v, in[i]);
00090 vector<vector<nat> > sub= separate_balls (w);
00091 for (nat j=0; j<N(sub); j++) {
00092
00093 nat l= N(sub[j]);
00094 vector<nat> add= fill<nat> (l);
00095 for (nat k=0; k<l; k++) add[k]= in[i][sub[j][k]];
00096 out << add;
00097 }
00098 }
00099 return out;
00100 }
00101
00102 template<typename R> vector<vector<nat> >
00103 separate_balls (const vector<ball<complex<R> > >& v) {
00104 vector<vector<nat> > sub= separate_balls (Re (v));
00105 return separate_balls (Im (v), sub);
00106 }
00107
00108 template<typename C> vector<vector<nat> >
00109 separate_balls (const vector<vector<ball<C> > >& v) {
00110 nat n= N(v);
00111 if (n == 0) return vector<vector<nat> > ();
00112 vector<nat> cnt= fill<nat> (n);
00113 for (nat i=0; i<n; i++) cnt[i]= i;
00114 vector<vector<nat> > sub= vec<vector<nat> > (cnt);
00115 nat d= N(v[0]);
00116 if (d == 0) return vec<vector<nat> > (cnt);
00117 for (nat i=0; i<d; i++) {
00118 vector<ball<C> > w= fill<ball<C> > (ball<C> (0), n);
00119 for (nat j=0; j<n; j++) {
00120 ASSERT (N(v[j]) == d, "vectors of same length expected");
00121 w[j]= v[j][i];
00122 }
00123 sub= separate_balls (w, sub);
00124 }
00125 return sub;
00126 }
00127
00128
00129
00130
00131
00132 template<typename C, typename V, typename W>
00133 struct homotopy_stepper_rep<ball<C>,homotopy_post_certify<V,W> >:
00134 public homotopy_stepper_rep<ball<C>,homotopy_abstract>
00135 {
00136 public:
00137 typedef homotopy_stepper<C,V> Numeric_stepper;
00138 typedef homotopy_stepper<ball<C>,W> Safe_stepper;
00139 typedef ball<C> Ball;
00140
00141 public:
00142 Numeric_stepper numeric_stepper;
00143 Safe_stepper safe_stepper;
00144 vector<Ball> init;
00145
00146 public:
00147 inline homotopy_stepper_rep (const Function& f):
00148 homotopy_stepper_rep<ball<C>,homotopy_abstract> (f),
00149 numeric_stepper (center (f)),
00150 safe_stepper (f) {}
00151
00152 vector<Ball>
00153 hom (const vector<Ball>& init, nat k, const Ball& t1) {
00154 return homx (safe_stepper, init, k, t1);
00155 }
00156
00157 vector<vector<Ball> >
00158 homvp (const vector<vector<Ball> >& init, nat k, const vector<Ball>& p) {
00159
00160
00161
00162 vector<vector<C> > mid= center (init);
00163 mid= homx (numeric_stepper, mid, k, center (p));
00164
00165
00166
00167 vector<vector<Ball> > fin= as<vector<vector<Ball> > > (mid);
00168 fin= homx (safe_stepper, fin, k, p);
00169
00170
00171
00172 nat n= N(init);
00173 bool busy= true;
00174 nat multiple= n;
00175 vector<bool> done= fill<bool> (false, n);
00176 while (busy) {
00177 busy= false;
00178 multiple= 0;
00179 vector<vector<nat> > parts= separate_balls (fin);
00180 for (nat i=0; i<N(parts); i++)
00181 if (N(parts[i]) > 1) {
00182 multiple += N(parts[i]);
00183 for (nat j=0; j<N(parts[i]); j++) {
00184 nat nr= parts[i][j];
00185 if (!done[nr]) {
00186
00187
00188 fin[nr]= homx (safe_stepper, init[nr], k, p);
00189
00190 done[nr]= true;
00191 busy= true;
00192 }
00193 }
00194 }
00195 }
00196
00197
00198
00199 return fin;
00200 }
00201 };
00202
00203 #undef Function
00204 }
00205 #endif // __MMX_HOMOTOPY_POST_CERTIFY_HPP