35#ifndef _CMGRAPHS_ODEAPPROX_H_
36#define _CMGRAPHS_ODEAPPROX_H_
49#include "chomp/system/config.h"
50#include "chomp/system/textfile.h"
69 double margin = 0.01);
78 void setParam (
const double *left,
const double *right,
int n);
83 void compute (
const double *xleft,
const double *xright,
84 double *yleft,
double *yright,
int dim,
85 const spcCoord *coord,
int subdiv)
const;
115 void RungeKutta (
double t,
double *x,
double step,
int dim,
116 double *buffer)
const;
119 static void computeRanges (
const double *samples,
int nSamples,
120 int dim,
double *minimal,
double *maximal);
134 step_ (step), nSteps_ (nSteps), nSamples_ (nSamples),
139 throw "Non-positive step requested in MapOdeApprox.";
142 throw "Non-positive number of steps requested "
147 throw "Non-positive number of samples requested "
150 static bool displayed =
false;
153 chomp::homology::sbug <<
"ODE approx: " << nSteps <<
154 " steps of " << step <<
" (1/" << (1.0 / step) <<
155 ") each, " << nSamples <<
156 " samples in each dir.\n";
184 const double fadeBegin = 0.1;
185 const double fadeEnd = 0.2;
191 for (
int i = 0; i < dim; ++ i)
194 double left = * (sides ++);
195 double right = * (sides ++);
200 distance = left - x [i];
201 else if (x [i] > right)
202 distance = x [i] - right;
207 double distBegin = fadeBegin * (right - left);
208 if (distance <= distBegin)
212 double distEnd = fadeEnd * (right - left);
213 if (distance >= distEnd)
217 y [i] *= (distEnd - distance) /
218 (distEnd - distBegin);
226 int dim,
double *buffer)
const
229 double *k2 = k1 + dim;
230 double *k3 = k2 + dim;
231 double *k4 = k3 + dim;
232 double *tmp = k4 + dim;
237 for (
int i = 0; i < dim; ++ i)
238 tmp [i] = x [i] + 0.5 * step * k1 [i];
242 for (
int i = 0; i < dim; ++ i)
243 tmp [i] = x [i] + 0.5 * step * k2 [i];
247 for (
int i = 0; i < dim; ++ i)
248 tmp [i] = x [i] + step * k3 [i];
252 for (
int i = 0; i < dim; ++ i)
254 x [i] += step / 6 * (k1 [i] + 2 * k2 [i] +
255 2 * k3 [i] + k4 [i]);
262 int dim,
double *minimal,
double *maximal)
264 const double *sample = samples;
265 for (
int n = 0; n < nSamples; ++ n)
267 for (
int i = 0; i < dim; ++ i)
269 if (!n || (minimal [i] > sample [i]))
270 minimal [i] = sample [i];
271 if (!n || (maximal [i] < sample [i]))
272 maximal [i] = sample [i];
280 double *yleft,
double *yright,
int dim,
const spcCoord *,
int)
const
283 using chomp::homology::sbug;
288 int interiorPoints = nSamplesInterior;
289 for (
int i = 1; i < dim; ++ i)
292 interiorPoints *= nSamplesInterior;
294 countPoints -= interiorPoints;
297 double *samples =
new double [(countPoints + 5) * dim];
298 double *buffer = samples + (countPoints * dim);
301 int *counters =
new int [dim];
302 for (
int i = 0; i < dim; ++ i)
305 double *curSample = samples;
306 while (curPoint < countPoints)
309 for (
int curIndex = 0; curIndex < dim; ++ curIndex)
313 counters [curIndex] = 0;
317 bool boundary =
false;
318 for (
int i = 0; i < dim; ++ i)
320 if ((counters [i] == 0) ||
337 for (
int i = 0; i < dim; ++ i)
339 if (counters [i] == 0)
340 *curSample = xleft [i];
342 *curSample = xright [i];
345 double fraction =
static_cast<double>
347 *curSample = xleft [i] + fraction *
348 (xright [i] - xleft [i]);
355 for (
int i = 0; i < dim; ++ i)
358 throw "Non-zero counter, bad programming, sorry!";
364 bool interrupted =
false;
365 for (
int step = 0; step <
nSteps_; ++ step)
368 double t = step *
step_;
369 double *sample = samples;
370 for (
int n = 0; n < countPoints; ++ n)
398 for (
int i = 0; i < dim; ++ i)
400 double collar = (yright [i] - yleft [i]) *
margin_;
402 yright [i] += collar;
This class defines a map for the nonlinear density dependent overcompensatory Leslie population model...
void setParam(const double *left, const double *right, int n)
Sets the parameters to the given intervals defined by their left and right coordinates.
void RungeKutta(double t, double *x, double step, int dim, double *buffer) const
The Runge-Kutta method for iterating a point, using the vector field defined in this class.
double step_
The size of the step for itegrating the flow.
MapOdeApprox & operator=(const MapOdeApprox &)
The assignment operator should not be used.
~MapOdeApprox()
The destructor.
void fadeVectorField(const double *x, double *y, int dim) const
Makes a correction to the vector field to make it fade gradually outside the bounding box if one is i...
MapOdeApprox(const MapOdeApprox &)
The copy constructor should not be used.
MapOdeApprox(double step, int nSteps, int nSamples, double margin=0.01)
The constructor in which one sets the step size and the number of steps for the non-rigorous integrat...
double margin_
The margin to add around the box (a fraction of its width).
int nSamples_
The number of samples in each direction.
virtual void vectorField(double t, const double *x, double *y, int dim) const =0
The vector field.
static void computeRanges(const double *samples, int nSamples, int dim, double *minimal, double *maximal)
Computes the ranges of coordinates.
void compute(const double *xleft, const double *xright, double *yleft, double *yright, int dim, const spcCoord *coord, int subdiv) const
Computes the image of a box whose left and right coordinates are given.
int nSteps_
The number of steps to use.
This class defines a map for the nonlinear density dependent overcompensatory Leslie population model...
int boundingBoxDim
The dimension of the bounding box.
double * boundingBox
A bounding box for the area where the trajectories are computed.
virtual void setParam(const double *left, const double *right, int n)
Sets the parameters to the given intervals defined by their left and right coordinates.
A generic method for computing a time-t map for ODEs.
int spcCoord
The type of coordinates of cubes in the phase space.