My old project for strange attractors
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 

175 lines
4.6 KiB

#include "Attractor.hpp"
using namespace std;
/*
Constructors & initialisers
*/
Attractor::Attractor() {
myAttractor = new Lorenz3D();
}
Attractor::Attractor(const char* const fileName) {
ifstream file(fileName);
cout << "Reading file " << fileName << "..." << endl;
if ( !file ) {
cerr << " Error reading file '" << fileName << "' dying now..." << endl;
exit(2);
}
// TODO : Use stfu
stfu::node system;
system.read(file);
stfu::node attractor = system.getChild("attractor");
string attractorType = attractor.getValue("type");
const string attractorDimension = attractor.getValue("dimensions");
for ( unsigned int i = 0; attractorType[i] != '\0'; i++ ) {
attractorType[i] = tolower(attractorType[i]);
}
const unsigned int dimension = atoi(attractorDimension.c_str());
cout << " Formula: " << attractorType << endl;
cout << " Dimensions: " << dimension << endl;
if ( attractorType == "lorenz" ){
if ( dimension == 3 ) {
myAttractor = new Lorenz3D();
} else {
cerr << "something wrong";
exit(37);
}
} else if ( attractorType == "polynomial" ) {
const string attractorOrde = attractor.getValue("orde");
const unsigned int orde = atoi(attractorOrde.c_str());
cout << " Orde: " << orde << endl;
myAttractor = new Polynomial(dimension, orde);
} else if ( attractorType == "polynomial a" ) {
if ( dimension == 3 ) {
myAttractor = new PolynomialA3D();
} else {
cerr << "something wrong";
exit(37);
}
} else if ( attractorType == "logistic" ) {
myAttractor = new Logistic(dimension);
} else if ( attractorType == "unravel" ) {
if ( dimension == 3 ) {
myAttractor = new Unravel3D();
} else {
cerr << "somtheing wrong";
exit(37);
}
} else {
cout << "'" << attractorType << "' not recognized" << endl;
exit(3);
}
unsigned int numberOfParameters = myAttractor->getNumberOfParameters();
double * & parameters = myAttractor->parameters();
for ( unsigned int i = 0; i < numberOfParameters; i++ ) {
stfu::node attractorParameters = attractor.getChild("parameters");
parameters[i] = atof(attractorParameters.getValue(i).c_str());
cout << " Parameter " << i << " set to " << parameters[i] << ", ";
}
cout << endl << " Reading file complete" << endl;
}
void Attractor::init_range() {
/*
// stabilize attractor
for ( unsigned int i = 0; i < 100000; i++ ) {
iterate();
if ( !is_chaos() ) {
cout << "Attractor died after " << i << " iterations" << endl;
exit(0);
}
}
// initialize ranges
for ( vector<Projector*>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
(*it)->extern_dim = dim;
(*it)->intern_dim = 2;
(*it)->init(point);
}
// update ranges
for ( unsigned int i = 0; i < 100000; i++ ) {
iterate();
if ( !is_chaos() ) {
cout << "Attractor died after " << i << " iterations" << endl;
exit(0);
}
for ( vector<Projector*>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
(*it)->update_range(point);
}
}
for ( vector<Projector*>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
(*it)->finish_range();
}
*/
}
bool Attractor::is_chaos() {
/*
check existence of attractor:
Escaping
Single point attractor
Lyapunov exponent
*/
/*
double sum = 0;
for ( unsigned int i = 0; i < dim; i++ ) {
const double dist = 0; //new_point[i] - point[i];
sum += dist*dist;
}
if ( sum >= 1.0e7 ) {
// big change => Escaping
return false;
}
if ( sum <= 1.0e-7 ) {
// small change => singularity
return false;
}
return true;
*/
return true;
}
void Attractor::iterate() {
myAttractor->iterate();
}
void Attractor::plot() {
for ( vector<Projector *>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
const double * point = myAttractor->vector();
(*it)->plot(point);
}
}
/*
IO & control
*/
void Attractor::output() {
const unsigned int* dim = (unsigned int*)myAttractor->getProperty("dimension");
const double * point = myAttractor->vector();
for ( unsigned int i = 0; i < *dim; i++ ) {
cout << point[i] << " ";
}
cout << endl;
delete dim;
}