Poincare map and return time - interval version
Computing rigorous bounds for Poincare map is quite similar to nonrigorous version - see Poincare maps - nonrigorous methods. We have to specify initial condition as doubleton set (see Representation of initial condition)
and call operator of class IPoincareMap
The following example is a complete proof of the existence of Lyapunov orbit L1 in the Planar Restricted Circular Three Body Problem for a fixed Jacobi constant.
Complete example (from examples/poincare/IPoincareMapExample.cpp):
#include <iostream>
#include "capd/capdlib.h"
using namespace std;
void pcr3bpVectorField(Node , Node in[], int , Node out[], int , Node params[], int )
{
Node mj = 1-params[0];
Node xMu = in[0] + params[0];
Node xMj = in[0] - mj;
Node xMuSquare = xMu^2;
Node xMjSquare = xMj^2;
Node ySquare = in[1]^2;
Node factor1 = mj*((xMuSquare+ySquare)^-1.5);
Node factor2 = params[0]*((xMjSquare+ySquare)^-1.5);
out[0] = in[2];
out[1] = in[3];
out[2] = in[0] - xMu*factor1 - xMj*factor2 + 2*in[3];
out[3] = in[1]*(1 - factor1 - factor2) - 2*in[2];
}
{
return sqrt(
sqr(x) + 2.*(mj/
abs(x+mu) + mu/
abs(x-mj)) + mu*mj - JacobiConstant);
}
cout.precision(17);
int dim=4, noParam=1;
IMap vf(pcr3bpVectorField,dim,dim,noParam);
vf.setParameter(0, mu);
L1[0] = 0.9208034913207435 +
interval(-1,1)*5e-15;
left[3] = toEnergyLevel(left[0],mu,JacobiConstant);
right[3] = toEnergyLevel(right[0],mu,JacobiConstant);
L1[3] = toEnergyLevel(L1[0],mu,JacobiConstant);
left = pm(leftSet);
right = pm(rightSet);
cout << "P(left)=(" << left[0] << "," << left[2] << ")" << endl;
cout << "P(right)=(" << right[0] << "," << right[2] << ")" << endl;
pm(set,returnTime);
cout << "half return time=" << returnTime << endl;
if(left[2].rightBound()<0. and right[2].leftBound()>0.)
cout <<
"The existence of L1 orbit validated with accuracy " <<
diam(L1[0]) << endl;
else
cout << "Could not validate L1 periodic orbit" << endl;
return 0;
}
Derivative of Poincare map.
The class IPoincareMap provides an overloaded operator for computation of Poincare map and its derivative. First, an initial condition for the main equation and for the variational equation must be specified - see Representation of initial condition.
We have to define an interval matrix that will store bound for set of monodromy matrices where and is a bound for the return time.
Eventually we have to call an operator
IVector P = pm(set,monodromyMatrix,returnTime);
- Note
- The last argument
returnTime
is optional and can be skipped for autonomous systems
After successful integration we have
P
bound for the Poincare map at the set of initial conditions set
- bound for the monodromy matrix
Given monodromy matrix we can recompute it to derivative of Poincare map by
IMatrix DP = pm.computeDP(P,monodromyMatrix,returnTime);
- Note
- for nonautonomous systems the argument
returnTime
can be skipped
- Note
- we split computation of derivative of Poincare map into computation of monodromy matrix and solving implicit equation. This is because the user can provide own and optimized routine for recomputation of monodromy matrix to derivative of Poincare map. For user convenience we provide a general routine
computeDP
.
- Note
- The matrix
DP
returned by computeDP
is in full dimension. One can take a submatrix of DP
that correspond to variables on the section.
Below we give an easy example of computing derivative of Poincare map. See also more advanced examples
Complete example (from examples/poincare/IPoincareMapDerivativeExample.cpp):
#include <iostream>
#include "capd/capdlib.h"
using namespace std;
{
cout.precision(17);
try{
IMap vectorField(
"par:a,b;var:x,y,z;fun:-(y+z),x+b*y,b+z*(x-a);");
interval data[] = {0.,-8.3809417428298 , 0.029590060630665};
IVector P = pm(set,monodromyMatrix,returnTime);
IMatrix DP = pm.computeDP(P,monodromyMatrix,returnTime);
cout << " u=" << u << endl;
cout << "P(u)=" << P << endl;
cout << "return time = " << returnTime << endl;
cout << "monodromyMatrix=" << monodromyMatrix << endl;
cout << "DP(u)=" << DP << endl;
}catch(exception& e)
{
cout << "\n\nException caught: "<< e.what() << endl;
}
return 0;
}