Exemplo n.º 1
0
static void
Random_Prm(DBL * Prm)
{
	int         i;

	for (i = 0; i < MAX_PRM; ++i)
		Prm[i] = Gauss_Rand(Mid_Prm[i], Amp_Prm[i], 4.0);
}
Exemplo n.º 2
0
/* Sets up initial conditions for a flow without all the extra baggage
   that goes with init_flow */
static void
restart_flow(ModeInfo * mi)
{
	flowstruct *sp;
	int         b;

	if (flows == NULL)
		return;
	sp = &flows[MI_SCREEN(mi)];
	sp->count = 0;

	/* Re-Initialize point positions, velocities, etc. */
	for (b = 0; b < sp->beecount; b++) {
		X(0, b) = Gauss_Rand(sp->range.x);
		Y(0, b) = (sp->yperiod > 0)?
			balance_rand(sp->range.y) : Gauss_Rand(sp->range.y);
		Z(0, b) = Gauss_Rand(sp->range.z);
	}
}
Exemplo n.º 3
0
static Bool
discover(ModeInfo * mi)
{
	flowstruct *sp;
	double l = 0;
	dvector dl;
	dvector max, min;
	double dl2, df, rs, lsum = 0, s, maxv2 = 0, v2;

	int N, i, nl = 0;

	if (flows == NULL)
		return 0;
	sp = &flows[MI_SCREEN(mi)];

	if(sp->count2 == 0) {
		/* initial conditions */
		sp->p2[0].x = Gauss_Rand(sp->range.x);
		sp->p2[0].y = (sp->yperiod > 0)?
			balance_rand(sp->range.y) : Gauss_Rand(sp->range.y);
		sp->p2[0].z = Gauss_Rand(sp->range.z);
		
		/* 1000 steps to find an attractor */
		/* Most cases explode out here */
		for(N=0; N < 1000; N++){
			Iterate(sp->p2, sp->ODE, sp->par2, sp->step2);
			if(sp->yperiod > 0 && sp->p2[0].y > sp->yperiod)
				sp->p2[0].y -= sp->yperiod;
			if(fabs(sp->p2[0].x) > LOST_IN_SPACE ||
			   fabs(sp->p2[0].y) > LOST_IN_SPACE ||
			   fabs(sp->p2[0].z) > LOST_IN_SPACE) {
				return 0;
			}
			sp->count2++;
		}
		/* Small perturbation */
		sp->p2[1].x = sp->p2[0].x + 0.000001;
		sp->p2[1].y = sp->p2[0].y;
		sp->p2[1].z = sp->p2[0].z;
	}

	/* Reset bounding box */
	max.x = min.x = sp->p2[0].x;
	max.y = min.y = sp->p2[0].y;
	max.z = min.z = sp->p2[0].z;

	/* Compute Lyapunov Exponent */

	/* (Technically, we're only estimating the largest Lyapunov
	   Exponent, but that's all we need to know to determine if we
	   have a strange attractor.) [TDA] */

	/* Fly two bees close together */
	for(N=0; N < 5000; N++){
		for(i=0; i< 2; i++) {			
			v2 = Iterate(sp->p2+i, sp->ODE, sp->par2, sp->step2);
			if(sp->yperiod > 0 && sp->p2[i].y > sp->yperiod)
				sp->p2[i].y -= sp->yperiod;
			
			if(fabs(sp->p2[i].x) > LOST_IN_SPACE ||
			   fabs(sp->p2[i].y) > LOST_IN_SPACE ||
			   fabs(sp->p2[i].z) > LOST_IN_SPACE) {
				return 0;
			}
			if(v2 > maxv2) maxv2 = v2; /* Track max v^2 */
		}

		/* find bounding box */
		if ( sp->p2[0].x < min.x )      min.x = sp->p2[0].x;
		else if ( sp->p2[0].x > max.x ) max.x = sp->p2[0].x;
		if ( sp->p2[0].y < min.y )      min.y = sp->p2[0].y;
		else if ( sp->p2[0].y > max.y ) max.y = sp->p2[0].y;
		if ( sp->p2[0].z < min.z )      min.z = sp->p2[0].z;
		else if ( sp->p2[0].z > max.z ) max.z = sp->p2[0].z;

		/* Measure how much we have to pull the two bees to prevent
		   them diverging. */
		dl.x = sp->p2[1].x - sp->p2[0].x;
		dl.y = sp->p2[1].y - sp->p2[0].y;
		dl.z = sp->p2[1].z - sp->p2[0].z;
		
		dl2 = dl.x*dl.x + dl.y*dl.y + dl.z*dl.z;
		if(dl2 > 0) {
			df = 1e12 * dl2;
			rs = 1/sqrt(df);
			sp->p2[1].x = sp->p2[0].x + rs * dl.x;
			sp->p2[1].y = sp->p2[0].y + rs * dl.y;
			sp->p2[1].z = sp->p2[0].z + rs * dl.z;
			lsum = lsum + log(df);
			nl = nl + 1;
			l = M_LOG2E / 2 * lsum / nl / sp->step2;
		}
		sp->count2++;
	}
	/* Anything that didn't explode has a finite attractor */
	/* If Lyapunov is negative then it probably hit a fixed point or a
     * limit cycle.  Positive Lyapunov indicates a strange attractor. */

	sp->lyap2 = l;

	sp->size2 = max.x - min.x;
	s = max.y - min.y;
	if(s > sp->size2) sp->size2 = s;
	s = max.z - min.z;
	if(s > sp->size2) sp->size2 = s;

	sp->mid2.x = (max.x + min.x) / 2;
	sp->mid2.y = (max.y + min.y) / 2;
	sp->mid2.z = (max.z + min.z) / 2;

	if(sqrt(maxv2) > sp->size2 * 0.2) {
		/* Flowing too fast, reduce step size.  This
		   helps to eliminate high-speed limit cycles,
		   which can show +ve Lyapunov due to integration
		   inaccuracy. */		
		sp->step2 /= 2;		
	}
	return 1;
}