1
Fork 0
This repository has been archived on 2025-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
awesome-attractor/projectors/Normalizer.cpp
Joshua Moerman c0938378f1 shorter main
2012-01-09 10:08:47 +01:00

105 lines
2 KiB
C++

#include <cmath>
#include "../Logger.hpp"
#include "Normalizer.hpp"
#pragma mark -
#pragma mark memory
Normalizer::Normalizer(unsigned int dimension) :
Projector(dimension, dimension),
range_min(0), range_max(0), offset(0),
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[i] = point[i]*factor + offset[i];
}
if(!ready) {
static unsigned int state = 0;
switch(state) {
case 0:
init_range();
break;
case 1000000:
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 = 1.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 > 1.0) {
factor = 1.0 / dist;
}
}
for(unsigned int i = 0; i < outputDimension; i++) {
offset[i] = -0.5*factor*(range_min[i] + range_max[i]);
}
}