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.
105 lines
2.0 KiB
105 lines
2.0 KiB
#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]);
|
|
}
|
|
}
|
|
|