Commit 0588a1ba authored by Martin Beseda's avatar Martin Beseda
Browse files

[NEW] Added Fortran ACSF cumulative API.

parent dcfae7b9
......@@ -2,4 +2,66 @@
// Created by martin on 06.12.19.
//
#include <make_unique.hpp>
#include <iostream>
#include <4neuro.h>
#include "ACSFFitCumulativeAPI.h"
#include "ACSFFITCumulativeAPI_CAPI.h"
int fit_ACSF_network_c(int niters,
int batch_size,
double tol,
const int* net_complx,
int net_complx_n,
const char* data_file,
const char* net_file,
int ng2,
const double* g2_cutoff_coefficients,
const double* g2_extensions,
const double* g2_shifts,
int ng5,
const double* g5_cutoff_coefficients,
const double* g5_extensions,
const bool* g5_shiftsmax,
const double* g5_angles,
int cross_validation_k,
int cross_validation_ntests,
const char* cross_validation_file,
const char* norm_file) {
try {
std::cout << data_file << std::endl;
std::cout << std::string(data_file) << std::endl;
fit_ACSF_network(niters,
batch_size,
tol,
*std::make_unique<std::vector<unsigned int>>(net_complx, net_complx + net_complx_n),
std::string(data_file),
std::string(net_file),
*std::make_unique<std::vector<double>>(g2_cutoff_coefficients, g2_cutoff_coefficients + ng2),
*std::make_unique<std::vector<double>>(g2_extensions, g2_extensions + ng2),
*std::make_unique<std::vector<double>>(g2_shifts, g2_shifts + ng2),
*std::make_unique<std::vector<double>>(g5_cutoff_coefficients, g5_cutoff_coefficients + ng5),
*std::make_unique<std::vector<double>>(g5_extensions, g5_extensions + ng5),
*std::make_unique<std::vector<bool>>(g5_shiftsmax, g5_shiftsmax + ng5),
*std::make_unique<std::vector<double>>(g5_angles, g5_angles + ng5),
cross_validation_k,
cross_validation_ntests,
std::string(cross_validation_file),
std::string(norm_file));
} catch (const std::exception& e) {
try {
std::throw_with_nested(std::runtime_error("Exception occured in fit_ACSF_network()! (ACSFFITCumulativeAPI_CAPI.cpp)"));
} catch(const std::exception& e2) {
print_exception(e2);
}
return 1;
} catch(...) {
std::cerr << "Non-exception error occured in fit_ACSF_network()! (ACSFFITCumulativeAPI_CAPI.cpp))";
return 2;
}
return 0;
}
\ No newline at end of file
......@@ -5,4 +5,27 @@
#ifndef LIB4NEURO_ACSFFITCUMULATIVEAPI_CAPI_H
#define LIB4NEURO_ACSFFITCUMULATIVEAPI_CAPI_H
extern "C" {
int fit_ACSF_network_c(int niters,
int batch_size,
double tol,
const int* net_complx,
int net_complx_n,
const char* data_file,
const char* net_file,
int ng2,
const double* g2_cutoff_coefficients,
const double* g2_extensions,
const double* g2_shifts,
int ng5,
const double* g5_cutoff_coefficients,
const double* g5_extensions,
const bool* g5_shiftsmax,
const double* g5_angles,
int cross_validation_k,
int cross_validation_ntests,
const char* cross_validation_file,
const char* norm_file);
};
#endif //LIB4NEURO_ACSFFITCUMULATIVEAPI_CAPI_H
......@@ -2,4 +2,316 @@
// Created by martin on 06.12.19.
//
#include <SymmetryFunction/SymmetryFunction.h>
#include <SymmetryFunction/Element.h>
#include <Reader/XYZReader.h>
#include <4neuro.h>
#include <exceptions.h>
#include "ACSFFitCumulativeAPI.h"
double optimize_via_LBMQ(l4n::NeuralNetwork& net,
l4n::ErrorFunction& ef,
unsigned int niters,
unsigned int nb,
double tol
) {
if( niters == 0 ){
return ef.eval(nullptr);
}
size_t max_iterations = niters;
size_t batch_size = nb;
double tolerance = tol;
double tolerance_gradient = tol * 1e-6;
double tolerance_parameters = tolerance_gradient;
if(l4n::mpi_rank == 0){
std::cout
<< "***********************************************************************************************************************"
<< std::endl;
}
l4n::LevenbergMarquardt lm(
max_iterations,
batch_size,
tolerance,
tolerance_gradient,
tolerance_parameters
);
double grate = 1e-2;
l4n::SmoothingLearning sl( lm, tolerance, grate );
lm.optimize(ef);
/* ERROR CALCULATION */
double err = ef.eval(nullptr);
/* Just for validation test purposes - NOT necessary for the example to work! */
return err;
}
double optimize_via_NormalizedGradientDescent(
l4n::NeuralNetwork& net,
l4n::ErrorFunction& ef,
unsigned int niters,
unsigned int nb,
double tol
) {
size_t max_iterations = niters;
size_t batch_size = nb;
double tolerance = tol * 1e-6;
if(l4n::mpi_rank == 0){
std::cout
<< "***********************************************************************************************************************"
<< std::endl;
}
l4n::NormalizedGradientDescent ngd(
tolerance,
max_iterations,
batch_size
);
ngd.optimize(ef);
/* ERROR CALCULATION */
double err = ef.eval(nullptr);
/* Just for validation test purposes - NOT necessary for the example to work! */
return err;
}
void fit_ACSF_network( unsigned int niters,
unsigned int batch_size,
double tol,
std::vector<unsigned int> &net_complx,
const std::string& data_file,
const std::string& net_file,
const std::vector<double> &g2_cutoff_coefficients,
const std::vector<double> &g2_extensions,
const std::vector<double> &g2_shifts,
const std::vector<double> &g5_cutoff_coefficients,
const std::vector<double> &g5_extensions,
const std::vector<bool> &g5_shiftsmax,
const std::vector<double> &g5_angles,
unsigned int cross_validation_k,
unsigned int cross_validation_ntests,
const std::string& cross_validation_file,
const std::string& norm_file
){
try {
/******************************** CREATING A SYSTEM OF RADIAL TRANS. FUNCTIONS ***************************/
/* Specify cutoff functions */
std::vector<lib4neuro::CutoffFunction2> g2_cutofffunctions;
for (auto el: g2_cutoff_coefficients) {
g2_cutofffunctions.emplace_back(lib4neuro::CutoffFunction2(el));
}
std::vector<lib4neuro::CutoffFunction2> g5_cutofffunctions;
for (auto el: g5_cutoff_coefficients) {
g5_cutofffunctions.emplace_back(lib4neuro::CutoffFunction2(el));
}
/* the used symmetry functions */
std::vector<lib4neuro::SymmetryFunction*> helium_sym_funcs(g2_extensions.size() + g5_extensions.size());
/* Specify G2 symmetry functions */
std::vector<lib4neuro::G2> G2functions;
for (size_t i = 0; i < g2_extensions.size(); ++i) {
G2functions.emplace_back(lib4neuro::G2(&g2_cutofffunctions[i],
g2_extensions[i],
g2_shifts[i]));
}
/* Specify G2 symmetry functions */
std::vector<lib4neuro::G5> G5functions;
auto shift = G2functions.size();
for (size_t i = 0; i < g5_extensions.size(); ++i) {
G5functions.emplace_back(lib4neuro::G5(&g5_cutofffunctions[i],
g5_extensions[i],
g5_shiftsmax[i],
g5_angles[i]));
}
for (size_t i = 0; i < g2_extensions.size(); ++i) {
helium_sym_funcs[i] = &G2functions[i];
}
for (size_t i = 0; i < g5_extensions.size(); ++i) {
helium_sym_funcs[i + shift] = &G5functions[i];
}
lib4neuro::Element helium = lib4neuro::Element("He",
helium_sym_funcs);
std::unordered_map<lib4neuro::ELEMENT_SYMBOL, lib4neuro::Element*> elements;
elements[lib4neuro::ELEMENT_SYMBOL::He] = &helium;
/**************************** FINISHED CREATING A SYSTEM OF RADIAL TRANS. FUNCTIONS ************************/
/**************************** READING COORDINATE DATA FILE ************************/
/* Read data */
lib4neuro::XYZReader reader(data_file,
true);
reader.read();
if (lib4neuro::mpi_rank == 0) {
std::cout << "Finished reading data" << std::endl;
}
std::shared_ptr<lib4neuro::DataSet> ds = reader.get_acsf_data_set(elements);
std::shared_ptr<lib4neuro::NormalizationStrategyACSF> ns;
try {
ns = std::make_shared<lib4neuro::NormalizationStrategyACSF>(norm_file, *reader.get_element_list());
}
catch (const std::exception& e) {
//TODO catch only specific exception to prevent catching some other 'real' errors
// if (lib4neuro::mpi_rank == 0) {
// std::cerr << e.what() << std::endl;
// }
ns = std::make_shared<lib4neuro::NormalizationStrategyACSF>(lib4neuro::NormalizationStrategyACSF(elements,
*reader.get_element_list(),
*ds->get_data()));
}
ds->set_normalization_strategy(ns);
ds->normalize( );
/**************************** FINISHED READING COORDINATE DATA FILE ************************/
/**************************** READING NETWORK FILE ************************/
lib4neuro::ACSFNeuralNetwork* net;
try {
net = new lib4neuro::ACSFNeuralNetwork(net_file, *reader.get_element_list());
}
catch (const std::exception& e) {
//TODO make exception specific for no NeuralNetwork to prevent catching of other errors!
if (lib4neuro::mpi_rank == 0) {
print_exception(e);
// std::cerr << e.what() << std::endl;
}
/* Create a neural network */
std::unordered_map<lib4neuro::ELEMENT_SYMBOL, std::vector<unsigned int>> n_hidden_neurons;
n_hidden_neurons[lib4neuro::ELEMENT_SYMBOL::He] = net_complx;
std::unordered_map<lib4neuro::ELEMENT_SYMBOL, std::vector<lib4neuro::NEURON_TYPE>> type_hidden_neurons;
for (auto el :n_hidden_neurons) {
for (auto i = 0; i < el.second.size() - 1; ++i) {
type_hidden_neurons[el.first].push_back(lib4neuro::NEURON_TYPE::LOGISTIC);
}
type_hidden_neurons[el.first].push_back(lib4neuro::NEURON_TYPE::LINEAR);
}
net = new lib4neuro::ACSFNeuralNetwork(elements,
*reader.get_element_list(),
reader.contains_charge() && !reader.get_ignore_charge(),
n_hidden_neurons,
type_hidden_neurons);
net->randomize_parameters();
}
/**************************** FINISHED READING NETWORK FILE ************************/
lib4neuro::MSE mse(net,
ds.get(),
false);
double err1 = optimize_via_LBMQ(*net,
mse,
niters,
batch_size,
tol);
ds->MPI_gather_data_on_master();
/* Print fit comparison with real data */
if ( lib4neuro::mpi_rank == 0 ) {
std::vector<double> output;
output.resize(1);
double max_error_abs = 0.0, max_error_rel = 0.0;
std::vector<std::vector<double>> out_dat;
for (auto e : *mse.get_dataset()->get_data()) {
net->eval_single(e.first,
output);
ns->de_normalize_output( e.second );
ns->de_normalize_output( output );
double error_ = std::abs(e.second.at(0) - output.at(0));
double error_rel = 2.0 * error_ / (std::abs(output.at(0)) + std::abs(e.second.at(0)));
out_dat.push_back({e.second[0], output[0], error_, error_rel});
if (max_error_abs < error_) {
max_error_abs = error_;
}
if (error_rel > max_error_rel) {
max_error_rel = error_rel;
}
}
std::cout << "*****************************************************" << std::endl;
std::cout << "maximal absolute error: " << max_error_abs << std::endl;
std::cout << "maximal relative error: " << 100 * max_error_rel << " %" << std::endl;
std::cout << "*****************************************************" << std::endl;
net->save_text( net_file );
ns->save_text( norm_file );
std::vector<unsigned int> data_indices(out_dat.size());
for( auto i = 0; i < out_dat.size(); ++i ){
data_indices[ i ] = i;
}
std::sort(
data_indices.begin(),
data_indices.end(),
[&out_dat](const unsigned int a, const unsigned int b){
if( out_dat.at(a).at(3) < out_dat.at(b).at(3) ){
return false;
}
if( out_dat.at(b).at(3) < out_dat.at(a).at(3) ){
return true;
}
return false;
}
);
if( niters == 0 ){
std::cout << "expected output " << "predicted output " << "absolute error " << "relative error" << std::endl;
for (auto el: data_indices) {
printf("%c%20.18f %c%20.18f %c%20.18f %c%20.18f\n",
out_dat.at(el).at(0) < 0?'-':' ',
std::abs(out_dat.at(el).at(0)),
out_dat.at(el).at(1) < 0?'-':' ',
std::abs(out_dat.at(el).at(1)),
out_dat.at(el).at(2) < 0?'-':' ',
std::abs(out_dat.at(el).at(2)),
out_dat.at(el).at(3) < 0?'-':' ',
std::abs(out_dat.at(el).at(3))
);
}
}
else{
for (auto el: data_indices) {
double error_ = out_dat.at(el).at(2);
double error_rel = out_dat.at(el).at(3);
if (error_rel > 0.05) {
printf("[%6d] %c%20.18f %c%20.18f %c%20.18f %c%20.18f\n",
el,
out_dat.at(el).at(0) < 0?'-':' ',
std::abs(out_dat.at(el).at(0)),
out_dat.at(el).at(1) < 0?'-':' ',
std::abs(out_dat.at(el).at(1)),
out_dat.at(el).at(2) < 0?'-':' ',
std::abs(out_dat.at(el).at(2)),
out_dat.at(el).at(3) < 0?'-':' ',
std::abs(out_dat.at(el).at(3))
);
}
}
}
}
} catch (...) {
std::throw_with_nested( std::runtime_error("fit_ACSF_network() error (ACSFFITCumulativeAPI.cpp)"));
}
}
\ No newline at end of file
......@@ -5,4 +5,25 @@
#ifndef LIB4NEURO_ACSFFITCUMULATIVEAPI_H
#define LIB4NEURO_ACSFFITCUMULATIVEAPI_H
#include <vector>
#include <string>
void fit_ACSF_network(unsigned int niters,
unsigned int batch_size,
double tol,
std::vector<unsigned int>& net_complx,
const std::string& data_file,
const std::string& net_file,
const std::vector<double> &g2_cutoff_coefficients,
const std::vector<double> &g2_extensions,
const std::vector<double> &g2_shifts,
const std::vector<double> &g5_cutoff_coefficients,
const std::vector<double> &g5_extensions,
const std::vector<bool> &g5_shiftsmax,
const std::vector<double> &g5_angles,
unsigned int cross_validation_k,
unsigned int cross_validation_ntests,
const std::string& cross_validation_file,
const std::string& norm_file);
#endif //LIB4NEURO_ACSFFITCUMULATIVEAPI_H
! Created by on 06.12.19.
module ACSFFitCumulativeAPI_FAPI
use iso_c_binding
implicit none
interface
function fit_ACSF_network_c(niters, &
batch_size, &
tol, &
net_complx, &
net_complx_n, &
data_file, &
net_file, &
ng2, &
g2_cutoff_coefficients, &
g2_extensions, &
g2_shifts, &
ng5, &
g5_cutoff_coefficients, &
g5_extensions, &
g5_shiftsmax, &
g5_angles, &
cross_validation_k, &
cross_validation_ntests, &
cross_validation_file, &
norm_file) bind(C, name="fit_ACSF_network_c")
use iso_c_binding
implicit none
! integer(c_int), value :: fit_ACSF_network
integer(c_int), value :: niters
integer(c_int), value :: batch_size
real(c_double), value :: tol
type(c_ptr), value :: net_complx
integer(c_int), value :: net_complx_n
type(c_ptr), value :: data_file
type(c_ptr), value :: net_file
integer(c_int), value :: ng2
type(c_ptr), value :: g2_cutoff_coefficients
type(c_ptr), value :: g2_extensions
type(c_ptr), value :: g2_shifts
integer(c_int), value :: ng5
type(c_ptr), value :: g5_cutoff_coefficients
type(c_ptr), value :: g5_extensions
type(c_ptr), value :: g5_shiftsmax
type(c_ptr), value :: g5_angles
integer(c_int), value :: cross_validation_k
integer(c_int), value :: cross_validation_ntests
type(c_ptr), value :: cross_validation_file
type(c_ptr), value :: norm_file
integer(c_int) :: fit_ACSF_network_c
end function fit_ACSF_network_c
end interface
contains
function fit_ACSF_network(niters, &
batch_size, &
tol, &
net_complx, &
net_complx_n, &
data_file, &
net_file, &
ng2, &
g2_cutoff_coefficients, &
g2_extensions, &
g2_shifts, &
ng5, &
g5_cutoff_coefficients, &
g5_extensions, &
g5_shiftsmax, &
g5_angles, &
cross_validation_k, &
cross_validation_ntests, &
cross_validation_file, &
norm_file) result(ret)
use iso_c_binding
implicit none
! integer(c_int), value :: fit_ACSF_network
integer(c_int), value :: niters
integer(c_int), value :: batch_size
real(c_double), value :: tol
type(c_ptr), value :: net_complx
integer(c_int), value :: net_complx_n
type(c_ptr), value :: data_file
type(c_ptr), value :: net_file
integer(c_int) :: ng2
type(c_ptr), value :: g2_cutoff_coefficients
type(c_ptr), value :: g2_extensions
type(c_ptr), value :: g2_shifts
integer(c_int), value :: ng5
type(c_ptr), value :: g5_cutoff_coefficients
type(c_ptr), value :: g5_extensions
type(c_ptr), value :: g5_shiftsmax
type(c_ptr), value :: g5_angles
integer(c_int), value :: cross_validation_k
integer(c_int), value :: cross_validation_ntests
type(c_ptr), value :: cross_validation_file
type(c_ptr), value :: norm_file
integer(c_int) :: ret
ret = fit_ACSF_network_c(niters, &
batch_size, &
tol, &
net_complx, &
net_complx_n, &
data_file, &
net_file, &
ng2, &
g2_cutoff_coefficients, &
g2_extensions, &
g2_shifts, &
ng5, &
g5_cutoff_coefficients, &
g5_extensions, &
g5_shiftsmax, &
g5_angles, &
cross_validation_k, &
cross_validation_ntests, &
cross_validation_file, &
norm_file)
end function fit_ACSF_network
end module ACSFFitCumulativeAPI_FAPI
\ No newline at end of file
......@@ -5,8 +5,6 @@
* @date 13.6.18 -
*/
#define ARMA_ALLOW_FAKE_GCC
#include <iostream>
#include <mpi.h>
#include <random>
......@@ -20,7 +18,7 @@
#include "NeuralNetwork.h"
#include "exceptions.h"
#include "../mpi_wrapper.h"
#include "MPIWrapper/mpi_wrapper.h"
namespace lib4neuro{
int network_evaluation_counter = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment