now making random attractors, works flut
This commit is contained in:
parent
0ab0acd86b
commit
1c5e58559d
10 changed files with 70 additions and 20 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "Logger.hpp"
|
#include "Logger.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "stfu/stf.hpp"
|
#include "stfu/stf.hpp"
|
||||||
|
@ -18,7 +19,7 @@ Attractor::Attractor(const std::string& filename) : kernel(0), projector(0) {
|
||||||
system.read(filename.c_str());
|
system.read(filename.c_str());
|
||||||
|
|
||||||
kernel = AttractorKernel::createAttractorKernel(system.getChild("AttractorKernel"));
|
kernel = AttractorKernel::createAttractorKernel(system.getChild("AttractorKernel"));
|
||||||
projector = Projector::createProjector(system.getChild(system.getValue("Projector")), system);
|
projector = Projector::createProjector(system.getChild(system.getValue("Projector")), kernel->getDimension());
|
||||||
}
|
}
|
||||||
|
|
||||||
Attractor::Attractor(){
|
Attractor::Attractor(){
|
||||||
|
@ -31,6 +32,7 @@ Attractor::Attractor(){
|
||||||
case 1:
|
case 1:
|
||||||
kernel_node.value("type") = "polynomial";
|
kernel_node.value("type") = "polynomial";
|
||||||
kernel_node.value("dimensions") = std::string() + (char)(rand()%3 + '2');
|
kernel_node.value("dimensions") = std::string() + (char)(rand()%3 + '2');
|
||||||
|
kernel_node.value("orde") = std::string() + (char)(rand()%5 + '1');
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
kernel_node.value("type") = "polynomial a";
|
kernel_node.value("type") = "polynomial a";
|
||||||
|
@ -46,12 +48,17 @@ Attractor::Attractor(){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << kernel_node << std::endl;
|
||||||
|
|
||||||
kernel = AttractorKernel::createAttractorKernel(kernel_node);
|
kernel = AttractorKernel::createAttractorKernel(kernel_node);
|
||||||
|
kernel->generate_random_parameters();
|
||||||
|
|
||||||
stfu::node projector_node;
|
stfu::node projector_node;
|
||||||
projector_node.value("dimensions") = "2";
|
projector_node.value("dimensions") = "2";
|
||||||
|
|
||||||
projector = Projector::createProjector(projector_node, projector_node);
|
std::cout << projector_node << std::endl;
|
||||||
|
|
||||||
|
projector = Projector::createProjector(projector_node, kernel->getDimension());
|
||||||
}
|
}
|
||||||
|
|
||||||
Attractor::~Attractor() {
|
Attractor::~Attractor() {
|
||||||
|
@ -62,8 +69,12 @@ Attractor::~Attractor() {
|
||||||
// this should probably done in the projector section
|
// this should probably done in the projector section
|
||||||
void Attractor::init_range() {
|
void Attractor::init_range() {
|
||||||
// stabilize attractor
|
// stabilize attractor
|
||||||
for(unsigned int i = 0; i < 100000; i++) {
|
for(unsigned int i = 0; i < 1000000; i++) {
|
||||||
iterate();
|
iterate();
|
||||||
|
if(kernel->convergent() || kernel->divergent()){
|
||||||
|
kernel->generate_random_parameters();
|
||||||
|
LogDebug("Generating new parameters.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,7 @@ AttractorKernel* AttractorKernel::createAttractorKernel(stfu::node& attractor) {
|
||||||
// read parameters
|
// read parameters
|
||||||
const unsigned int numberOfParameters = myAttractor->getNumberOfParameters();
|
const unsigned int numberOfParameters = myAttractor->getNumberOfParameters();
|
||||||
|
|
||||||
|
if(attractor.children.find("parameters") != attractor.children.end())
|
||||||
for(unsigned int i = 0; i < numberOfParameters; i++) {
|
for(unsigned int i = 0; i < numberOfParameters; i++) {
|
||||||
stfu::node attractorParameters = attractor.getChild("parameters");
|
stfu::node attractorParameters = attractor.getChild("parameters");
|
||||||
(*myAttractor)[i] = atof(attractorParameters.getValue(i).c_str());
|
(*myAttractor)[i] = atof(attractorParameters.getValue(i).c_str());
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef ATTRACTORKERNEL_HPP
|
#ifndef ATTRACTORKERNEL_HPP
|
||||||
#define ATTRACTORKERNEL_HPP
|
#define ATTRACTORKERNEL_HPP
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "stfu/stf.hpp"
|
#include "stfu/stf.hpp"
|
||||||
|
|
||||||
class AttractorKernel {
|
class AttractorKernel {
|
||||||
|
@ -30,6 +32,30 @@ public:
|
||||||
double const& operator[](const unsigned int index) const;
|
double const& operator[](const unsigned int index) const;
|
||||||
unsigned int getNumberOfParameters() const;
|
unsigned int getNumberOfParameters() const;
|
||||||
|
|
||||||
|
virtual void generate_random_parameters() {
|
||||||
|
for(unsigned int i = 0; i < numberOfParameters; ++i)
|
||||||
|
parameters[i] = 2.0 * rand() / double(RAND_MAX) - 1.0;
|
||||||
|
for(unsigned int i = 0; i < dimension; ++i)
|
||||||
|
vectorNew[i] = vectorOld[i] = 6.0 * rand() / double(RAND_MAX) - 3.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tests
|
||||||
|
bool convergent(){
|
||||||
|
double sum = 0.0;
|
||||||
|
for(unsigned int i = 0; i < dimension; ++i){
|
||||||
|
sum += (vectorNew[i] - vectorOld[i])*(vectorNew[i] - vectorOld[i]);
|
||||||
|
}
|
||||||
|
return sum < 1.0e-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool divergent(){
|
||||||
|
double sum = 0.0;
|
||||||
|
for(unsigned int i = 0; i < dimension; ++i){
|
||||||
|
sum += (vectorNew[i] - vectorOld[i])*(vectorNew[i] - vectorOld[i]);
|
||||||
|
}
|
||||||
|
return sum > 1.0e3;
|
||||||
|
}
|
||||||
|
|
||||||
// iterate his formula, implemented by subclasses
|
// iterate his formula, implemented by subclasses
|
||||||
virtual void operator()() = 0;
|
virtual void operator()() = 0;
|
||||||
|
|
||||||
|
|
|
@ -53,11 +53,9 @@ void Projector::plot(const double* point) {
|
||||||
|
|
||||||
#include "projectors/Normalizer.hpp"
|
#include "projectors/Normalizer.hpp"
|
||||||
|
|
||||||
Projector* Projector::createProjector(stfu::node& projector, stfu::node& system) {
|
Projector* Projector::createProjector(stfu::node& projector, unsigned int input_dimension) {
|
||||||
const std::string attractorDimension = projector.getValue("dimensions");
|
|
||||||
const unsigned int dimension = atoi(attractorDimension.c_str());
|
|
||||||
|
|
||||||
Projector* output = new Normalizer(dimension);
|
Projector* output = new Normalizer(input_dimension);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
void plot(const double* point);
|
void plot(const double* point);
|
||||||
|
|
||||||
// factory function
|
// factory function
|
||||||
static Projector* createProjector(stfu::node& projector, stfu::node& system);
|
static Projector* createProjector(stfu::node& projector, unsigned int input_dimension);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PROJECTOR_HPP
|
#endif // PROJECTOR_HPP
|
||||||
|
|
|
@ -74,6 +74,7 @@ void PNG::output_file(const char* filename) const {
|
||||||
|
|
||||||
if(n <= 10) {
|
if(n <= 10) {
|
||||||
LogInfo("not enough data\n");
|
LogInfo("not enough data\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,12 @@ public:
|
||||||
|
|
||||||
virtual void operator()();
|
virtual void operator()();
|
||||||
|
|
||||||
|
virtual void generate_random_parameters(){
|
||||||
|
for(unsigned int i = 0; i < numberOfParameters; ++i){
|
||||||
|
parameters[i] = rand() / double(RAND_MAX) + 3.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LOGISTIC_HPP
|
#endif // LOGISTIC_HPP
|
||||||
|
|
|
@ -14,6 +14,13 @@ public:
|
||||||
|
|
||||||
virtual void operator()();
|
virtual void operator()();
|
||||||
|
|
||||||
|
virtual void generate_random_parameters(){
|
||||||
|
parameters[0] = rand() / double(RAND_MAX) * 0.01;
|
||||||
|
parameters[1] = rand() / double(RAND_MAX) * 10.0 + 23.0;
|
||||||
|
parameters[2] = rand() / double(RAND_MAX) * 4.0 + 8.0;
|
||||||
|
parameters[3] = rand() / double(RAND_MAX) * 1.5 + 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LORENZ_HPP
|
#endif // LORENZ_HPP
|
||||||
|
|
4
main.cpp
4
main.cpp
|
@ -84,7 +84,7 @@ int main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Attractor& myAttractor = *my_attractor_ptr;
|
Attractor& myAttractor = *my_attractor_ptr;
|
||||||
myAttractor.projector->canvas = new PNG(width, height, 3);
|
myAttractor.projector->canvas = new PNG(width, height, 1);
|
||||||
myAttractor.init_range();
|
myAttractor.init_range();
|
||||||
|
|
||||||
LogInfo("\nRendering\n");
|
LogInfo("\nRendering\n");
|
||||||
|
@ -112,7 +112,7 @@ int main(int argc, char* argv[]) {
|
||||||
time_t t = time(0);
|
time_t t = time(0);
|
||||||
struct tm* lt = localtime(&t);
|
struct tm* lt = localtime(&t);
|
||||||
int r = rand() % 10;
|
int r = rand() % 10;
|
||||||
sprintf(filename, "render/attractor_%04d-%02d-%02d_%02d-%02d-%02d-%01d.raw", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, r);
|
sprintf(filename, "render/attractor_%04d-%02d-%02d_%02d-%02d-%02d-%01d.png", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, r);
|
||||||
|
|
||||||
start = clock();
|
start = clock();
|
||||||
myAttractor.projector->canvas->output_file(filename);
|
myAttractor.projector->canvas->output_file(filename);
|
||||||
|
|
|
@ -43,7 +43,7 @@ void Normalizer::deallocate() {
|
||||||
|
|
||||||
void Normalizer::project(const double* point) {
|
void Normalizer::project(const double* point) {
|
||||||
for(unsigned int i = 0; i < inputDimension; ++i) {
|
for(unsigned int i = 0; i < inputDimension; ++i) {
|
||||||
projectedPoint[0] = point[0]*factor + offset[0];
|
projectedPoint[i] = point[i]*factor + offset[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ready) {
|
if(!ready) {
|
||||||
|
@ -53,7 +53,7 @@ void Normalizer::project(const double* point) {
|
||||||
case 0:
|
case 0:
|
||||||
init_range();
|
init_range();
|
||||||
break;
|
break;
|
||||||
case 500000:
|
case 1000000:
|
||||||
finish_range();
|
finish_range();
|
||||||
ready = true;
|
ready = true;
|
||||||
break;
|
break;
|
||||||
|
@ -86,11 +86,11 @@ void Normalizer::update_range() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Normalizer::finish_range() {
|
void Normalizer::finish_range() {
|
||||||
factor = 2.0 / (range_max[0] - range_min[0]);
|
factor = 1.0 / (range_max[0] - range_min[0]);
|
||||||
for(unsigned int i = 1; i < outputDimension; i++) {
|
for(unsigned int i = 1; i < outputDimension; i++) {
|
||||||
double dist = range_max[i] - range_min[i];
|
double dist = range_max[i] - range_min[i];
|
||||||
if(factor * dist > 2.0) {
|
if(factor * dist > 1.0) {
|
||||||
factor = 2.0 / dist;
|
factor = 1.0 / dist;
|
||||||
//teh_size = canvas->size[i];
|
//teh_size = canvas->size[i];
|
||||||
LogDebug("Crap for dimension %d\n", i);
|
LogDebug("Crap for dimension %d\n", i);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue