Browse Source

Merge branch 'master' of localhost:AwesomeAttractor

master
Joshua Moerman (@Kassalade) 14 years ago
parent
commit
3d4e11ddea
  1. 53
      Attractor.cpp
  2. 9
      Attractor.hpp
  3. 28
      AttractorKernel.cpp
  4. 2
      AttractorKernel.hpp
  5. 26
      AwesomeAttractor.cbp
  6. 244
      Canvas.cpp
  7. 48
      Canvas.hpp
  8. 22
      Logger.hpp
  9. 110
      Parameters.cpp
  10. 34
      Parameters.hpp
  11. 124
      Projector.cpp
  12. 47
      Projector.hpp
  13. 126
      Vector.cpp
  14. 31
      Vector.hpp
  15. 2
      attractors/testAttractor.stf
  16. 4
      attractors/testLorenz.stf
  17. 2
      attractors/testPolynomial.stf
  18. 2
      attractors/testUnravel.stf
  19. 16
      attractors/testUnravelNew.stf
  20. 137
      canvae/PNG.cpp
  21. 27
      canvae/PNG.hpp
  22. 61
      canvae/Raw.cpp
  23. 24
      canvae/Raw.hpp
  24. 12
      cleanCode.sh
  25. 16
      defines.hpp
  26. 191
      main.cpp
  27. 24
      ostream_helpers.h
  28. 102
      projectors/Normalizer.cpp
  29. 29
      projectors/Normalizer.hpp
  30. 10
      projectors/Projection.cpp
  31. 16
      projectors/Projection.hpp

53
Attractor.cpp

