Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <cmath>
#include <stdexcept>
#include "../mpi_wrapper.h"
#include "NormalizationStrategyACSF.h"
#include "exceptions.h"
lib4neuro::NormalizationStrategyACSF::NormalizationStrategyACSF(
const std::unordered_map<ELEMENT_SYMBOL, Element*>& element_description,
const std::vector<ELEMENT_SYMBOL> &element_order,
const std::vector<std::pair<std::vector<double>, std::vector<double>>> &data
){
this->order_of_elements = element_order;
this->outputs_min = std::numeric_limits<double>::max();
this->outputs_max = std::numeric_limits<double>::min();
for( auto el: element_description ){
this->number_of_inputs_per_element[ el.first ] = el.second->getSymmetryFunctions()->size();
this->inputs_min[el.first] = std::vector<double>(this->number_of_inputs_per_element[ el.first ]);
this->inputs_max[el.first] = std::vector<double>(this->number_of_inputs_per_element[ el.first ]);
std::fill(this->inputs_min[el.first].begin(), inputs_min[el.first].end(), std::numeric_limits<double>::max());
std::fill(this->inputs_max[el.first].begin(), inputs_max[el.first].end(), std::numeric_limits<double>::min());
}
unsigned int first_input_idx;
for( auto d: data ){
first_input_idx = 0;
for( auto el: this->order_of_elements ){
for( unsigned int j = 0; j < this->number_of_inputs_per_element[ el ]; ++j ){
this->inputs_min[el][ j ] = std::min(this->inputs_min[el][ j ], d.first[ j + first_input_idx ] );
this->inputs_max[el][ j ] = std::max(this->inputs_max[el][ j ], d.first[ j + first_input_idx ] );
}
first_input_idx += this->number_of_inputs_per_element[ el ];
}
this->outputs_min = std::min( this->outputs_min, d.second[ 0 ] );
this->outputs_max = std::max( this->outputs_max, d.second[ 0 ] );
}
/* sycnhronization of normalized data */
MPI_Allreduce( MPI_IN_PLACE, &this->outputs_min, 1, MPI_DOUBLE, MPI_MIN, lib4neuro::mpi_active_comm );
MPI_Allreduce( MPI_IN_PLACE, &this->outputs_max, 1, MPI_DOUBLE, MPI_MAX, lib4neuro::mpi_active_comm );
for( auto el: element_description ){
MPI_Allreduce( MPI_IN_PLACE, &this->inputs_min[el.first][ 0 ], this->inputs_min[el.first].size(), MPI_DOUBLE, MPI_MIN, lib4neuro::mpi_active_comm );
MPI_Allreduce( MPI_IN_PLACE, &this->inputs_max[el.first][ 0 ], this->inputs_max[el.first].size(), MPI_DOUBLE, MPI_MAX, lib4neuro::mpi_active_comm );
}
}
void lib4neuro::NormalizationStrategyACSF::normalize_input(std::vector<double> &inp){
unsigned int first_input_idx = 0;
double len, dist2min;
for( auto el: this->order_of_elements ){
for( unsigned int j = 0; j < this->number_of_inputs_per_element[ el ]; ++j ){
len = this->inputs_max[ el ][ j ] - this->inputs_min[ el ][ j ];
dist2min = inp[ j + first_input_idx ] - this->inputs_min[ el ][ j ];
inp[ j + first_input_idx ] = 2*(dist2min/len) - 1.0;
}
first_input_idx += this->number_of_inputs_per_element[ el ];
}
}
void lib4neuro::NormalizationStrategyACSF::de_normalize_input(std::vector<double> &inp){
unsigned int first_input_idx = 0;
double len, dist2min;
for( auto el: this->order_of_elements ){
for( unsigned int j = 0; j < this->number_of_inputs_per_element[ el ]; ++j ){
len = this->inputs_max[ el ][ j ] - this->inputs_min[ el ][ j ];
inp[ j + first_input_idx ] = (inp[ j + first_input_idx ] + 1.0)*len*0.5 + this->inputs_min[ el ][ j ];
}
first_input_idx += this->number_of_inputs_per_element[ el ];
}
}
void lib4neuro::NormalizationStrategyACSF::normalize_output(std::vector<double> &out){
double len, dist2min;
len = this->outputs_max - this->outputs_min;
dist2min = out[ 0 ] - this->outputs_min;
out[ 0 ] = 2*(dist2min/len) - 1.0;
}
void lib4neuro::NormalizationStrategyACSF::de_normalize_output(std::vector<double> &out){
double len;
len = this->outputs_max - this->outputs_min;
out[ 0 ] = (out[ 0 ] + 1.0) * len * 0.5 + this->outputs_min;
}