Skip to content
Snippets Groups Projects
NormalizationStrategyACSF.cpp 3.79 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
    #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;
    }