@ -1,6 +1,6 @@
#include "Attractor.hpp"
#include <iostream>
#include "Logger.hpp"
#include <fstream>
#include <cstdlib>
#include <string>
@ -10,20 +10,19 @@
#include "Projector.hpp"
Attractor::Attractor(const char* const fileName) {
Attractor::Attractor(const std::string& filename) : kernel(0), projector(0) {
// opening file
std::cout << "Reading file " << fileName << "..." << std::endl;
LogInfo("Reading file '%s'...\n", filename.c_str());
stfu::node system;
system.read(fileName);
stfu::node attractor = system.getChild("AttractorKernel");
myAttractor = AttractorKernel::createAttractorKernel(attractor);
system.read(filename.c_str());
kernel = AttractorKernel::createAttractorKernel(system.getChild("AttractorKernel"));
projector = Projector::createProjector(system.getChild(system.getValue("Projector")), system);
}
Attractor::~Attractor(){
delete myAttractor;
delete kernel;
}
@ -33,28 +32,6 @@ void Attractor::init_range() {
for ( unsigned int i = 0; i < 100000; i++ ) {
iterate();
}
// initialize projectors with dimension and first point
const unsigned int dimension = myAttractor->getDimension();
const double * point = myAttractor->vector();
for ( std::vector<Projector*>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
(*it)->extern_dim = dimension;
(*it)->intern_dim = 2;
(*it)->init(point);
}
// update ranges
for ( unsigned int i = 0; i < 100000; i++ ) {
iterate();
for ( std::vector<Projector*>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
(*it)->update_range(point);
}
}
for ( std::vector<Projector*>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
(*it)->finish_range();
}
}
bool Attractor::is_chaos() {
@ -84,14 +61,12 @@ bool Attractor::is_chaos() {
}
void Attractor::iterate() {
(*myAttractor)();
(*kernel)();
}
void Attractor::plot() {
for ( std::vector<Projector *>::iterator it = projectors.begin(); it != projectors.end(); it++ ) {
const double * point = myAttractor->vector();
(*it)->plot(point);
}
const double * point = kernel->vector();
projector->plot(point);
}
@ -99,11 +74,11 @@ void Attractor::plot() {
IO & control
*/
void Attractor::output() {
const unsigned int dimension = myAttractor->getDimension();
const double * point = myAttractor->vector();
const unsigned int dimension = kernel->getDimension();
const double * point = kernel->vector();
for ( unsigned int i = 0; i < dimension; i++ ) {
std::cout << point[i] << " ";
LogMoreInfo("%f, ", point[i]);
}
std::cout << std::endl;
LogMoreInfo("\n");
}

9
Attractor.hpp

@ -1,6 +1,7 @@
#ifndef ATTRACTOR_HPP
#define ATTRACTOR_HPP
#include <string>
#include <vector>
class Projector;
@ -9,14 +10,14 @@ class AttractorKernel;
class Attractor {
private:
AttractorKernel * myAttractor;
AttractorKernel * kernel;
public:
// should be private really
std::vector<Projector *> projectors;
Projector* projector;
Attractor(const char* const filename);
Attractor(const std::string& filename);
~Attractor();
void init_range();
@ -26,6 +27,8 @@ public:
void plot();
void output();
friend std::ostream& operator<<(std::ostream& os, Attractor const& x);
};
#endif // ATTRACTOR_HPP

28
AttractorKernel.cpp

@ -8,8 +8,8 @@
*/
#include "AttractorKernel.hpp"
#include "Logger.hpp"
#include <algorithm>
#include <iostream>
#pragma mark -
#pragma mark memory
@ -19,9 +19,8 @@ numberOfParameters(numberOfParameters), dimension(dimension){
try {
allocate();
}
catch (std::exception& e) {
std::cout << "Couldn't construct AttractorKernel: " << e.what() << std::endl;
} catch (std::exception& e) {
LogError("Couldn't construct Attractorkernel: %s\n", e.what());
dealloc();
}
@ -85,7 +84,6 @@ unsigned int AttractorKernel::getDimension() const{
#pragma mark -
#pragma mark factory function
#include "AttractorKernel.hpp"
#include "kernels/Logistic.hpp"
#include "kernels/Lorenz3D.hpp"
#include "kernels/Polynomial.hpp"
@ -105,8 +103,8 @@ AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
// }
const unsigned int dimension = atoi(attractorDimension.c_str());
std::cout << " Formula: " << attractorType << std::endl;
std::cout << " Dimensions: " << dimension << std::endl;
LogMoreInfo(" Formula: %s\n", attractorType.c_str());
LogMoreInfo(" Dimensions: %d\n", dimension);
// depending on type, make the formula object
@ -114,20 +112,20 @@ AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
if ( dimension == 3 ) {
myAttractor = new Lorenz3D();
} else {
std::cerr << "something wrong";
LogError("something wrong\n");
exit(37);
}
} else if ( attractorType == "polynomial" ) {
const std::string attractorOrde = attractor.getValue("orde");
const unsigned int orde = atoi(attractorOrde.c_str());
std::cout << " Orde: " << orde << std::endl;
LogMoreInfo(" Orde: %d\n", orde);
myAttractor = new Polynomial(dimension, orde);
} else if ( attractorType == "polynomial a" ) {
if ( dimension == 3 ) {
myAttractor = new PolynomialA3D();
} else {
std::cerr << "something wrong";
LogError("something wrong\n");
exit(37);
}
} else if ( attractorType == "logistic" ) {
@ -136,12 +134,12 @@ AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
if ( dimension == 3 ) {
myAttractor = new Unravel3D();
} else {
std::cerr << "something wrong";
LogError("something wrong\n");
exit(37);
}
} else {
std::cout << "'" << attractorType << "' not recognized" << std::endl;
exit(3);
LogError("'%s' not recognized\n", attractorType.c_str());
exit(37);
}
@ -151,10 +149,10 @@ AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
for ( unsigned int i = 0; i < numberOfParameters; i++ ) {
stfu::node attractorParameters = attractor.getChild("parameters");
(*myAttractor)[i] = atof(attractorParameters.getValue(i).c_str());
std::cout << " Parameter " << i << " set to " << (*myAttractor)[i] << ", ";
LogMoreInfo(" Parameter %d set to %f, ", i, (*myAttractor)[i]);
}
std::cout << std::endl << " Reading file complete" << std::endl;
LogMoreInfo("\n Reading file complete\n");
return myAttractor;
}

2
AttractorKernel.hpp

@ -22,7 +22,6 @@ protected:
// stuff used by subclasses
AttractorKernel(const unsigned int dimension, const unsigned int numberOfParameters);
void reallocParameters(const unsigned int numberOfParameters);
public:
@ -47,5 +46,6 @@ public:
};
#endif // ATTRACTORKERNEL_HPP

26
AwesomeAttractor.cbp

@ -50,16 +50,15 @@
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-Wno-unknown-pragmas" />
</Compiler>
<Linker>
<Add library="libpng" />
</Linker>
<Unit filename="Attractor.cpp" />
<Unit filename="Attractor.hpp" />
<Unit filename="AttractorKernel.cpp" />
<Unit filename="AttractorKernel.hpp" />
<Unit filename="Canvas.cpp" />
<Unit filename="Canvas.hpp" />
<Unit filename="Logger.hpp" />
<Unit filename="Projector.cpp" />
<Unit filename="Projector.hpp">
<Option compilerVar="CC" />
@ -68,6 +67,14 @@
<Unit filename="attractors/testLorenz.stf" />
<Unit filename="attractors/testPolynomial.stf" />
<Unit filename="attractors/testUnravel.stf" />
<Unit filename="canvae/PNG.cpp">
<Option target="&lt;{~None~}&gt;" />
</Unit>
<Unit filename="canvae/PNG.hpp">
<Option target="&lt;{~None~}&gt;" />
</Unit>
<Unit filename="canvae/Raw.cpp" />
<Unit filename="canvae/Raw.hpp" />
<Unit filename="defines.hpp" />
<Unit filename="kernels/Logistic.cpp" />
<Unit filename="kernels/Logistic.hpp" />
@ -81,8 +88,17 @@
<Unit filename="kernels/Unravel3D.hpp" />
<Unit filename="main.cpp" />
<Unit filename="myMath.hpp" />
<Unit filename="pngwriter/pngwriter.cc" />
<Unit filename="pngwriter/pngwriter.h" />
<Unit filename="ostream_helpers.h" />
<Unit filename="pngwriter/pngwriter.cc">
<Option target="&lt;{~None~}&gt;" />
</Unit>
<Unit filename="pngwriter/pngwriter.h">
<Option target="&lt;{~None~}&gt;" />
</Unit>
<Unit filename="projectors/Normalizer.cpp" />
<Unit filename="projectors/Normalizer.hpp" />
<Unit filename="projectors/Projection.cpp" />
<Unit filename="projectors/Projection.hpp" />
<Unit filename="stfu/stf.cpp" />
<Unit filename="stfu/stf.hpp" />
<Extensions>

244
Canvas.cpp

@ -1,245 +1,3 @@
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <cassert>
#include "pngwriter/pngwriter.h"
#include "Canvas.hpp"
Canvas::Canvas(unsigned int width, unsigned int height, unsigned int num_colors):
dim(2), width(width), height(height), num_colors(num_colors), v(0) {
int_array = new unsigned int[width*height*num_colors];
size = new unsigned int[2];
size[0] = width;
size[1] = height;
assert(int_array != NULL);
clear();
#ifdef HARDDEBUG
cout << "New canvas" << endl;
#endif
}
void Canvas::clear() {
for ( unsigned int i = 0; i < width*height*num_colors; i++ ) {
int_array[i] = 0;
}
}
//void Canvas::update_viewwindow() {
//
// //width and height of attractor
// const double dx = xmax - xmin;
// const double dy = ymax - ymin;
//
// //fix aspect ratio
// if ( dx > dy * ((float)width / height) ) {
// const double height2 = dx * ((float)height / width);
// const double middle = 0.5 * (ymax + ymin);
// ymax = middle + 0.5 * height2;
// ymin = middle - 0.5 * height2;
//
// } else {
// const double width2 = dy * ((float)width / height);
// const double middle = 0.5 * (xmax + xmin);
// xmax = middle + 0.5 * width2;
// xmin = middle - 0.5 * width2;
// }
//
// //add a 4% marge
// xmin -= 0.02 * dx;
// xmax += 0.02 * dx;
// ymin -= 0.02 * dy;
// ymax += 0.02 * dy;
//
// //constants for speed
// constant1 = width / (xmax - xmin);
// constant2 = height / (ymax - ymin);
//}
void Canvas::plot(double x, double y) {
// gets x and y coordinate
// ranges [-1, 1] and [-1, 1]
// so how to do the aspect shiz, i don't know
const unsigned int x_int = x*width + width*.5;
const unsigned int y_int = y*width + height*.5;
const unsigned int index = x_int + width * y_int;
if(x_int < width && y_int < height) {
int_array[index]++;
}
}
void Canvas::plot(double x, double y, unsigned int c) {
// same as plot(double x, double y)
// now with color control
const unsigned int x_int = x*width + width*.5;
const unsigned int y_int = y*width + height*.5;
const unsigned int index = x_int + width * y_int + width*height*c;
if(x_int < width && y_int < height) {
int_array[index]++;
}
}
void Canvas::plot(double x, double y, unsigned int c, double intensity) {
// same as plot(double x, double y, unsigned int c)
// but now uses the float array (not yet implemented
}
/*
I/O functions
*/
void Canvas::output() {
std::cout << "Canvas: " << std::endl;
std::cout << "Dimensions: " << width << " x " << height << " x " << num_colors << std::endl;
}
void Canvas::output_file(const char * filename){
unsigned int * max_int = new unsigned int[num_colors];
double * power = new double[num_colors];
for ( unsigned int i = 0; i < num_colors; i++ ) {
max_int[i] = 0;
double cumulative = 0;
unsigned int n = 0;
for ( unsigned int j = 0; j < width*height; j++) {
if ( max_int[i] < int_array[j+i*width*height] ) {
max_int[i] = int_array[j+i*width*height];
}
if ( int_array[j+i*width*height] ) {
cumulative += int_array[j+i*width*height];
n++;
}
}
if ( n > 100 ) {
const double average = cumulative / (double)n;
power[i] = -2.5/log(average/(double)max_int[i]);
if ( power[i] < 0 )
power[i] = 1;
} else {
power[i] = 1;
}
if ( n <= 10 ) {
std::cout << "not enough data" << std::endl;
}
}
const double vibrancy = 2.0;
double averagePower = 0;
for ( unsigned int i = 0; i < num_colors; i++ ) {
averagePower += power[i];
}
averagePower /= (double)num_colors;
for ( unsigned int i = 0; i < num_colors; i++ ) {
power[i] = vibrancy*power[i] + (1.0 - vibrancy)*averagePower;
}
pngwriter * pngFile = new pngwriter(width, height, 0.0, filename);
pngFile->setcompressionlevel(9);
pngFile->settext("Attractor", "Joshua Moerman", "A awesome attractor", "AwesomeAttractor");
for ( unsigned int x = 0; x < width; x++ ) {
for ( unsigned int y = 0; y < height; y++ ) {
double r = 0.0;
double g = 0.0;
double b = 0.0;
for ( unsigned int c = 0; c < num_colors; c++ ) {
const double norm_value = (double)int_array[x + y*width + c*width*height]/max_int[c];
switch(c){
case 0: {
r = (pow(norm_value, power[c]))*3.5;
break;
}
case 1: {
g = (pow(norm_value, power[c]))*3.0;
break;
}
case 2: {
b = (pow(norm_value, power[c]))*3.0;
break;
}
default:
break;
}
}
//pngwriter clips values for me
pngFile->plot(x, y, r, g, b);
}
}
delete[] max_int;
delete[] power;
std::cout << "ready for writing file i suppose: " << filename << std::endl;
std::ofstream file(filename);
if ( !file ) {
std::cout << "jij hebt pech, geen png voor jou" << std::endl;
}
std::cout << filename << std::endl;
pngFile->close();
}
void Canvas::output_file(){
char filename[50];
time_t t = time(0);
struct tm* lt = localtime(&t);
int r = rand() % 10;
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);
output_file(filename);
}
void Canvas::output_raw(const char * filename){
std::ofstream outfile (filename, std::ofstream::binary);
outfile.write(reinterpret_cast<char*>(int_array), sizeof(unsigned int)*width*height*num_colors);
}
void Canvas::output_raw(){
char filename[52];
time_t t = time(0);
struct tm* lt = localtime(&t);
int r = rand() % 10;
sprintf(filename, "render/canv%dx%d_%04d-%02d-%02d_%02d-%02d-%02d-%01d.canv", width, height, lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, r);
output_raw(filename);
}
void Canvas::input_raw(const char * filename){
std::ifstream infile(filename, std::ifstream::binary);
if ( ! infile ) {
std::cout << "poep" << std::endl;
return;
}
infile.seekg (0, std::ios::end);
int length = infile.tellg();
infile.seekg (0, std::ios::beg);
std::cout << "length: " << length << " =? " << static_cast<int>(width*height*num_colors*sizeof(unsigned int)) << std::endl;
infile.read (reinterpret_cast<char*>(int_array), sizeof (unsigned int)*width*height*num_colors);
}
// lol

48
Canvas.hpp

@ -2,49 +2,21 @@
#define CANVAS_HPP
//#include "Vector.hpp"
#include "Attractor.hpp"
#include "Projector.hpp"
class Canvas {
protected:
// TODO : Canvas class abstraheren (zodat er makkelijk verschillende soorten canvae gemaakt kunnen worden)
unsigned int dimension;
Canvas (const unsigned int dimension) : dimension (dimension) {};
class Canvas{
friend class Projector;
public:
unsigned int dim;
unsigned int width;
unsigned int height;
unsigned int num_colors;
unsigned int getDimension() const { return dimension; };
unsigned int * size;
virtual ~Canvas() {};
unsigned int * int_array;
public:
double v;
Canvas(unsigned int width, unsigned int height, unsigned int num_colors = 1);
void clear();
void plot(double x, double y);
void plot(double x, double y, unsigned int c);
// TODO : make double array in canvas (ander soort canvas)
// TODO : subpixel sampling (anders soort canvas)
void plot(double x, double y, unsigned int c, double intensity);
void output();
//void output(Vector& point);
void output_file(const char * filename);
void output_file();
void output_raw(const char * filename);
void output_raw();
void input_raw(const char * filename);
virtual void clear() = 0;
virtual void plot (const double * normalizedPosition) = 0;
virtual void output_file (const char * filename) const = 0;
};
#endif // CANVAS_HPP

22
Logger.hpp

@ -0,0 +1,22 @@
#ifndef LOGGER_HPP_INCLUDED
#define LOGGER_HPP_INCLUDED
#include <cstdio>
extern int verbose;
#define LogDebug(s, ...) \
if ( verbose >= 3 ) printf(s, ##__VA_ARGS__);
#define LogMoreInfo(s, ...) \
if ( verbose >= 2 ) printf(s, ##__VA_ARGS__);
#define LogInfo(s, ...) \
if ( verbose >= 1 ) printf(s, ##__VA_ARGS__);
#define LogError(s, ...) \
if ( verbose >= 0 ) { printf("%s, %d: ", __FILE__, __LINE__); printf(s, ##__VA_ARGS__); }
#endif // LOGGER_HPP_INCLUDED

110
Parameters.cpp

@ -1,110 +0,0 @@
#include <iostream>
using namespace std;
#include "Parameters.hpp"
Parameters::Parameters(unsigned int num_parameters, float default_val):
num_parameters(num_parameters) {
begin = new (nothrow) Vector(num_parameters, default_val);
eind = new (nothrow) Vector(num_parameters, default_val);
interpolated = new (nothrow) Vector(num_parameters, default_val);
// *interpolated = *begin
check_pointers();
#ifdef HARDDEBUG
cout << "New Parameters with one default val:" << endl << *this << endl;
#endif
}
/*Parameters::Parameters(unsigned int num_parameters, float default_val1, float default_val2):
num_parameters(num_parameters) {
begin = new (nothrow) Vector(num_parameters, default_val1);
eind = new (nothrow) Vector(num_parameters, default_val2);
interpolated = new (nothrow) Vector(num_parameters, default_val1);
// *interpolated = *begin
check_pointers();
#ifdef HARDDEBUG
cout << "New Parameters with two default vals:" << endl << *this << endl;
#endif
}*/
Parameters::~Parameters() {
delete begin;
delete eind;
delete interpolated;
#ifdef HARDDEBUG
cout << "Parameters deleted" << endl;
#endif
}
void Parameters::check_pointers() {
assert(begin != NULL);
assert(eind != NULL);
assert(interpolated != NULL);
}
void Parameters::set(unsigned int parameter, float val1, float val2) {
assert(parameter < num_parameters);
begin->coordinates[parameter] = val1;
eind->coordinates[parameter] = val2;
interpolated->coordinates[parameter] = val1;
#ifdef HARDDEBUG
cout << "Parameter " << parameter << " set to: " << val1 << " - " << val2 << endl;
#endif
}
void Parameters::set(unsigned int parameter, float val) {
assert(parameter < num_parameters);
begin->coordinates[parameter] = val;
eind->coordinates[parameter] = val;
interpolated->coordinates[parameter] = val;
#ifdef HARDDEBUG
cout << "Parameter " << parameter << " set to: " << val << endl;
#endif
}
float Parameters::get(unsigned int parameter) {
assert(parameter < num_parameters);
#ifdef HARDDEBUG
cout << "Asked for parameter " << parameter << " with value:" << interpolated->coordinates[parameter] << endl;
#endif
return interpolated->coordinates[parameter];
}
void Parameters::interpolate(float time) {
/*
Dit is mogelijk met vector rekenen:
(*interpolated) = (*begin) * ( 1.0 - time ) + (*eind) * time;
Maar we doen het per element, zodat we simpelere code hebben,
geen vectoren hoeven te returnen en makkelijker kunnen optimaliseren
*/
const float invtime = 1.0 - time;
for ( unsigned int i = 0; i < num_parameters; i++ ) {
interpolated->coordinates[i] = invtime * begin->coordinates[i] + time * eind->coordinates[i];
}
#ifdef HARDDEBUG
cout << "interpolate() result" << endl << *interpolated << endl;
#endif
}
ostream& operator<<(ostream& os, const Parameters& param) {
os << param.num_parameters << endl;
os << "Begin:" << endl << *param.begin << endl;
os << "Eind:" << endl << *param.eind << endl;
os << "Interpolated:" << endl << *param.interpolated << endl;
os <<endl;
return os;
}

34
Parameters.hpp

@ -1,34 +0,0 @@
#ifndef PARAMETER_HPP
#define PARAMETER_HPP
#include "Vector.hpp"
class Parameters {
Vector * begin;
Vector * eind;
Vector * interpolated;
void check_pointers();
public:
// for checks and assertions
unsigned int num_parameters;
Parameters(unsigned int num_parameters, float default_val = 0.0);
//Parameters(unsigned int num_parameters, float default_val1, float default_val2);
~Parameters();
void set(unsigned int parameter, float val1, float val2);
void set(unsigned int parameter, float val);
float get(unsigned int parameter);
void interpolate(float time);
// output operator
friend ostream& operator<<(ostream& os, const Parameters& param);
};
#endif // PARAMETER_HPP

124
Projector.cpp

@ -1,109 +1,61 @@
#include <iostream>
#include <cmath>
#include <cassert>
#include "Logger.hpp"
#include "Projector.hpp"
#include "Canvas.hpp"
#include "myMath.hpp"
void Projector::init(const double * point) {
init_vector();
#include <algorithm>
project(point);
init_range();
}
void Projector::init_vector() {
project_point = new double[intern_dim];
offset = new double[intern_dim];
assert(project_point != NULL);
assert(offset != NULL);
}
void Projector::init_range() {
range_min = new double[intern_dim];
range_max = new double[intern_dim];
#include "Canvas.hpp"
assert(range_min != NULL);
assert(range_max != NULL);
#pragma mark -
#pragma mark memory
for ( unsigned int i = 0; i < intern_dim; i++ ) {
range_min[i] = range_max[i] = project_point[i];
Projector::Projector(unsigned int inputDimension, unsigned int outputDimension) : canvas(0), projector(0), projectedPoint(0), inputDimension(inputDimension), outputDimension(outputDimension), ready(true) {
try {
allocate();
} catch(std::exception& e) {
LogError("Couldn't construct Projector: %s\n", e.what());
deallocate();
}
std::fill_n(projectedPoint, outputDimension, 0.0);
}
void Projector::update_range(const double * point) {
project(point);
for ( unsigned int i = 0; i < intern_dim; i++ ) {
if ( project_point[i] < range_min[i] ) {
range_min[i] = project_point[i];
} else if ( project_point[i] > range_max[i] ) {
range_max[i] = project_point[i];
}
}
Projector::~Projector(){
deallocate();
}
void Projector::finish_range() {
// double max_dist = 0.0;
// for ( unsigned int i = 0; i < intern_dim; i++ ) {
// const double dist = range_max[i] - range_min[i];
// if ( dist > max_dist )
// max_dist = dist;
// }
//
// factor = 0.9/max_dist;
// for ( unsigned int i = 0; i < intern_dim; i++ ) {
// offset[i] = -0.5*factor*(range_min[i] + range_max[i]);
// }
factor = canvas->size[0] / (range_max[0] - range_min[0]);
unsigned int teh_size = canvas->size[0];
for ( unsigned int i = 1; i < intern_dim; i++ ) {
double dist = range_max[i] - range_min[i];
if ( factor * dist > (double)canvas->size[i] ) {
factor = (double)canvas->size[i] / dist;
//teh_size = canvas->size[i];
std::cout << "crap for dim" << i << std::endl;
}
}
factor /= (double)teh_size;
for ( unsigned int i = 0; i < intern_dim; i++ ) {
offset[i] = -0.5*factor*(range_min[i] + range_max[i]);
}
void Projector::allocate() {
projectedPoint = new double[outputDimension];
}
void Projector::project(const double * point) {
assert(extern_dim >= 2);
project_point[0] = point[0];
project_point[1] = point[1];
void Projector::deallocate() {
delete[] projectedPoint;
projectedPoint = NULL;
}
#pragma mark -
#pragma mark plot
void Projector::plot(const double * point) {
void Projector::plot(const double* point) {
project(point);
const double x = project_point[0]*factor + offset[0];
const double y = project_point[1]*factor + offset[1];
//cout << x << ", " << y << endl;
if(ready) {
if(canvas != NULL) {
canvas->plot(projectedPoint);
}
canvas->plot(x, y);
if ( even(point[2]*17) )
canvas->plot(x, y, 1);
if ( even(point[2]*17+0.6) )
canvas->plot(x, y, 2);
if(projector != NULL) {
projector->plot(projectedPoint);
}
}
}
#pragma mark -
#pragma mark factory function
void Projector::output(){
std::cout << "Projector properties: " << std::endl;
std::cout << " factor: " << factor << std::endl;
for ( unsigned int i = 0; i < intern_dim; i++ ) {
std::cout << " dimension " << i << ": offset: " << offset[i] << ", range: [" << range_min[i] << ", " << range_max[i] << "]" << std::endl;
}
#include "projectors/Normalizer.hpp"
Projector* Projector::createProjector(stfu::node const& projector, stfu::node const& system) {
Projector* output = new Normalizer(3);
return new Normalizer(3);
}

47
Projector.hpp

@ -1,40 +1,37 @@
#ifndef PROJECTOR_HPP
#define PROJECTOR_HPP
#include "stfu/stf.hpp"
class Canvas;
class Projector{
public:
class Projector {
private:
void allocate();
void deallocate();
protected:
Canvas* canvas;
Projector* projector;
unsigned int extern_dim;
unsigned int intern_dim;
double* projectedPoint;
Canvas * canvas;
double * project_point;
unsigned int inputDimension;
unsigned int outputDimension;
double * range_min;
double * range_max;
double factor;
double * offset;
bool ready;
void init(const double * point);
void init_vector();
void init_range();
void update_range(const double * point);
void finish_range();
virtual void project(const double* point) = 0;
public:
Projector(unsigned int inputDimension, unsigned int outputDimension);
virtual ~Projector();
// TODO : Matrix gebruiken voor lineaire afbeelding
// TODO : Over kleuren nadenken
/*
Kleurmodi:
-genormalizeerde coordinaten als kleurintensiteit (gebruikt fp canvas)
-kleurbanden, dus met een periodieke functie (gebruikt int canvas)
*/
void project(const double * point);
void plot(const double * point);
// delegates forward trough the chain, know wha i'm sayin'?
void plot(const double* point);
void output();
// factory function
static Projector* createProjector(stfu::node const& projector, stfu::node const& system);
};
#endif // PROJECTOR_HPP

126
Vector.cpp

@ -1,126 +0,0 @@
#include <iostream>
using namespace std;
#include "Vector.hpp"
Vector::Vector():
dimension(0) {
coordinates = new (nothrow) float[0];
assert(coordinates != NULL);
#ifdef HARDDEBUG
cout << "New vector (without elements)" << endl;
#endif
}
Vector::Vector(unsigned int d):
dimension(d) {
coordinates = new (nothrow) float[dimension];
assert(coordinates != NULL);
#ifdef HARDDEBUG
cout << "New vector:" << endl << *this << endl;
#endif
}
Vector::Vector(unsigned int d, float default_val):
dimension(d) {
coordinates = new (nothrow) float[dimension];
assert(coordinates != NULL);
for (unsigned int i = 0; i < dimension; i++) {
coordinates[i] = default_val;
}
#ifdef HARDDEBUG
cout << "New vector with default values:" << endl << *this << endl;
#endif
}
Vector::~Vector() {
delete[] coordinates;
#ifdef HARDDEBUG
cout << "coordinates deleted" << endl;
#endif
}
Vector& Vector::operator=(const Vector& a) {
if ( dimension != a.dimension ) {
dimension = a.dimension;
delete[] coordinates;
coordinates = new float[dimension];
#ifdef HARDDEBUG
cout << "Dimensions were not equal, made new vector" << endl;
#endif
}
for ( unsigned int i = 0; i < dimension; i++ ) {
coordinates[i] = a.coordinates[i];
}
#ifdef HARDDEBUG
cout << "operator= result" << endl << *this << endl;
#endif
return *this;
}
ostream& operator<<(ostream& os, const Vector& a) {
os << a.dimension << endl;
for ( unsigned int i = 0; i < a.dimension; i++ ) {
os << a.coordinates[i] << " ";
}
os << endl;
return os;
}
float& Vector::operator[](const unsigned int index) {
assert(index < dimension);
return coordinates[index];
}
// matig werkende optelling en scalaire vermenigvuldiging van vectoren
/*
Vector Vector::operator+(const Vector a) const {
if ( dimension != a.dimension ) {
cout << "WARNING: dimensions not equal in vector addition" << endl;
exit(1);
} else {
static Vector ret(dimension);
for ( unsigned int i = 0; i < dimension; i++ ) {
ret.coordinates[i] = coordinates[i] + a.coordinates[i];
}
#ifdef HARDDEBUG
cout << "operator+ result" << endl << ret << endl;
#endif
return ret;
}
}
Vector Vector::operator*(const float a) const {
static Vector ret(dimension);
for ( unsigned int i = 0; i < dimension; i++ ) {
ret.coordinates[i] = coordinates[i] * a;
}
#ifdef HARDDEBUG
cout << "operator* result" << endl << ret << endl;
#endif
return ret;
}
*/

31
Vector.hpp

@ -1,31 +0,0 @@
#ifndef VECTOR_HPP
#define VECTOR_HPP
class Vector {
public:
unsigned int dimension;
float * coordinates;
// const, dest
Vector();
Vector(unsigned int d);
Vector(unsigned int d, float default_val);
~Vector();
// output operator
friend ostream& operator<<(ostream& os, const Vector& a);
// easy access
float& Vector::operator[](const unsigned int index);
// vector rekenen
Vector& operator=(const Vector& a);
// faaloperatoren
// Vector operator+(const Vector a) const;
// Vector operator*(const float a) const;
};
#endif // VECTOR_HPP

2
attractors/testAttractor.stf

@ -2,7 +2,7 @@
input: "attractor"
output: "png"
attractor: {
AttractorKernel: {
type: lorenz/unravel/polynomial/polynomial a/logistic
=> "polynomial"
dimensions: most types only support 3D

4
attractors/testLorenz.stf

@ -2,9 +2,9 @@
input: "attractor"
output: "png"
attractor: {
AttractorKernel: {
type: lorenz/unravel/polynomial/polynomial a/logistic
=> "Lorenz"
=> "lorenz"
dimensions: most types only support 3D
=> "3"

2
attractors/testPolynomial.stf

@ -2,7 +2,7 @@
input: "attractor"
output: "png"
attractor: {
AttractorKernel: {
type: lorenz/unravel/polynomial/polynomial a/logistic
=> "polynomial"
dimensions: most types only support 3D

2
attractors/testUnravel.stf

@ -2,7 +2,7 @@
input: "attractor"
output: "png"
attractor: {
AttractorKernel: {
type: lorenz/unravel/polynomial/polynomial a/logistic
=> "unravel"
dimensions: most types only support 3D

16
attractors/testUnravelNew.stf

@ -1,6 +1,5 @@
input: "AttractorKernel"
output: "Canvas"
Projector: "FirstProjector"
iterations: "100000"
AttractorKernel: {
@ -19,11 +18,13 @@ AttractorKernel: {
}
}
projections: Applied in order they appear {
:{
FirstProjector: {
type: "auto center"
}
:{
Projector: "SecondProjector"
}
SecondProjector {
type: "lineair map"
matrix:
@ -31,7 +32,8 @@ projections: Applied in order they appear {
:{ :"1" :"0" :"0" }
:{ :"0" :"1" :"0" }
}
}
Canvas: "Canvas"
}
Canvas: {

137
canvae/PNG.cpp

@ -0,0 +1,137 @@
#include "../Logger.hpp"
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <cassert>
#include "../pngwriter/pngwriter.h"
#include "PNG.hpp"
PNG::PNG(unsigned int width, unsigned int height, unsigned int num_colors):
Canvas(2), width(width), height(height), num_colors(num_colors), v(0) {
int_array = new unsigned int[width*height*num_colors];
assert(int_array != NULL);
clear();
LogDebug("New Canvas\n");
}
void PNG::clear() {
for ( unsigned int i = 0; i < width*height*num_colors; i++ ) {
int_array[i] = 0;
}
}
void PNG::plot(double * position) {
const double& x = position[0];
const double& y = position[1];
const unsigned int x_int = x*width + width*.5;
const unsigned int y_int = y*width + height*.5;
const unsigned int index = x_int + width * y_int;
if(x_int < width && y_int < height) {
int_array[index]++;
}
}
/*
I/O functions
*/
void PNG::output_file(const char * filename){
unsigned int * max_int = new unsigned int[num_colors];
double * power = new double[num_colors];
for ( unsigned int i = 0; i < num_colors; i++ ) {
max_int[i] = 0;
double cumulative = 0;
unsigned int n = 0;
for ( unsigned int j = 0; j < width*height; j++) {
if ( max_int[i] < int_array[j+i*width*height] ) {
max_int[i] = int_array[j+i*width*height];
}
if ( int_array[j+i*width*height] ) {
cumulative += int_array[j+i*width*height];
n++;
}
}
if ( n > 100 ) {
const double average = cumulative / (double)n;
power[i] = -2.5/log(average/(double)max_int[i]);
if ( power[i] < 0 )
power[i] = 1;
} else {
power[i] = 1;
}
if ( n <= 10 ) {
LogInfo("not enough data\n");
}
}
const double vibrancy = 2.0;
double averagePower = 0;
for ( unsigned int i = 0; i < num_colors; i++ ) {
averagePower += power[i];
}
averagePower /= (double)num_colors;
for ( unsigned int i = 0; i < num_colors; i++ ) {
power[i] = vibrancy*power[i] + (1.0 - vibrancy)*averagePower;
}
pngwriter * pngFile = new pngwriter(width, height, 0.0, filename);
pngFile->setcompressionlevel(9);
pngFile->settext("Attractor", "Joshua Moerman", "A awesome attractor", "AwesomeAttractor");
for ( unsigned int x = 0; x < width; x++ ) {
for ( unsigned int y = 0; y < height; y++ ) {
double r = 0.0;
double g = 0.0;
double b = 0.0;
for ( unsigned int c = 0; c < num_colors; c++ ) {
const double norm_value = (double)int_array[x + y*width + c*width*height]/max_int[c];
switch(c){
case 0: {
r = (pow(norm_value, power[c]))*3.5;
break;
}
case 1: {
g = (pow(norm_value, power[c]))*3.0;
break;
}
case 2: {
b = (pow(norm_value, power[c]))*3.0;
break;
}
default:
break;
}
}
//pngwriter clips values for me
pngFile->plot(x, y, r, g, b);
}
}
delete[] max_int;
delete[] power;
LogInfo("Writing %s\n", filename);
std::ofstream file(filename);
if ( !file ) {
LogError("Couldn't write to file");
}
pngFile->close();
LogMoreInfo("File written");
}

27
canvae/PNG.hpp

@ -0,0 +1,27 @@
#ifndef PNG_HPP
#define PNG_HPP
#include "../Canvas.hpp"
class PNG : public Canvas {
unsigned int width;
unsigned int height;
unsigned int num_colors;
unsigned int * int_array;
public:
double v;
PNG (unsigned int width, unsigned int height, unsigned int num_colors = 1);
virtual void clear();
virtual void plot (const double * normalizedPosition);
virtual void output_file (const char * filename) const;
};
#endif // PNG_HPP

61
canvae/Raw.cpp

@ -0,0 +1,61 @@
#include "../Logger.hpp"
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <cassert>
#include <algorithm>
#include <numeric>
#include <functional>
#include "Raw.hpp"
Raw::Raw (const unsigned int dimension, const unsigned int* sizes_):
Canvas(dimension) {
sizes = new unsigned int[dimension];
assert(sizes != NULL);
std::copy(sizes_, sizes_ + dimension, sizes);
sizesMultiplied = new unsigned int[dimension];
assert(sizesMultiplied != NULL);
sizesMultiplied[0] = 1;
for ( unsigned int i = 1; i < dimension; ++i ) {
sizesMultiplied[i] = sizesMultiplied[i-1]*sizes[i-1];
}
arraySize = 1;
for ( unsigned int i = 0; i < dimension; ++i ) {
arraySize *= sizes[i];
}
pixelArray = new unsigned int[arraySize];
assert(pixelArray != NULL);
clear();
LogDebug("New RawCanvas of dimension %d\n", dimension);
}
void Raw::clear() {
std::fill_n(pixelArray, arraySize, 0);
}
void Raw::plot(const double * position) {
unsigned int index = 0;
for ( unsigned int i = 0; i < dimension; ++i ) {
index += (unsigned int)(position[i]*sizes[i] + 0.5*sizes[i])*sizesMultiplied[i];
}
if(index < arraySize) {
pixelArray[index]++;
}
}
/*
I/O functions
*/
void Raw::output_file(const char * filename) const{
std::ofstream outfile (filename, std::ofstream::binary);
outfile.write(reinterpret_cast<char*>(pixelArray), sizeof(unsigned int)*arraySize);
}

24
canvae/Raw.hpp

@ -0,0 +1,24 @@
#ifndef RAW_HPP
#define RAW_HPP
#include "../Canvas.hpp"
class Raw : public Canvas {
unsigned int * sizes;
unsigned int * sizesMultiplied;
unsigned int * pixelArray;
unsigned int arraySize;
public:
Raw (const unsigned int dimension, const unsigned int* sizes);
virtual void clear();
virtual void plot (const double * normalizedPosition);
virtual void output_file (const char * filename) const;
};
#endif // RAW_HPP

12
cleanCode.sh

@ -0,0 +1,12 @@
DIRS="./*.cpp ./*.hpp ./kernels/*.cpp ./kernels/*.hpp ./attractors/*.stf"
echo "This program will delete all trailing whitespaces and will replace spaces with tabs"
for file in ${DIRS}
do
echo "yay ${file}"
unexpand -t 4 ${file} | sed 's/[ \t]*$//' > ${file}.new
cat ${file}.new > ${file}
rm ${file}.new
done

16
defines.hpp

@ -1,15 +1,13 @@
//TODO: do this with files
#define ATTRACTOR_FILE "attractors/testUnravel.stf"
#define DEFAULT_ATTRACTOR_FILE "attractors/testUnravel.stf"
#ifdef UNI_BUILD
#warning Building for the RU, are you sure?
#define WIDTH 8000
#define HEIGHT 8000
#define ITERATIONS 4200000000
#define DEFAULT_WIDTH 8000
#define DEFAULT_HEIGHT 8000
#define DEFAULT_ITERATIONS 4200000000
#else
#define WIDTH 800
#define HEIGHT 800
#define ITERATIONS 1000000
#define DEFAULT_WIDTH 800
#define DEFAULT_HEIGHT 800
#define DEFAULT_ITERATIONS 1000000
#endif

191
main.cpp

@ -1,147 +1,118 @@
#include "Logger.hpp"
#include <iostream>
#include <ctime>
#include <valarray>
#include <cstring>
#include "Attractor.hpp"
#include "Canvas.hpp"
#include "Projector.hpp"
#include "canvae/Raw.hpp"
#include "ostream_helpers.h"
#include "defines.hpp"
int main(int argc, char *argv[]) {
clock_t start, end;
double totalTime, totalIterations;
int verbose;
void showHelpText() {
std::cout << "Awesome Attractor, version " << __DATE__ << std::endl;
std::cout << "Usage: AwesomeAttractor [OPTION]... FILE" << std::endl << std::endl;
std::cout << "Optons:" << std::endl;
std::cout << " --help Shows this help" << std::endl;
std::cout << " -q quiet mode" << std::endl;
std::cout << " -v verbose mode" << std::endl;
std::cout << " -V loud mode" << std::endl;
std::cout << " -w N Sets width of output image to N" << std::endl;
std::cout << " -h N Sets height of output image to N" << std::endl;
std::cout << " -i N Sets number of iterations to N" << std::endl;
exit(0);
}
int main(int argc, char* argv[]) {
verbose = 0;
std::string attractorFile = DEFAULT_ATTRACTOR_FILE;
unsigned int iterations = DEFAULT_ITERATIONS;
unsigned int width = DEFAULT_WIDTH;
unsigned int height = DEFAULT_HEIGHT;
if(argc <= 1) {
showHelpText();
}
for(int i = 1; i < argc; ++i) {
if(strcmp(argv[i], "-v") == 0) {
verbose = 1;
} else if(strcmp(argv[i], "-q") == 0) {
verbose = -1;
} else if(strcmp(argv[i], "--help") == 0) {
showHelpText();
} else if(strcmp(argv[i], "-V") == 0) {
verbose = 3;
} else if(strcmp(argv[i], "-w") == 0) {
width = atoi(argv[++i]);
} else if(strcmp(argv[i], "-h") == 0) {
height = atoi(argv[++i]);
} else if(strcmp(argv[i], "-i") == 0) {
iterations = atoi(argv[++i]);
} else {
attractorFile = argv[i];
}
}
LogInfo("Awesome Attractor, version %s\n", __DATE__);
// initialising stuff
Attractor myAttractor(ATTRACTOR_FILE);
Attractor myAttractor(attractorFile);
Projector projection;
Canvas canvas(WIDTH, HEIGHT, 3);
projection.canvas = &canvas;
/*unsigned int sizes[] = {128, 128, 128};
Canvas* canvas = new Raw(3, sizes);
projection.canvas = canvas;*/
myAttractor.projectors.push_back(&projection);
myAttractor.init_range();
projection.output();
//projection.output();
LogInfo("\nRendering\n");
unsigned int iterations = ITERATIONS;
clock_t start, end;
start = clock();
for ( unsigned int j = 1; j <= 100; j++ ) {
for ( unsigned int i = 0; i <= iterations; i++ ) {
for(unsigned int j = 1; j <= 100; ++j) {
for(unsigned int i = 0; i <= iterations; i++) {
myAttractor.iterate();
myAttractor.plot();
}
system("clear");
myAttractor.output();
std::cout << j << "% done" << std::endl;
if(verbose >= 0) {
std::cout << "\r" << j << "% done" << std::flush;
}
}
end = clock();
totalIterations = 100.0*iterations;
totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC));
printf("\ntotal clock time: %f\n", totalTime );
printf("average iterations per second: %f\n\n", totalIterations/((double)(end-start)/(double)(CLOCKS_PER_SEC)) );
double totalIterations = 100.0*iterations;
double totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC));
LogInfo("\nTotal clock time: %f\n", totalTime);
LogMoreInfo("Average iterations per second: %f\n\n", totalIterations/totalTime);
// saving output
char filename[50];
time_t t = time(0);
struct tm* lt = localtime(&t);
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);
start = clock();
canvas.output_file();
//canvas->output_file(filename);
end = clock();
totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC));
printf("total clock time for writing png: %f\n", totalTime );
printf("\n Awesome Attractor, version %s\n", __DATE__);
LogInfo("Total clock time for writing png: %f\n", totalTime);
/*if ( argc <= 2 ) {
cout << endl << "nothing to do..." << endl;
cout << "usage:" << endl;
cout << " rendering to canvas: -a my_attractor.attr 500000000 my_attractor.canv 800 600 3" << endl;
cout << " canvas to png: -c my_attractor.canv 800 600 3 my_atttractor.png" << endl << endl;
exit(0);
}
int mode;
string argv1 = argv[1];
if ( argv1 == "-a" ) {
cout << "rendermode" << endl;
mode = 1;
} else if ( argv1 == "-c" ) {
cout << "canvasmode" << endl;
mode = 2;
} else {
cout << "i do.. i do... i do not understand... \"" << argv1 << "\""<< endl;
exit(0);
}
switch ( mode ) {
case 1: {
if ( argc != 8 ) {
cout << "all parameters must be set..." << endl;
exit(0);
}
string attractorFile = argv[2];
unsigned int iterations = atoi(argv[3]);
string canvasFile = argv[4];
unsigned int width = atoi(argv[5]);
unsigned int height = atoi(argv[6]);
unsigned int numColors = atoi(argv[7]);
Attractor attract(attractorFile.c_str());
cout << attractorFile << " is read" << endl;
Projector projection;
Canvas canvas(width, height, numColors);
projection.canvas = &canvas;
attract.projectors.push_back(&projection);
attract.init_range();
projection.output();
for ( unsigned int j = 1; j <= 100; j++ ) {
for ( unsigned int i = 0; 100*i <= iterations; i++ ) {
attract.iterate();
attract.plot();
}
cout << j << "% done" << endl;
}
canvas.output_raw(canvasFile.c_str());
cout << canvasFile << " is outputted" << endl;
break;
}
case 2: {
if ( argc != 7 ) {
cout << "all parameters must be set..." << endl;
exit(0);
}
string canvasFile = argv[2];
unsigned int width = atoi(argv[3]);
unsigned int height = atoi(argv[4]);
unsigned int numColors = atoi(argv[5]);
string pngFile = argv[6];
Canvas canvas(width, height, numColors);
canvas.input_raw(canvasFile.c_str());
cout << canvasFile << " is read" << endl;
for ( double v = -1.5; v < 1.6; v += 1.5 ) {
canvas.v = v;
canvas.output_file();
}
cout << pngFile << " was exported" << endl;
break;
}
default: {
cout << "WTF" << endl;
break;
}
}*/
return 0;
}

24
ostream_helpers.h

@ -0,0 +1,24 @@
#ifndef OSTREAM_HELPERS_HPP
#define OSTREAM_HELPERS_HPP
#include <iterator>
#include <algorithm>
#include "AttractorKernel.hpp"
#include "Attractor.hpp"
std::ostream& operator<<(std::ostream& os, AttractorKernel const& x) {
const unsigned int dimension = x.getDimension();
const double * point = x.vector();
std::copy(point, point+dimension, std::ostream_iterator<double>(os, ", "));
return os;
}
std::ostream& operator<<(std::ostream& os, Attractor const& x) {
os << x.kernel << "\n";
os << x.projector << "\n";
return os;
}
#endif // OSTREAM_HELPERS_HPP

102
projectors/Normalizer.cpp

@ -0,0 +1,102 @@
#include "../Logger.hpp"
#include "Normalizer.hpp"
#pragma mark -
#pragma mark memory
Normalizer::Normalizer(unsigned int dimension) : Projector(dimension, dimension), factor(1) {
ready = false;
try {
allocate();
} catch (std::exception& e) {
LogError("Couldn't construct Normalizer (Projector): %s\n", e.what());
deallocate();
}
std::fill_n(range_min, outputDimension, 0.0);
std::fill_n(range_max, outputDimension, 0.0);
std::fill_n(offset, outputDimension, 0.0);
}
Normalizer::~Normalizer() {
deallocate();
}
void Normalizer::allocate(){
range_min = new double[outputDimension];
range_max = new double[outputDimension];
offset = new double[outputDimension];
}
void Normalizer::deallocate(){
delete[] range_min;
range_min = 0;
delete[] range_max;
range_max = 0;
delete[] offset;
offset = 0;
}
#pragma mark -
#pragma mark plot
void Normalizer::project(const double * point) {
for ( unsigned int i = 0; i < inputDimension; ++i ) {
projectedPoint[0] = point[0]*factor + offset[0];
}
if(!ready){
static unsigned int state = 0;
switch(state) {
case 0:
init_range();
break;
case 500000:
finish_range();
ready = true;
break;
default:
update_range();
break;
}
++state;
}
}
#pragma mark -
#pragma mark setting up
void Normalizer::init_range() {
for ( unsigned int i = 0; i < outputDimension; i++ ) {
range_min[i] = range_max[i] = projectedPoint[i];
}
}
void Normalizer::update_range() {
for ( unsigned int i = 0; i < outputDimension; i++ ) {
if ( projectedPoint[i] < range_min[i] ) {
range_min[i] = projectedPoint[i];
} else if ( projectedPoint[i] > range_max[i] ) {
range_max[i] = projectedPoint[i];
}
}
}
void Normalizer::finish_range() {
factor = 2.0 / (range_max[0] - range_min[0]);
for ( unsigned int i = 1; i < outputDimension; i++ ) {
double dist = range_max[i] - range_min[i];
if ( factor * dist > 2.0 ) {
factor = 2.0 / dist;
//teh_size = canvas->size[i];
LogDebug("Crap for dimension %d\n", i);
}
}
for ( unsigned int i = 0; i < outputDimension; i++ ) {
offset[i] = -0.5*factor*(range_min[i] + range_max[i]);
}
}

29
projectors/Normalizer.hpp

@ -0,0 +1,29 @@
#ifndef NORMALIZER_HPP
#define NORMALIZER_HPP
#include "../Projector.hpp"
class Normalizer : public Projector {
private:
double* range_min;
double* range_max;
double* offset;
double factor;
void allocate();
void deallocate();
void init_range();
void update_range();
void finish_range();
protected:
virtual void project(const double* point);
public:
Normalizer(unsigned int dimension);
virtual ~Normalizer();
};
#endif // NORMALIZER_HPP

10
projectors/Projection.cpp

@ -0,0 +1,10 @@
#include "Projection.hpp"
Projection::Projection(unsigned int inputDimension, unsigned int outputDimension) : Projector(inputDimension, outputDimension){
}
void Projection::project(const double* point){
for ( unsigned int i = 0; i < inputDimension; ++i){
projectedPoint[i] = point[i];
}
}

16
projectors/Projection.hpp

@ -0,0 +1,16 @@
#ifndef PROJECTION_HPP
#define PROJECTION_HPP
#include "../Projector.hpp"
class Projection : public Projector {
protected:
virtual void project(const double* point);
public:
Projection(unsigned int inputDimension, unsigned int outputDimension);
};
#endif // PROJECTION_HPP