From 6969a4045454ee7cbb852a17011683920dbbdeb1 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Wed, 17 Oct 2018 01:54:06 +0200 Subject: [PATCH 01/18] Add exponential activation function --- include/ExponentialActivationFunction.hpp | 1 + lib/headers.am | 2 +- lib/sources.am | 2 +- src/actf/ActivationFunctionManager.cpp | 4 ++- src/actf/ActivationFunctionManager.hpp | 2 ++ src/actf/ExponentialActivationFunction.cpp | 38 ++++++++++++++++++++++ src/actf/ExponentialActivationFunction.hpp | 33 +++++++++++++++++++ test/ut5/main.cpp | 24 +++++++------- 8 files changed, 92 insertions(+), 14 deletions(-) create mode 120000 include/ExponentialActivationFunction.hpp create mode 100644 src/actf/ExponentialActivationFunction.cpp create mode 100644 src/actf/ExponentialActivationFunction.hpp diff --git a/include/ExponentialActivationFunction.hpp b/include/ExponentialActivationFunction.hpp new file mode 120000 index 0000000..8912540 --- /dev/null +++ b/include/ExponentialActivationFunction.hpp @@ -0,0 +1 @@ +../src/actf/ExponentialActivationFunction.hpp \ No newline at end of file diff --git a/lib/headers.am b/lib/headers.am index 1ad34e9..dbad00c 100644 --- a/lib/headers.am +++ b/lib/headers.am @@ -1,2 +1,2 @@ pkginclude_HEADERS = \ -../src/io/PrintUtilities.hpp ../src/unit/InputUnit.hpp ../src/unit/ShifterScalerUnit.hpp ../src/unit/ActivationUnit.hpp ../src/unit/FedActivationUnit.hpp ../src/unit/NetworkUnit.hpp ../src/unit/NNUnit.hpp ../src/unit/FedUnit.hpp ../src/unit/ShifterScalerNNUnit.hpp ../src/unit/OutputNNUnit.hpp ../src/unit/OffsetUnit.hpp ../src/layer/NNLayer.hpp ../src/layer/NetworkLayer.hpp ../src/layer/OutputNNLayer.hpp ../src/layer/InputLayer.hpp ../src/layer/FedLayer.hpp ../src/network/FeedForwardNeuralNetwork.hpp ../src/feeder/FeederInterface.hpp ../src/feeder/WeightedFeeder.hpp ../src/feeder/VariableFeeder.hpp ../src/feeder/SmartBetaGenerator.hpp ../src/feeder/NNRay.hpp ../src/feeder/StaticFeeder.hpp ../src/trainer/NNTrainerGSL.hpp ../src/trainer/NNTrainingData.hpp ../src/trainer/NNTrainingConfig.hpp ../src/trainer/NNTrainer.hpp ../src/serialize/SerializableComponent.hpp ../src/serialize/StringCodeUtilities.hpp ../src/feature_maps/PairSumMapUnit.hpp ../src/feature_maps/FeatureMapLayer.hpp ../src/feature_maps/PairSumMap.hpp ../src/feature_maps/EuclideanDistanceMapUnit.hpp ../src/feature_maps/PairDifferenceMapUnit.hpp ../src/feature_maps/EuclideanDistanceMap.hpp ../src/feature_maps/EuclideanPairDistanceMap.hpp ../src/feature_maps/IdentityMapUnit.hpp ../src/feature_maps/PairDifferenceMap.hpp ../src/feature_maps/FeatureMapUnit.hpp ../src/feature_maps/EuclideanPairDistanceMapUnit.hpp ../src/feature_maps/MultiDimStaticMap.hpp ../src/feature_maps/IdentityMap.hpp ../src/feature_maps/OneDimStaticMap.hpp ../src/feature_maps/ActivationMapUnit.hpp ../src/actf/ActivationFunctionManager.hpp ../src/actf/SRLUActivationFunction.hpp ../src/actf/TanSigmoidActivationFunction.hpp ../src/actf/SineActivationFunction.hpp ../src/actf/LogisticActivationFunction.hpp ../src/actf/ActivationFunctionInterface.hpp ../src/actf/SELUActivationFunction.hpp ../src/actf/IdentityActivationFunction.hpp ../src/actf/GaussianActivationFunction.hpp ../src/actf/ReLUActivationFunction.hpp \ No newline at end of file +../src/io/PrintUtilities.hpp ../src/unit/InputUnit.hpp ../src/unit/ShifterScalerUnit.hpp ../src/unit/ActivationUnit.hpp ../src/unit/FedActivationUnit.hpp ../src/unit/NetworkUnit.hpp ../src/unit/NNUnit.hpp ../src/unit/FedUnit.hpp ../src/unit/ShifterScalerNNUnit.hpp ../src/unit/OutputNNUnit.hpp ../src/unit/OffsetUnit.hpp ../src/layer/NNLayer.hpp ../src/layer/NetworkLayer.hpp ../src/layer/OutputNNLayer.hpp ../src/layer/InputLayer.hpp ../src/layer/FedLayer.hpp ../src/network/FeedForwardNeuralNetwork.hpp ../src/feeder/FeederInterface.hpp ../src/feeder/WeightedFeeder.hpp ../src/feeder/VariableFeeder.hpp ../src/feeder/SmartBetaGenerator.hpp ../src/feeder/NNRay.hpp ../src/feeder/StaticFeeder.hpp ../src/trainer/NNTrainerGSL.hpp ../src/trainer/NNTrainingData.hpp ../src/trainer/NNTrainingConfig.hpp ../src/trainer/NNTrainer.hpp ../src/serialize/SerializableComponent.hpp ../src/serialize/StringCodeUtilities.hpp ../src/feature_maps/PairSumMapUnit.hpp ../src/feature_maps/FeatureMapLayer.hpp ../src/feature_maps/PairSumMap.hpp ../src/feature_maps/EuclideanDistanceMapUnit.hpp ../src/feature_maps/PairDifferenceMapUnit.hpp ../src/feature_maps/EuclideanDistanceMap.hpp ../src/feature_maps/EuclideanPairDistanceMap.hpp ../src/feature_maps/IdentityMapUnit.hpp ../src/feature_maps/PairDifferenceMap.hpp ../src/feature_maps/FeatureMapUnit.hpp ../src/feature_maps/EuclideanPairDistanceMapUnit.hpp ../src/feature_maps/MultiDimStaticMap.hpp ../src/feature_maps/IdentityMap.hpp ../src/feature_maps/OneDimStaticMap.hpp ../src/feature_maps/ActivationMapUnit.hpp ../src/actf/ActivationFunctionManager.hpp ../src/actf/SRLUActivationFunction.hpp ../src/actf/TanSigmoidActivationFunction.hpp ../src/actf/SineActivationFunction.hpp ../src/actf/ExponentialActivationFunction.hpp ../src/actf/LogisticActivationFunction.hpp ../src/actf/ActivationFunctionInterface.hpp ../src/actf/SELUActivationFunction.hpp ../src/actf/IdentityActivationFunction.hpp ../src/actf/GaussianActivationFunction.hpp ../src/actf/ReLUActivationFunction.hpp \ No newline at end of file diff --git a/lib/sources.am b/lib/sources.am index 02610bf..7e5617f 100644 --- a/lib/sources.am +++ b/lib/sources.am @@ -1,2 +1,2 @@ libffnn_la_SOURCES = \ -../src/io/PrintUtilities.cpp ../src/unit/ActivationUnit.cpp ../src/unit/InputUnit.cpp ../src/unit/OutputNNUnit.cpp ../src/unit/NetworkUnit.cpp ../src/unit/FedUnit.cpp ../src/layer/NNLayer.cpp ../src/layer/InputLayer.cpp ../src/layer/OutputNNLayer.cpp ../src/layer/FedLayer.cpp ../src/layer/NetworkLayer.cpp ../src/network/FeedForwardNeuralNetwork.cpp ../src/feeder/NNRay.cpp ../src/feeder/WeightedFeeder.cpp ../src/feeder/FeederInterface.cpp ../src/feeder/SmartBetaGenerator.cpp ../src/feeder/VariableFeeder.cpp ../src/trainer/NNTrainerGSL.cpp ../src/trainer/NNTrainer.cpp ../src/serialize/StringCodeUtilities.cpp ../src/feature_maps/EuclideanPairDistanceMap.cpp ../src/feature_maps/IdentityMap.cpp ../src/feature_maps/FeatureMapLayer.cpp ../src/feature_maps/PairSumMap.cpp ../src/feature_maps/PairDifferenceMap.cpp ../src/feature_maps/MultiDimStaticMap.cpp ../src/feature_maps/OneDimStaticMap.cpp ../src/feature_maps/EuclideanDistanceMap.cpp ../src/actf/LogisticActivationFunction.cpp ../src/actf/ReLUActivationFunction.cpp ../src/actf/SELUActivationFunction.cpp ../src/actf/GaussianActivationFunction.cpp ../src/actf/ActivationFunctionManager.cpp ../src/actf/TanSigmoidActivationFunction.cpp ../src/actf/SineActivationFunction.cpp ../src/actf/SRLUActivationFunction.cpp \ No newline at end of file +../src/io/PrintUtilities.cpp ../src/unit/ActivationUnit.cpp ../src/unit/InputUnit.cpp ../src/unit/OutputNNUnit.cpp ../src/unit/NetworkUnit.cpp ../src/unit/FedUnit.cpp ../src/layer/NNLayer.cpp ../src/layer/InputLayer.cpp ../src/layer/OutputNNLayer.cpp ../src/layer/FedLayer.cpp ../src/layer/NetworkLayer.cpp ../src/network/FeedForwardNeuralNetwork.cpp ../src/feeder/NNRay.cpp ../src/feeder/WeightedFeeder.cpp ../src/feeder/FeederInterface.cpp ../src/feeder/SmartBetaGenerator.cpp ../src/feeder/VariableFeeder.cpp ../src/trainer/NNTrainerGSL.cpp ../src/trainer/NNTrainer.cpp ../src/serialize/StringCodeUtilities.cpp ../src/feature_maps/EuclideanPairDistanceMap.cpp ../src/feature_maps/IdentityMap.cpp ../src/feature_maps/FeatureMapLayer.cpp ../src/feature_maps/PairSumMap.cpp ../src/feature_maps/PairDifferenceMap.cpp ../src/feature_maps/MultiDimStaticMap.cpp ../src/feature_maps/OneDimStaticMap.cpp ../src/feature_maps/EuclideanDistanceMap.cpp ../src/actf/LogisticActivationFunction.cpp ../src/actf/ReLUActivationFunction.cpp ../src/actf/SELUActivationFunction.cpp ../src/actf/GaussianActivationFunction.cpp ../src/actf/ActivationFunctionManager.cpp ../src/actf/TanSigmoidActivationFunction.cpp ../src/actf/ExponentialActivationFunction.cpp ../src/actf/SineActivationFunction.cpp ../src/actf/SRLUActivationFunction.cpp \ No newline at end of file diff --git a/src/actf/ActivationFunctionManager.cpp b/src/actf/ActivationFunctionManager.cpp index 20add3d..d959b8a 100644 --- a/src/actf/ActivationFunctionManager.cpp +++ b/src/actf/ActivationFunctionManager.cpp @@ -12,6 +12,7 @@ namespace std_actf{ SELUActivationFunction selu_actf = SELUActivationFunction(); SRLUActivationFunction srlu_actf = SRLUActivationFunction(); SineActivationFunction sin_actf = SineActivationFunction(); + ExponentialActivationFunction exp_actf = ExponentialActivationFunction(); std::vector supported_actf = { &id_actf, @@ -21,7 +22,8 @@ namespace std_actf{ &relu_actf, &selu_actf, &srlu_actf, - &sin_actf + &sin_actf, + &exp_actf }; ActivationFunctionInterface * provideActivationFunction(const std::string &idCode, const std::string ¶ms){ diff --git a/src/actf/ActivationFunctionManager.hpp b/src/actf/ActivationFunctionManager.hpp index 2184931..9ba632c 100644 --- a/src/actf/ActivationFunctionManager.hpp +++ b/src/actf/ActivationFunctionManager.hpp @@ -11,6 +11,7 @@ #include "SELUActivationFunction.hpp" #include "SRLUActivationFunction.hpp" #include "SineActivationFunction.hpp" +#include "ExponentialActivationFunction.hpp" #include #include @@ -26,6 +27,7 @@ namespace std_actf{ extern SELUActivationFunction selu_actf; extern SRLUActivationFunction srlu_actf; extern SineActivationFunction sin_actf; + extern ExponentialActivationFunction exp_actf; extern std::vector supported_actf; diff --git a/src/actf/ExponentialActivationFunction.cpp b/src/actf/ExponentialActivationFunction.cpp new file mode 100644 index 0000000..fbf413d --- /dev/null +++ b/src/actf/ExponentialActivationFunction.cpp @@ -0,0 +1,38 @@ +#include "ExponentialActivationFunction.hpp" + +#include + + +// Activation Function Interface implementation + + +double ExponentialActivationFunction::f(const double &in) +{ + return exp(in); +} + + +double ExponentialActivationFunction::f1d(const double &in) +{ + return exp(in); +} + + +double ExponentialActivationFunction::f2d(const double &in) +{ + return exp(in); +} + + +double ExponentialActivationFunction::f3d(const double &in) +{ + return exp(in); +} + +void ExponentialActivationFunction::fad(const double &in, double &v, double &v1d, double &v2d, double &v3d, const bool flag_d1, const bool flag_d2, const bool flag_d3) +{ + v = exp(in); + v1d = flag_d1 ? v : 0.; + v2d = flag_d2 ? v : 0.; + v3d = flag_d3 ? v : 0.; +} diff --git a/src/actf/ExponentialActivationFunction.hpp b/src/actf/ExponentialActivationFunction.hpp new file mode 100644 index 0000000..599840a --- /dev/null +++ b/src/actf/ExponentialActivationFunction.hpp @@ -0,0 +1,33 @@ +#ifndef EXPONENTIAL_ACTIVATION_FUNCTION +#define EXPONENTIAL_ACTIVATION_FUNCTION + +#include "ActivationFunctionInterface.hpp" +#include + +class ExponentialActivationFunction: public ActivationFunctionInterface +{ +public: + // getters + ActivationFunctionInterface * getCopy(){return new ExponentialActivationFunction();} + std::string getIdCode(){return "EXP";} + + // input should be in the range [-1 : 1] -> mu=0 sigma=1/sqrt(3) + double getIdealInputMu(){return 0.;} + double getIdealInputSigma(){return 0.577350269189626;} + + // we can use default implementation for output mu/sigma + + // computation + double f(const double &in); + + double f1d(const double &in); + + double f2d(const double &in); + + double f3d(const double &in); + + void fad(const double &in, double &v, double &v1d, double &v2d, double &v3d, const bool flag_d1 = false, const bool flag_d2 = false, const bool flag_d3 = false); +}; + + +#endif diff --git a/test/ut5/main.cpp b/test/ut5/main.cpp index 1fb363b..d383ffb 100644 --- a/test/ut5/main.cpp +++ b/test/ut5/main.cpp @@ -10,15 +10,17 @@ int main(){ using namespace std; - const double TINY = 0.0001; + const double TINY_DEFAULT = 0.0001; const double dx = 0.0001; vector x_to_test = {-3., -2.5, -2., -1.5, -1.0, -0.5, -0.25, -0.001, 0.001, 0.25, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0}; for (ActivationFunctionInterface * actf : std_actf::supported_actf){ - // cout << "actf = " << actf->getIdCode() << endl; + const double TINY = actf->getIdCode() == "EXP" ? 0.002 : TINY_DEFAULT; + cout << "actf = " << actf->getIdCode() << endl; + for (double x : x_to_test){ - // cout << " x = " << x << endl; + cout << " x = " << x << endl; const double f = actf->f(x); @@ -29,8 +31,8 @@ int main(){ const double fdx = actf->f(xdx); const double num_f1d = (fdx - f)/dx; - // cout << " f1d = " << f1d << endl; - // cout << " num_f1d = " << num_f1d << endl; + cout << " f1d = " << f1d << endl; + cout << " num_f1d = " << num_f1d << endl; assert( abs(num_f1d-f1d) < TINY ); @@ -41,8 +43,8 @@ int main(){ const double fmdx = actf->f(xmdx); const double num_f2d = (fdx - 2.*f + fmdx)/(dx*dx); - // cout << " f2d = " << f2d << endl; - // cout << " num_f2d = " << num_f2d << endl; + cout << " f2d = " << f2d << endl; + cout << " num_f2d = " << num_f2d << endl; assert( abs(num_f2d-f2d) < TINY ); @@ -52,9 +54,9 @@ int main(){ const double fdxdx = actf->f(x+dx+dx); const double num_f3d = (fdxdx - 3.*fdx +3*f - fmdx)/(dx*dx*dx); - // cout << " f3d = " << f3d << endl; - // cout << " num_f3d = " << num_f3d << endl; - assert( abs(num_f3d-f3d) < TINY*20. ); + cout << " f3d = " << f3d << endl; + cout << " num_f3d = " << num_f3d << endl; + assert( abs(num_f3d-f3d) < TINY*20 ); // -- check the fad function @@ -66,7 +68,7 @@ int main(){ assert( abs(fad_f3d-f3d) < TINY ); } - // cout << endl; + cout << endl; } return 0; From f871c0a13ceaa86a77edd90d7f5a526d3a77c038 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Wed, 17 Oct 2018 01:54:35 +0200 Subject: [PATCH 02/18] fix tiny bug --- src/unit/FedActivationUnit.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/unit/FedActivationUnit.hpp b/src/unit/FedActivationUnit.hpp index 03631de..a6d74f1 100644 --- a/src/unit/FedActivationUnit.hpp +++ b/src/unit/FedActivationUnit.hpp @@ -19,8 +19,8 @@ class FedActivationUnit: public FedUnit, public ActivationUnit virtual ~FedActivationUnit(){} // return the output mean value (mu) and standard deviation (sigma) - virtual double getOutputMu(){return _actf->getOutputMu(FedUnit::getOutputMu());} - virtual double getOutputSigma(){return _actf->getOutputSigma(FedUnit::getOutputSigma());} + virtual double getOutputMu(){return _actf->getOutputMu(FedUnit::getOutputMu(), FedUnit::getOutputSigma());} + virtual double getOutputSigma(){return _actf->getOutputSigma(FedUnit::getOutputMu(), FedUnit::getOutputSigma());} // string code getters / setter virtual std::string getMemberTreeCode(){return composeCodes(FedUnit::getMemberTreeCode(), ActivationUnit::getMemberTreeCode());} // append actf treeCode From 4777c1317cc50f32d1f6e7e1004b5d9f8187ffa5 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Wed, 19 Dec 2018 23:26:01 +0100 Subject: [PATCH 03/18] hack to random initialization during training, to make fitting more stable for setups with feature maps --- src/feature_maps/EuclideanDistanceMap.cpp | 2 +- src/feature_maps/EuclideanPairDistanceMap.cpp | 2 +- src/trainer/NNTrainer.cpp | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/feature_maps/EuclideanDistanceMap.cpp b/src/feature_maps/EuclideanDistanceMap.cpp index cc3a5c8..e4167f9 100644 --- a/src/feature_maps/EuclideanDistanceMap.cpp +++ b/src/feature_maps/EuclideanDistanceMap.cpp @@ -90,7 +90,7 @@ double EuclideanDistanceMap::getFeedSigma() double sigma = 0.; for (size_t i=0; i<_ndim; ++i) { - sigma += 4.0 * srcv[i]*srcv[i] * pow(_sources[i]->getOutputSigma(), 2); // (d²/dx² sigmaX)² + sigma += 4.0 * pow(srcv[i] * _sources[i]->getOutputSigma(), 2); // (d/dx * sigmaX)² } return sqrt(sigma); diff --git a/src/feature_maps/EuclideanPairDistanceMap.cpp b/src/feature_maps/EuclideanPairDistanceMap.cpp index fec11a8..8fb5df3 100644 --- a/src/feature_maps/EuclideanPairDistanceMap.cpp +++ b/src/feature_maps/EuclideanPairDistanceMap.cpp @@ -58,7 +58,7 @@ double EuclideanPairDistanceMap::getFeedSigma() double sigma = 0.; for (size_t i=0; i<_ndim; ++i) { - sigma += 2.0 * pow(srcv[i] - srcv[i+_ndim], 2) * ( pow(_sources[i]->getOutputSigma(), 2) + pow(_sources[i+_ndim]->getOutputSigma(), 2) ); // (d²/dx² sigmaX)² + sigma += 2.0 * pow(srcv[i] - srcv[i+_ndim], 2) * ( pow(_sources[i]->getOutputSigma(), 2) + pow(_sources[i+_ndim]->getOutputSigma(), 2) ); // (d/dx * sigmaX)² } return sqrt(sigma); diff --git a/src/trainer/NNTrainer.cpp b/src/trainer/NNTrainer.cpp index 794493d..4db21c1 100644 --- a/src/trainer/NNTrainer.cpp +++ b/src/trainer/NNTrainer.cpp @@ -3,6 +3,7 @@ #include #include +#include // --- Helpers @@ -129,6 +130,12 @@ void NNTrainer::bestFit(FeedForwardNeuralNetwork * const ffnn, double * bestfit, while(true) { // initial parameters if (flag_smart_beta) smart_beta::generateSmartBeta(ffnn); + else if (ffnn->getNFeatureMapLayers() > 0) { // hack because of fitting problems when using FMLs + random_device rdev; + mt19937_64 rgen = std::mt19937_64(rdev()); + uniform_real_distribution rd(-0.1,0.1); + for (int i=0; igetNBeta(); ++i) ffnn->setBeta(i, rd(rgen)); + } else ffnn->randomizeBetas(); findFit(ffnn, fit, err, verbose); // try new fit From 85129c532b12901cc3fe74dd68172f8e19fb6508 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Tue, 22 Jan 2019 18:20:57 +0100 Subject: [PATCH 04/18] any (std::)abs() -> fabs(), to be consistent and safe --- src/feeder/SmartBetaGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/feeder/SmartBetaGenerator.cpp b/src/feeder/SmartBetaGenerator.cpp index 07a7800..f9bdb08 100644 --- a/src/feeder/SmartBetaGenerator.cpp +++ b/src/feeder/SmartBetaGenerator.cpp @@ -191,7 +191,7 @@ namespace smart_beta{ vector beta_v; FeederInterface * rayj = L->getFedUnit(idx[j])->getFeeder(); for (int ib=BETA_INDEX_OFFSET; ibgetNBeta(); ++ib) beta_v.push_back(rayj->getBeta(ib)); - const double dot_product = abs(inner_product(begin(beta_u), end(beta_u), begin(beta_v), 0.0))/inner_product(begin(beta_u), end(beta_u), begin(beta_u), 0.0); + const double dot_product = fabs(inner_product(begin(beta_u), end(beta_u), begin(beta_v), 0.0))/inner_product(begin(beta_u), end(beta_u), begin(beta_u), 0.0); if (min_dot_product < 0.) min_dot_product = dot_product; if (dot_product < min_dot_product) min_dot_product = dot_product; } From b6e8b25cebff79eae373ebfe54cd9f2f94a1f94c Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Tue, 5 Feb 2019 20:11:43 +0100 Subject: [PATCH 05/18] Small configure.ac change that was used on Oculus cluster --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6847995..edd50a1 100644 --- a/configure.ac +++ b/configure.ac @@ -80,7 +80,7 @@ AC_PROG_LN_S AC_PROG_RANLIB # check for c++11 support (and add compiler flag) -AX_CXX_COMPILE_STDCXX(11, noext, mandatory) +#AX_CXX_COMPILE_STDCXX(11, ext, mandatory) # check for valgrind AX_VALGRIND_CHECK From 7ea4bb6b5fd8619d3cb8074580a8f5e9a7d5ae59 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Sun, 10 Feb 2019 22:06:15 +0100 Subject: [PATCH 06/18] Small bug fix in get/setVP methods (that luckily didn't affect any production runs) --- src/network/FeedForwardNeuralNetwork.cpp | 25 +++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/network/FeedForwardNeuralNetwork.cpp b/src/network/FeedForwardNeuralNetwork.cpp index a99a5f7..902066c 100644 --- a/src/network/FeedForwardNeuralNetwork.cpp +++ b/src/network/FeedForwardNeuralNetwork.cpp @@ -227,12 +227,10 @@ void FeedForwardNeuralNetwork::getVariationalParameter(double * vp) int ivp = 0; for (vector::size_type i=0; i<_L.size(); ++i) { int idmax = _L[i]->getMaxVariationalParameterIndex(); - if (ivp<=idmax) { - for ( ; ivpgetVariationalParameter(ivp, vp[ivp]); - if (!status) { - cout << endl << "ERROR FeedForwardNeuralNetwork::getVariationalParameter : index " << ivp << " not found in layer " << i << " with max index " << idmax << endl << endl; - } + for ( ; ivp<=idmax; ++ivp) { + bool status = _L[i]->getVariationalParameter(ivp, vp[ivp]); + if (!status) { + cout << endl << "ERROR FeedForwardNeuralNetwork::getVariationalParameter : index " << ivp << " not found in layer " << i << " with max index " << idmax << endl << endl; } } } @@ -247,8 +245,9 @@ void FeedForwardNeuralNetwork::setVariationalParameter(const int &ivp, const dou } for (vector::size_type i=0; i<_L.size(); ++i) { if (ivp<=_L[i]->getMaxVariationalParameterIndex()) { - _L[i]->setVariationalParameter(ivp, vp); - return; + bool status = _L[i]->setVariationalParameter(ivp, vp); + if (status) return; + else break; } } cout << endl << "ERROR FeedForwardNeuralNetwork::setVariationalParameter : index " << ivp << " not found" << endl << endl; @@ -262,12 +261,10 @@ void FeedForwardNeuralNetwork::setVariationalParameter(const double * vp) int ivp = 0; for (vector::size_type i=0; i<_L.size(); ++i) { int idmax = _L[i]->getMaxVariationalParameterIndex(); - if (ivp<=idmax) { - for ( ; ivp<=idmax; ++ivp) { - bool status = _L[i]->setVariationalParameter(ivp, vp[ivp]); - if (!status) { - cout << endl << "ERROR FeedForwardNeuralNetwork::setVariationalParameter : index " << ivp << " not found in layer " << i << " with max index " << idmax << endl << endl; - } + for ( ; ivp<=idmax; ++ivp) { + bool status = _L[i]->setVariationalParameter(ivp, vp[ivp]); + if (!status) { + cout << endl << "ERROR FeedForwardNeuralNetwork::setVariationalParameter : index " << ivp << " not found in layer " << i << " with max index " << idmax << endl << endl; } } } From 1f38da00543d8e6ab059f19a75091e6558de32c6 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Thu, 21 Feb 2019 16:37:50 +0100 Subject: [PATCH 07/18] Transition to cmake, but not perfectly finished. TravisCI, new file structure and comfortable benchmarking/profiling will be done later. --- .gitignore | 86 +- .travis.yml => .travis.bak | 0 CMakeLists.txt | 40 + Makefile.am | 34 - autogen.sh | 2 - benchmark/Makefile.am | 6 - benchmark/bench.am | 27 - benchmark/bench_actfs_derivs/Makefile.am | 1 - benchmark/bench_actfs_ffprop/Makefile.am | 1 - build.sh | 7 + config_template.sh | 16 + configure.ac | 153 ---- doc/user_manual.pdf | Bin 519505 -> 519484 bytes examples/CMakeLists.txt | 12 + examples/Makefile.am | 1 - examples/README.md | 8 +- examples/ex1/Makefile.am | 1 - examples/ex1/run.sh | 3 + examples/ex10/Makefile.am | 1 - examples/ex10/plot.py | 3 +- examples/ex10/run.sh | 6 + examples/ex2/Makefile.am | 1 - examples/ex2/run.sh | 3 + examples/ex3/Makefile.am | 1 - examples/ex3/run.sh | 3 + examples/ex4/Makefile.am | 1 - examples/ex4/run.sh | 3 + examples/ex5/Makefile.am | 1 - examples/ex5/run.sh | 3 + examples/ex6/Makefile.am | 1 - examples/ex6/run.sh | 3 + examples/ex7/Makefile.am | 1 - examples/ex7/main.cpp | 5 +- examples/ex7/run.sh | 3 + examples/ex8/Makefile.am | 1 - examples/ex8/run.sh | 4 + examples/ex9/Makefile.am | 1 - examples/ex9/plot.py | 3 +- examples/ex9/run.sh | 6 + examples/example.am | 8 - include/Makefile.am | 5 - include/README.md | 8 - lib/Makefile.am | 40 - lib/README.md | 6 - lib/headers.am | 2 - lib/sources.am | 2 - m4/README.md | 3 - m4/ax_ac_append_to_file.m4 | 32 - m4/ax_ac_print_to_file.m4 | 32 - m4/ax_add_am_macro_static.m4 | 28 - m4/ax_add_am_macros_static.m4 | 38 - m4/ax_check_enable_debug.m4 | 125 --- m4/ax_check_gnu_make.m4 | 95 --- m4/ax_coverage.m4 | 166 ---- m4/ax_cxx_compile_stdcxx.m4 | 949 ----------------------- m4/ax_file_escapes.m4 | 30 - m4/ax_valgrind_check.m4 | 239 ------ script/README.md | 5 - script/config_template.sh | 26 - script/generate_ac_config_files.sh | 5 - src/CMakeLists.txt | 5 + src/README.md | 3 - test/CMakeLists.txt | 25 + test/Makefile.am | 14 - test/README.md | 6 + test/run.sh | 12 + test/test.am | 14 - test/ut1/Makefile.am | 1 - test/ut10/Makefile.am | 1 - test/ut2/Makefile.am | 1 - test/ut3/Makefile.am | 1 - test/ut4/Makefile.am | 1 - test/ut5/Makefile.am | 1 - test/ut6/Makefile.am | 1 - test/ut7/Makefile.am | 1 - test/ut8/Makefile.am | 1 - test/ut9/Makefile.am | 1 - 77 files changed, 176 insertions(+), 2209 deletions(-) rename .travis.yml => .travis.bak (100%) create mode 100644 CMakeLists.txt delete mode 100644 Makefile.am delete mode 100755 autogen.sh delete mode 100644 benchmark/Makefile.am delete mode 100644 benchmark/bench.am delete mode 100644 benchmark/bench_actfs_derivs/Makefile.am delete mode 100644 benchmark/bench_actfs_ffprop/Makefile.am create mode 100755 build.sh create mode 100755 config_template.sh delete mode 100644 configure.ac create mode 100644 examples/CMakeLists.txt delete mode 100644 examples/Makefile.am delete mode 100644 examples/ex1/Makefile.am create mode 100755 examples/ex1/run.sh delete mode 100644 examples/ex10/Makefile.am create mode 100755 examples/ex10/run.sh delete mode 100644 examples/ex2/Makefile.am create mode 100755 examples/ex2/run.sh delete mode 100644 examples/ex3/Makefile.am create mode 100755 examples/ex3/run.sh delete mode 100644 examples/ex4/Makefile.am create mode 100755 examples/ex4/run.sh delete mode 100644 examples/ex5/Makefile.am create mode 100755 examples/ex5/run.sh delete mode 100644 examples/ex6/Makefile.am create mode 100755 examples/ex6/run.sh delete mode 100644 examples/ex7/Makefile.am create mode 100755 examples/ex7/run.sh delete mode 100644 examples/ex8/Makefile.am create mode 100755 examples/ex8/run.sh delete mode 100644 examples/ex9/Makefile.am create mode 100755 examples/ex9/run.sh delete mode 100644 examples/example.am delete mode 100644 include/Makefile.am delete mode 100644 include/README.md delete mode 100644 lib/Makefile.am delete mode 100644 lib/README.md delete mode 100644 lib/headers.am delete mode 100644 lib/sources.am delete mode 100644 m4/README.md delete mode 100644 m4/ax_ac_append_to_file.m4 delete mode 100644 m4/ax_ac_print_to_file.m4 delete mode 100644 m4/ax_add_am_macro_static.m4 delete mode 100644 m4/ax_add_am_macros_static.m4 delete mode 100644 m4/ax_check_enable_debug.m4 delete mode 100644 m4/ax_check_gnu_make.m4 delete mode 100644 m4/ax_coverage.m4 delete mode 100644 m4/ax_cxx_compile_stdcxx.m4 delete mode 100644 m4/ax_file_escapes.m4 delete mode 100644 m4/ax_valgrind_check.m4 delete mode 100644 script/README.md delete mode 100755 script/config_template.sh delete mode 100755 script/generate_ac_config_files.sh create mode 100644 src/CMakeLists.txt delete mode 100644 src/README.md create mode 100644 test/CMakeLists.txt delete mode 100644 test/Makefile.am create mode 100755 test/run.sh delete mode 100644 test/test.am delete mode 100644 test/ut1/Makefile.am delete mode 100644 test/ut10/Makefile.am delete mode 100644 test/ut2/Makefile.am delete mode 100644 test/ut3/Makefile.am delete mode 100644 test/ut4/Makefile.am delete mode 100644 test/ut5/Makefile.am delete mode 100644 test/ut6/Makefile.am delete mode 100644 test/ut7/Makefile.am delete mode 100644 test/ut8/Makefile.am delete mode 100644 test/ut9/Makefile.am diff --git a/.gitignore b/.gitignore index c08bd91..89fb9a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# -- Mac OS files (from github's Global/OSX.gitignore) -- +<# -- Mac OS files (from github's Global/OSX.gitignore) -- .DS_Store .AppleDouble .LSOverride @@ -58,85 +58,11 @@ xcuserdata DerivedData *.xcuserstate -# -- Automake files (http://www.gnu.org/software/automake) - -Makefile -Makefile.in -.libs -.dirstamp -test-suite.log -/ar-lib -/mdate-sh -/py-compile -/test-driver -/ylwrap - -# --- Autoconf files (http://www.gnu.org/software/autoconf) - -aminclude_static.am -config.h -config.h.in -config.h.in~ -config.log -config.status -.deps -autom4te.cache -/autoscan.log -/autoscan-*.log -/aclocal.m4 -/compile -/config.guess -/config.h.in -/config.sub -/configure -/configure.scan -/depcomp -/install-sh -/missing -/stamp-h1 - -# --- Files added by autoreconf -i - -/ltmain.sh -libtool -COPYING -INSTALL - -# --- Texinfo files (http://www.gnu.org/software/texinfo) - -/texinfo.tex - -# --- M4 files (http://www.gnu.org/software/m4) - -m4/libtool.m4 -m4/ltoptions.m4 -m4/ltsugar.m4 -m4/ltversion.m4 -m4/lt~obsolete.m4 - # -- project specific ignores -- +lib* +build config.sh -exe -exe.prof* -vgcore* -*.o -*.dSYM -*.swp -*.swo -*.gcno -*.lo -*.la -*.gcda -*.log -*.trs - -test/*.txt -test/ut*/*.txt - -benchmark/*/benchmark_*.out - -examples/*/*.txt -examples/*/*/*.txt +vgcore* doc/*.aux doc/*.dvi @@ -149,8 +75,6 @@ doc/*.fdb_latexmk doc/*.fls doc/*.ilg doc/*.ind -doc/*.lb doc/auto + doc/doxygen/*/* -!doc/doxygen/doxygen.conf -!doc/doxygen/doxygen.html diff --git a/.travis.yml b/.travis.bak similarity index 100% rename from .travis.yml rename to .travis.bak diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ffa7d8b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required (VERSION 3.5) +include(FindPackageHandleStandardArgs) + +project (ffnn LANGUAGES CXX VERSION 0.0.1) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${USER_CXX_FLAGS}") + +if (USE_COVERAGE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") +endif() + +# find packages +message(STATUS "Configured GSL_ROOT_DIR: ${GSL_ROOT_DIR}") + +if (USE_OPENMP) + find_package(OpenMP) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENMP=1") + message(STATUS "OPENMP_LIBRARY_PATHS: ${OpenMP_CXX_LIBRARY}") + message(STATUS "OPENMP_LIBRARIES: ${OpenMP_CXX_LIBRARIES}") +endif() + +find_package(GSL) +message(STATUS "GSL_INCLUDE_DIRS: ${GSL_INCLUDE_DIRS}") +message(STATUS "GSL_LIBRARIES: ${GSL_LIBRARIES}") + +message(STATUS "Configured CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") +message(STATUS "Configured CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") + +# set header / library paths +include_directories(include/ "${GSL_INCLUDE_DIRS}") # headers + +enable_testing() + +# continue with subdirectories +add_subdirectory(src) +add_subdirectory(test) +add_subdirectory(examples) diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 57fb694..0000000 --- a/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -ACLOCAL_AMFLAGS = -I m4 - -SUBDIRS = lib test benchmark examples - -# SUBDIRS targets - -lib: - cd lib && $(MAKE) - -test: lib - cd test && $(MAKE) - -benchmark: lib - cd benchmark && $(MAKE) - -examples: lib - cd examples && $(MAKE) - - -# Special targets - -include-links: - cd include && $(MAKE) include-links - -source-lists: - cd lib && $(MAKE) source-lists - -update-sources: include-links source-lists - - -run-benchmarks: benchmark - cd benchmark && $(MAKE) run-benchmarks - -.PHONY: lib test benchmark examples source-lists include-links update-sources run-benchmarks diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 36c207e..0000000 --- a/autogen.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -autoreconf -fi || exit 1 diff --git a/benchmark/Makefile.am b/benchmark/Makefile.am deleted file mode 100644 index de4df3b..0000000 --- a/benchmark/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -SUBDIRS = bench_actfs_derivs bench_actfs_ffprop - -run-benchmarks: - for dir in $(SUBDIRS); do \ - if [[ "$$dir" == *"bench_"* ]]; then $(MAKE) -C $$dir run-benchmark; fi; \ - done diff --git a/benchmark/bench.am b/benchmark/bench.am deleted file mode 100644 index e2464de..0000000 --- a/benchmark/bench.am +++ /dev/null @@ -1,27 +0,0 @@ -AM_LDFLAGS += -lffnn -AM_CPPFLAGS += -I../common - -if !DEBUG - AM_CXXFLAGS += $(OPTFLAGS) -endif - -if PROFILING - AM_CXXFLAGS += $(PROF_CFLAGS) - AM_LDFLAGS += $(PROF_LFLAGS) -endif - -noinst_PROGRAMS = exe -exe_SOURCES = main.cpp - -if PROFILING -clean-local: - rm -f exe.prof* - -run-benchmark: exe - CPUPROFILE=exe.prof ./exe > benchmark_new.out - pprof --text exe exe.prof -else -run-benchmark: exe - ./exe > benchmark_new.out - cat benchmark_new.out -endif diff --git a/benchmark/bench_actfs_derivs/Makefile.am b/benchmark/bench_actfs_derivs/Makefile.am deleted file mode 100644 index 6f0c190..0000000 --- a/benchmark/bench_actfs_derivs/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../bench.am diff --git a/benchmark/bench_actfs_ffprop/Makefile.am b/benchmark/bench_actfs_ffprop/Makefile.am deleted file mode 100644 index 6f0c190..0000000 --- a/benchmark/bench_actfs_ffprop/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../bench.am diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..34766d9 --- /dev/null +++ b/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +. ./config.sh +mkdir -p build +cd build +cmake -DCMAKE_CXX_COMPILER="${CXX_COMPILER}" -DUSER_CXX_FLAGS="${CXX_FLAGS}" -DUSE_COVERAGE="${USE_COVERAGE}" -DGSL_ROOT_DIR="${GSL_ROOT}" .. +make -j$(nproc) diff --git a/config_template.sh b/config_template.sh new file mode 100755 index 0000000..2cbd154 --- /dev/null +++ b/config_template.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +#C++ compiler +CXX_COMPILER="g++" + +# C++ flags +CXX_FLAGS="-O3 -flto -Wall -Wno-unused-function" + +# add coverage flags +USE_COVERAGE=0 + +# use MPI for integration +USE_OPENMP=0 + +# GNU Scientific Library +GSL_ROOT="" # provide a path if not in system location diff --git a/configure.ac b/configure.ac deleted file mode 100644 index edd50a1..0000000 --- a/configure.ac +++ /dev/null @@ -1,153 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ([2.69]) -AC_INIT([FFNN], [0.1], [ithanil@mail.uni-paderborn.de]) -: ${CXXFLAGS=""} # delete default optimization user flags -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_MACRO_DIRS([m4]) -AC_LANG([C++]) - -AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) - -# --- Options - -# Add debug support -AX_CHECK_ENABLE_DEBUG() -AM_CONDITIONAL(DEBUG, test x"$ax_enable_debug" = x"yes") -AM_COND_IF(DEBUG, - AC_DEFINE(DEBUG, 1, [Define to 0 if this is a release build]), - AC_DEFINE(DEBUG, 0, [Define to 1 or higher if this is a debug build])) - - -# Add coverage support (gcov) -AC_PROG_CXX -AX_COVERAGE() -AM_CONDITIONAL(COVERAGE, test "x$enable_coverage" = x"yes") -AM_COND_IF(COVERAGE, - AC_DEFINE(COVERAGE, 1, [Define to 0 if you don't need code coverage statistics.]), - AC_DEFINE(COVERAGE, 0, [Define to 1 or higher if you want to generate code coverage statistics.])) - - -# Add profiling support (gperftools) -AC_ARG_ENABLE(profiling, - AS_HELP_STRING( - [--enable-profiling], - [enable profiling, default: no]), - [case "${enableval}" in - yes) profiling=true ;; - no) profiling=false ;; - esac], - [profiling=false]) -AM_CONDITIONAL(PROFILING, test x"$profiling" = x"true") -AM_COND_IF(PROFILING, - AC_DEFINE(PROFILING, 1, [Define to 0 if you don't need performance profiling.]), - AC_DEFINE(PROFILING, 0, [Define to 1 or higher if you want to generate performance profiles.])) - - -# Add OpenMP support -AC_ARG_ENABLE(openmp, - AS_HELP_STRING( - [--enable-openmp], - [enable openmp, default: no]), - [case "${enableval}" in - yes) openmp=true ;; - no) openmp=false ;; - esac], - [openmp=false]) -AM_CONDITIONAL(OPENMP, test x"$openmp" = x"true") -AM_COND_IF(OPENMP, - AC_DEFINE(OPENMP, 1, [Define to 0 if you don't want to use threading via OpenMP.]), - AC_DEFINE(OPENMP, 0, [Define to 1 or higher if you want to enable OpenMP threading.])) - - - -# --- Checks - -AM_PROG_AR - -LT_INIT # use libtool - -# Checks for programs. -AC_PROG_AWK -AC_PROG_INSTALL -AC_PROG_MAKE_SET -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX -AC_PROG_CXXCPP -AC_PROG_LN_S -AC_PROG_RANLIB - -# check for c++11 support (and add compiler flag) -#AX_CXX_COMPILE_STDCXX(11, ext, mandatory) - -# check for valgrind -AX_VALGRIND_CHECK - - -# Checks for libraries. - -# Checks for header files. - -AC_CHECK_HEADERS([gsl/gsl_vector.h gsl/gsl_matrix.h gsl/gsl_blas.h gsl/gsl_multifit_nlinear.h], [ ], [ AC_MSG_ERROR([Unable to find one or more required GSL headers!]) ]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_CHECK_HEADER_STDBOOL -AC_C_INLINE -AC_TYPE_SIZE_T - -# Checks for library functions. -AC_CHECK_FUNCS([pow sqrt]) - - - -# --- Compiler flags - -AC_SUBST([DEBUGFLAGS], ["-g -O0"]) -AM_COND_IF(PROFILING, AC_SUBST([OPTFLAGS], ["-O3"]), AC_SUBST([OPTFLAGS], ["-O3 -flto"])) -AC_SUBST([PROF_CFLAGS], ["-g -DWITHGPERFTOOLS"]) -AC_SUBST([PROF_LFLAGS], ["-lprofiler"]) -AC_SUBST([OMP_CFLAGS], ["-DOPENMP -fopenmp"]) -AC_SUBST([OMP_LFLAGS], ["-lomp"]) - -AC_SUBST([AM_CXXFLAGS], ["-Wall"]) -AC_SUBST([AM_CPPFLAGS], ["-I$(pwd)/include"]) -AC_SUBST([AM_LDFLAGS], ["-L$(pwd)/lib -lgsl -lgslcblas"]) - - -# --- Makefiles - -# output of ./script/generate_ac_config_files.sh -AC_CONFIG_FILES([ -lib/Makefile -include/Makefile -test/ut10/Makefile -test/ut1/Makefile -test/ut8/Makefile -test/ut2/Makefile -test/ut5/Makefile -test/ut9/Makefile -test/ut3/Makefile -test/ut7/Makefile -test/Makefile -test/ut6/Makefile -test/ut4/Makefile -examples/ex9/Makefile -examples/ex7/Makefile -examples/ex1/Makefile -examples/ex6/Makefile -examples/ex4/Makefile -examples/ex5/Makefile -examples/ex2/Makefile -examples/Makefile -examples/ex8/Makefile -examples/ex3/Makefile -examples/ex10/Makefile -Makefile -benchmark/bench_actfs_derivs/Makefile -benchmark/Makefile -benchmark/bench_actfs_ffprop/Makefile -]) - -AC_OUTPUT diff --git a/doc/user_manual.pdf b/doc/user_manual.pdf index 4c2e87b11aa9d343fd421be9c731a29559910d9e..327281573f47dc0433634ac067e16f9a4d6c0913 100644 GIT binary patch delta 61208 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νiixK`wPheP8NGSN;(h~KCvDcxTGHc_o>d`7@U^5D=^wF3WRQx1aL0&`CEdb<7e7|MQ>7V22 z3pXMyg*;NbK7hG*|7k)vmSn5}iUkx++KvMQ?KKCv2Pvpqoa8ATAcgWY$j#B74e76) zgm(ttGK;{-P`Npt6Q3@wF>mwmT@~CBO(Txe!h)WRnYp)hLk=#K*RkSaI`O-S^(oxc z3zm{gLiPe<>yD(RFkrgNNId4|pKRdNf8K=Z<7s3I#)D}51V^)Kt`NQB12)NhG-hFE zb+wiieOP@f4P*0yf`+dh!ujlSBC1F)!NRGswbcMz!JpI!j*quFnlCt#9zj}5@T9jD zB0fb_iUU1(gL#8>DKraDQfZ`b9!52hAmt$fhj6^DN zNP%=e)Xt*pmof)`suwjj5$)mx;tTAkAS2Ny169*&)4HB<;@ynDiqi@YKd-XR_NGHI z>~3n^$AxZ=ydmzv=T}P`A|4@ zxMnlwp}?*%U?Zq!(Xv#e6bP=4%Z=CU5QW)uVlNEuJF~QvaBVzI#cI+dpP}!z7@H}`s>Z6{;t&*`h^aW1D zIx$>lwfquM`pw6c@J2*Rp@02EW-!+Tce3Nnr0Q-gOB$EM0`DJo53}c#px}F$D z8(OHz7+#TDh6X@>&W7LDGDBB;=#~MHd%i z*Twf-?X6z_)iV(PLXW=hJb#ooJC2KIblY1?@-nG6Z-6B;tSM1vD^%d;p*l)&F-VLa zh8c?ocV>6BQ4AqobEbn)VnEdrA(4T-FS@q|1o|E>Zjy)|j;Ve-K5Y^`7vE5=_j67( z=c0-#?nBJox<1W*X8d5z{*;gMTA0!i&PoksQ_Pu|mQS;!#hVQyApV9&X+zi9i;wHpN38$2lEr`3iX3RDv$p;#*Cfx{&8+^CXt$S6UU)n?Zpp2R1H&`pp($S|M-9-GEp{eh4 zuo0YpjM8o;0|h3weFMuoVvG`2D3+o6+nlj?C~dZv$U;ili-S}NuDbij_-CttJAt*a zrN$2X<2SNV;*43pp&Wmelb}^`-#x{1DHHA|#B(egFb}`@n?}ewpE7|&!XPx%RUc8i zD^#_SyvU}9xsYau0_E~k_LAP`sENp5vM8YmP5;`~z~v;>8$BzEP+H#m9S|j+KnPtH zHh;}5AXqYs<(ebpFDn5q^f74$t9l#FdEn(pjX z!e+*-9AyqiG(SGGQ68g(ma-jovyP&tUVTYi#SW;#M-WtHZ5t zsKa_j%E|#8Fr1|Uq$vil1k1Ej`i?n8q_x%gd`mD78m~FgkTEUWaT5tcC55)35JEAn z&r!GH-P{3t2xjc*G&`KD2*y>Hnk|gMDCvBCz^?bC?am|ObxO``^a{gd^*2%4b=Q6~ z^$VFsLTP^renY^p?MT|J2Wv!fPk@EnV`zV%QvfrQjpiJSwl`8<9sKAP@7F%E?0_+wx-f!1&O*`Lrql&y__SaWimnJQ_EBm?ip|H=7DETt2U z!uEUnk-mrU)|IIY zawdi}#=%YeW533QZzG&J7<@2A5iFX}Qs8TS^REnNql!A@EFG&9{{cuE5Nw&Kds_x1 zzFS9)0(zJqI!Rx6_sFVq3&>J8z+j<8AVj^gy!Syi5NMy|dMXM01ZuYB+ z$MR&bu618DMVqm;6%B~Yw2zVF|1CJdY}q+cnF+objc~DWw#=eEb`c zn?};P#C9!6!%Kba#>4kH9dYzyTNFk%eoI24IMBhf?Wq!?ME5|Vjlv#T9ICsz-+PTVat z{qIJi);1{*aE#Y`8z|>g5l4C&w0kN-ncbkSqQ_OmSs^NL(e^WQt=HF}99!A70m>b{ zK{IOJ`U(N(DO1^>a3hjTxMw2-tj1Cqz$pCh&a*_F_%p820pqIM*y;P4Z%Q@VJ@|Zv z;bTuwf49su`8|ra+sx4dZ-WcpS5}1Gk$bpUh%xUQX1%avSAKkoh9#~Lsgxn7?q;^^ zJOd!0>E<^7Lo%wXhia{>hYleDW9IrFt?OpXbSBSOaF?s`k4gh5YkJMMiBD& zV%>8R))~tc%t(n7Ld8s)g;A*WIge1udzr0pSzUC9(JNu$USI}}<0 zt3y2LBEk(gMn>yH?ols!gpw!Ql*p0(E{h_Ny%K?GbFn zVumb|0*Oz|1V58>X>AS@;8?#2r+=fAPf0RaNHGIv7D@NJ?j|%322sAz92h&0VZ}_f zh9;K|&Zttf5T7KGCT$`4Ri(v>KRxZrS(2rS zVo54h+042DIibeRk#8ha6A;5q)TJT|8D0Cud?ms%M)3zJQIPr$HIt%|rfkgEIxv@Q z!yhT$IrQ>EIuu;sTdo<`ov;@f?o9o@cj7MJ-yBL@hInvPFdps@4c@P}RRzD#eV2?w z=*96pYwq6c7y-u8#+;YG9v-r+4veu+dEH+hBP}ttM>>M*uc|M>2~ASMWXKI z*%%#f3BAC@LELfLp_#CNyn_I)pPxZ&jRRKIgTjo8hrQ!$T82KOMR}%Xb4mZbC&$&(}kHu9>nVmM^~S zl%y9Op9+IFzMiaqY`rXP?V~7%#rJDx4nj30B#B}W6$qM!#T?-4ZyDYF`|bQ^lBOMQ zGGb9$sB%AFxbaIfduT*DXTOWA$LoG$_r4&K*3V~Et@GNLk8;x(K}{|8 zFSPm&rJ&Vd)E48@<=xZqao&|blbNdJ@>jBDZ=_nzZK)-h03cCAo~l-Fa(eK-nKkIL z@Nq#%*pnx`p-0M!*|6CsoY7mE4MpINf=)~PlcfT=zV87KAwsod-MR+9$pd;2Dseu{q{xRb!^U^yn z$3Lm*FPrL#1sp+Re?!f@&L@?5OQO#3JeQE5o1_-sTMkMcw0J{r4l874Q*zt?W;?)}?1w17SzoxbKN=6?9Ow)||mxcL^PsZ3-)$BHzCjK#AIS~Gb)oO&<&Xi>fYav0?K;x2ru-N4jUPwm6{uD+vtwr z7^rmPvg8XzZdIKYSLQ*M=J{rx?UwKiJf*0P`$p49NvOh>FZXx0+~dbZ*S_ijTQnry!2Qd~dzHxbYGK)W zmx!V{lN(%5XzqtsOx73P+sC`QpNzpRv?ruDgm-^BzdvH%AHa5Zlg8-MFuPmOOLZ6V z{KlDG(W4zSe=C}&2tadi!^&N-_DB^hL%*c~1PfK25_@AQ_v7Aw_z9=tZ22)*-tQhn ziu^gWYQl-BmEmE_j+j(`)GKA{YAIJRe>{A6YGJWIv{A=Z_3I@-cF?7~@zOw|Ey>ZnLRcOAt&Q5Ls z$|XnLowK8Zukz=Aw&iQ2-VR+gMo@0}zY@OavqP)NKF{wh|6W%v3K6#J?-Op7ErOub zvVUT4)ib_~THnPBn!fu;X_64{d`Wn|$8{V3aSP8P&T|OQi#4=6MCcXsCEnIGAK|Rc z?dJ1UzO7!B0H+y3+kODPn6|Sq4N>xdw1^A}M$SnpoEZE@BbMQ~8q_Hb*qi0y-O2m1 z6x3`3)l?d2JtD`PX-*N8Pw8(2@j;s6pu9)&G~lHW-oo*{hk}__tuh{A*op={yWjl$ z+CIafwO9l+V*dRKBVsLg)ZLP1JkEB-(M1v|19R}R;(J~tp73wCL^ye{o zGaM3Q9DkE0PnWHn=yNT<<{3uTlo6`)Br=#MA-WQQ+MgCa)nMh~^03g_ zt&z1U`YP!PI~9%-k&?1ZZ8QzQ$PJOHZ*&Lqr$zxK)T6nU0%)d|;)uafkh#I^9GvvI z_|c7ki@CvS+eZ>y_Rl4!r6f$k4vC(Lz-r}q$W^Odd~%a zGtWeyF%rPHef5U&_@uUaIJ49EMCZ+}Z%$4iAAA2|*NfW`bWDX#5Z?s>^L9N(!14Z# zO?s}naM<hMyWXS_|Y)J8U1D%cjo_>%8u18W0KJ zf>(V%uoZO9*X!u<0F@@qjVSxgn`ZI90`qR1&l^!!Te{7~=L-Hob6f{+1_AMUE*Y_` zpLAW_(C!RT>ojhEKzu$P+A}4FMXi>)`>bt)KO|I|>2}^l%a^(VQ|rp5TRhX1@1-{= zG;a8RQ)Nn%s+(-f)!>Qx`GRFOw;HQeRy&RL;o$%Cp0~e6hVa^bSSRJ;U-XaFb(&qM zJsak}PH3lVg|8)zU*}tOD`^iwFDmD<;(xo`vNu+vNDVm?=Hz;b4ANZAR!e{W`M8|B z*1iCj=gDN0)CB&_4W$(SyV+cEZIa>C@rIuY>=z>Ul7Utf#tME{11i^qa?IasX>qYQ zCw5Hg)|X1Vh2U)!uCPqc{Eo(5wVi<$y%si`<^p|s0%h=|5=E5PeY*_Ow0IJFZ+_Zd ziwbS{p^{U4OvaF&l5wZl$!l8u%)jZ&0^+j*JuNZC3V_yCAb*ySFZ$-@P>oswX9PSx zCYYf*3U4oej=@zfeQ4t_No9?5<905Psep}c6F~e6lzpUtzrwm{qWZT(SkxUykA@r0 zWI!PH+Z#-;s(2Oh(DjLXla;h#_j5tD2|H?u$q!i~#{v!`t?~*)5ag3}|3gq!d?6zL z77f~fNg&NEg@CbU@QF`Jllexdf#&D^pI$)~JH`@qTO6EtH|b8rqVrB|av}At<@vbc z?cQZ&N4~Nkc0;8;@21I8#f_CPX@W2C{u!VB%t8kTSW25pW0# z5X!scG;IH%!&K-T+6+2}{lg!Dd6)eA|A6+iv>eXD>_0FWkUpM??@)hj#zH+`)oua> z(EbyO@V|lLKNbZISBexb=&y4(K{5hY?8k3ldjqn1AWpj!4E}95XxKuT-VyL53|$Am zh2Gx$TEW>*7}h}|+HMLVBce#0K!?QR+v>90ik{|jnwq3{(w2{GfHkHz}oFQ!*6()42oHv(}1W#~3gQ_7V@lRe~MtK1Xn z&G=RLr@9~=TUYfE4A`txa{eK11iDymf)uHO5SSdEXz$bMOl@BBws7-O-eAg;2A#5O#PvAjEn)Sk8N0v1K`P($pH@srp zmdY0XHrFzSg{(8O52}^*M8b9^F#7s|6jZASOokYts7_{D9w}BkZPkapg`lfK#JY6M zZ}kI*s5lXrHF14XRVN+_3C1*&ccS-VQ?Za7!v!WiXBrRB*;Q0 z$(aB&YCTF&sjHa~H2<^V<(lM&QW)BIakLtC&n^Nn=qfTN^8qFRIQ)F$Z&!tRi-2q??8ukHsl6 zuo&mj26NKhbFwIJO0m;V37CSi{F&(u3PW^7Z_w!f;0LBz8S7~b38T{I_^lBw z@$WIst%<5mMON?;Ojj5`NNaXCeiv?|_9Oo{RqemWSojXm6gq9XO(A0NjV2UN85p$E z#*I1~Q4^WMmdb!&`C69iBlt|P1{EGjsVyzWEy`l^@*bXr7}XwWscq$7<>pNEwWVw! zH~mU+ExB-|3ek?b#|4D#HMkO#Da$520Tx*j+LS7uAA7XVUb zyP^Hf(Es?>!!Yz^By~3L)qc*$Rg5m5<|1Q)V_jKuTkktb z7)|WS?M6{we|Z1G8Ys%o!X9W!pObV)Y6svo_TRzt<6+EuS65Y!MH1XJ>ZjfkL4;7I zsL!=cmZ;Azp4c##=5}xMLiO7-MY;%MX?i#{m`UW%^g?`h<<+mp{`Ko@S!#yMy~XV_ z1S2?s^fREztCKPQaTY;Ztzw7C6Q?xpJRM1}v@v$Y!R>3iYgTtchH2ptsuVr?^v)D? zv0ps6`f4qc-z706maP;XT8X%sgdc~G;OiRcGr3NU{q@&f2F{c5w?11#(_!KXZ9~r`tr#O3^m`?lpQyof=>wU_lZ4NjNwGqu~HOOQ?OC1{BksU?)j5Dm(gfmn+Y(*a(6aEyaOFKj1 zQNXJaXgL(TFrpU3d&ls*3HyWt0J0>L-qpw1jz9-Z+ec_bp#}MFX)8pi1Ux2;;9It_wq-KZqzmp$5;0_e|7ReWT4TQjmdKP4yZFNTj2$8V zj7P9AJY5nEvyEzd!Hg;q%~MT)KQt0u<4g<+2He?Y17e>46k548(SHAWjj%`!v=K4B zK0$U6+r3!wrzvnRaCBdfs1Ujo+PzSV%M4$S%?w@-&5T};%nV!)%#2)*&J0}-t`Pen zCNKFzXj-URa$2lfRJ~xO(4yc>sZrTh$wjGB*+sch>0XIe`CeI#i9x7ZNWCbv2rJPW z*%5aV4_H!JB2%NMDNN1BDiSiw;6iODcXB$gjKCMOPbv31z>O#q&&^sBcIB+E9Q#D$ zjk(~i|0_ih5l&W5Q5Zdx70#C!B*sDJDQ!lTSShwb_9|<}lDH`5{>@Xtj4$!87$(`H zl-hTdBC%#NH(50%l}Rym)9&CS7f+@Zy&0 zUUTB4b`l3?9EUH7`9Wpm20ERo!}pK8eGL?>w;#M3DCK&2aMAJo@aPs2Syryw#@@vm zmGMKFk4Y8HzL@ODIP`}l1?+y>-Cd0??$5?v?^Lrtyy;G7x6ywM9*;Ss+rDfyr_qQ$ zCjj-RV3)5pn-oXCl1dI(?B|Yk`rSiHy=GaD{f0^;SWW|{W$N7{%bE^ypZ8yt_ORQZ zhZT|ompYoB_U~KQ6^aAfzBO;+GG+RR;Zq*{%Op5pgJkT)Z}t2}j5wfw`}`b12q6Ba z6kyXy653I5aTBajaWUpu$1%bMaD4!uS1OX{@iKp8kZa#-xa${KvhLoOVLKK?aQDnL z!#m^T{qoue*)@B-0+!}{C=bIcQBPzv5wc)0mYBR{E@MdZqhhF(t$txq#$RTX7F;L;dcs4gG=zmOdADE+(cFw`Q3MxbB3fxA zhy^#fAir`vb5yvdN#P*iCm)VP01IR?X#PXb!qdOl>6(Z3g*};{v@z9Fb|ug$L~342 z8P5|hng*~F_#&RRRA;`Naxc*Bg5!We?Iei~Ex z>HSREL}=Ws2cUZ}!>EzpFeIsBm3~6hsLEBR3o{3q*xV-s{F;V_YpE+tUf#MvFCM26 zn-ScX{Sr!xI)}zfOFoB2{VxDMMlXFg0lVOX&?DacHvzXCOcf4l+vPpV^cz%nT|goZ z789M3R$raJG3X#zC?oE^arMhAV>SCxR6HrU>(s84CwVHL*5dc^xMAY zgG?0fg%$YhJ^kGkoHm;o_}7l*`~TIM#l_Xw+110@+yajM-$KU821h|5t|$TbzW`~7 BET{kg diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..7dfe385 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,12 @@ +link_libraries(ffnn) + +add_executable(ex1.exe ex1/main.cpp) +add_executable(ex2.exe ex2/main.cpp) +add_executable(ex3.exe ex3/main.cpp) +add_executable(ex4.exe ex4/main.cpp) +add_executable(ex5.exe ex5/main.cpp) +add_executable(ex6.exe ex6/main.cpp) +add_executable(ex7.exe ex7/main.cpp) +add_executable(ex8.exe ex8/main.cpp) +add_executable(ex9.exe ex9/main.cpp) +add_executable(ex10.exe ex10/main.cpp) diff --git a/examples/Makefile.am b/examples/Makefile.am deleted file mode 100644 index 3ece124..0000000 --- a/examples/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 diff --git a/examples/README.md b/examples/README.md index 73aa4ad..cc5a275 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,9 +1,10 @@ # LEGEND OF THE EXAMPLES -Make sure the examples are compiled, by running `make examples` in the project root folder. -Execute an example by switching into one of the example folders and running `./exe`. +Make sure the examples are compiled, by running `./build.sh` in the project root folder. +Execute an example by switching into one of the example folders and running `./run.sh`. +Note that the actual example executables reside inside the build/ folder, from project root. Some examples might also contain a `plot.py` script to show a plot. -Run it after the exe by `python plot.py` (requires matplotlib). +Run it after the executable has terminated, via `python plot.py` (requires matplotlib). ## Example 1 @@ -59,6 +60,7 @@ Run it after the exe by `python plot.py` (requires matplotlib). `ex9/`: use NNTrainer(GSL) to make FFNN fit a gaussian + ## Example 10 `ex10/`: use a FeatureMapLayer to fit more easily a gaussian of x-y-distance diff --git a/examples/ex1/Makefile.am b/examples/ex1/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex1/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex1/run.sh b/examples/ex1/run.sh new file mode 100755 index 0000000..315481f --- /dev/null +++ b/examples/ex1/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd ../../build/examples +./ex1.exe diff --git a/examples/ex10/Makefile.am b/examples/ex10/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex10/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex10/plot.py b/examples/ex10/plot.py index 82f328c..56af7b8 100644 --- a/examples/ex10/plot.py +++ b/examples/ex10/plot.py @@ -22,11 +22,12 @@ def f_d1_2(y): def f_d2_2(y): return f_d1_2(y) * (2*(x0-y) - 2*y) - 4.0 * f_v_2(y) +prefix = '../../build/examples/' fnames = ['v_0_0','v_1_0', 'd1_0_0', 'd1_1_0', 'd2_0_0', 'd2_1_0'] files = {} for fname in fnames: - files[fname + '_' + 'NN'] = './' + fname + '.txt' + files[fname + '_' + 'NN'] = prefix + fname + '.txt' data = {} for file in files: diff --git a/examples/ex10/run.sh b/examples/ex10/run.sh new file mode 100755 index 0000000..7365751 --- /dev/null +++ b/examples/ex10/run.sh @@ -0,0 +1,6 @@ +#!/bin/sh +( +cd ../../build/examples +./ex10.exe +) +python plot.py diff --git a/examples/ex2/Makefile.am b/examples/ex2/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex2/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex2/run.sh b/examples/ex2/run.sh new file mode 100755 index 0000000..d2054c1 --- /dev/null +++ b/examples/ex2/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd ../../build/examples +./ex2.exe diff --git a/examples/ex3/Makefile.am b/examples/ex3/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex3/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex3/run.sh b/examples/ex3/run.sh new file mode 100755 index 0000000..3b42d77 --- /dev/null +++ b/examples/ex3/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd ../../build/examples +./ex3.exe diff --git a/examples/ex4/Makefile.am b/examples/ex4/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex4/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex4/run.sh b/examples/ex4/run.sh new file mode 100755 index 0000000..3e7aba3 --- /dev/null +++ b/examples/ex4/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd ../../build/examples +./ex4.exe diff --git a/examples/ex5/Makefile.am b/examples/ex5/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex5/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex5/run.sh b/examples/ex5/run.sh new file mode 100755 index 0000000..943d004 --- /dev/null +++ b/examples/ex5/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd ../../build/examples +./ex5.exe diff --git a/examples/ex6/Makefile.am b/examples/ex6/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex6/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex6/run.sh b/examples/ex6/run.sh new file mode 100755 index 0000000..0a25c76 --- /dev/null +++ b/examples/ex6/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd ../../build/examples +./ex6.exe diff --git a/examples/ex7/Makefile.am b/examples/ex7/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex7/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex7/main.cpp b/examples/ex7/main.cpp index f9d49b0..3c4a8aa 100644 --- a/examples/ex7/main.cpp +++ b/examples/ex7/main.cpp @@ -80,10 +80,9 @@ int main() { writePlotFile(ffnn, base_input, input_i, output_i, min, max, npoints, "getFirstDerivative", "v1d.txt"); writePlotFile(ffnn, base_input, input_i, output_i, min, max, npoints, "getSecondDerivative", "v2d.txt"); + cout << "Done! In the files v.txt, v1d.txt, and v2d.txt we stored the values, and you can use any software you like to plot them (perhaps gnuplot?)." << endl << endl; - cout << "Done! In the files v.txt, v1d.txt, and v2d.txt we stored the values, and you can use any software you like to plot them (perhaps gnuplot?)."; + cout << "Note that the executable was run within the build/examples/ directory, so you have to look there to find the mentioned output files." << endl; - - cout << endl << endl; return 0; } diff --git a/examples/ex7/run.sh b/examples/ex7/run.sh new file mode 100755 index 0000000..d4186f5 --- /dev/null +++ b/examples/ex7/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd ../../build/examples +./ex7.exe diff --git a/examples/ex8/Makefile.am b/examples/ex8/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex8/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex8/run.sh b/examples/ex8/run.sh new file mode 100755 index 0000000..708394e --- /dev/null +++ b/examples/ex8/run.sh @@ -0,0 +1,4 @@ +#!/bin/sh +cp stored_ffnn.txt ../../build/examples/ +cd ../../build/examples +./ex8.exe diff --git a/examples/ex9/Makefile.am b/examples/ex9/Makefile.am deleted file mode 100644 index 7b3221b..0000000 --- a/examples/ex9/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../example.am diff --git a/examples/ex9/plot.py b/examples/ex9/plot.py index e37a506..02d65f7 100644 --- a/examples/ex9/plot.py +++ b/examples/ex9/plot.py @@ -3,11 +3,12 @@ gauss_a = 1.0 gauss_b = 0 +prefix = '../../build/examples/' fnames = ['v_0_0','d1_0_0','d2_0_0'] files = {} for fname in fnames: - files[fname + '_' + 'NN'] = './' + fname + '.txt' + files[fname + '_' + 'NN'] = prefix + fname + '.txt' data = {} for file in files: diff --git a/examples/ex9/run.sh b/examples/ex9/run.sh new file mode 100755 index 0000000..973b4b4 --- /dev/null +++ b/examples/ex9/run.sh @@ -0,0 +1,6 @@ +#!/bin/sh +( +cd ../../build/examples +./ex9.exe +) +python plot.py diff --git a/examples/example.am b/examples/example.am deleted file mode 100644 index 2cd421f..0000000 --- a/examples/example.am +++ /dev/null @@ -1,8 +0,0 @@ -AM_LDFLAGS += -lffnn - -if !DEBUG - AM_CXXFLAGS += $(OPTFLAGS) -endif - -noinst_PROGRAMS = exe -exe_SOURCES = main.cpp diff --git a/include/Makefile.am b/include/Makefile.am deleted file mode 100644 index 1c1aee1..0000000 --- a/include/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -include-links: - rm -f *.hpp - ln -s ../src/*/*.hpp ./ - -.PHONY: include-links diff --git a/include/README.md b/include/README.md deleted file mode 100644 index 2930f78..0000000 --- a/include/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# include - -In this folder we maintain symbolic links to all headers in src, to allow flat include statements. - -If you add or remove source files in src, you should run the following from project root: - `make update-sources` - -This will update the lib and include folders to a changed src. diff --git a/lib/Makefile.am b/lib/Makefile.am deleted file mode 100644 index af8e3e3..0000000 --- a/lib/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -if !DEBUG -if !COVERAGE - AM_CXXFLAGS += $(OPTFLAGS) -endif -endif - -if COVERAGE - AM_CPPFLAGS += $(COVERAGE_CPPFLAGS) - AM_CXXFLAGS += $(COVERAGE_CXXFLAGS) - AM_LDFLAGS += $(COVERAGE_LDFLAGS) -endif - -if PROFILING - AM_CXXFLAGS += $(PROF_CFLAGS) - AM_LDFLAGS += $(PROF_LFLAGS) -endif - -if OPENMP - AM_CXXFLAGS += $(OMP_CFLAGS) - AM_LDFLAGS += $(OMP_LFLAGS) -endif - -lib_LTLIBRARIES = libffnn.la -include headers.am -include sources.am - -if COVERAGE -clean-local: - rm -f ../src/*/*.gcda - rm -f ../src/*/*.gcno - rm -f ../src/*/*.gcov -endif - -source-lists: - echo "pkginclude_HEADERS = \\" > headers.am - find ../src/ -name *.hpp | tr '\n' ' ' >> headers.am - echo "libffnn_la_SOURCES = \\" > sources.am - find ../src/ -name *.cpp | tr '\n' ' ' >> sources.am - -.PHONY: source-lists diff --git a/lib/README.md b/lib/README.md deleted file mode 100644 index e2a2dba..0000000 --- a/lib/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# lib - -In this folder the library will be built before installing. Just run `make` here or `make lib` from root folder. - -Also this is a default library search path for the project, -so one way to provide external libraries outside of standard paths is by dropping or linking them in here. diff --git a/lib/headers.am b/lib/headers.am deleted file mode 100644 index dbad00c..0000000 --- a/lib/headers.am +++ /dev/null @@ -1,2 +0,0 @@ -pkginclude_HEADERS = \ -../src/io/PrintUtilities.hpp ../src/unit/InputUnit.hpp ../src/unit/ShifterScalerUnit.hpp ../src/unit/ActivationUnit.hpp ../src/unit/FedActivationUnit.hpp ../src/unit/NetworkUnit.hpp ../src/unit/NNUnit.hpp ../src/unit/FedUnit.hpp ../src/unit/ShifterScalerNNUnit.hpp ../src/unit/OutputNNUnit.hpp ../src/unit/OffsetUnit.hpp ../src/layer/NNLayer.hpp ../src/layer/NetworkLayer.hpp ../src/layer/OutputNNLayer.hpp ../src/layer/InputLayer.hpp ../src/layer/FedLayer.hpp ../src/network/FeedForwardNeuralNetwork.hpp ../src/feeder/FeederInterface.hpp ../src/feeder/WeightedFeeder.hpp ../src/feeder/VariableFeeder.hpp ../src/feeder/SmartBetaGenerator.hpp ../src/feeder/NNRay.hpp ../src/feeder/StaticFeeder.hpp ../src/trainer/NNTrainerGSL.hpp ../src/trainer/NNTrainingData.hpp ../src/trainer/NNTrainingConfig.hpp ../src/trainer/NNTrainer.hpp ../src/serialize/SerializableComponent.hpp ../src/serialize/StringCodeUtilities.hpp ../src/feature_maps/PairSumMapUnit.hpp ../src/feature_maps/FeatureMapLayer.hpp ../src/feature_maps/PairSumMap.hpp ../src/feature_maps/EuclideanDistanceMapUnit.hpp ../src/feature_maps/PairDifferenceMapUnit.hpp ../src/feature_maps/EuclideanDistanceMap.hpp ../src/feature_maps/EuclideanPairDistanceMap.hpp ../src/feature_maps/IdentityMapUnit.hpp ../src/feature_maps/PairDifferenceMap.hpp ../src/feature_maps/FeatureMapUnit.hpp ../src/feature_maps/EuclideanPairDistanceMapUnit.hpp ../src/feature_maps/MultiDimStaticMap.hpp ../src/feature_maps/IdentityMap.hpp ../src/feature_maps/OneDimStaticMap.hpp ../src/feature_maps/ActivationMapUnit.hpp ../src/actf/ActivationFunctionManager.hpp ../src/actf/SRLUActivationFunction.hpp ../src/actf/TanSigmoidActivationFunction.hpp ../src/actf/SineActivationFunction.hpp ../src/actf/ExponentialActivationFunction.hpp ../src/actf/LogisticActivationFunction.hpp ../src/actf/ActivationFunctionInterface.hpp ../src/actf/SELUActivationFunction.hpp ../src/actf/IdentityActivationFunction.hpp ../src/actf/GaussianActivationFunction.hpp ../src/actf/ReLUActivationFunction.hpp \ No newline at end of file diff --git a/lib/sources.am b/lib/sources.am deleted file mode 100644 index 7e5617f..0000000 --- a/lib/sources.am +++ /dev/null @@ -1,2 +0,0 @@ -libffnn_la_SOURCES = \ -../src/io/PrintUtilities.cpp ../src/unit/ActivationUnit.cpp ../src/unit/InputUnit.cpp ../src/unit/OutputNNUnit.cpp ../src/unit/NetworkUnit.cpp ../src/unit/FedUnit.cpp ../src/layer/NNLayer.cpp ../src/layer/InputLayer.cpp ../src/layer/OutputNNLayer.cpp ../src/layer/FedLayer.cpp ../src/layer/NetworkLayer.cpp ../src/network/FeedForwardNeuralNetwork.cpp ../src/feeder/NNRay.cpp ../src/feeder/WeightedFeeder.cpp ../src/feeder/FeederInterface.cpp ../src/feeder/SmartBetaGenerator.cpp ../src/feeder/VariableFeeder.cpp ../src/trainer/NNTrainerGSL.cpp ../src/trainer/NNTrainer.cpp ../src/serialize/StringCodeUtilities.cpp ../src/feature_maps/EuclideanPairDistanceMap.cpp ../src/feature_maps/IdentityMap.cpp ../src/feature_maps/FeatureMapLayer.cpp ../src/feature_maps/PairSumMap.cpp ../src/feature_maps/PairDifferenceMap.cpp ../src/feature_maps/MultiDimStaticMap.cpp ../src/feature_maps/OneDimStaticMap.cpp ../src/feature_maps/EuclideanDistanceMap.cpp ../src/actf/LogisticActivationFunction.cpp ../src/actf/ReLUActivationFunction.cpp ../src/actf/SELUActivationFunction.cpp ../src/actf/GaussianActivationFunction.cpp ../src/actf/ActivationFunctionManager.cpp ../src/actf/TanSigmoidActivationFunction.cpp ../src/actf/ExponentialActivationFunction.cpp ../src/actf/SineActivationFunction.cpp ../src/actf/SRLUActivationFunction.cpp \ No newline at end of file diff --git a/m4/README.md b/m4/README.md deleted file mode 100644 index cd7aa05..0000000 --- a/m4/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# m4 - -In this folder we collect special m4 macros for autoconf. diff --git a/m4/ax_ac_append_to_file.m4 b/m4/ax_ac_append_to_file.m4 deleted file mode 100644 index 242b3d5..0000000 --- a/m4/ax_ac_append_to_file.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_ac_append_to_file.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_AC_APPEND_TO_FILE([FILE],[DATA]) -# -# DESCRIPTION -# -# Appends the specified data to the specified Autoconf is run. If you want -# to append to a file when configure is run use AX_APPEND_TO_FILE instead. -# -# LICENSE -# -# Copyright (c) 2009 Allan Caffee -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 10 - -AC_DEFUN([AX_AC_APPEND_TO_FILE],[ -AC_REQUIRE([AX_FILE_ESCAPES]) -m4_esyscmd( -AX_FILE_ESCAPES -[ -printf "%s" "$2" >> "$1" -]) -]) diff --git a/m4/ax_ac_print_to_file.m4 b/m4/ax_ac_print_to_file.m4 deleted file mode 100644 index 642dfc1..0000000 --- a/m4/ax_ac_print_to_file.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_ac_print_to_file.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_AC_PRINT_TO_FILE([FILE],[DATA]) -# -# DESCRIPTION -# -# Writes the specified data to the specified file when Autoconf is run. If -# you want to print to a file when configure is run use AX_PRINT_TO_FILE -# instead. -# -# LICENSE -# -# Copyright (c) 2009 Allan Caffee -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 10 - -AC_DEFUN([AX_AC_PRINT_TO_FILE],[ -m4_esyscmd( -AC_REQUIRE([AX_FILE_ESCAPES]) -[ -printf "%s" "$2" > "$1" -]) -]) diff --git a/m4/ax_add_am_macro_static.m4 b/m4/ax_add_am_macro_static.m4 deleted file mode 100644 index 6442d24..0000000 --- a/m4/ax_add_am_macro_static.m4 +++ /dev/null @@ -1,28 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_add_am_macro_static.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_ADD_AM_MACRO_STATIC([RULE]) -# -# DESCRIPTION -# -# Adds the specified rule to $AMINCLUDE. -# -# LICENSE -# -# Copyright (c) 2009 Tom Howard -# Copyright (c) 2009 Allan Caffee -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 8 - -AC_DEFUN([AX_ADD_AM_MACRO_STATIC],[ - AC_REQUIRE([AX_AM_MACROS_STATIC]) - AX_AC_APPEND_TO_FILE(AMINCLUDE_STATIC,[$1]) -]) diff --git a/m4/ax_add_am_macros_static.m4 b/m4/ax_add_am_macros_static.m4 deleted file mode 100644 index f4cee8c..0000000 --- a/m4/ax_add_am_macros_static.m4 +++ /dev/null @@ -1,38 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_am_macros_static.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_AM_MACROS_STATIC -# -# DESCRIPTION -# -# Adds support for macros that create Automake rules. You must manually -# add the following line -# -# include $(top_srcdir)/aminclude_static.am -# -# to your Makefile.am files. -# -# LICENSE -# -# Copyright (c) 2009 Tom Howard -# Copyright (c) 2009 Allan Caffee -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 11 - -AC_DEFUN([AMINCLUDE_STATIC],[aminclude_static.am]) - -AC_DEFUN([AX_AM_MACROS_STATIC], -[ -AX_AC_PRINT_TO_FILE(AMINCLUDE_STATIC,[ -# ]AMINCLUDE_STATIC[ generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on ]m4_esyscmd([LC_ALL=C date])[ -]) -]) diff --git a/m4/ax_check_enable_debug.m4 b/m4/ax_check_enable_debug.m4 deleted file mode 100644 index 5c4a262..0000000 --- a/m4/ax_check_enable_debug.m4 +++ /dev/null @@ -1,125 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_ENABLE_DEBUG([enable by default=yes/info/profile/no], [ENABLE DEBUG VARIABLES ...], [DISABLE DEBUG VARIABLES NDEBUG ...], [IS-RELEASE]) -# -# DESCRIPTION -# -# Check for the presence of an --enable-debug option to configure, with -# the specified default value used when the option is not present. Return -# the value in the variable $ax_enable_debug. -# -# Specifying 'yes' adds '-g -O0' to the compilation flags for all -# languages. Specifying 'info' adds '-g' to the compilation flags. -# Specifying 'profile' adds '-g -pg' to the compilation flags and '-pg' to -# the linking flags. Otherwise, nothing is added. -# -# Define the variables listed in the second argument if debug is enabled, -# defaulting to no variables. Defines the variables listed in the third -# argument if debug is disabled, defaulting to NDEBUG. All lists of -# variables should be space-separated. -# -# If debug is not enabled, ensure AC_PROG_* will not add debugging flags. -# Should be invoked prior to any AC_PROG_* compiler checks. -# -# IS-RELEASE can be used to change the default to 'no' when making a -# release. Set IS-RELEASE to 'yes' or 'no' as appropriate. By default, it -# uses the value of $ax_is_release, so if you are using the AX_IS_RELEASE -# macro, there is no need to pass this parameter. -# -# AX_IS_RELEASE([git-directory]) -# AX_CHECK_ENABLE_DEBUG() -# -# LICENSE -# -# Copyright (c) 2011 Rhys Ulerich -# Copyright (c) 2014, 2015 Philip Withnall -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. - -#serial 8 - -AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ - AC_BEFORE([$0],[AC_PROG_CC])dnl - AC_BEFORE([$0],[AC_PROG_CXX])dnl - AC_BEFORE([$0],[AC_PROG_F77])dnl - AC_BEFORE([$0],[AC_PROG_FC])dnl - - AC_MSG_CHECKING(whether to enable debugging) - - ax_enable_debug_default=m4_tolower(m4_normalize(ifelse([$1],,[no],[$1]))) - ax_enable_debug_is_release=m4_tolower(m4_normalize(ifelse([$4],, - [$ax_is_release], - [$4]))) - - # If this is a release, override the default. - AS_IF([test "$ax_enable_debug_is_release" = "yes"], - [ax_enable_debug_default="no"]) - - m4_define(ax_enable_debug_vars,[m4_normalize(ifelse([$2],,,[$2]))]) - m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))]) - - AC_ARG_ENABLE(debug, - [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])], - [],enable_debug=$ax_enable_debug_default) - - # empty mean debug yes - AS_IF([test "x$enable_debug" = "x"], - [enable_debug="yes"]) - - # case of debug - AS_CASE([$enable_debug], - [yes],[ - AC_MSG_RESULT(yes) - CFLAGS="${CFLAGS} -g -O0" - CXXFLAGS="${CXXFLAGS} -g -O0" - FFLAGS="${FFLAGS} -g -O0" - FCFLAGS="${FCFLAGS} -g -O0" - OBJCFLAGS="${OBJCFLAGS} -g -O0" - ], - [info],[ - AC_MSG_RESULT(info) - CFLAGS="${CFLAGS} -g" - CXXFLAGS="${CXXFLAGS} -g" - FFLAGS="${FFLAGS} -g" - FCFLAGS="${FCFLAGS} -g" - OBJCFLAGS="${OBJCFLAGS} -g" - ], - [profile],[ - AC_MSG_RESULT(profile) - CFLAGS="${CFLAGS} -g -pg" - CXXFLAGS="${CXXFLAGS} -g -pg" - FFLAGS="${FFLAGS} -g -pg" - FCFLAGS="${FCFLAGS} -g -pg" - OBJCFLAGS="${OBJCFLAGS} -g -pg" - LDFLAGS="${LDFLAGS} -pg" - ], - [ - AC_MSG_RESULT(no) - dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags - dnl by setting any unset environment flag variables - AS_IF([test "x${CFLAGS+set}" != "xset"], - [CFLAGS=""]) - AS_IF([test "x${CXXFLAGS+set}" != "xset"], - [CXXFLAGS=""]) - AS_IF([test "x${FFLAGS+set}" != "xset"], - [FFLAGS=""]) - AS_IF([test "x${FCFLAGS+set}" != "xset"], - [FCFLAGS=""]) - AS_IF([test "x${OBJCFLAGS+set}" != "xset"], - [OBJCFLAGS=""]) - ]) - - dnl Define various variables if debugging is disabled. - dnl assert.h is a NOP if NDEBUG is defined, so define it by default. - AS_IF([test "x$enable_debug" = "xyes"], - [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])], - [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])]) - ax_enable_debug=$enable_debug -]) - diff --git a/m4/ax_check_gnu_make.m4 b/m4/ax_check_gnu_make.m4 deleted file mode 100644 index 6811043..0000000 --- a/m4/ax_check_gnu_make.m4 +++ /dev/null @@ -1,95 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_check_gnu_make.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_GNU_MAKE([run-if-true],[run-if-false]) -# -# DESCRIPTION -# -# This macro searches for a GNU version of make. If a match is found: -# -# * The makefile variable `ifGNUmake' is set to the empty string, otherwise -# it is set to "#". This is useful for including a special features in a -# Makefile, which cannot be handled by other versions of make. -# * The makefile variable `ifnGNUmake' is set to #, otherwise -# it is set to the empty string. This is useful for including a special -# features in a Makefile, which can be handled -# by other versions of make or to specify else like clause. -# * The variable `_cv_gnu_make_command` is set to the command to invoke -# GNU make if it exists, the empty string otherwise. -# * The variable `ax_cv_gnu_make_command` is set to the command to invoke -# GNU make by copying `_cv_gnu_make_command`, otherwise it is unset. -# * If GNU Make is found, its version is extracted from the output of -# `make --version` as the last field of a record of space-separated -# columns and saved into the variable `ax_check_gnu_make_version`. -# * Additionally if GNU Make is found, run shell code run-if-true -# else run shell code run-if-false. -# -# Here is an example of its use: -# -# Makefile.in might contain: -# -# # A failsafe way of putting a dependency rule into a makefile -# $(DEPEND): -# $(CC) -MM $(srcdir)/*.c > $(DEPEND) -# -# @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND))) -# @ifGNUmake@ include $(DEPEND) -# @ifGNUmake@ else -# fallback code -# @ifGNUmake@ endif -# -# Then configure.in would normally contain: -# -# AX_CHECK_GNU_MAKE() -# AC_OUTPUT(Makefile) -# -# Then perhaps to cause gnu make to override any other make, we could do -# something like this (note that GNU make always looks for GNUmakefile -# first): -# -# if ! test x$_cv_gnu_make_command = x ; then -# mv Makefile GNUmakefile -# echo .DEFAULT: > Makefile ; -# echo \ $_cv_gnu_make_command \$@ >> Makefile; -# fi -# -# Then, if any (well almost any) other make is called, and GNU make also -# exists, then the other make wraps the GNU make. -# -# LICENSE -# -# Copyright (c) 2008 John Darrington -# Copyright (c) 2015 Enrico M. Crisostomo -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 11 - -AC_DEFUN([AX_CHECK_GNU_MAKE],dnl - [AC_PROG_AWK - AC_CACHE_CHECK([for GNU make],[_cv_gnu_make_command],[dnl - _cv_gnu_make_command="" ; -dnl Search all the common names for GNU make - for a in "$MAKE" make gmake gnumake ; do - if test -z "$a" ; then continue ; fi ; - if "$a" --version 2> /dev/null | grep GNU 2>&1 > /dev/null ; then - _cv_gnu_make_command=$a ; - AX_CHECK_GNU_MAKE_HEADLINE=$("$a" --version 2> /dev/null | grep "GNU Make") - ax_check_gnu_make_version=$(echo ${AX_CHECK_GNU_MAKE_HEADLINE} | ${AWK} -F " " '{ print $(NF); }') - break ; - fi - done ;]) -dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise - AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifGNUmake], ["#"])], [AS_VAR_SET([ifGNUmake], [""])]) - AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifnGNUmake], [""])], [AS_VAR_SET([ifGNUmake], ["#"])]) - AS_VAR_IF([_cv_gnu_make_command], [""], [AS_UNSET(ax_cv_gnu_make_command)], [AS_VAR_SET([ax_cv_gnu_make_command], [${_cv_gnu_make_command}])]) - AS_VAR_IF([_cv_gnu_make_command], [""],[$2],[$1]) - AC_SUBST([ifGNUmake]) - AC_SUBST([ifnGNUmake]) -]) diff --git a/m4/ax_coverage.m4 b/m4/ax_coverage.m4 deleted file mode 100644 index 0a6c93c..0000000 --- a/m4/ax_coverage.m4 +++ /dev/null @@ -1,166 +0,0 @@ -# =============================================================================== -# Adapted from https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html -# ================================================================================ -# -# SYNOPSIS -# -# AX_COVERAGE() -# -# DESCRIPTION -# -# Defines COVERAGE_CPPFLAGS, COVERAGE_CFLAGS, -# COVERAGE_CXXFLAGS and COVERAGE_LDFLAGS which should be included -# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every -# build target (program or library) which should be built with code -# coverage support. Also add rules using AX_ADD_AM_MACRO_STATIC; and -# $enable_coverage which can be used in subsequent configure output. -# COVERAGE_ENABLED is defined and substituted, and corresponds to the -# value of the --enable-coverage option, which defaults to being -# disabled. -# -# Test also for gcov program and create GCOV variable that could be -# substituted. -# -# Note that all optimization flags in CFLAGS must be disabled when code -# coverage is enabled. -# -# Usage example: -# -# configure.ac: -# -# AX_COVERAGE -# -# Makefile.am: -# -# include $(top_srcdir)/aminclude_static.am -# -# my_program_LIBS = ... $(COVERAGE_LDFLAGS) ... -# my_program_CPPFLAGS = ... $(COVERAGE_CPPFLAGS) ... -# my_program_CFLAGS = ... $(COVERAGE_CFLAGS) ... -# my_program_CXXFLAGS = ... $(COVERAGE_CXXFLAGS) ... -# -# clean-local: coverage-clean -# dist-clean-local: coverage-dist-clean -# -# This code was derived from Makefile.decl in GLib, originally licensed -# under LGPLv2.1+. -# -# LICENSE -# -# Copyright (c) 2012, 2016 Philip Withnall -# Copyright (c) 2012 Xan Lopez -# Copyright (c) 2012 Christian Persch -# Copyright (c) 2012 Paolo Borelli -# Copyright (c) 2012 Dan Winship -# Copyright (c) 2015,2018 Bastien ROUCARIES -# -# Modified in 2018 by Jan Kessler. -# -# This library is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . - -#serial 31 - -m4_define(_AX_COVERAGE_RULES,[ -AX_ADD_AM_MACRO_STATIC([ - -# Code coverage -# -if COVERAGE_ENABLED - ifeq (\$(abs_builddir), \$(abs_top_builddir)) - -coverage-clean: - -find . \\( -name \"*.gcda\" -o -name \"*.gcno\" -o -name \"*.gcov\" \\) -delete - -coverage-dist-clean: -A][M_DISTCHECK_CONFIGURE_FLAGS = \$(A][M_DISTCHECK_CONFIGURE_FLAGS) --disable-coverage - - else # ifneq (\$(abs_builddir), \$(abs_top_builddir)) - -check-coverage: check - -coverage-clean: - -coverage-dist-clean: - - endif # ifeq (\$(abs_builddir), \$(abs_top_builddir)) - -else #! COVERAGE_ENABLED - -# Use recursive makes in order to ignore errors during check -check-coverage: - @echo \"Need to reconfigure with --enable-coverage\" - -coverage-clean: - -coverage-dist-clean: - -endif #COVERAGE_ENABLED - -.PHONY: check-coverage coverage-dist-clean coverage-clean - -]) -]) - -AC_DEFUN([_AX_COVERAGE_ENABLED],[ - AX_CHECK_GNU_MAKE([],[AC_MSG_ERROR([not using GNU make that is needed for coverage])]) - AC_REQUIRE([AX_ADD_AM_MACRO_STATIC]) - # check for gcov - AC_CHECK_TOOL([GCOV], - [$_AX_COVERAGE_GCOV_PROG_WITH], - [:]) - AS_IF([test "X$GCOV" = "X:"], - [AC_MSG_ERROR([gcov is needed to do coverage])]) - AC_SUBST([GCOV]) - - dnl Build the code coverage flags - dnl Define COVERAGE_LDFLAGS for backwards compatibility - COVERAGE_CPPFLAGS="" - COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - COVERAGE_LDFLAGS="--coverage" - - dnl Check if g++ is being used - - AC_SUBST([COVERAGE_CPPFLAGS]) - AC_SUBST([COVERAGE_CFLAGS]) - AC_SUBST([COVERAGE_CXXFLAGS]) - AC_SUBST([COVERAGE_LDFLAGS]) -]) - -AC_DEFUN([AX_COVERAGE],[ - dnl Check for --enable-coverage - - # allow to override gcov location - AC_ARG_WITH([gcov], - [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], - [_AX_COVERAGE_GCOV_PROG_WITH=$with_gcov], - [_AX_COVERAGE_GCOV_PROG_WITH=gcov]) - - AC_MSG_CHECKING([whether to build with code coverage support]) - AC_ARG_ENABLE([coverage], - AS_HELP_STRING([--enable-coverage], - [Whether to enable code coverage support]),, - enable_coverage=no) - - AM_CONDITIONAL([COVERAGE_ENABLED], [test "x$enable_coverage" = xyes]) - AC_SUBST([COVERAGE_ENABLED], [$enable_coverage]) - AC_MSG_RESULT($enable_coverage) - - AS_IF([ test "x$enable_coverage" = xyes ], [ - _AX_COVERAGE_ENABLED - ]) - - _AX_COVERAGE_RULES -]) - diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 deleted file mode 100644 index e5eb94f..0000000 --- a/m4/ax_cxx_compile_stdcxx.m4 +++ /dev/null @@ -1,949 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the specified -# version of the C++ standard. If necessary, add switches to CXX and -# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) -# or '14' (for the C++14 standard). -# -# The second argument, if specified, indicates whether you insist on an -# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -# -std=c++11). If neither is specified, you get whatever works, with -# preference for an extended mode. -# -# The third argument, if specified 'mandatory' or if left unspecified, -# indicates that baseline support for the specified C++ standard is -# required and that the macro should error out if no mode with that -# support is found. If specified 'optional', then configuration proceeds -# regardless, after defining HAVE_CXX${VERSION} if and only if a -# supporting mode is found. -# -# LICENSE -# -# Copyright (c) 2008 Benjamin Kosnik -# Copyright (c) 2012 Zack Weinberg -# Copyright (c) 2013 Roy Stogner -# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov -# Copyright (c) 2015 Paul Norman -# Copyright (c) 2015 Moritz Klammler -# Copyright (c) 2016, 2018 Krzesimir Nowak -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 10 - -dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro -dnl (serial version number 13). - -AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl - m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], - [$1], [14], [ax_cxx_compile_alternatives="14 1y"], - [$1], [17], [ax_cxx_compile_alternatives="17 1z"], - [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl - m4_if([$2], [], [], - [$2], [ext], [], - [$2], [noext], [], - [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl - m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], - [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], - [$3], [optional], [ax_cxx_compile_cxx$1_required=false], - [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) - AC_LANG_PUSH([C++])dnl - ac_success=no - - m4_if([$2], [noext], [], [dnl - if test x$ac_success = xno; then - for alternative in ${ax_cxx_compile_alternatives}; do - switch="-std=gnu++${alternative}" - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi - ac_success=yes - break - fi - done - fi]) - - m4_if([$2], [ext], [], [dnl - if test x$ac_success = xno; then - dnl HP's aCC needs +std=c++11 according to: - dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf - dnl Cray's crayCC needs "-h std=c++11" - for alternative in ${ax_cxx_compile_alternatives}; do - for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi - ac_success=yes - break - fi - done - if test x$ac_success = xyes; then - break - fi - done - fi]) - AC_LANG_POP([C++]) - if test x$ax_cxx_compile_cxx$1_required = xtrue; then - if test x$ac_success = xno; then - AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) - fi - fi - if test x$ac_success = xno; then - HAVE_CXX$1=0 - AC_MSG_NOTICE([No compiler with C++$1 support was found]) - else - HAVE_CXX$1=1 - AC_DEFINE(HAVE_CXX$1,1, - [define if the compiler supports basic C++$1 syntax]) - fi - AC_SUBST(HAVE_CXX$1) -]) - - -dnl Test body for checking C++11 support - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], - _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 -) - - -dnl Test body for checking C++14 support - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], - _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 - _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 -) - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], - _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 - _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 - _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 -) - -dnl Tests for new features in C++11 - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ - -// If the compiler admits that it is not ready for C++11, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201103L - -#error "This is not a C++11 compiler" - -#else - -namespace cxx11 -{ - - namespace test_static_assert - { - - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - } - - namespace test_final_override - { - - struct Base - { - virtual void f() {} - }; - - struct Derived : public Base - { - virtual void f() override {} - }; - - } - - namespace test_double_right_angle_brackets - { - - template < typename T > - struct check {}; - - typedef check single_type; - typedef check> double_type; - typedef check>> triple_type; - typedef check>>> quadruple_type; - - } - - namespace test_decltype - { - - int - f() - { - int a = 1; - decltype(a) b = 2; - return a + b; - } - - } - - namespace test_type_deduction - { - - template < typename T1, typename T2 > - struct is_same - { - static const bool value = false; - }; - - template < typename T > - struct is_same - { - static const bool value = true; - }; - - template < typename T1, typename T2 > - auto - add(T1 a1, T2 a2) -> decltype(a1 + a2) - { - return a1 + a2; - } - - int - test(const int c, volatile int v) - { - static_assert(is_same::value == true, ""); - static_assert(is_same::value == false, ""); - static_assert(is_same::value == false, ""); - auto ac = c; - auto av = v; - auto sumi = ac + av + 'x'; - auto sumf = ac + av + 1.0; - static_assert(is_same::value == true, ""); - static_assert(is_same::value == true, ""); - static_assert(is_same::value == true, ""); - static_assert(is_same::value == false, ""); - static_assert(is_same::value == true, ""); - return (sumf > 0.0) ? sumi : add(c, v); - } - - } - - namespace test_noexcept - { - - int f() { return 0; } - int g() noexcept { return 0; } - - static_assert(noexcept(f()) == false, ""); - static_assert(noexcept(g()) == true, ""); - - } - - namespace test_constexpr - { - - template < typename CharT > - unsigned long constexpr - strlen_c_r(const CharT *const s, const unsigned long acc) noexcept - { - return *s ? strlen_c_r(s + 1, acc + 1) : acc; - } - - template < typename CharT > - unsigned long constexpr - strlen_c(const CharT *const s) noexcept - { - return strlen_c_r(s, 0UL); - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("1") == 1UL, ""); - static_assert(strlen_c("example") == 7UL, ""); - static_assert(strlen_c("another\0example") == 7UL, ""); - - } - - namespace test_rvalue_references - { - - template < int N > - struct answer - { - static constexpr int value = N; - }; - - answer<1> f(int&) { return answer<1>(); } - answer<2> f(const int&) { return answer<2>(); } - answer<3> f(int&&) { return answer<3>(); } - - void - test() - { - int i = 0; - const int c = 0; - static_assert(decltype(f(i))::value == 1, ""); - static_assert(decltype(f(c))::value == 2, ""); - static_assert(decltype(f(0))::value == 3, ""); - } - - } - - namespace test_uniform_initialization - { - - struct test - { - static const int zero {}; - static const int one {1}; - }; - - static_assert(test::zero == 0, ""); - static_assert(test::one == 1, ""); - - } - - namespace test_lambdas - { - - void - test1() - { - auto lambda1 = [](){}; - auto lambda2 = lambda1; - lambda1(); - lambda2(); - } - - int - test2() - { - auto a = [](int i, int j){ return i + j; }(1, 2); - auto b = []() -> int { return '0'; }(); - auto c = [=](){ return a + b; }(); - auto d = [&](){ return c; }(); - auto e = [a, &b](int x) mutable { - const auto identity = [](int y){ return y; }; - for (auto i = 0; i < a; ++i) - a += b--; - return x + identity(a + b); - }(0); - return a + b + c + d + e; - } - - int - test3() - { - const auto nullary = [](){ return 0; }; - const auto unary = [](int x){ return x; }; - using nullary_t = decltype(nullary); - using unary_t = decltype(unary); - const auto higher1st = [](nullary_t f){ return f(); }; - const auto higher2nd = [unary](nullary_t f1){ - return [unary, f1](unary_t f2){ return f2(unary(f1())); }; - }; - return higher1st(nullary) + higher2nd(nullary)(unary); - } - - } - - namespace test_variadic_templates - { - - template - struct sum; - - template - struct sum - { - static constexpr auto value = N0 + sum::value; - }; - - template <> - struct sum<> - { - static constexpr auto value = 0; - }; - - static_assert(sum<>::value == 0, ""); - static_assert(sum<1>::value == 1, ""); - static_assert(sum<23>::value == 23, ""); - static_assert(sum<1, 2>::value == 3, ""); - static_assert(sum<5, 5, 11>::value == 21, ""); - static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); - - } - - // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae - // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function - // because of this. - namespace test_template_alias_sfinae - { - - struct foo {}; - - template - using member = typename T::member_type; - - template - void func(...) {} - - template - void func(member*) {} - - void test(); - - void test() { func(0); } - - } - -} // namespace cxx11 - -#endif // __cplusplus >= 201103L - -]]) - - -dnl Tests for new features in C++14 - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ - -// If the compiler admits that it is not ready for C++14, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201402L - -#error "This is not a C++14 compiler" - -#else - -namespace cxx14 -{ - - namespace test_polymorphic_lambdas - { - - int - test() - { - const auto lambda = [](auto&&... args){ - const auto istiny = [](auto x){ - return (sizeof(x) == 1UL) ? 1 : 0; - }; - const int aretiny[] = { istiny(args)... }; - return aretiny[0]; - }; - return lambda(1, 1L, 1.0f, '1'); - } - - } - - namespace test_binary_literals - { - - constexpr auto ivii = 0b0000000000101010; - static_assert(ivii == 42, "wrong value"); - - } - - namespace test_generalized_constexpr - { - - template < typename CharT > - constexpr unsigned long - strlen_c(const CharT *const s) noexcept - { - auto length = 0UL; - for (auto p = s; *p; ++p) - ++length; - return length; - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("x") == 1UL, ""); - static_assert(strlen_c("test") == 4UL, ""); - static_assert(strlen_c("another\0test") == 7UL, ""); - - } - - namespace test_lambda_init_capture - { - - int - test() - { - auto x = 0; - const auto lambda1 = [a = x](int b){ return a + b; }; - const auto lambda2 = [a = lambda1(x)](){ return a; }; - return lambda2(); - } - - } - - namespace test_digit_separators - { - - constexpr auto ten_million = 100'000'000; - static_assert(ten_million == 100000000, ""); - - } - - namespace test_return_type_deduction - { - - auto f(int& x) { return x; } - decltype(auto) g(int& x) { return x; } - - template < typename T1, typename T2 > - struct is_same - { - static constexpr auto value = false; - }; - - template < typename T > - struct is_same - { - static constexpr auto value = true; - }; - - int - test() - { - auto x = 0; - static_assert(is_same::value, ""); - static_assert(is_same::value, ""); - return x; - } - - } - -} // namespace cxx14 - -#endif // __cplusplus >= 201402L - -]]) - - -dnl Tests for new features in C++17 - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ - -// If the compiler admits that it is not ready for C++17, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201703L - -#error "This is not a C++17 compiler" - -#else - -#include -#include -#include - -namespace cxx17 -{ - - namespace test_constexpr_lambdas - { - - constexpr int foo = [](){return 42;}(); - - } - - namespace test::nested_namespace::definitions - { - - } - - namespace test_fold_expression - { - - template - int multiply(Args... args) - { - return (args * ... * 1); - } - - template - bool all(Args... args) - { - return (args && ...); - } - - } - - namespace test_extended_static_assert - { - - static_assert (true); - - } - - namespace test_auto_brace_init_list - { - - auto foo = {5}; - auto bar {5}; - - static_assert(std::is_same, decltype(foo)>::value); - static_assert(std::is_same::value); - } - - namespace test_typename_in_template_template_parameter - { - - template typename X> struct D; - - } - - namespace test_fallthrough_nodiscard_maybe_unused_attributes - { - - int f1() - { - return 42; - } - - [[nodiscard]] int f2() - { - [[maybe_unused]] auto unused = f1(); - - switch (f1()) - { - case 17: - f1(); - [[fallthrough]]; - case 42: - f1(); - } - return f1(); - } - - } - - namespace test_extended_aggregate_initialization - { - - struct base1 - { - int b1, b2 = 42; - }; - - struct base2 - { - base2() { - b3 = 42; - } - int b3; - }; - - struct derived : base1, base2 - { - int d; - }; - - derived d1 {{1, 2}, {}, 4}; // full initialization - derived d2 {{}, {}, 4}; // value-initialized bases - - } - - namespace test_general_range_based_for_loop - { - - struct iter - { - int i; - - int& operator* () - { - return i; - } - - const int& operator* () const - { - return i; - } - - iter& operator++() - { - ++i; - return *this; - } - }; - - struct sentinel - { - int i; - }; - - bool operator== (const iter& i, const sentinel& s) - { - return i.i == s.i; - } - - bool operator!= (const iter& i, const sentinel& s) - { - return !(i == s); - } - - struct range - { - iter begin() const - { - return {0}; - } - - sentinel end() const - { - return {5}; - } - }; - - void f() - { - range r {}; - - for (auto i : r) - { - [[maybe_unused]] auto v = i; - } - } - - } - - namespace test_lambda_capture_asterisk_this_by_value - { - - struct t - { - int i; - int foo() - { - return [*this]() - { - return i; - }(); - } - }; - - } - - namespace test_enum_class_construction - { - - enum class byte : unsigned char - {}; - - byte foo {42}; - - } - - namespace test_constexpr_if - { - - template - int f () - { - if constexpr(cond) - { - return 13; - } - else - { - return 42; - } - } - - } - - namespace test_selection_statement_with_initializer - { - - int f() - { - return 13; - } - - int f2() - { - if (auto i = f(); i > 0) - { - return 3; - } - - switch (auto i = f(); i + 4) - { - case 17: - return 2; - - default: - return 1; - } - } - - } - - namespace test_template_argument_deduction_for_class_templates - { - - template - struct pair - { - pair (T1 p1, T2 p2) - : m1 {p1}, - m2 {p2} - {} - - T1 m1; - T2 m2; - }; - - void f() - { - [[maybe_unused]] auto p = pair{13, 42u}; - } - - } - - namespace test_non_type_auto_template_parameters - { - - template - struct B - {}; - - B<5> b1; - B<'a'> b2; - - } - - namespace test_structured_bindings - { - - int arr[2] = { 1, 2 }; - std::pair pr = { 1, 2 }; - - auto f1() -> int(&)[2] - { - return arr; - } - - auto f2() -> std::pair& - { - return pr; - } - - struct S - { - int x1 : 2; - volatile double y1; - }; - - S f3() - { - return {}; - } - - auto [ x1, y1 ] = f1(); - auto& [ xr1, yr1 ] = f1(); - auto [ x2, y2 ] = f2(); - auto& [ xr2, yr2 ] = f2(); - const auto [ x3, y3 ] = f3(); - - } - - namespace test_exception_spec_type_system - { - - struct Good {}; - struct Bad {}; - - void g1() noexcept; - void g2(); - - template - Bad - f(T*, T*); - - template - Good - f(T1*, T2*); - - static_assert (std::is_same_v); - - } - - namespace test_inline_variables - { - - template void f(T) - {} - - template inline T g(T) - { - return T{}; - } - - template<> inline void f<>(int) - {} - - template<> int g<>(int) - { - return 5; - } - - } - -} // namespace cxx17 - -#endif // __cplusplus < 201703L - -]]) - diff --git a/m4/ax_file_escapes.m4 b/m4/ax_file_escapes.m4 deleted file mode 100644 index a86fdc3..0000000 --- a/m4/ax_file_escapes.m4 +++ /dev/null @@ -1,30 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_file_escapes.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_FILE_ESCAPES -# -# DESCRIPTION -# -# Writes the specified data to the specified file. -# -# LICENSE -# -# Copyright (c) 2008 Tom Howard -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 8 - -AC_DEFUN([AX_FILE_ESCAPES],[ -AX_DOLLAR="\$" -AX_SRB="\\135" -AX_SLB="\\133" -AX_BS="\\\\" -AX_DQ="\"" -]) diff --git a/m4/ax_valgrind_check.m4 b/m4/ax_valgrind_check.m4 deleted file mode 100644 index 7033798..0000000 --- a/m4/ax_valgrind_check.m4 +++ /dev/null @@ -1,239 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off) -# AX_VALGRIND_CHECK() -# -# DESCRIPTION -# -# AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows -# running `make check` under a variety of Valgrind tools to check for -# memory and threading errors. -# -# Defines VALGRIND_CHECK_RULES which should be substituted in your -# Makefile; and $enable_valgrind which can be used in subsequent configure -# output. VALGRIND_ENABLED is defined and substituted, and corresponds to -# the value of the --enable-valgrind option, which defaults to being -# enabled if Valgrind is installed and disabled otherwise. Individual -# Valgrind tools can be disabled via --disable-valgrind-, the -# default is configurable via the AX_VALGRIND_DFLT command or is to use -# all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT -# calls must be made before the call to AX_VALGRIND_CHECK. -# -# If unit tests are written using a shell script and automake's -# LOG_COMPILER system, the $(VALGRIND) variable can be used within the -# shell scripts to enable Valgrind, as described here: -# -# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html -# -# Usage example: -# -# configure.ac: -# -# AX_VALGRIND_DFLT([sgcheck], [off]) -# AX_VALGRIND_CHECK -# -# in each Makefile.am with tests: -# -# @VALGRIND_CHECK_RULES@ -# VALGRIND_SUPPRESSIONS_FILES = my-project.supp -# EXTRA_DIST = my-project.supp -# -# This results in a "check-valgrind" rule being added. Running `make -# check-valgrind` in that directory will recursively run the module's test -# suite (`make check`) once for each of the available Valgrind tools (out -# of memcheck, helgrind and drd) while the sgcheck will be skipped unless -# enabled again on the commandline with --enable-valgrind-sgcheck. The -# results for each check will be output to test-suite-$toolname.log. The -# target will succeed if there are zero errors and fail otherwise. -# -# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in -# memcheck, helgrind, drd and sgcheck. These are useful because often only -# some of those tools can be ran cleanly on a codebase. -# -# The macro supports running with and without libtool. -# -# LICENSE -# -# Copyright (c) 2014, 2015, 2016 Philip Withnall -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 17 - -dnl Configured tools -m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]]) -m4_set_add_all([valgrind_exp_tool_set], [sgcheck]) -m4_foreach([vgtool], [valgrind_tool_list], - [m4_define([en_dflt_valgrind_]vgtool, [on])]) - -AC_DEFUN([AX_VALGRIND_DFLT],[ - m4_define([en_dflt_valgrind_$1], [$2]) -])dnl - -AM_EXTRA_RECURSIVE_TARGETS([check-valgrind]) -m4_foreach([vgtool], [valgrind_tool_list], - [AM_EXTRA_RECURSIVE_TARGETS([check-valgrind-]vgtool)]) - -AC_DEFUN([AX_VALGRIND_CHECK],[ - dnl Check for --enable-valgrind - AC_ARG_ENABLE([valgrind], - [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])], - [enable_valgrind=$enableval],[enable_valgrind=]) - - AS_IF([test "$enable_valgrind" != "no"],[ - # Check for Valgrind. - AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind]) - AS_IF([test "$VALGRIND" = ""],[ - AS_IF([test "$enable_valgrind" = "yes"],[ - AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind]) - ],[ - enable_valgrind=no - ]) - ],[ - enable_valgrind=yes - ]) - ]) - - AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) - AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind]) - - # Check for Valgrind tools we care about. - [valgrind_enabled_tools=] - m4_foreach([vgtool],[valgrind_tool_list],[ - AC_ARG_ENABLE([valgrind-]vgtool, - m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl -[AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl -[AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]), - [enable_valgrind_]vgtool[=$enableval], - [enable_valgrind_]vgtool[=]) - AS_IF([test "$enable_valgrind" = "no"],[ - enable_valgrind_]vgtool[=no], - [test "$enable_valgrind_]vgtool[" ]dnl -m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[ - AC_CACHE_CHECK([for Valgrind tool ]vgtool, - [ax_cv_valgrind_tool_]vgtool,[ - ax_cv_valgrind_tool_]vgtool[=no - m4_set_contains([valgrind_exp_tool_set],vgtool, - [m4_define([vgtoolx],[exp-]vgtool)], - [m4_define([vgtoolx],vgtool)]) - AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[ - ax_cv_valgrind_tool_]vgtool[=yes - ]) - ]) - AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[ - AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ - AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool) - ],[ - enable_valgrind_]vgtool[=no - ]) - ],[ - enable_valgrind_]vgtool[=yes - ]) - ]) - AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ - valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])[" - ]) - AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool) - ]) - AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["]) - AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools]) - -[VALGRIND_CHECK_RULES=' -# Valgrind check -# -# Optional: -# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions -# files to load. (Default: empty) -# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. -# (Default: --num-callers=30) -# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: -# memcheck, helgrind, drd, sgcheck). (Default: various) - -# Optional variables -VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) -VALGRIND_FLAGS ?= --num-callers=30 -VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no -VALGRIND_helgrind_FLAGS ?= --history-level=approx -VALGRIND_drd_FLAGS ?= -VALGRIND_sgcheck_FLAGS ?= - -# Internal use -valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) - -valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) -valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) -valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) -valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) - -valgrind_quiet = $(valgrind_quiet_$(V)) -valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) -valgrind_quiet_0 = --quiet -valgrind_v_use = $(valgrind_v_use_$(V)) -valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY)) -valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%-am,%,$''@):; - -# Support running with and without libtool. -ifneq ($(LIBTOOL),) -valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute -else -valgrind_lt = -endif - -# Use recursive makes in order to ignore errors during check -check-valgrind-am: -ifeq ($(VALGRIND_ENABLED),yes) - $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k \ - $(foreach tool, $(valgrind_enabled_tools), check-valgrind-$(tool)) -else - @echo "Need to reconfigure with --enable-valgrind" -endif - -# Valgrind running -VALGRIND_TESTS_ENVIRONMENT = \ - $(TESTS_ENVIRONMENT) \ - env VALGRIND=$(VALGRIND) \ - G_SLICE=always-malloc,debug-blocks \ - G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly - -VALGRIND_LOG_COMPILER = \ - $(valgrind_lt) \ - $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) - -define valgrind_tool_rule -check-valgrind-$(1)-am: -ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes) -ifneq ($$(TESTS),) - $$(valgrind_v_use)$$(MAKE) check-TESTS \ - TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \ - LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \ - LOG_FLAGS="$$(valgrind_$(1)_flags)" \ - TEST_SUITE_LOG=test-suite-$(1).log -endif -else ifeq ($$(VALGRIND_ENABLED),yes) - @echo "Need to reconfigure with --enable-valgrind-$(1)" -else - @echo "Need to reconfigure with --enable-valgrind" -endif -endef - -$(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool)))) - -A''M_DISTCHECK_CONFIGURE_FLAGS ?= -A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind - -MOSTLYCLEANFILES ?= -MOSTLYCLEANFILES += $(valgrind_log_files) - -.PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools)) -'] - - AC_SUBST([VALGRIND_CHECK_RULES]) - m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])]) -]) diff --git a/script/README.md b/script/README.md deleted file mode 100644 index f307ee4..0000000 --- a/script/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# script - -In this folder we collect various useful scripts. - -NOTE: All scripts are expecting to be called from project root directory. diff --git a/script/config_template.sh b/script/config_template.sh deleted file mode 100755 index 643e8cb..0000000 --- a/script/config_template.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Config script for custom library and header paths or C++ compiler choice -# -# If you want to edit this template script/config_template.sh, -# copy it over to something like config.sh and edit the gitignored copy. -# - -# C++ compiler -export CXX="g++" - -# C++ flags -export CXXFLAGS="" - -# GSL Library -GSL_L="-L/usr/local/lib" -GSL_I="-I/usr/local/include" - - -# ! DO NOT EDIT THE FOLLOWING ! - -# linker flags -export LDFLAGS="${GSL_L}" - -# pre-processor flags -export CPPFLAGS="${GSL_I}" diff --git a/script/generate_ac_config_files.sh b/script/generate_ac_config_files.sh deleted file mode 100755 index a264112..0000000 --- a/script/generate_ac_config_files.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# echo a AC_CONFIG_FILES block containing a Makefile for every Makefile.am found -echo "AC_CONFIG_FILES([" -find . -name Makefile.am | sed 's/\.\///g' | sed 's/\.am//g' -echo "])" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..cb30bfa --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB SOURCES "*/*.cpp") +add_library(ffnn SHARED ${SOURCES}) +target_link_libraries(ffnn "${GSL_LIBRARIES}") # shared libs +add_library(ffnn_static STATIC ${SOURCES}) +target_link_libraries(ffnn_static "{$GSL_LIBRARIES}") # static (+ some shared) libs diff --git a/src/README.md b/src/README.md deleted file mode 100644 index 584f12c..0000000 --- a/src/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# src - -Here you find all source files of the library. To build the library, do `cd ../lib && make` or `cd ../ && make lib`. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..c1e07d1 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,25 @@ +include_directories(common/) +link_libraries(ffnn) + +add_executable(check main.cpp) +add_executable(ut1.exe ut1/main.cpp) +add_executable(ut2.exe ut2/main.cpp) +add_executable(ut3.exe ut3/main.cpp) +add_executable(ut4.exe ut4/main.cpp) +add_executable(ut5.exe ut5/main.cpp) +add_executable(ut6.exe ut6/main.cpp) +add_executable(ut7.exe ut7/main.cpp) +add_executable(ut8.exe ut8/main.cpp) +add_executable(ut9.exe ut9/main.cpp) +add_executable(ut10.exe ut10/main.cpp) + +add_test(ut1 ut1.exe) +add_test(ut2 ut2.exe) +add_test(ut3 ut3.exe) +add_test(ut4 ut4.exe) +add_test(ut5 ut5.exe) +add_test(ut6 ut6.exe) +add_test(ut7 ut7.exe) +add_test(ut8 ut8.exe) +add_test(ut9 ut9.exe) +add_test(ut10 ut10.exe) diff --git a/test/Makefile.am b/test/Makefile.am deleted file mode 100644 index 037128f..0000000 --- a/test/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -include test.am - -SUBDIRS = ut1 ut2 ut3 ut4 ut5 ut6 ut7 ut8 ut9 ut10 - -TESTS = exe ut1/exe ut2/exe ut3/exe ut4/exe ut5/exe ut6/exe ut7/exe ut8/exe ut9/exe ut10/exe -AUTOMAKE_OPTIONS = parallel-tests -if !OPENMP -if VALGRIND_ENABLED - @VALGRIND_CHECK_RULES@ - LOG_COMPILER = $(LIBTOOL) e $(VALGRIND) --leak-check=full --track-origins=yes -else - LOG_COMPILER = $(LIBTOOL) e -endif -endif diff --git a/test/README.md b/test/README.md index 8f61fe0..2454c7c 100644 --- a/test/README.md +++ b/test/README.md @@ -54,3 +54,9 @@ Use `make check` either inside test directory (i.e. run all tests) or in a speci ## Unit Test 9 `ut9/`: check that the trainers find perfect fits for a target function resembling a NN + + + +## Unit Test 10 + +`ut10/`: check the derivatives and file storing when feature maps are used diff --git a/test/run.sh b/test/run.sh new file mode 100755 index 0000000..cdd0266 --- /dev/null +++ b/test/run.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +VALGRIND="valgrind --leak-check=full --track-origins=yes" + +cd ../build/test/ +${VALGRIND} ./check +for exe in ./ut*.exe; do + echo + echo "Running test ${exe}..." + ${VALGRIND} ${exe} + echo +done diff --git a/test/test.am b/test/test.am deleted file mode 100644 index 34ac8d3..0000000 --- a/test/test.am +++ /dev/null @@ -1,14 +0,0 @@ -AM_LDFLAGS += -lffnn - -if !DEBUG # then we want to add debug flags manually - AM_CXXFLAGS += $(DEBUGFLAGS) -endif - -noinst_PROGRAMS = exe -exe_SOURCES = main.cpp - -clean-local: - rm -f *.txt -if VALGRIND_ENABLED - rm -f vgcore.* -endif diff --git a/test/ut1/Makefile.am b/test/ut1/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut1/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut10/Makefile.am b/test/ut10/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut10/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut2/Makefile.am b/test/ut2/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut2/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut3/Makefile.am b/test/ut3/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut3/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut4/Makefile.am b/test/ut4/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut4/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut5/Makefile.am b/test/ut5/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut5/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut6/Makefile.am b/test/ut6/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut6/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut7/Makefile.am b/test/ut7/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut7/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut8/Makefile.am b/test/ut8/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut8/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am diff --git a/test/ut9/Makefile.am b/test/ut9/Makefile.am deleted file mode 100644 index 5d916f2..0000000 --- a/test/ut9/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -include ../test.am From bf4f819e004fa19b44e0074f9fa95c440960a9e3 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Thu, 21 Feb 2019 18:57:53 +0100 Subject: [PATCH 08/18] adapted true include/src split (no symlinks), to match the new style of other NNVMC repos --- include/ActivationFunctionInterface.hpp | 1 - include/ActivationFunctionManager.hpp | 1 - include/ActivationMapUnit.hpp | 1 - include/ActivationUnit.hpp | 1 - include/EuclideanDistanceMap.hpp | 1 - include/EuclideanDistanceMapUnit.hpp | 1 - include/EuclideanPairDistanceMap.hpp | 1 - include/EuclideanPairDistanceMapUnit.hpp | 1 - include/ExponentialActivationFunction.hpp | 1 - include/FeatureMapLayer.hpp | 1 - include/FeatureMapUnit.hpp | 1 - include/FedActivationUnit.hpp | 1 - include/FedLayer.hpp | 1 - include/FedUnit.hpp | 1 - include/FeedForwardNeuralNetwork.hpp | 1 - include/FeederInterface.hpp | 1 - include/GaussianActivationFunction.hpp | 1 - include/IdentityActivationFunction.hpp | 1 - include/IdentityMap.hpp | 1 - include/IdentityMapUnit.hpp | 1 - include/InputLayer.hpp | 1 - include/InputUnit.hpp | 1 - include/LogisticActivationFunction.hpp | 1 - include/MultiDimStaticMap.hpp | 1 - include/NNLayer.hpp | 1 - include/NNRay.hpp | 1 - include/NNTrainer.hpp | 1 - include/NNTrainerGSL.hpp | 1 - include/NNTrainingConfig.hpp | 1 - include/NNTrainingData.hpp | 1 - include/NNUnit.hpp | 1 - include/NetworkLayer.hpp | 1 - include/NetworkUnit.hpp | 1 - include/OffsetUnit.hpp | 1 - include/OneDimStaticMap.hpp | 1 - include/OutputNNLayer.hpp | 1 - include/OutputNNUnit.hpp | 1 - include/PairDifferenceMap.hpp | 1 - include/PairDifferenceMapUnit.hpp | 1 - include/PairSumMap.hpp | 1 - include/PairSumMapUnit.hpp | 1 - include/PrintUtilities.hpp | 1 - include/ReLUActivationFunction.hpp | 1 - include/SELUActivationFunction.hpp | 1 - include/SRLUActivationFunction.hpp | 1 - include/SerializableComponent.hpp | 1 - include/ShifterScalerNNUnit.hpp | 1 - include/ShifterScalerUnit.hpp | 1 - include/SineActivationFunction.hpp | 1 - include/SmartBetaGenerator.hpp | 1 - include/StaticFeeder.hpp | 1 - include/StringCodeUtilities.hpp | 1 - include/TanSigmoidActivationFunction.hpp | 1 - include/VariableFeeder.hpp | 1 - include/WeightedFeeder.hpp | 1 - include/ffnn | 1 - {src => include/ffnn}/actf/ActivationFunctionInterface.hpp | 2 +- {src => include/ffnn}/actf/ActivationFunctionManager.hpp | 0 {src => include/ffnn}/actf/ExponentialActivationFunction.hpp | 2 +- {src => include/ffnn}/actf/GaussianActivationFunction.hpp | 0 {src => include/ffnn}/actf/IdentityActivationFunction.hpp | 0 {src => include/ffnn}/actf/LogisticActivationFunction.hpp | 0 {src => include/ffnn}/actf/ReLUActivationFunction.hpp | 0 {src => include/ffnn}/actf/SELUActivationFunction.hpp | 0 {src => include/ffnn}/actf/SRLUActivationFunction.hpp | 0 {src => include/ffnn}/actf/SineActivationFunction.hpp | 0 {src => include/ffnn}/actf/TanSigmoidActivationFunction.hpp | 0 {src/feeder => include/ffnn/feed}/FeederInterface.hpp | 0 {src/feeder => include/ffnn/feed}/NNRay.hpp | 0 {src/feeder => include/ffnn/feed}/SmartBetaGenerator.hpp | 0 {src/feeder => include/ffnn/feed}/StaticFeeder.hpp | 0 {src/feeder => include/ffnn/feed}/VariableFeeder.hpp | 0 {src/feeder => include/ffnn/feed}/WeightedFeeder.hpp | 0 {src/feature_maps => include/ffnn/fmap}/ActivationMapUnit.hpp | 0 .../feature_maps => include/ffnn/fmap}/EuclideanDistanceMap.hpp | 0 .../ffnn/fmap}/EuclideanDistanceMapUnit.hpp | 0 .../ffnn/fmap}/EuclideanPairDistanceMap.hpp | 0 .../ffnn/fmap}/EuclideanPairDistanceMapUnit.hpp | 0 {src/feature_maps => include/ffnn/fmap}/FeatureMapLayer.hpp | 0 {src/feature_maps => include/ffnn/fmap}/FeatureMapUnit.hpp | 0 {src/feature_maps => include/ffnn/fmap}/IdentityMap.hpp | 0 {src/feature_maps => include/ffnn/fmap}/IdentityMapUnit.hpp | 0 {src/feature_maps => include/ffnn/fmap}/MultiDimStaticMap.hpp | 0 {src/feature_maps => include/ffnn/fmap}/OneDimStaticMap.hpp | 0 {src/feature_maps => include/ffnn/fmap}/PairDifferenceMap.hpp | 0 .../ffnn/fmap}/PairDifferenceMapUnit.hpp | 0 {src/feature_maps => include/ffnn/fmap}/PairSumMap.hpp | 0 {src/feature_maps => include/ffnn/fmap}/PairSumMapUnit.hpp | 0 {src => include/ffnn}/io/PrintUtilities.hpp | 0 {src => include/ffnn}/layer/FedLayer.hpp | 0 {src => include/ffnn}/layer/InputLayer.hpp | 0 {src => include/ffnn}/layer/NNLayer.hpp | 0 {src => include/ffnn}/layer/NetworkLayer.hpp | 0 {src => include/ffnn}/layer/OutputNNLayer.hpp | 0 {src/network => include/ffnn/net}/FeedForwardNeuralNetwork.hpp | 0 .../serialize => include/ffnn/serial}/SerializableComponent.hpp | 0 {src/serialize => include/ffnn/serial}/StringCodeUtilities.hpp | 0 {src/trainer => include/ffnn/train}/NNTrainer.hpp | 0 {src/trainer => include/ffnn/train}/NNTrainerGSL.hpp | 0 {src/trainer => include/ffnn/train}/NNTrainingConfig.hpp | 0 {src/trainer => include/ffnn/train}/NNTrainingData.hpp | 0 {src => include/ffnn}/unit/ActivationUnit.hpp | 0 {src => include/ffnn}/unit/FedActivationUnit.hpp | 0 {src => include/ffnn}/unit/FedUnit.hpp | 0 {src => include/ffnn}/unit/InputUnit.hpp | 0 {src => include/ffnn}/unit/NNUnit.hpp | 0 {src => include/ffnn}/unit/NetworkUnit.hpp | 0 {src => include/ffnn}/unit/OffsetUnit.hpp | 0 {src => include/ffnn}/unit/OutputNNUnit.hpp | 0 {src => include/ffnn}/unit/ShifterScalerNNUnit.hpp | 0 {src => include/ffnn}/unit/ShifterScalerUnit.hpp | 0 src/{feeder => feed}/FeederInterface.cpp | 0 src/{feeder => feed}/NNRay.cpp | 0 src/{feeder => feed}/SmartBetaGenerator.cpp | 0 src/{feeder => feed}/VariableFeeder.cpp | 0 src/{feeder => feed}/WeightedFeeder.cpp | 0 src/{feature_maps => fmap}/EuclideanDistanceMap.cpp | 0 src/{feature_maps => fmap}/EuclideanPairDistanceMap.cpp | 0 src/{feature_maps => fmap}/FeatureMapLayer.cpp | 0 src/{feature_maps => fmap}/IdentityMap.cpp | 0 src/{feature_maps => fmap}/MultiDimStaticMap.cpp | 0 src/{feature_maps => fmap}/OneDimStaticMap.cpp | 0 src/{feature_maps => fmap}/PairDifferenceMap.cpp | 0 src/{feature_maps => fmap}/PairSumMap.cpp | 0 src/{network => net}/FeedForwardNeuralNetwork.cpp | 0 src/{serialize => serial}/StringCodeUtilities.cpp | 0 src/{trainer => train}/NNTrainer.cpp | 0 src/{trainer => train}/NNTrainerGSL.cpp | 0 128 files changed, 2 insertions(+), 58 deletions(-) delete mode 120000 include/ActivationFunctionInterface.hpp delete mode 120000 include/ActivationFunctionManager.hpp delete mode 120000 include/ActivationMapUnit.hpp delete mode 120000 include/ActivationUnit.hpp delete mode 120000 include/EuclideanDistanceMap.hpp delete mode 120000 include/EuclideanDistanceMapUnit.hpp delete mode 120000 include/EuclideanPairDistanceMap.hpp delete mode 120000 include/EuclideanPairDistanceMapUnit.hpp delete mode 120000 include/ExponentialActivationFunction.hpp delete mode 120000 include/FeatureMapLayer.hpp delete mode 120000 include/FeatureMapUnit.hpp delete mode 120000 include/FedActivationUnit.hpp delete mode 120000 include/FedLayer.hpp delete mode 120000 include/FedUnit.hpp delete mode 120000 include/FeedForwardNeuralNetwork.hpp delete mode 120000 include/FeederInterface.hpp delete mode 120000 include/GaussianActivationFunction.hpp delete mode 120000 include/IdentityActivationFunction.hpp delete mode 120000 include/IdentityMap.hpp delete mode 120000 include/IdentityMapUnit.hpp delete mode 120000 include/InputLayer.hpp delete mode 120000 include/InputUnit.hpp delete mode 120000 include/LogisticActivationFunction.hpp delete mode 120000 include/MultiDimStaticMap.hpp delete mode 120000 include/NNLayer.hpp delete mode 120000 include/NNRay.hpp delete mode 120000 include/NNTrainer.hpp delete mode 120000 include/NNTrainerGSL.hpp delete mode 120000 include/NNTrainingConfig.hpp delete mode 120000 include/NNTrainingData.hpp delete mode 120000 include/NNUnit.hpp delete mode 120000 include/NetworkLayer.hpp delete mode 120000 include/NetworkUnit.hpp delete mode 120000 include/OffsetUnit.hpp delete mode 120000 include/OneDimStaticMap.hpp delete mode 120000 include/OutputNNLayer.hpp delete mode 120000 include/OutputNNUnit.hpp delete mode 120000 include/PairDifferenceMap.hpp delete mode 120000 include/PairDifferenceMapUnit.hpp delete mode 120000 include/PairSumMap.hpp delete mode 120000 include/PairSumMapUnit.hpp delete mode 120000 include/PrintUtilities.hpp delete mode 120000 include/ReLUActivationFunction.hpp delete mode 120000 include/SELUActivationFunction.hpp delete mode 120000 include/SRLUActivationFunction.hpp delete mode 120000 include/SerializableComponent.hpp delete mode 120000 include/ShifterScalerNNUnit.hpp delete mode 120000 include/ShifterScalerUnit.hpp delete mode 120000 include/SineActivationFunction.hpp delete mode 120000 include/SmartBetaGenerator.hpp delete mode 120000 include/StaticFeeder.hpp delete mode 120000 include/StringCodeUtilities.hpp delete mode 120000 include/TanSigmoidActivationFunction.hpp delete mode 120000 include/VariableFeeder.hpp delete mode 120000 include/WeightedFeeder.hpp delete mode 120000 include/ffnn rename {src => include/ffnn}/actf/ActivationFunctionInterface.hpp (98%) rename {src => include/ffnn}/actf/ActivationFunctionManager.hpp (100%) rename {src => include/ffnn}/actf/ExponentialActivationFunction.hpp (94%) rename {src => include/ffnn}/actf/GaussianActivationFunction.hpp (100%) rename {src => include/ffnn}/actf/IdentityActivationFunction.hpp (100%) rename {src => include/ffnn}/actf/LogisticActivationFunction.hpp (100%) rename {src => include/ffnn}/actf/ReLUActivationFunction.hpp (100%) rename {src => include/ffnn}/actf/SELUActivationFunction.hpp (100%) rename {src => include/ffnn}/actf/SRLUActivationFunction.hpp (100%) rename {src => include/ffnn}/actf/SineActivationFunction.hpp (100%) rename {src => include/ffnn}/actf/TanSigmoidActivationFunction.hpp (100%) rename {src/feeder => include/ffnn/feed}/FeederInterface.hpp (100%) rename {src/feeder => include/ffnn/feed}/NNRay.hpp (100%) rename {src/feeder => include/ffnn/feed}/SmartBetaGenerator.hpp (100%) rename {src/feeder => include/ffnn/feed}/StaticFeeder.hpp (100%) rename {src/feeder => include/ffnn/feed}/VariableFeeder.hpp (100%) rename {src/feeder => include/ffnn/feed}/WeightedFeeder.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/ActivationMapUnit.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/EuclideanDistanceMap.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/EuclideanDistanceMapUnit.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/EuclideanPairDistanceMap.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/EuclideanPairDistanceMapUnit.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/FeatureMapLayer.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/FeatureMapUnit.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/IdentityMap.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/IdentityMapUnit.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/MultiDimStaticMap.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/OneDimStaticMap.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/PairDifferenceMap.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/PairDifferenceMapUnit.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/PairSumMap.hpp (100%) rename {src/feature_maps => include/ffnn/fmap}/PairSumMapUnit.hpp (100%) rename {src => include/ffnn}/io/PrintUtilities.hpp (100%) rename {src => include/ffnn}/layer/FedLayer.hpp (100%) rename {src => include/ffnn}/layer/InputLayer.hpp (100%) rename {src => include/ffnn}/layer/NNLayer.hpp (100%) rename {src => include/ffnn}/layer/NetworkLayer.hpp (100%) rename {src => include/ffnn}/layer/OutputNNLayer.hpp (100%) rename {src/network => include/ffnn/net}/FeedForwardNeuralNetwork.hpp (100%) rename {src/serialize => include/ffnn/serial}/SerializableComponent.hpp (100%) rename {src/serialize => include/ffnn/serial}/StringCodeUtilities.hpp (100%) rename {src/trainer => include/ffnn/train}/NNTrainer.hpp (100%) rename {src/trainer => include/ffnn/train}/NNTrainerGSL.hpp (100%) rename {src/trainer => include/ffnn/train}/NNTrainingConfig.hpp (100%) rename {src/trainer => include/ffnn/train}/NNTrainingData.hpp (100%) rename {src => include/ffnn}/unit/ActivationUnit.hpp (100%) rename {src => include/ffnn}/unit/FedActivationUnit.hpp (100%) rename {src => include/ffnn}/unit/FedUnit.hpp (100%) rename {src => include/ffnn}/unit/InputUnit.hpp (100%) rename {src => include/ffnn}/unit/NNUnit.hpp (100%) rename {src => include/ffnn}/unit/NetworkUnit.hpp (100%) rename {src => include/ffnn}/unit/OffsetUnit.hpp (100%) rename {src => include/ffnn}/unit/OutputNNUnit.hpp (100%) rename {src => include/ffnn}/unit/ShifterScalerNNUnit.hpp (100%) rename {src => include/ffnn}/unit/ShifterScalerUnit.hpp (100%) rename src/{feeder => feed}/FeederInterface.cpp (100%) rename src/{feeder => feed}/NNRay.cpp (100%) rename src/{feeder => feed}/SmartBetaGenerator.cpp (100%) rename src/{feeder => feed}/VariableFeeder.cpp (100%) rename src/{feeder => feed}/WeightedFeeder.cpp (100%) rename src/{feature_maps => fmap}/EuclideanDistanceMap.cpp (100%) rename src/{feature_maps => fmap}/EuclideanPairDistanceMap.cpp (100%) rename src/{feature_maps => fmap}/FeatureMapLayer.cpp (100%) rename src/{feature_maps => fmap}/IdentityMap.cpp (100%) rename src/{feature_maps => fmap}/MultiDimStaticMap.cpp (100%) rename src/{feature_maps => fmap}/OneDimStaticMap.cpp (100%) rename src/{feature_maps => fmap}/PairDifferenceMap.cpp (100%) rename src/{feature_maps => fmap}/PairSumMap.cpp (100%) rename src/{network => net}/FeedForwardNeuralNetwork.cpp (100%) rename src/{serialize => serial}/StringCodeUtilities.cpp (100%) rename src/{trainer => train}/NNTrainer.cpp (100%) rename src/{trainer => train}/NNTrainerGSL.cpp (100%) diff --git a/include/ActivationFunctionInterface.hpp b/include/ActivationFunctionInterface.hpp deleted file mode 120000 index 75854ab..0000000 --- a/include/ActivationFunctionInterface.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/ActivationFunctionInterface.hpp \ No newline at end of file diff --git a/include/ActivationFunctionManager.hpp b/include/ActivationFunctionManager.hpp deleted file mode 120000 index 9d2e63e..0000000 --- a/include/ActivationFunctionManager.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/ActivationFunctionManager.hpp \ No newline at end of file diff --git a/include/ActivationMapUnit.hpp b/include/ActivationMapUnit.hpp deleted file mode 120000 index b0b181e..0000000 --- a/include/ActivationMapUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/ActivationMapUnit.hpp \ No newline at end of file diff --git a/include/ActivationUnit.hpp b/include/ActivationUnit.hpp deleted file mode 120000 index 307e155..0000000 --- a/include/ActivationUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/ActivationUnit.hpp \ No newline at end of file diff --git a/include/EuclideanDistanceMap.hpp b/include/EuclideanDistanceMap.hpp deleted file mode 120000 index 3fce84a..0000000 --- a/include/EuclideanDistanceMap.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/EuclideanDistanceMap.hpp \ No newline at end of file diff --git a/include/EuclideanDistanceMapUnit.hpp b/include/EuclideanDistanceMapUnit.hpp deleted file mode 120000 index 3f22015..0000000 --- a/include/EuclideanDistanceMapUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/EuclideanDistanceMapUnit.hpp \ No newline at end of file diff --git a/include/EuclideanPairDistanceMap.hpp b/include/EuclideanPairDistanceMap.hpp deleted file mode 120000 index 927fa7f..0000000 --- a/include/EuclideanPairDistanceMap.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/EuclideanPairDistanceMap.hpp \ No newline at end of file diff --git a/include/EuclideanPairDistanceMapUnit.hpp b/include/EuclideanPairDistanceMapUnit.hpp deleted file mode 120000 index 2b83b6b..0000000 --- a/include/EuclideanPairDistanceMapUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/EuclideanPairDistanceMapUnit.hpp \ No newline at end of file diff --git a/include/ExponentialActivationFunction.hpp b/include/ExponentialActivationFunction.hpp deleted file mode 120000 index 8912540..0000000 --- a/include/ExponentialActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/ExponentialActivationFunction.hpp \ No newline at end of file diff --git a/include/FeatureMapLayer.hpp b/include/FeatureMapLayer.hpp deleted file mode 120000 index bb95934..0000000 --- a/include/FeatureMapLayer.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/FeatureMapLayer.hpp \ No newline at end of file diff --git a/include/FeatureMapUnit.hpp b/include/FeatureMapUnit.hpp deleted file mode 120000 index 982d82a..0000000 --- a/include/FeatureMapUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/FeatureMapUnit.hpp \ No newline at end of file diff --git a/include/FedActivationUnit.hpp b/include/FedActivationUnit.hpp deleted file mode 120000 index 7aeff95..0000000 --- a/include/FedActivationUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/FedActivationUnit.hpp \ No newline at end of file diff --git a/include/FedLayer.hpp b/include/FedLayer.hpp deleted file mode 120000 index 2ddbc09..0000000 --- a/include/FedLayer.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/layer/FedLayer.hpp \ No newline at end of file diff --git a/include/FedUnit.hpp b/include/FedUnit.hpp deleted file mode 120000 index fec5d8e..0000000 --- a/include/FedUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/FedUnit.hpp \ No newline at end of file diff --git a/include/FeedForwardNeuralNetwork.hpp b/include/FeedForwardNeuralNetwork.hpp deleted file mode 120000 index 6aaefcf..0000000 --- a/include/FeedForwardNeuralNetwork.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/network/FeedForwardNeuralNetwork.hpp \ No newline at end of file diff --git a/include/FeederInterface.hpp b/include/FeederInterface.hpp deleted file mode 120000 index 07af2b2..0000000 --- a/include/FeederInterface.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feeder/FeederInterface.hpp \ No newline at end of file diff --git a/include/GaussianActivationFunction.hpp b/include/GaussianActivationFunction.hpp deleted file mode 120000 index d086109..0000000 --- a/include/GaussianActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/GaussianActivationFunction.hpp \ No newline at end of file diff --git a/include/IdentityActivationFunction.hpp b/include/IdentityActivationFunction.hpp deleted file mode 120000 index 2ee49c8..0000000 --- a/include/IdentityActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/IdentityActivationFunction.hpp \ No newline at end of file diff --git a/include/IdentityMap.hpp b/include/IdentityMap.hpp deleted file mode 120000 index dcd074d..0000000 --- a/include/IdentityMap.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/IdentityMap.hpp \ No newline at end of file diff --git a/include/IdentityMapUnit.hpp b/include/IdentityMapUnit.hpp deleted file mode 120000 index 5ec4cac..0000000 --- a/include/IdentityMapUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/IdentityMapUnit.hpp \ No newline at end of file diff --git a/include/InputLayer.hpp b/include/InputLayer.hpp deleted file mode 120000 index f1e0e6d..0000000 --- a/include/InputLayer.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/layer/InputLayer.hpp \ No newline at end of file diff --git a/include/InputUnit.hpp b/include/InputUnit.hpp deleted file mode 120000 index 7a8053c..0000000 --- a/include/InputUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/InputUnit.hpp \ No newline at end of file diff --git a/include/LogisticActivationFunction.hpp b/include/LogisticActivationFunction.hpp deleted file mode 120000 index a07a9f2..0000000 --- a/include/LogisticActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/LogisticActivationFunction.hpp \ No newline at end of file diff --git a/include/MultiDimStaticMap.hpp b/include/MultiDimStaticMap.hpp deleted file mode 120000 index 47c3af1..0000000 --- a/include/MultiDimStaticMap.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/MultiDimStaticMap.hpp \ No newline at end of file diff --git a/include/NNLayer.hpp b/include/NNLayer.hpp deleted file mode 120000 index faea353..0000000 --- a/include/NNLayer.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/layer/NNLayer.hpp \ No newline at end of file diff --git a/include/NNRay.hpp b/include/NNRay.hpp deleted file mode 120000 index 3cd3534..0000000 --- a/include/NNRay.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feeder/NNRay.hpp \ No newline at end of file diff --git a/include/NNTrainer.hpp b/include/NNTrainer.hpp deleted file mode 120000 index 787c2dd..0000000 --- a/include/NNTrainer.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/trainer/NNTrainer.hpp \ No newline at end of file diff --git a/include/NNTrainerGSL.hpp b/include/NNTrainerGSL.hpp deleted file mode 120000 index 40c9d07..0000000 --- a/include/NNTrainerGSL.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/trainer/NNTrainerGSL.hpp \ No newline at end of file diff --git a/include/NNTrainingConfig.hpp b/include/NNTrainingConfig.hpp deleted file mode 120000 index 6402999..0000000 --- a/include/NNTrainingConfig.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/trainer/NNTrainingConfig.hpp \ No newline at end of file diff --git a/include/NNTrainingData.hpp b/include/NNTrainingData.hpp deleted file mode 120000 index 4c282f8..0000000 --- a/include/NNTrainingData.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/trainer/NNTrainingData.hpp \ No newline at end of file diff --git a/include/NNUnit.hpp b/include/NNUnit.hpp deleted file mode 120000 index 1fb45d0..0000000 --- a/include/NNUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/NNUnit.hpp \ No newline at end of file diff --git a/include/NetworkLayer.hpp b/include/NetworkLayer.hpp deleted file mode 120000 index e5bc725..0000000 --- a/include/NetworkLayer.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/layer/NetworkLayer.hpp \ No newline at end of file diff --git a/include/NetworkUnit.hpp b/include/NetworkUnit.hpp deleted file mode 120000 index 3bed987..0000000 --- a/include/NetworkUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/NetworkUnit.hpp \ No newline at end of file diff --git a/include/OffsetUnit.hpp b/include/OffsetUnit.hpp deleted file mode 120000 index b09e0e4..0000000 --- a/include/OffsetUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/OffsetUnit.hpp \ No newline at end of file diff --git a/include/OneDimStaticMap.hpp b/include/OneDimStaticMap.hpp deleted file mode 120000 index 62c7050..0000000 --- a/include/OneDimStaticMap.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/OneDimStaticMap.hpp \ No newline at end of file diff --git a/include/OutputNNLayer.hpp b/include/OutputNNLayer.hpp deleted file mode 120000 index 8f139e8..0000000 --- a/include/OutputNNLayer.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/layer/OutputNNLayer.hpp \ No newline at end of file diff --git a/include/OutputNNUnit.hpp b/include/OutputNNUnit.hpp deleted file mode 120000 index 3dd2df5..0000000 --- a/include/OutputNNUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/OutputNNUnit.hpp \ No newline at end of file diff --git a/include/PairDifferenceMap.hpp b/include/PairDifferenceMap.hpp deleted file mode 120000 index 219f5e6..0000000 --- a/include/PairDifferenceMap.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/PairDifferenceMap.hpp \ No newline at end of file diff --git a/include/PairDifferenceMapUnit.hpp b/include/PairDifferenceMapUnit.hpp deleted file mode 120000 index 979b4d7..0000000 --- a/include/PairDifferenceMapUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/PairDifferenceMapUnit.hpp \ No newline at end of file diff --git a/include/PairSumMap.hpp b/include/PairSumMap.hpp deleted file mode 120000 index 87936cf..0000000 --- a/include/PairSumMap.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/PairSumMap.hpp \ No newline at end of file diff --git a/include/PairSumMapUnit.hpp b/include/PairSumMapUnit.hpp deleted file mode 120000 index 4cf64f8..0000000 --- a/include/PairSumMapUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feature_maps/PairSumMapUnit.hpp \ No newline at end of file diff --git a/include/PrintUtilities.hpp b/include/PrintUtilities.hpp deleted file mode 120000 index fe7bb2b..0000000 --- a/include/PrintUtilities.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/io/PrintUtilities.hpp \ No newline at end of file diff --git a/include/ReLUActivationFunction.hpp b/include/ReLUActivationFunction.hpp deleted file mode 120000 index 351f3aa..0000000 --- a/include/ReLUActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/ReLUActivationFunction.hpp \ No newline at end of file diff --git a/include/SELUActivationFunction.hpp b/include/SELUActivationFunction.hpp deleted file mode 120000 index 1577ff5..0000000 --- a/include/SELUActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/SELUActivationFunction.hpp \ No newline at end of file diff --git a/include/SRLUActivationFunction.hpp b/include/SRLUActivationFunction.hpp deleted file mode 120000 index 4c112a4..0000000 --- a/include/SRLUActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/SRLUActivationFunction.hpp \ No newline at end of file diff --git a/include/SerializableComponent.hpp b/include/SerializableComponent.hpp deleted file mode 120000 index 2f3d283..0000000 --- a/include/SerializableComponent.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/serialize/SerializableComponent.hpp \ No newline at end of file diff --git a/include/ShifterScalerNNUnit.hpp b/include/ShifterScalerNNUnit.hpp deleted file mode 120000 index f62507f..0000000 --- a/include/ShifterScalerNNUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/ShifterScalerNNUnit.hpp \ No newline at end of file diff --git a/include/ShifterScalerUnit.hpp b/include/ShifterScalerUnit.hpp deleted file mode 120000 index 88632e9..0000000 --- a/include/ShifterScalerUnit.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/unit/ShifterScalerUnit.hpp \ No newline at end of file diff --git a/include/SineActivationFunction.hpp b/include/SineActivationFunction.hpp deleted file mode 120000 index 88a719b..0000000 --- a/include/SineActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/SineActivationFunction.hpp \ No newline at end of file diff --git a/include/SmartBetaGenerator.hpp b/include/SmartBetaGenerator.hpp deleted file mode 120000 index 166b4ec..0000000 --- a/include/SmartBetaGenerator.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feeder/SmartBetaGenerator.hpp \ No newline at end of file diff --git a/include/StaticFeeder.hpp b/include/StaticFeeder.hpp deleted file mode 120000 index e1e9450..0000000 --- a/include/StaticFeeder.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feeder/StaticFeeder.hpp \ No newline at end of file diff --git a/include/StringCodeUtilities.hpp b/include/StringCodeUtilities.hpp deleted file mode 120000 index 1c74df8..0000000 --- a/include/StringCodeUtilities.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/serialize/StringCodeUtilities.hpp \ No newline at end of file diff --git a/include/TanSigmoidActivationFunction.hpp b/include/TanSigmoidActivationFunction.hpp deleted file mode 120000 index b0dce7a..0000000 --- a/include/TanSigmoidActivationFunction.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/actf/TanSigmoidActivationFunction.hpp \ No newline at end of file diff --git a/include/VariableFeeder.hpp b/include/VariableFeeder.hpp deleted file mode 120000 index a535164..0000000 --- a/include/VariableFeeder.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feeder/VariableFeeder.hpp \ No newline at end of file diff --git a/include/WeightedFeeder.hpp b/include/WeightedFeeder.hpp deleted file mode 120000 index 7d4516e..0000000 --- a/include/WeightedFeeder.hpp +++ /dev/null @@ -1 +0,0 @@ -../src/feeder/WeightedFeeder.hpp \ No newline at end of file diff --git a/include/ffnn b/include/ffnn deleted file mode 120000 index 6a04314..0000000 --- a/include/ffnn +++ /dev/null @@ -1 +0,0 @@ -./ \ No newline at end of file diff --git a/src/actf/ActivationFunctionInterface.hpp b/include/ffnn/actf/ActivationFunctionInterface.hpp similarity index 98% rename from src/actf/ActivationFunctionInterface.hpp rename to include/ffnn/actf/ActivationFunctionInterface.hpp index 0feb448..77791c1 100644 --- a/src/actf/ActivationFunctionInterface.hpp +++ b/include/ffnn/actf/ActivationFunctionInterface.hpp @@ -1,7 +1,7 @@ #ifndef ACTIVATION_FUNCTION_INTERFACE #define ACTIVATION_FUNCTION_INTERFACE -#include "SerializableComponent.hpp" +#include "ffnn/serial/SerializableComponent.hpp" #include #include diff --git a/src/actf/ActivationFunctionManager.hpp b/include/ffnn/actf/ActivationFunctionManager.hpp similarity index 100% rename from src/actf/ActivationFunctionManager.hpp rename to include/ffnn/actf/ActivationFunctionManager.hpp diff --git a/src/actf/ExponentialActivationFunction.hpp b/include/ffnn/actf/ExponentialActivationFunction.hpp similarity index 94% rename from src/actf/ExponentialActivationFunction.hpp rename to include/ffnn/actf/ExponentialActivationFunction.hpp index 599840a..6504e90 100644 --- a/src/actf/ExponentialActivationFunction.hpp +++ b/include/ffnn/actf/ExponentialActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef EXPONENTIAL_ACTIVATION_FUNCTION #define EXPONENTIAL_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include class ExponentialActivationFunction: public ActivationFunctionInterface diff --git a/src/actf/GaussianActivationFunction.hpp b/include/ffnn/actf/GaussianActivationFunction.hpp similarity index 100% rename from src/actf/GaussianActivationFunction.hpp rename to include/ffnn/actf/GaussianActivationFunction.hpp diff --git a/src/actf/IdentityActivationFunction.hpp b/include/ffnn/actf/IdentityActivationFunction.hpp similarity index 100% rename from src/actf/IdentityActivationFunction.hpp rename to include/ffnn/actf/IdentityActivationFunction.hpp diff --git a/src/actf/LogisticActivationFunction.hpp b/include/ffnn/actf/LogisticActivationFunction.hpp similarity index 100% rename from src/actf/LogisticActivationFunction.hpp rename to include/ffnn/actf/LogisticActivationFunction.hpp diff --git a/src/actf/ReLUActivationFunction.hpp b/include/ffnn/actf/ReLUActivationFunction.hpp similarity index 100% rename from src/actf/ReLUActivationFunction.hpp rename to include/ffnn/actf/ReLUActivationFunction.hpp diff --git a/src/actf/SELUActivationFunction.hpp b/include/ffnn/actf/SELUActivationFunction.hpp similarity index 100% rename from src/actf/SELUActivationFunction.hpp rename to include/ffnn/actf/SELUActivationFunction.hpp diff --git a/src/actf/SRLUActivationFunction.hpp b/include/ffnn/actf/SRLUActivationFunction.hpp similarity index 100% rename from src/actf/SRLUActivationFunction.hpp rename to include/ffnn/actf/SRLUActivationFunction.hpp diff --git a/src/actf/SineActivationFunction.hpp b/include/ffnn/actf/SineActivationFunction.hpp similarity index 100% rename from src/actf/SineActivationFunction.hpp rename to include/ffnn/actf/SineActivationFunction.hpp diff --git a/src/actf/TanSigmoidActivationFunction.hpp b/include/ffnn/actf/TanSigmoidActivationFunction.hpp similarity index 100% rename from src/actf/TanSigmoidActivationFunction.hpp rename to include/ffnn/actf/TanSigmoidActivationFunction.hpp diff --git a/src/feeder/FeederInterface.hpp b/include/ffnn/feed/FeederInterface.hpp similarity index 100% rename from src/feeder/FeederInterface.hpp rename to include/ffnn/feed/FeederInterface.hpp diff --git a/src/feeder/NNRay.hpp b/include/ffnn/feed/NNRay.hpp similarity index 100% rename from src/feeder/NNRay.hpp rename to include/ffnn/feed/NNRay.hpp diff --git a/src/feeder/SmartBetaGenerator.hpp b/include/ffnn/feed/SmartBetaGenerator.hpp similarity index 100% rename from src/feeder/SmartBetaGenerator.hpp rename to include/ffnn/feed/SmartBetaGenerator.hpp diff --git a/src/feeder/StaticFeeder.hpp b/include/ffnn/feed/StaticFeeder.hpp similarity index 100% rename from src/feeder/StaticFeeder.hpp rename to include/ffnn/feed/StaticFeeder.hpp diff --git a/src/feeder/VariableFeeder.hpp b/include/ffnn/feed/VariableFeeder.hpp similarity index 100% rename from src/feeder/VariableFeeder.hpp rename to include/ffnn/feed/VariableFeeder.hpp diff --git a/src/feeder/WeightedFeeder.hpp b/include/ffnn/feed/WeightedFeeder.hpp similarity index 100% rename from src/feeder/WeightedFeeder.hpp rename to include/ffnn/feed/WeightedFeeder.hpp diff --git a/src/feature_maps/ActivationMapUnit.hpp b/include/ffnn/fmap/ActivationMapUnit.hpp similarity index 100% rename from src/feature_maps/ActivationMapUnit.hpp rename to include/ffnn/fmap/ActivationMapUnit.hpp diff --git a/src/feature_maps/EuclideanDistanceMap.hpp b/include/ffnn/fmap/EuclideanDistanceMap.hpp similarity index 100% rename from src/feature_maps/EuclideanDistanceMap.hpp rename to include/ffnn/fmap/EuclideanDistanceMap.hpp diff --git a/src/feature_maps/EuclideanDistanceMapUnit.hpp b/include/ffnn/fmap/EuclideanDistanceMapUnit.hpp similarity index 100% rename from src/feature_maps/EuclideanDistanceMapUnit.hpp rename to include/ffnn/fmap/EuclideanDistanceMapUnit.hpp diff --git a/src/feature_maps/EuclideanPairDistanceMap.hpp b/include/ffnn/fmap/EuclideanPairDistanceMap.hpp similarity index 100% rename from src/feature_maps/EuclideanPairDistanceMap.hpp rename to include/ffnn/fmap/EuclideanPairDistanceMap.hpp diff --git a/src/feature_maps/EuclideanPairDistanceMapUnit.hpp b/include/ffnn/fmap/EuclideanPairDistanceMapUnit.hpp similarity index 100% rename from src/feature_maps/EuclideanPairDistanceMapUnit.hpp rename to include/ffnn/fmap/EuclideanPairDistanceMapUnit.hpp diff --git a/src/feature_maps/FeatureMapLayer.hpp b/include/ffnn/fmap/FeatureMapLayer.hpp similarity index 100% rename from src/feature_maps/FeatureMapLayer.hpp rename to include/ffnn/fmap/FeatureMapLayer.hpp diff --git a/src/feature_maps/FeatureMapUnit.hpp b/include/ffnn/fmap/FeatureMapUnit.hpp similarity index 100% rename from src/feature_maps/FeatureMapUnit.hpp rename to include/ffnn/fmap/FeatureMapUnit.hpp diff --git a/src/feature_maps/IdentityMap.hpp b/include/ffnn/fmap/IdentityMap.hpp similarity index 100% rename from src/feature_maps/IdentityMap.hpp rename to include/ffnn/fmap/IdentityMap.hpp diff --git a/src/feature_maps/IdentityMapUnit.hpp b/include/ffnn/fmap/IdentityMapUnit.hpp similarity index 100% rename from src/feature_maps/IdentityMapUnit.hpp rename to include/ffnn/fmap/IdentityMapUnit.hpp diff --git a/src/feature_maps/MultiDimStaticMap.hpp b/include/ffnn/fmap/MultiDimStaticMap.hpp similarity index 100% rename from src/feature_maps/MultiDimStaticMap.hpp rename to include/ffnn/fmap/MultiDimStaticMap.hpp diff --git a/src/feature_maps/OneDimStaticMap.hpp b/include/ffnn/fmap/OneDimStaticMap.hpp similarity index 100% rename from src/feature_maps/OneDimStaticMap.hpp rename to include/ffnn/fmap/OneDimStaticMap.hpp diff --git a/src/feature_maps/PairDifferenceMap.hpp b/include/ffnn/fmap/PairDifferenceMap.hpp similarity index 100% rename from src/feature_maps/PairDifferenceMap.hpp rename to include/ffnn/fmap/PairDifferenceMap.hpp diff --git a/src/feature_maps/PairDifferenceMapUnit.hpp b/include/ffnn/fmap/PairDifferenceMapUnit.hpp similarity index 100% rename from src/feature_maps/PairDifferenceMapUnit.hpp rename to include/ffnn/fmap/PairDifferenceMapUnit.hpp diff --git a/src/feature_maps/PairSumMap.hpp b/include/ffnn/fmap/PairSumMap.hpp similarity index 100% rename from src/feature_maps/PairSumMap.hpp rename to include/ffnn/fmap/PairSumMap.hpp diff --git a/src/feature_maps/PairSumMapUnit.hpp b/include/ffnn/fmap/PairSumMapUnit.hpp similarity index 100% rename from src/feature_maps/PairSumMapUnit.hpp rename to include/ffnn/fmap/PairSumMapUnit.hpp diff --git a/src/io/PrintUtilities.hpp b/include/ffnn/io/PrintUtilities.hpp similarity index 100% rename from src/io/PrintUtilities.hpp rename to include/ffnn/io/PrintUtilities.hpp diff --git a/src/layer/FedLayer.hpp b/include/ffnn/layer/FedLayer.hpp similarity index 100% rename from src/layer/FedLayer.hpp rename to include/ffnn/layer/FedLayer.hpp diff --git a/src/layer/InputLayer.hpp b/include/ffnn/layer/InputLayer.hpp similarity index 100% rename from src/layer/InputLayer.hpp rename to include/ffnn/layer/InputLayer.hpp diff --git a/src/layer/NNLayer.hpp b/include/ffnn/layer/NNLayer.hpp similarity index 100% rename from src/layer/NNLayer.hpp rename to include/ffnn/layer/NNLayer.hpp diff --git a/src/layer/NetworkLayer.hpp b/include/ffnn/layer/NetworkLayer.hpp similarity index 100% rename from src/layer/NetworkLayer.hpp rename to include/ffnn/layer/NetworkLayer.hpp diff --git a/src/layer/OutputNNLayer.hpp b/include/ffnn/layer/OutputNNLayer.hpp similarity index 100% rename from src/layer/OutputNNLayer.hpp rename to include/ffnn/layer/OutputNNLayer.hpp diff --git a/src/network/FeedForwardNeuralNetwork.hpp b/include/ffnn/net/FeedForwardNeuralNetwork.hpp similarity index 100% rename from src/network/FeedForwardNeuralNetwork.hpp rename to include/ffnn/net/FeedForwardNeuralNetwork.hpp diff --git a/src/serialize/SerializableComponent.hpp b/include/ffnn/serial/SerializableComponent.hpp similarity index 100% rename from src/serialize/SerializableComponent.hpp rename to include/ffnn/serial/SerializableComponent.hpp diff --git a/src/serialize/StringCodeUtilities.hpp b/include/ffnn/serial/StringCodeUtilities.hpp similarity index 100% rename from src/serialize/StringCodeUtilities.hpp rename to include/ffnn/serial/StringCodeUtilities.hpp diff --git a/src/trainer/NNTrainer.hpp b/include/ffnn/train/NNTrainer.hpp similarity index 100% rename from src/trainer/NNTrainer.hpp rename to include/ffnn/train/NNTrainer.hpp diff --git a/src/trainer/NNTrainerGSL.hpp b/include/ffnn/train/NNTrainerGSL.hpp similarity index 100% rename from src/trainer/NNTrainerGSL.hpp rename to include/ffnn/train/NNTrainerGSL.hpp diff --git a/src/trainer/NNTrainingConfig.hpp b/include/ffnn/train/NNTrainingConfig.hpp similarity index 100% rename from src/trainer/NNTrainingConfig.hpp rename to include/ffnn/train/NNTrainingConfig.hpp diff --git a/src/trainer/NNTrainingData.hpp b/include/ffnn/train/NNTrainingData.hpp similarity index 100% rename from src/trainer/NNTrainingData.hpp rename to include/ffnn/train/NNTrainingData.hpp diff --git a/src/unit/ActivationUnit.hpp b/include/ffnn/unit/ActivationUnit.hpp similarity index 100% rename from src/unit/ActivationUnit.hpp rename to include/ffnn/unit/ActivationUnit.hpp diff --git a/src/unit/FedActivationUnit.hpp b/include/ffnn/unit/FedActivationUnit.hpp similarity index 100% rename from src/unit/FedActivationUnit.hpp rename to include/ffnn/unit/FedActivationUnit.hpp diff --git a/src/unit/FedUnit.hpp b/include/ffnn/unit/FedUnit.hpp similarity index 100% rename from src/unit/FedUnit.hpp rename to include/ffnn/unit/FedUnit.hpp diff --git a/src/unit/InputUnit.hpp b/include/ffnn/unit/InputUnit.hpp similarity index 100% rename from src/unit/InputUnit.hpp rename to include/ffnn/unit/InputUnit.hpp diff --git a/src/unit/NNUnit.hpp b/include/ffnn/unit/NNUnit.hpp similarity index 100% rename from src/unit/NNUnit.hpp rename to include/ffnn/unit/NNUnit.hpp diff --git a/src/unit/NetworkUnit.hpp b/include/ffnn/unit/NetworkUnit.hpp similarity index 100% rename from src/unit/NetworkUnit.hpp rename to include/ffnn/unit/NetworkUnit.hpp diff --git a/src/unit/OffsetUnit.hpp b/include/ffnn/unit/OffsetUnit.hpp similarity index 100% rename from src/unit/OffsetUnit.hpp rename to include/ffnn/unit/OffsetUnit.hpp diff --git a/src/unit/OutputNNUnit.hpp b/include/ffnn/unit/OutputNNUnit.hpp similarity index 100% rename from src/unit/OutputNNUnit.hpp rename to include/ffnn/unit/OutputNNUnit.hpp diff --git a/src/unit/ShifterScalerNNUnit.hpp b/include/ffnn/unit/ShifterScalerNNUnit.hpp similarity index 100% rename from src/unit/ShifterScalerNNUnit.hpp rename to include/ffnn/unit/ShifterScalerNNUnit.hpp diff --git a/src/unit/ShifterScalerUnit.hpp b/include/ffnn/unit/ShifterScalerUnit.hpp similarity index 100% rename from src/unit/ShifterScalerUnit.hpp rename to include/ffnn/unit/ShifterScalerUnit.hpp diff --git a/src/feeder/FeederInterface.cpp b/src/feed/FeederInterface.cpp similarity index 100% rename from src/feeder/FeederInterface.cpp rename to src/feed/FeederInterface.cpp diff --git a/src/feeder/NNRay.cpp b/src/feed/NNRay.cpp similarity index 100% rename from src/feeder/NNRay.cpp rename to src/feed/NNRay.cpp diff --git a/src/feeder/SmartBetaGenerator.cpp b/src/feed/SmartBetaGenerator.cpp similarity index 100% rename from src/feeder/SmartBetaGenerator.cpp rename to src/feed/SmartBetaGenerator.cpp diff --git a/src/feeder/VariableFeeder.cpp b/src/feed/VariableFeeder.cpp similarity index 100% rename from src/feeder/VariableFeeder.cpp rename to src/feed/VariableFeeder.cpp diff --git a/src/feeder/WeightedFeeder.cpp b/src/feed/WeightedFeeder.cpp similarity index 100% rename from src/feeder/WeightedFeeder.cpp rename to src/feed/WeightedFeeder.cpp diff --git a/src/feature_maps/EuclideanDistanceMap.cpp b/src/fmap/EuclideanDistanceMap.cpp similarity index 100% rename from src/feature_maps/EuclideanDistanceMap.cpp rename to src/fmap/EuclideanDistanceMap.cpp diff --git a/src/feature_maps/EuclideanPairDistanceMap.cpp b/src/fmap/EuclideanPairDistanceMap.cpp similarity index 100% rename from src/feature_maps/EuclideanPairDistanceMap.cpp rename to src/fmap/EuclideanPairDistanceMap.cpp diff --git a/src/feature_maps/FeatureMapLayer.cpp b/src/fmap/FeatureMapLayer.cpp similarity index 100% rename from src/feature_maps/FeatureMapLayer.cpp rename to src/fmap/FeatureMapLayer.cpp diff --git a/src/feature_maps/IdentityMap.cpp b/src/fmap/IdentityMap.cpp similarity index 100% rename from src/feature_maps/IdentityMap.cpp rename to src/fmap/IdentityMap.cpp diff --git a/src/feature_maps/MultiDimStaticMap.cpp b/src/fmap/MultiDimStaticMap.cpp similarity index 100% rename from src/feature_maps/MultiDimStaticMap.cpp rename to src/fmap/MultiDimStaticMap.cpp diff --git a/src/feature_maps/OneDimStaticMap.cpp b/src/fmap/OneDimStaticMap.cpp similarity index 100% rename from src/feature_maps/OneDimStaticMap.cpp rename to src/fmap/OneDimStaticMap.cpp diff --git a/src/feature_maps/PairDifferenceMap.cpp b/src/fmap/PairDifferenceMap.cpp similarity index 100% rename from src/feature_maps/PairDifferenceMap.cpp rename to src/fmap/PairDifferenceMap.cpp diff --git a/src/feature_maps/PairSumMap.cpp b/src/fmap/PairSumMap.cpp similarity index 100% rename from src/feature_maps/PairSumMap.cpp rename to src/fmap/PairSumMap.cpp diff --git a/src/network/FeedForwardNeuralNetwork.cpp b/src/net/FeedForwardNeuralNetwork.cpp similarity index 100% rename from src/network/FeedForwardNeuralNetwork.cpp rename to src/net/FeedForwardNeuralNetwork.cpp diff --git a/src/serialize/StringCodeUtilities.cpp b/src/serial/StringCodeUtilities.cpp similarity index 100% rename from src/serialize/StringCodeUtilities.cpp rename to src/serial/StringCodeUtilities.cpp diff --git a/src/trainer/NNTrainer.cpp b/src/train/NNTrainer.cpp similarity index 100% rename from src/trainer/NNTrainer.cpp rename to src/train/NNTrainer.cpp diff --git a/src/trainer/NNTrainerGSL.cpp b/src/train/NNTrainerGSL.cpp similarity index 100% rename from src/trainer/NNTrainerGSL.cpp rename to src/train/NNTrainerGSL.cpp From 1f91f379d04064132a72326b49bd2288aea7edd6 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Thu, 21 Feb 2019 20:37:25 +0100 Subject: [PATCH 09/18] Change directory structure to match the other NNVMC repos --- CMakeLists.txt | 1 + README.md | 67 +++---------------- benchmark/CMakeLists.txt | 5 ++ benchmark/README.md | 13 ++-- benchmark/bench_actfs_derivs/main.cpp | 4 +- benchmark/bench_actfs_derivs/run.sh | 9 +++ benchmark/bench_actfs_ffprop/main.cpp | 6 +- benchmark/bench_actfs_ffprop/run.sh | 9 +++ benchmark/common/FFNNBenchmarks.cpp | 2 +- examples/README.md | 6 +- examples/ex1/main.cpp | 4 +- examples/ex10/main.cpp | 2 +- examples/ex2/main.cpp | 4 +- examples/ex3/main.cpp | 4 +- examples/ex4/main.cpp | 4 +- examples/ex5/main.cpp | 4 +- examples/ex6/main.cpp | 4 +- examples/ex7/main.cpp | 4 +- examples/ex8/main.cpp | 4 +- examples/ex9/main.cpp | 2 +- .../ffnn/actf/ActivationFunctionManager.hpp | 20 +++--- .../ffnn/actf/GaussianActivationFunction.hpp | 2 +- .../ffnn/actf/IdentityActivationFunction.hpp | 2 +- .../ffnn/actf/LogisticActivationFunction.hpp | 2 +- include/ffnn/actf/ReLUActivationFunction.hpp | 2 +- include/ffnn/actf/SELUActivationFunction.hpp | 2 +- include/ffnn/actf/SRLUActivationFunction.hpp | 2 +- include/ffnn/actf/SineActivationFunction.hpp | 2 +- .../actf/TanSigmoidActivationFunction.hpp | 2 +- include/ffnn/feed/FeederInterface.hpp | 2 +- include/ffnn/feed/NNRay.hpp | 4 +- include/ffnn/feed/SmartBetaGenerator.hpp | 8 +-- include/ffnn/feed/StaticFeeder.hpp | 6 +- include/ffnn/feed/VariableFeeder.hpp | 6 +- include/ffnn/feed/WeightedFeeder.hpp | 6 +- include/ffnn/fmap/ActivationMapUnit.hpp | 4 +- include/ffnn/fmap/EuclideanDistanceMap.hpp | 4 +- .../ffnn/fmap/EuclideanDistanceMapUnit.hpp | 4 +- .../ffnn/fmap/EuclideanPairDistanceMap.hpp | 4 +- .../fmap/EuclideanPairDistanceMapUnit.hpp | 4 +- include/ffnn/fmap/FeatureMapLayer.hpp | 18 ++--- include/ffnn/fmap/FeatureMapUnit.hpp | 4 +- include/ffnn/fmap/IdentityMap.hpp | 6 +- include/ffnn/fmap/IdentityMapUnit.hpp | 4 +- include/ffnn/fmap/MultiDimStaticMap.hpp | 4 +- include/ffnn/fmap/OneDimStaticMap.hpp | 4 +- include/ffnn/fmap/PairDifferenceMap.hpp | 6 +- include/ffnn/fmap/PairDifferenceMapUnit.hpp | 4 +- include/ffnn/fmap/PairSumMap.hpp | 6 +- include/ffnn/fmap/PairSumMapUnit.hpp | 4 +- include/ffnn/io/PrintUtilities.hpp | 2 +- include/ffnn/layer/FedLayer.hpp | 4 +- include/ffnn/layer/InputLayer.hpp | 4 +- include/ffnn/layer/NNLayer.hpp | 14 ++-- include/ffnn/layer/NetworkLayer.hpp | 8 +-- include/ffnn/layer/OutputNNLayer.hpp | 8 +-- include/ffnn/net/FeedForwardNeuralNetwork.hpp | 16 ++--- include/ffnn/serial/SerializableComponent.hpp | 2 +- include/ffnn/train/NNTrainer.hpp | 8 +-- include/ffnn/train/NNTrainerGSL.hpp | 8 +-- include/ffnn/train/NNTrainingConfig.hpp | 2 +- include/ffnn/unit/ActivationUnit.hpp | 6 +- include/ffnn/unit/FedActivationUnit.hpp | 10 +-- include/ffnn/unit/FedUnit.hpp | 4 +- include/ffnn/unit/InputUnit.hpp | 2 +- include/ffnn/unit/NNUnit.hpp | 10 +-- include/ffnn/unit/NetworkUnit.hpp | 4 +- include/ffnn/unit/OffsetUnit.hpp | 2 +- include/ffnn/unit/OutputNNUnit.hpp | 6 +- include/ffnn/unit/ShifterScalerNNUnit.hpp | 10 +-- include/ffnn/unit/ShifterScalerUnit.hpp | 4 +- src/actf/ActivationFunctionManager.cpp | 2 +- src/actf/ExponentialActivationFunction.cpp | 2 +- src/actf/GaussianActivationFunction.cpp | 2 +- src/actf/LogisticActivationFunction.cpp | 2 +- src/actf/ReLUActivationFunction.cpp | 4 +- src/actf/SELUActivationFunction.cpp | 4 +- src/actf/SRLUActivationFunction.cpp | 2 +- src/actf/SineActivationFunction.cpp | 2 +- src/actf/TanSigmoidActivationFunction.cpp | 2 +- src/feed/FeederInterface.cpp | 8 +-- src/feed/NNRay.cpp | 6 +- src/feed/SmartBetaGenerator.cpp | 16 ++--- src/feed/VariableFeeder.cpp | 2 +- src/feed/WeightedFeeder.cpp | 2 +- src/fmap/EuclideanDistanceMap.cpp | 6 +- src/fmap/EuclideanPairDistanceMap.cpp | 6 +- src/fmap/FeatureMapLayer.cpp | 8 +-- src/fmap/IdentityMap.cpp | 4 +- src/fmap/MultiDimStaticMap.cpp | 6 +- src/fmap/OneDimStaticMap.cpp | 6 +- src/fmap/PairDifferenceMap.cpp | 4 +- src/fmap/PairSumMap.cpp | 4 +- src/io/PrintUtilities.cpp | 8 +-- src/layer/FedLayer.cpp | 6 +- src/layer/InputLayer.cpp | 4 +- src/layer/NNLayer.cpp | 8 +-- src/layer/NetworkLayer.cpp | 6 +- src/layer/OutputNNLayer.cpp | 8 +-- src/net/FeedForwardNeuralNetwork.cpp | 8 +-- src/serial/StringCodeUtilities.cpp | 2 +- src/train/NNTrainer.cpp | 4 +- src/train/NNTrainerGSL.cpp | 2 +- src/unit/ActivationUnit.cpp | 6 +- src/unit/FedUnit.cpp | 4 +- src/unit/InputUnit.cpp | 2 +- src/unit/NetworkUnit.cpp | 2 +- src/unit/OutputNNUnit.cpp | 2 +- test/README.md | 3 +- test/common/checkDerivatives.hpp | 2 +- test/common/checkStoreOnFile.hpp | 2 +- test/main.cpp | 2 +- test/ut1/main.cpp | 2 +- test/ut10/main.cpp | 4 +- test/ut2/main.cpp | 4 +- test/ut3/main.cpp | 6 +- test/ut4/main.cpp | 6 +- test/ut5/main.cpp | 4 +- test/ut6/main.cpp | 2 +- test/ut7/main.cpp | 12 ++-- test/ut8/main.cpp | 4 +- test/ut9/main.cpp | 4 +- 122 files changed, 322 insertions(+), 347 deletions(-) create mode 100644 benchmark/CMakeLists.txt create mode 100755 benchmark/bench_actfs_derivs/run.sh create mode 100755 benchmark/bench_actfs_ffprop/run.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index ffa7d8b..c302e09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,4 +37,5 @@ enable_testing() # continue with subdirectories add_subdirectory(src) add_subdirectory(test) +add_subdirectory(benchmark) add_subdirectory(examples) diff --git a/README.md b/README.md index e9103d0..1940429 100644 --- a/README.md +++ b/README.md @@ -24,69 +24,20 @@ However, in principle any system with C++11 supporting compiler should work, at # Build the library -Make sure you have a reasonably recent development version (>=2.3?) of the GSL library on your system. Furthermore, we rely on the Autotools build system and libtool. -Optionally, if you have valgrind installed on your system, it will be used to check for memory errors when running unittests. +Make sure you have a reasonably recent development version (>=2.3?) of the GSL library on your system. Furthermore, we rely on the CMake build system. -If you have the GSL librariy in non-standard paths or want to use custom compiler flags, copy a little script: +Before compiling, copy the config template: + `cp config_template.sh config.sh` - `cp script/config_template.sh config.sh` +and edit it as needed (especially if you have the GSL library in non-standard paths. -Now edit `config.sh` to your needs and before proceeding run: +If you are done, simply use the following script to compile the library and all tests, benchmarks and examples: + `./build.sh` - `source config.sh` +Note that we build out-of-tree, so the compiled library and executable files can be found in the directories under `./build/`. -If you have the prerequisites, you may setup the build environment by using the following script in the top level directory: - - `./autogen.sh` - -Now you want to configure the build process for your platform by invoking: - - `./configure` - -Finally, you are ready to compile all the code files in our repository together, by: - - `make` or `make -jN` - -where N is the number of parallel threads used by make. Alternatively, you may use the following make targets to build only subparts of the project: - - `make lib`, `make test`, `make benchmark`, `make examples` - - -As long as you changed, but didn't remove or add source files, it is sufficient to only run `make` again to rebuild. - -If you however removed old or added new code files under `src/`, you need to first update the source file lists and include links. Do so by invoking from root folder: - - `make update-sources` - -NOTE: All the subdirectories of test, benchmark and examples support calling `make` inside them to recompile local changes. - - - -# Installation - -To install the freshly built library and headers into the standard system paths, run (usually sudo is required): - `make install` - -If you however want to install the library under a custom path, before installing you have to use - `./configure --prefix=/your/absolute/path - - - -# Build options - -You may enable special compiler flags by using one or more of the following options after `configure`: - - `--enable-debug` : Enables flags (like \-g and \-O0) suitable for debugging - - `--enable-coverage` : Enables flags to generate test coverage reports via gcov - - `--enable-profiling` : Enables flags to generate performance profiles for benchmarks - - - - -## Multi-threading: OpenMP +# Multi-threading: OpenMP This library supports multi-threading computation with a shared memory paradigm, thanks to OpenMP. -To activate this feature use `--enable-openmp` at configuration. Currently it is not recommended to use this for most cases. +To activate this feature, set `USE_OPENMP=1` inside your config.sh, before building. Currently it is not recommended to use this, in most cases. diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt new file mode 100644 index 0000000..53f2cd2 --- /dev/null +++ b/benchmark/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(common/) +link_libraries(ffnn) + +add_executable(bench_actfs_derivs bench_actfs_derivs/main.cpp) +add_executable(bench_actfs_ffprop bench_actfs_ffprop/main.cpp) diff --git a/benchmark/README.md b/benchmark/README.md index 8b2a837..9df8ce3 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -15,21 +15,20 @@ Currently there are the following benchmarks: # Using the benchmarks Enter the desired benchmark's directory and execute: - `make run-benchmark` + `./run.sh` -Instead you may also run all benchmarks together by calling from root or from top benchmark folder: - `make run-benchmarks` - -Each benchmark will write the result into a file `benchmark_new.out`. For visualization execute the plot script: +Each benchmark will write the results to the command line output by default. +If you save it into a file `benchmark_new.out` instead (e.g. via `./run.sh > benchmark_new.out`), you may visualize the result by using: `python plot.py benchmark_new.out` To let the plot compare the new result versus an older one, you have to provide the old output file like: `python plot.py benchmark_old.out benchmark_new.out`. -You may also change new/old to more meaningful labels, anything like benchmark_*.out is allowed (except extra _ or . characters). +You may also change new/old to more meaningful labels, anything like benchmark_*.out is allowed (except extra _ or . characters). The +provided labels will be used automatically to create the plot legends. -# Profiling +# Profiling (currently unavailable) If you want to use the benchmarks for profiling, recompile the library and benchmarks after configuring `./configure --enable-profiling` diff --git a/benchmark/bench_actfs_derivs/main.cpp b/benchmark/bench_actfs_derivs/main.cpp index 1b7d1b3..3f451ac 100644 --- a/benchmark/bench_actfs_derivs/main.cpp +++ b/benchmark/bench_actfs_derivs/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "ActivationFunctionManager.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/io/PrintUtilities.hpp" #include "FFNNBenchmarks.cpp" diff --git a/benchmark/bench_actfs_derivs/run.sh b/benchmark/bench_actfs_derivs/run.sh new file mode 100755 index 0000000..51059cf --- /dev/null +++ b/benchmark/bench_actfs_derivs/run.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +bench=bench_actfs_derivs + +cd ../../build/benchmark/ +echo +echo "Running benchmark ${bench}..." +./${bench} +echo diff --git a/benchmark/bench_actfs_ffprop/main.cpp b/benchmark/bench_actfs_ffprop/main.cpp index de19c6f..c48c33b 100644 --- a/benchmark/bench_actfs_ffprop/main.cpp +++ b/benchmark/bench_actfs_ffprop/main.cpp @@ -2,9 +2,9 @@ #include #include -#include "ActivationFunctionManager.hpp" -#include "PrintUtilities.hpp" -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/io/PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" #include "FFNNBenchmarks.cpp" diff --git a/benchmark/bench_actfs_ffprop/run.sh b/benchmark/bench_actfs_ffprop/run.sh new file mode 100755 index 0000000..4b78680 --- /dev/null +++ b/benchmark/bench_actfs_ffprop/run.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +bench=bench_actfs_ffprop + +cd ../../build/benchmark/ +echo +echo "Running benchmark ${bench}..." +./${bench} +echo diff --git a/benchmark/common/FFNNBenchmarks.cpp b/benchmark/common/FFNNBenchmarks.cpp index 3074769..d11bfbe 100644 --- a/benchmark/common/FFNNBenchmarks.cpp +++ b/benchmark/common/FFNNBenchmarks.cpp @@ -2,7 +2,7 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" #include "Timer.cpp" double benchmark_FFPropagate(FeedForwardNeuralNetwork * const ffnn, const double * const * const xdata, const int neval) { diff --git a/examples/README.md b/examples/README.md index cc5a275..9c466ac 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,9 +2,9 @@ Make sure the examples are compiled, by running `./build.sh` in the project root folder. Execute an example by switching into one of the example folders and running `./run.sh`. -Note that the actual example executables reside inside the build/ folder, from project root. -Some examples might also contain a `plot.py` script to show a plot. -Run it after the executable has terminated, via `python plot.py` (requires matplotlib). +Note that the actual example executables reside inside the build/ folder under the project's root. +Some examples might also contain a `plot.py` script to show a plot. It gets called automatically +by `./run.sh` after the executable has terminated, but requires python with matplotlib. ## Example 1 diff --git a/examples/ex1/main.cpp b/examples/ex1/main.cpp index 9303eaf..2f997aa 100644 --- a/examples/ex1/main.cpp +++ b/examples/ex1/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" int main() { diff --git a/examples/ex10/main.cpp b/examples/ex10/main.cpp index 9c11f4c..0d40080 100644 --- a/examples/ex10/main.cpp +++ b/examples/ex10/main.cpp @@ -2,7 +2,7 @@ #include #include -#include "NNTrainerGSL.hpp" +#include "ffnn/train/NNTrainerGSL.hpp" /* diff --git a/examples/ex2/main.cpp b/examples/ex2/main.cpp index df7d0a7..1c056ae 100644 --- a/examples/ex2/main.cpp +++ b/examples/ex2/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" int main() { diff --git a/examples/ex3/main.cpp b/examples/ex3/main.cpp index 3117b70..65ba533 100644 --- a/examples/ex3/main.cpp +++ b/examples/ex3/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" diff --git a/examples/ex4/main.cpp b/examples/ex4/main.cpp index 62a1434..7fefa06 100644 --- a/examples/ex4/main.cpp +++ b/examples/ex4/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" diff --git a/examples/ex5/main.cpp b/examples/ex5/main.cpp index 97a7f63..dae97fb 100644 --- a/examples/ex5/main.cpp +++ b/examples/ex5/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" diff --git a/examples/ex6/main.cpp b/examples/ex6/main.cpp index 3f46dbe..2b43483 100644 --- a/examples/ex6/main.cpp +++ b/examples/ex6/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" diff --git a/examples/ex7/main.cpp b/examples/ex7/main.cpp index 3c4a8aa..5df548f 100644 --- a/examples/ex7/main.cpp +++ b/examples/ex7/main.cpp @@ -2,8 +2,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" diff --git a/examples/ex8/main.cpp b/examples/ex8/main.cpp index b330c22..05d77f7 100644 --- a/examples/ex8/main.cpp +++ b/examples/ex8/main.cpp @@ -4,8 +4,8 @@ #include #include -#include "PrintUtilities.hpp" -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" diff --git a/examples/ex9/main.cpp b/examples/ex9/main.cpp index 9d9556b..8f985a9 100644 --- a/examples/ex9/main.cpp +++ b/examples/ex9/main.cpp @@ -2,7 +2,7 @@ #include #include -#include "NNTrainerGSL.hpp" +#include "ffnn/train/NNTrainerGSL.hpp" /* diff --git a/include/ffnn/actf/ActivationFunctionManager.hpp b/include/ffnn/actf/ActivationFunctionManager.hpp index 9ba632c..5ee0c70 100644 --- a/include/ffnn/actf/ActivationFunctionManager.hpp +++ b/include/ffnn/actf/ActivationFunctionManager.hpp @@ -2,16 +2,16 @@ #define ACTIVATION_FUNCTION_MANAGER -#include "ActivationFunctionInterface.hpp" -#include "IdentityActivationFunction.hpp" -#include "LogisticActivationFunction.hpp" -#include "GaussianActivationFunction.hpp" -#include "TanSigmoidActivationFunction.hpp" -#include "ReLUActivationFunction.hpp" -#include "SELUActivationFunction.hpp" -#include "SRLUActivationFunction.hpp" -#include "SineActivationFunction.hpp" -#include "ExponentialActivationFunction.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/IdentityActivationFunction.hpp" +#include "ffnn/actf/LogisticActivationFunction.hpp" +#include "ffnn/actf/GaussianActivationFunction.hpp" +#include "ffnn/actf/TanSigmoidActivationFunction.hpp" +#include "ffnn/actf/ReLUActivationFunction.hpp" +#include "ffnn/actf/SELUActivationFunction.hpp" +#include "ffnn/actf/SRLUActivationFunction.hpp" +#include "ffnn/actf/SineActivationFunction.hpp" +#include "ffnn/actf/ExponentialActivationFunction.hpp" #include #include diff --git a/include/ffnn/actf/GaussianActivationFunction.hpp b/include/ffnn/actf/GaussianActivationFunction.hpp index 078af2f..8831f63 100644 --- a/include/ffnn/actf/GaussianActivationFunction.hpp +++ b/include/ffnn/actf/GaussianActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef GAUSSIAN_ACTIVATION_FUNCTION #define GAUSSIAN_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include diff --git a/include/ffnn/actf/IdentityActivationFunction.hpp b/include/ffnn/actf/IdentityActivationFunction.hpp index 0a2cf17..9a99f38 100644 --- a/include/ffnn/actf/IdentityActivationFunction.hpp +++ b/include/ffnn/actf/IdentityActivationFunction.hpp @@ -3,7 +3,7 @@ #include -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" class IdentityActivationFunction: public ActivationFunctionInterface { diff --git a/include/ffnn/actf/LogisticActivationFunction.hpp b/include/ffnn/actf/LogisticActivationFunction.hpp index cea269f..178d4cd 100644 --- a/include/ffnn/actf/LogisticActivationFunction.hpp +++ b/include/ffnn/actf/LogisticActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef LOGISTIC_ACTIVATION_FUNCTION #define LOGISTIC_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include class LogisticActivationFunction: public ActivationFunctionInterface diff --git a/include/ffnn/actf/ReLUActivationFunction.hpp b/include/ffnn/actf/ReLUActivationFunction.hpp index aff9943..0778bd0 100644 --- a/include/ffnn/actf/ReLUActivationFunction.hpp +++ b/include/ffnn/actf/ReLUActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef RELU_ACTIVATION_FUNCTION #define RELU_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include diff --git a/include/ffnn/actf/SELUActivationFunction.hpp b/include/ffnn/actf/SELUActivationFunction.hpp index 289b107..3b70d5e 100644 --- a/include/ffnn/actf/SELUActivationFunction.hpp +++ b/include/ffnn/actf/SELUActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef SELU_ACTIVATION_FUNCTION #define SELU_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include class SELUActivationFunction: public ActivationFunctionInterface diff --git a/include/ffnn/actf/SRLUActivationFunction.hpp b/include/ffnn/actf/SRLUActivationFunction.hpp index 88fc230..634c2b5 100644 --- a/include/ffnn/actf/SRLUActivationFunction.hpp +++ b/include/ffnn/actf/SRLUActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef SRLU_ACTIVATION_FUNCTION #define SRLU_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include // Smooth Rectified Linear Unit ( == ln(1+exp(x)) ) diff --git a/include/ffnn/actf/SineActivationFunction.hpp b/include/ffnn/actf/SineActivationFunction.hpp index c2a491b..7f70719 100644 --- a/include/ffnn/actf/SineActivationFunction.hpp +++ b/include/ffnn/actf/SineActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef SINE_ACTIVATION_FUNCTION #define SINE_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include diff --git a/include/ffnn/actf/TanSigmoidActivationFunction.hpp b/include/ffnn/actf/TanSigmoidActivationFunction.hpp index 2c78102..41d2173 100644 --- a/include/ffnn/actf/TanSigmoidActivationFunction.hpp +++ b/include/ffnn/actf/TanSigmoidActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef TANSIGMOID_ACTIVATION_FUNCTION #define TANSIGMOID_ACTIVATION_FUNCTION -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include diff --git a/include/ffnn/feed/FeederInterface.hpp b/include/ffnn/feed/FeederInterface.hpp index 0e98d5d..3d68c9c 100644 --- a/include/ffnn/feed/FeederInterface.hpp +++ b/include/ffnn/feed/FeederInterface.hpp @@ -1,7 +1,7 @@ #ifndef FEEDER_INTERFACE #define FEEDER_INTERFACE -#include "SerializableComponent.hpp" +#include "ffnn/serial/SerializableComponent.hpp" #include #include diff --git a/include/ffnn/feed/NNRay.hpp b/include/ffnn/feed/NNRay.hpp index 8ec582f..3962d5a 100644 --- a/include/ffnn/feed/NNRay.hpp +++ b/include/ffnn/feed/NNRay.hpp @@ -1,8 +1,8 @@ #ifndef NN_RAY #define NN_RAY -#include "WeightedFeeder.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/feed/WeightedFeeder.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include diff --git a/include/ffnn/feed/SmartBetaGenerator.hpp b/include/ffnn/feed/SmartBetaGenerator.hpp index 6fb2751..5c283b2 100644 --- a/include/ffnn/feed/SmartBetaGenerator.hpp +++ b/include/ffnn/feed/SmartBetaGenerator.hpp @@ -1,10 +1,10 @@ #ifndef SMART_BETA_GENERATOR #define SMART_BETA_GENERATOR -#include "FeedForwardNeuralNetwork.hpp" -#include "FedLayer.hpp" -#include "FeederInterface.hpp" -#include "NNRay.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/layer/FedLayer.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/feed/NNRay.hpp" namespace smart_beta { diff --git a/include/ffnn/feed/StaticFeeder.hpp b/include/ffnn/feed/StaticFeeder.hpp index 9d809fb..4de935c 100644 --- a/include/ffnn/feed/StaticFeeder.hpp +++ b/include/ffnn/feed/StaticFeeder.hpp @@ -1,9 +1,9 @@ #ifndef STATIC_FEEDER #define STATIC_FEEDER -#include "FeederInterface.hpp" -#include "NetworkUnit.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include #include diff --git a/include/ffnn/feed/VariableFeeder.hpp b/include/ffnn/feed/VariableFeeder.hpp index 64315e5..bb2c6f7 100644 --- a/include/ffnn/feed/VariableFeeder.hpp +++ b/include/ffnn/feed/VariableFeeder.hpp @@ -1,9 +1,9 @@ #ifndef VARIABLE_FEEDER #define VARIABLE_FEEDER -#include "FeederInterface.hpp" -#include "NetworkUnit.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include #include diff --git a/include/ffnn/feed/WeightedFeeder.hpp b/include/ffnn/feed/WeightedFeeder.hpp index 9a46afa..6f56d3c 100644 --- a/include/ffnn/feed/WeightedFeeder.hpp +++ b/include/ffnn/feed/WeightedFeeder.hpp @@ -1,9 +1,9 @@ #ifndef WEIGHTED_FEEDER #define WEIGHTED_FEEDER -#include "VariableFeeder.hpp" -#include "NetworkUnit.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/feed/VariableFeeder.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include #include diff --git a/include/ffnn/fmap/ActivationMapUnit.hpp b/include/ffnn/fmap/ActivationMapUnit.hpp index c89e26f..f47c943 100644 --- a/include/ffnn/fmap/ActivationMapUnit.hpp +++ b/include/ffnn/fmap/ActivationMapUnit.hpp @@ -1,8 +1,8 @@ #ifndef ACTIVATION_MAP_UNIT #define ACTIVATION_MAP_UNIT -#include "FedActivationUnit.hpp" -#include "FeederInterface.hpp" +#include "ffnn/unit/FedActivationUnit.hpp" +#include "ffnn/feed/FeederInterface.hpp" #include #include diff --git a/include/ffnn/fmap/EuclideanDistanceMap.hpp b/include/ffnn/fmap/EuclideanDistanceMap.hpp index 8d56525..3f7e6e7 100644 --- a/include/ffnn/fmap/EuclideanDistanceMap.hpp +++ b/include/ffnn/fmap/EuclideanDistanceMap.hpp @@ -1,8 +1,8 @@ #ifndef EUCLIDEAN_DISTANCE_MAP #define EUCLIDEAN_DISTANCE_MAP -#include "MultiDimStaticMap.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/fmap/MultiDimStaticMap.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include #include diff --git a/include/ffnn/fmap/EuclideanDistanceMapUnit.hpp b/include/ffnn/fmap/EuclideanDistanceMapUnit.hpp index d0726bb..6df2d51 100644 --- a/include/ffnn/fmap/EuclideanDistanceMapUnit.hpp +++ b/include/ffnn/fmap/EuclideanDistanceMapUnit.hpp @@ -1,8 +1,8 @@ #ifndef EUCLIDEAN_DISTANCE_MAP_UNIT #define EUCLIDEAN_DISTANCE_MAP_UNIT -#include "FeatureMapUnit.hpp" -#include "EuclideanDistanceMap.hpp" +#include "ffnn/fmap/FeatureMapUnit.hpp" +#include "ffnn/fmap/EuclideanDistanceMap.hpp" #include diff --git a/include/ffnn/fmap/EuclideanPairDistanceMap.hpp b/include/ffnn/fmap/EuclideanPairDistanceMap.hpp index cb76f5b..42a7a6a 100644 --- a/include/ffnn/fmap/EuclideanPairDistanceMap.hpp +++ b/include/ffnn/fmap/EuclideanPairDistanceMap.hpp @@ -1,8 +1,8 @@ #ifndef EUCLIDEAN_PAIR_DISTANCE_MAP #define EUCLIDEAN_PAIR_DISTANCE_MAP -#include "MultiDimStaticMap.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/fmap/MultiDimStaticMap.hpp" +#include "ffnn/layer/NetworkLayer.hpp" // takes coordinates on input side and calculates squared euclidean distance of a pair class EuclideanPairDistanceMap: public MultiDimStaticMap diff --git a/include/ffnn/fmap/EuclideanPairDistanceMapUnit.hpp b/include/ffnn/fmap/EuclideanPairDistanceMapUnit.hpp index 704944b..04e3ec0 100644 --- a/include/ffnn/fmap/EuclideanPairDistanceMapUnit.hpp +++ b/include/ffnn/fmap/EuclideanPairDistanceMapUnit.hpp @@ -1,8 +1,8 @@ #ifndef EUCLIDEAN_PAIR_DISTANCE_MAP_UNIT #define EUCLIDEAN_PAIR_DISTANCE_MAP_UNIT -#include "FeatureMapUnit.hpp" -#include "EuclideanPairDistanceMap.hpp" +#include "ffnn/fmap/FeatureMapUnit.hpp" +#include "ffnn/fmap/EuclideanPairDistanceMap.hpp" #include diff --git a/include/ffnn/fmap/FeatureMapLayer.hpp b/include/ffnn/fmap/FeatureMapLayer.hpp index b6aaaeb..c8878bc 100644 --- a/include/ffnn/fmap/FeatureMapLayer.hpp +++ b/include/ffnn/fmap/FeatureMapLayer.hpp @@ -1,15 +1,15 @@ #ifndef FEATURE_MAP_LAYER #define FEATURE_MAP_LAYER -#include "NetworkLayer.hpp" -#include "FedLayer.hpp" -#include "FedUnit.hpp" - -#include "PairSumMapUnit.hpp" -#include "PairDifferenceMapUnit.hpp" -#include "EuclideanDistanceMapUnit.hpp" -#include "EuclideanPairDistanceMapUnit.hpp" -#include "IdentityMapUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" +#include "ffnn/layer/FedLayer.hpp" +#include "ffnn/unit/FedUnit.hpp" + +#include "ffnn/fmap/PairSumMapUnit.hpp" +#include "ffnn/fmap/PairDifferenceMapUnit.hpp" +#include "ffnn/fmap/EuclideanDistanceMapUnit.hpp" +#include "ffnn/fmap/EuclideanPairDistanceMapUnit.hpp" +#include "ffnn/fmap/IdentityMapUnit.hpp" class FeatureMapLayer: public FedLayer { diff --git a/include/ffnn/fmap/FeatureMapUnit.hpp b/include/ffnn/fmap/FeatureMapUnit.hpp index c6bf108..0e1f18f 100644 --- a/include/ffnn/fmap/FeatureMapUnit.hpp +++ b/include/ffnn/fmap/FeatureMapUnit.hpp @@ -1,8 +1,8 @@ #ifndef FEATURE_MAP_UNIT #define FEATURE_MAP_UNIT -#include "FedUnit.hpp" -#include "FeederInterface.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/feed/FeederInterface.hpp" #include #include diff --git a/include/ffnn/fmap/IdentityMap.hpp b/include/ffnn/fmap/IdentityMap.hpp index 3dd8314..b93cb18 100644 --- a/include/ffnn/fmap/IdentityMap.hpp +++ b/include/ffnn/fmap/IdentityMap.hpp @@ -1,9 +1,9 @@ #ifndef IDENTITY_MAP #define IDENTITY_MAP -#include "OneDimStaticMap.hpp" -#include "NetworkUnit.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/fmap/OneDimStaticMap.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include #include // NULL diff --git a/include/ffnn/fmap/IdentityMapUnit.hpp b/include/ffnn/fmap/IdentityMapUnit.hpp index e1ff473..af9bb68 100644 --- a/include/ffnn/fmap/IdentityMapUnit.hpp +++ b/include/ffnn/fmap/IdentityMapUnit.hpp @@ -1,8 +1,8 @@ #ifndef IDENTITY_MAP_UNIT #define IDENTITY_MAP_UNIT -#include "FeatureMapUnit.hpp" -#include "IdentityMap.hpp" +#include "ffnn/fmap/FeatureMapUnit.hpp" +#include "ffnn/fmap/IdentityMap.hpp" #include diff --git a/include/ffnn/fmap/MultiDimStaticMap.hpp b/include/ffnn/fmap/MultiDimStaticMap.hpp index 17128bb..4317ce3 100644 --- a/include/ffnn/fmap/MultiDimStaticMap.hpp +++ b/include/ffnn/fmap/MultiDimStaticMap.hpp @@ -1,8 +1,8 @@ #ifndef MULTI_DIM_STATIC_MAP #define MULTI_DIM_STATIC_MAP -#include "StaticFeeder.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/feed/StaticFeeder.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include diff --git a/include/ffnn/fmap/OneDimStaticMap.hpp b/include/ffnn/fmap/OneDimStaticMap.hpp index 4f00485..e12c397 100644 --- a/include/ffnn/fmap/OneDimStaticMap.hpp +++ b/include/ffnn/fmap/OneDimStaticMap.hpp @@ -1,8 +1,8 @@ #ifndef ONE_DIM_STATIC_MAP #define ONE_DIM_STATIC_MAP -#include "StaticFeeder.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/feed/StaticFeeder.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include diff --git a/include/ffnn/fmap/PairDifferenceMap.hpp b/include/ffnn/fmap/PairDifferenceMap.hpp index 128a93d..0ea7c67 100644 --- a/include/ffnn/fmap/PairDifferenceMap.hpp +++ b/include/ffnn/fmap/PairDifferenceMap.hpp @@ -1,9 +1,9 @@ #ifndef PAIR_DIFFERENCE_MAP #define PAIR_DIFFERENCE_MAP -#include "OneDimStaticMap.hpp" -#include "NetworkUnit.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/fmap/OneDimStaticMap.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include #include // NULL diff --git a/include/ffnn/fmap/PairDifferenceMapUnit.hpp b/include/ffnn/fmap/PairDifferenceMapUnit.hpp index e310e3e..def2bc9 100644 --- a/include/ffnn/fmap/PairDifferenceMapUnit.hpp +++ b/include/ffnn/fmap/PairDifferenceMapUnit.hpp @@ -1,8 +1,8 @@ #ifndef PAIR_DIFFERENCE_MAP_UNIT #define PAIR_DIFFERENCE_MAP_UNIT -#include "FeatureMapUnit.hpp" -#include "PairDifferenceMap.hpp" +#include "ffnn/fmap/FeatureMapUnit.hpp" +#include "ffnn/fmap/PairDifferenceMap.hpp" #include diff --git a/include/ffnn/fmap/PairSumMap.hpp b/include/ffnn/fmap/PairSumMap.hpp index ecf3925..c7f7de5 100644 --- a/include/ffnn/fmap/PairSumMap.hpp +++ b/include/ffnn/fmap/PairSumMap.hpp @@ -1,9 +1,9 @@ #ifndef PAIR_SUM_MAP #define PAIR_SUM_MAP -#include "OneDimStaticMap.hpp" -#include "NetworkUnit.hpp" -#include "NetworkLayer.hpp" +#include "ffnn/fmap/OneDimStaticMap.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" #include #include // NULL diff --git a/include/ffnn/fmap/PairSumMapUnit.hpp b/include/ffnn/fmap/PairSumMapUnit.hpp index 9b47013..eab6798 100644 --- a/include/ffnn/fmap/PairSumMapUnit.hpp +++ b/include/ffnn/fmap/PairSumMapUnit.hpp @@ -1,8 +1,8 @@ #ifndef PAIR_SUM_MAP_UNIT #define PAIR_SUM_MAP_UNIT -#include "FeatureMapUnit.hpp" -#include "PairSumMap.hpp" +#include "ffnn/fmap/FeatureMapUnit.hpp" +#include "ffnn/fmap/PairSumMap.hpp" #include diff --git a/include/ffnn/io/PrintUtilities.hpp b/include/ffnn/io/PrintUtilities.hpp index 875beab..d6bb1dd 100644 --- a/include/ffnn/io/PrintUtilities.hpp +++ b/include/ffnn/io/PrintUtilities.hpp @@ -2,7 +2,7 @@ #define PRINT_UTILITIES -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" #include diff --git a/include/ffnn/layer/FedLayer.hpp b/include/ffnn/layer/FedLayer.hpp index 171ef10..f323948 100644 --- a/include/ffnn/layer/FedLayer.hpp +++ b/include/ffnn/layer/FedLayer.hpp @@ -1,8 +1,8 @@ #ifndef FED_NETWORK_LAYER #define FED_NETWORK_LAYER -#include "FedUnit.hpp" -#include "NNRay.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/feed/NNRay.hpp" #include diff --git a/include/ffnn/layer/InputLayer.hpp b/include/ffnn/layer/InputLayer.hpp index c719822..6e96825 100644 --- a/include/ffnn/layer/InputLayer.hpp +++ b/include/ffnn/layer/InputLayer.hpp @@ -1,8 +1,8 @@ #ifndef INPUT_LAYER #define INPUT_LAYER -#include "NetworkLayer.hpp" -#include "InputUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" +#include "ffnn/unit/InputUnit.hpp" #include #include diff --git a/include/ffnn/layer/NNLayer.hpp b/include/ffnn/layer/NNLayer.hpp index a871ac8..7740964 100644 --- a/include/ffnn/layer/NNLayer.hpp +++ b/include/ffnn/layer/NNLayer.hpp @@ -1,13 +1,13 @@ #ifndef NN_LAYER #define NN_LAYER -#include "FedLayer.hpp" -#include "NetworkLayer.hpp" -#include "NNUnit.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" -#include "FeederInterface.hpp" -#include "NNRay.hpp" +#include "ffnn/layer/FedLayer.hpp" +#include "ffnn/layer/NetworkLayer.hpp" +#include "ffnn/unit/NNUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/feed/NNRay.hpp" #include #include diff --git a/include/ffnn/layer/NetworkLayer.hpp b/include/ffnn/layer/NetworkLayer.hpp index 136bb9b..4edbc65 100644 --- a/include/ffnn/layer/NetworkLayer.hpp +++ b/include/ffnn/layer/NetworkLayer.hpp @@ -1,10 +1,10 @@ #ifndef NETWORK_LAYER #define NETWORK_LAYER -#include "SerializableComponent.hpp" -#include "StringCodeUtilities.hpp" -#include "NetworkUnit.hpp" -#include "OffsetUnit.hpp" +#include "ffnn/serial/SerializableComponent.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/unit/OffsetUnit.hpp" #include #include diff --git a/include/ffnn/layer/OutputNNLayer.hpp b/include/ffnn/layer/OutputNNLayer.hpp index 935486f..1fb69f4 100644 --- a/include/ffnn/layer/OutputNNLayer.hpp +++ b/include/ffnn/layer/OutputNNLayer.hpp @@ -1,10 +1,10 @@ #ifndef OUTPUT_NN_LAYER #define OUTPUT_NN_LAYER -#include "NNLayer.hpp" -#include "OutputNNUnit.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" +#include "ffnn/layer/NNLayer.hpp" +#include "ffnn/unit/OutputNNUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" #include #include diff --git a/include/ffnn/net/FeedForwardNeuralNetwork.hpp b/include/ffnn/net/FeedForwardNeuralNetwork.hpp index c6ac107..5cf90b7 100644 --- a/include/ffnn/net/FeedForwardNeuralNetwork.hpp +++ b/include/ffnn/net/FeedForwardNeuralNetwork.hpp @@ -1,14 +1,14 @@ #ifndef FEED_FORWARD_NEURAL_NETWORK #define FEED_FORWARD_NEURAL_NETWORK -#include "ActivationFunctionInterface.hpp" -#include "NetworkLayer.hpp" -#include "InputLayer.hpp" -#include "FedLayer.hpp" -#include "NNLayer.hpp" -#include "OutputNNLayer.hpp" -#include "FeatureMapLayer.hpp" -#include "NetworkUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/layer/NetworkLayer.hpp" +#include "ffnn/layer/InputLayer.hpp" +#include "ffnn/layer/FedLayer.hpp" +#include "ffnn/layer/NNLayer.hpp" +#include "ffnn/layer/OutputNNLayer.hpp" +#include "ffnn/fmap/FeatureMapLayer.hpp" +#include "ffnn/unit/NetworkUnit.hpp" #include #include diff --git a/include/ffnn/serial/SerializableComponent.hpp b/include/ffnn/serial/SerializableComponent.hpp index 8c84b61..cd7fb86 100644 --- a/include/ffnn/serial/SerializableComponent.hpp +++ b/include/ffnn/serial/SerializableComponent.hpp @@ -1,7 +1,7 @@ #ifndef SERIALIZABLE_COMPONENT #define SERIALIZABLE_COMPONENT -#include "StringCodeUtilities.hpp" // for functions on stringCodes, look there for documentation about stringCodes +#include "ffnn/serial/StringCodeUtilities.hpp" // for functions on stringCodes, look there for documentation about stringCodes #include diff --git a/include/ffnn/train/NNTrainer.hpp b/include/ffnn/train/NNTrainer.hpp index 25ca0b2..36cf4d3 100644 --- a/include/ffnn/train/NNTrainer.hpp +++ b/include/ffnn/train/NNTrainer.hpp @@ -1,10 +1,10 @@ #ifndef NN_TRAINER #define NN_TRAINER -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" -#include "NNTrainingData.hpp" -#include "NNTrainingConfig.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" +#include "ffnn/train/NNTrainingData.hpp" +#include "ffnn/train/NNTrainingConfig.hpp" #include #include // NULL diff --git a/include/ffnn/train/NNTrainerGSL.hpp b/include/ffnn/train/NNTrainerGSL.hpp index 7769254..60b380b 100644 --- a/include/ffnn/train/NNTrainerGSL.hpp +++ b/include/ffnn/train/NNTrainerGSL.hpp @@ -1,10 +1,10 @@ #ifndef NN_TRAINER_GSL #define NN_TRAINER_GSL -#include "NNTrainer.hpp" -#include "NNTrainingData.hpp" -#include "NNTrainingConfig.hpp" -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/train/NNTrainer.hpp" +#include "ffnn/train/NNTrainingData.hpp" +#include "ffnn/train/NNTrainingConfig.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" #include diff --git a/include/ffnn/train/NNTrainingConfig.hpp b/include/ffnn/train/NNTrainingConfig.hpp index 0d7064e..9bf7f84 100644 --- a/include/ffnn/train/NNTrainingConfig.hpp +++ b/include/ffnn/train/NNTrainingConfig.hpp @@ -1,7 +1,7 @@ #ifndef NN_TRAINING_CONFIG #define NN_TRAINING_CONFIG -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" // holds the required configuration parameters for the trainer struct NNTrainingConfig { diff --git a/include/ffnn/unit/ActivationUnit.hpp b/include/ffnn/unit/ActivationUnit.hpp index 13f1e6d..493f28e 100644 --- a/include/ffnn/unit/ActivationUnit.hpp +++ b/include/ffnn/unit/ActivationUnit.hpp @@ -1,9 +1,9 @@ #ifndef ACTIVATION_UNIT #define ACTIVATION_UNIT -#include "NetworkUnit.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" #include #include diff --git a/include/ffnn/unit/FedActivationUnit.hpp b/include/ffnn/unit/FedActivationUnit.hpp index a6d74f1..3a3dc87 100644 --- a/include/ffnn/unit/FedActivationUnit.hpp +++ b/include/ffnn/unit/FedActivationUnit.hpp @@ -1,11 +1,11 @@ #ifndef FED_ACTIVATION_UNIT #define FED_ACTIVATION_UNIT -#include "FedUnit.hpp" -#include "ActivationUnit.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" -#include "FeederInterface.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/unit/ActivationUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/feed/FeederInterface.hpp" #include diff --git a/include/ffnn/unit/FedUnit.hpp b/include/ffnn/unit/FedUnit.hpp index 8a4d38a..1fc6fd9 100644 --- a/include/ffnn/unit/FedUnit.hpp +++ b/include/ffnn/unit/FedUnit.hpp @@ -1,8 +1,8 @@ #ifndef FED_UNIT #define FED_UNIT -#include "NetworkUnit.hpp" -#include "FeederInterface.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/feed/FeederInterface.hpp" #include #include // for NULL diff --git a/include/ffnn/unit/InputUnit.hpp b/include/ffnn/unit/InputUnit.hpp index 252e845..fa0a4a2 100644 --- a/include/ffnn/unit/InputUnit.hpp +++ b/include/ffnn/unit/InputUnit.hpp @@ -1,7 +1,7 @@ #ifndef INPUT_UNIT #define INPUT_UNIT -#include "ShifterScalerUnit.hpp" +#include "ffnn/unit/ShifterScalerUnit.hpp" #include // Input Unit diff --git a/include/ffnn/unit/NNUnit.hpp b/include/ffnn/unit/NNUnit.hpp index f393c63..8e1678b 100644 --- a/include/ffnn/unit/NNUnit.hpp +++ b/include/ffnn/unit/NNUnit.hpp @@ -1,11 +1,11 @@ #ifndef NN_UNIT #define NN_UNIT -#include "FedActivationUnit.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" -#include "FeederInterface.hpp" -#include "NNRay.hpp" +#include "ffnn/unit/FedActivationUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/feed/NNRay.hpp" #include #include diff --git a/include/ffnn/unit/NetworkUnit.hpp b/include/ffnn/unit/NetworkUnit.hpp index fc79d15..a81974a 100644 --- a/include/ffnn/unit/NetworkUnit.hpp +++ b/include/ffnn/unit/NetworkUnit.hpp @@ -1,8 +1,8 @@ #ifndef NETWORK_UNIT #define NETWORK_UNIT -#include "SerializableComponent.hpp" -#include "FeederInterface.hpp" +#include "ffnn/serial/SerializableComponent.hpp" +#include "ffnn/feed/FeederInterface.hpp" #include #include // for NULL diff --git a/include/ffnn/unit/OffsetUnit.hpp b/include/ffnn/unit/OffsetUnit.hpp index 80c3a98..58c6c8f 100644 --- a/include/ffnn/unit/OffsetUnit.hpp +++ b/include/ffnn/unit/OffsetUnit.hpp @@ -1,7 +1,7 @@ #ifndef OFFSET_UNIT #define OFFSET_UNIT -#include "NetworkUnit.hpp" +#include "ffnn/unit/NetworkUnit.hpp" // Offset Unit class OffsetUnit: public NetworkUnit diff --git a/include/ffnn/unit/OutputNNUnit.hpp b/include/ffnn/unit/OutputNNUnit.hpp index ef8db67..ae1d7f1 100644 --- a/include/ffnn/unit/OutputNNUnit.hpp +++ b/include/ffnn/unit/OutputNNUnit.hpp @@ -1,9 +1,9 @@ #ifndef OUTPUT_NN_UNIT #define OUTPUT_NN_UNIT -#include "ShifterScalerNNUnit.hpp" -#include "ActivationFunctionManager.hpp" -#include "NNRay.hpp" +#include "ffnn/unit/ShifterScalerNNUnit.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/feed/NNRay.hpp" // Output Neural Network Unit class OutputNNUnit: public ShifterScalerNNUnit diff --git a/include/ffnn/unit/ShifterScalerNNUnit.hpp b/include/ffnn/unit/ShifterScalerNNUnit.hpp index bcb53bb..28e3204 100644 --- a/include/ffnn/unit/ShifterScalerNNUnit.hpp +++ b/include/ffnn/unit/ShifterScalerNNUnit.hpp @@ -1,11 +1,11 @@ #ifndef SHIFTER_SCALER_NN_UNIT #define SHIFTER_SCALER_NN_UNIT -#include "ShifterScalerUnit.hpp" -#include "NNUnit.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" -#include "NNRay.hpp" +#include "ffnn/unit/ShifterScalerUnit.hpp" +#include "ffnn/unit/NNUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/feed/NNRay.hpp" #include // for NULL #include diff --git a/include/ffnn/unit/ShifterScalerUnit.hpp b/include/ffnn/unit/ShifterScalerUnit.hpp index 7a3f3f5..d8cd9f1 100644 --- a/include/ffnn/unit/ShifterScalerUnit.hpp +++ b/include/ffnn/unit/ShifterScalerUnit.hpp @@ -1,8 +1,8 @@ #ifndef SHIFTER_SCALER_UNIT #define SHIFTER_SCALER_UNIT -#include "NetworkUnit.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include diff --git a/src/actf/ActivationFunctionManager.cpp b/src/actf/ActivationFunctionManager.cpp index d959b8a..6093c34 100644 --- a/src/actf/ActivationFunctionManager.cpp +++ b/src/actf/ActivationFunctionManager.cpp @@ -1,4 +1,4 @@ -#include "ActivationFunctionManager.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" #include diff --git a/src/actf/ExponentialActivationFunction.cpp b/src/actf/ExponentialActivationFunction.cpp index fbf413d..137305a 100644 --- a/src/actf/ExponentialActivationFunction.cpp +++ b/src/actf/ExponentialActivationFunction.cpp @@ -1,4 +1,4 @@ -#include "ExponentialActivationFunction.hpp" +#include "ffnn/actf/ExponentialActivationFunction.hpp" #include diff --git a/src/actf/GaussianActivationFunction.cpp b/src/actf/GaussianActivationFunction.cpp index d540f3c..b2f0091 100644 --- a/src/actf/GaussianActivationFunction.cpp +++ b/src/actf/GaussianActivationFunction.cpp @@ -1,4 +1,4 @@ -#include "GaussianActivationFunction.hpp" +#include "ffnn/actf/GaussianActivationFunction.hpp" #include diff --git a/src/actf/LogisticActivationFunction.cpp b/src/actf/LogisticActivationFunction.cpp index b90601e..3712b8b 100644 --- a/src/actf/LogisticActivationFunction.cpp +++ b/src/actf/LogisticActivationFunction.cpp @@ -1,4 +1,4 @@ -#include "LogisticActivationFunction.hpp" +#include "ffnn/actf/LogisticActivationFunction.hpp" #include diff --git a/src/actf/ReLUActivationFunction.cpp b/src/actf/ReLUActivationFunction.cpp index fe84718..7320ba4 100644 --- a/src/actf/ReLUActivationFunction.cpp +++ b/src/actf/ReLUActivationFunction.cpp @@ -1,5 +1,5 @@ -#include "ReLUActivationFunction.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/actf/ReLUActivationFunction.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/actf/SELUActivationFunction.cpp b/src/actf/SELUActivationFunction.cpp index e9399fc..19682b9 100644 --- a/src/actf/SELUActivationFunction.cpp +++ b/src/actf/SELUActivationFunction.cpp @@ -1,5 +1,5 @@ -#include "SELUActivationFunction.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/actf/SELUActivationFunction.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/actf/SRLUActivationFunction.cpp b/src/actf/SRLUActivationFunction.cpp index 7a08c51..813c3be 100644 --- a/src/actf/SRLUActivationFunction.cpp +++ b/src/actf/SRLUActivationFunction.cpp @@ -1,4 +1,4 @@ -#include "SRLUActivationFunction.hpp" +#include "ffnn/actf/SRLUActivationFunction.hpp" #include diff --git a/src/actf/SineActivationFunction.cpp b/src/actf/SineActivationFunction.cpp index 9f1422c..50c5170 100644 --- a/src/actf/SineActivationFunction.cpp +++ b/src/actf/SineActivationFunction.cpp @@ -1,4 +1,4 @@ -#include "SineActivationFunction.hpp" +#include "ffnn/actf/SineActivationFunction.hpp" #include diff --git a/src/actf/TanSigmoidActivationFunction.cpp b/src/actf/TanSigmoidActivationFunction.cpp index c6e0465..bf3251d 100644 --- a/src/actf/TanSigmoidActivationFunction.cpp +++ b/src/actf/TanSigmoidActivationFunction.cpp @@ -1,4 +1,4 @@ -#include "TanSigmoidActivationFunction.hpp" +#include "ffnn/actf/TanSigmoidActivationFunction.hpp" #include diff --git a/src/feed/FeederInterface.cpp b/src/feed/FeederInterface.cpp index 72b4f7e..e34c615 100644 --- a/src/feed/FeederInterface.cpp +++ b/src/feed/FeederInterface.cpp @@ -1,7 +1,7 @@ -#include "FeederInterface.hpp" -#include "NetworkLayer.hpp" -#include "NetworkUnit.hpp" -#include "FedUnit.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/layer/NetworkLayer.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/unit/FedUnit.hpp" #include // --- Base Destructor diff --git a/src/feed/NNRay.cpp b/src/feed/NNRay.cpp index a608f34..969f54b 100644 --- a/src/feed/NNRay.cpp +++ b/src/feed/NNRay.cpp @@ -1,6 +1,6 @@ -#include "NNRay.hpp" -#include "NetworkUnit.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/feed/NNRay.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/feed/SmartBetaGenerator.cpp b/src/feed/SmartBetaGenerator.cpp index f9bdb08..ca33019 100644 --- a/src/feed/SmartBetaGenerator.cpp +++ b/src/feed/SmartBetaGenerator.cpp @@ -1,11 +1,11 @@ -#include "SmartBetaGenerator.hpp" - -#include "ActivationFunctionInterface.hpp" -#include "NetworkUnit.hpp" -#include "FedUnit.hpp" -#include "NNUnit.hpp" -#include "FeederInterface.hpp" -#include "NNRay.hpp" +#include "ffnn/feed/SmartBetaGenerator.hpp" + +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/unit/NetworkUnit.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/unit/NNUnit.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/feed/NNRay.hpp" #include #include diff --git a/src/feed/VariableFeeder.cpp b/src/feed/VariableFeeder.cpp index fa90c4d..ff818a8 100644 --- a/src/feed/VariableFeeder.cpp +++ b/src/feed/VariableFeeder.cpp @@ -1,4 +1,4 @@ -#include "VariableFeeder.hpp" +#include "ffnn/feed/VariableFeeder.hpp" #include diff --git a/src/feed/WeightedFeeder.cpp b/src/feed/WeightedFeeder.cpp index 35265cf..4121f95 100644 --- a/src/feed/WeightedFeeder.cpp +++ b/src/feed/WeightedFeeder.cpp @@ -1,4 +1,4 @@ -#include "WeightedFeeder.hpp" +#include "ffnn/feed/WeightedFeeder.hpp" // --- clear method diff --git a/src/fmap/EuclideanDistanceMap.cpp b/src/fmap/EuclideanDistanceMap.cpp index e4167f9..5724fec 100644 --- a/src/fmap/EuclideanDistanceMap.cpp +++ b/src/fmap/EuclideanDistanceMap.cpp @@ -1,6 +1,6 @@ -#include "EuclideanDistanceMap.hpp" -#include "StringCodeUtilities.hpp" -#include "NetworkUnit.hpp" +#include "ffnn/fmap/EuclideanDistanceMap.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" +#include "ffnn/unit/NetworkUnit.hpp" #include #include diff --git a/src/fmap/EuclideanPairDistanceMap.cpp b/src/fmap/EuclideanPairDistanceMap.cpp index 8fb5df3..816c3ea 100644 --- a/src/fmap/EuclideanPairDistanceMap.cpp +++ b/src/fmap/EuclideanPairDistanceMap.cpp @@ -1,6 +1,6 @@ -#include "EuclideanPairDistanceMap.hpp" -#include "StringCodeUtilities.hpp" -#include "NetworkUnit.hpp" +#include "ffnn/fmap/EuclideanPairDistanceMap.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" +#include "ffnn/unit/NetworkUnit.hpp" #include #include diff --git a/src/fmap/FeatureMapLayer.cpp b/src/fmap/FeatureMapLayer.cpp index 0d29fa3..35053ae 100644 --- a/src/fmap/FeatureMapLayer.cpp +++ b/src/fmap/FeatureMapLayer.cpp @@ -1,7 +1,7 @@ -#include "FeatureMapLayer.hpp" -#include "NetworkLayer.hpp" -#include "FedUnit.hpp" -#include "FeederInterface.hpp" +#include "ffnn/fmap/FeatureMapLayer.hpp" +#include "ffnn/layer/NetworkLayer.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/feed/FeederInterface.hpp" #include diff --git a/src/fmap/IdentityMap.cpp b/src/fmap/IdentityMap.cpp index af71ded..57bb13c 100644 --- a/src/fmap/IdentityMap.cpp +++ b/src/fmap/IdentityMap.cpp @@ -1,5 +1,5 @@ -#include "IdentityMap.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/fmap/IdentityMap.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/fmap/MultiDimStaticMap.cpp b/src/fmap/MultiDimStaticMap.cpp index d710ceb..2fd9fa0 100644 --- a/src/fmap/MultiDimStaticMap.cpp +++ b/src/fmap/MultiDimStaticMap.cpp @@ -1,6 +1,6 @@ -#include "MultiDimStaticMap.hpp" -#include "StringCodeUtilities.hpp" -#include "NetworkUnit.hpp" +#include "ffnn/fmap/MultiDimStaticMap.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" +#include "ffnn/unit/NetworkUnit.hpp" #include #include diff --git a/src/fmap/OneDimStaticMap.cpp b/src/fmap/OneDimStaticMap.cpp index 2ea884c..12989c0 100644 --- a/src/fmap/OneDimStaticMap.cpp +++ b/src/fmap/OneDimStaticMap.cpp @@ -1,6 +1,6 @@ -#include "OneDimStaticMap.hpp" -#include "StringCodeUtilities.hpp" -#include "NetworkUnit.hpp" +#include "ffnn/fmap/OneDimStaticMap.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" +#include "ffnn/unit/NetworkUnit.hpp" #include #include diff --git a/src/fmap/PairDifferenceMap.cpp b/src/fmap/PairDifferenceMap.cpp index 64855a6..d6a7f13 100644 --- a/src/fmap/PairDifferenceMap.cpp +++ b/src/fmap/PairDifferenceMap.cpp @@ -1,5 +1,5 @@ -#include "PairDifferenceMap.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/fmap/PairDifferenceMap.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/fmap/PairSumMap.cpp b/src/fmap/PairSumMap.cpp index ebc7b48..25c34aa 100644 --- a/src/fmap/PairSumMap.cpp +++ b/src/fmap/PairSumMap.cpp @@ -1,5 +1,5 @@ -#include "PairSumMap.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/fmap/PairSumMap.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/io/PrintUtilities.cpp b/src/io/PrintUtilities.cpp index c705dbf..a061eb5 100644 --- a/src/io/PrintUtilities.cpp +++ b/src/io/PrintUtilities.cpp @@ -1,7 +1,7 @@ -#include "PrintUtilities.hpp" -#include "FeederInterface.hpp" -#include "FedUnit.hpp" -#include "NNUnit.hpp" +#include "ffnn/io/PrintUtilities.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/unit/NNUnit.hpp" #include #include diff --git a/src/layer/FedLayer.cpp b/src/layer/FedLayer.cpp index 2c3cd08..f488033 100644 --- a/src/layer/FedLayer.cpp +++ b/src/layer/FedLayer.cpp @@ -1,6 +1,6 @@ -#include "FedLayer.hpp" -#include "FeederInterface.hpp" -#include "FedUnit.hpp" +#include "ffnn/layer/FedLayer.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/unit/FedUnit.hpp" #include diff --git a/src/layer/InputLayer.cpp b/src/layer/InputLayer.cpp index dc1283c..5d542aa 100644 --- a/src/layer/InputLayer.cpp +++ b/src/layer/InputLayer.cpp @@ -1,5 +1,5 @@ -#include "InputLayer.hpp" -#include "InputUnit.hpp" +#include "ffnn/layer/InputLayer.hpp" +#include "ffnn/unit/InputUnit.hpp" // --- Register Unit diff --git a/src/layer/NNLayer.cpp b/src/layer/NNLayer.cpp index a7b4609..4f45946 100644 --- a/src/layer/NNLayer.cpp +++ b/src/layer/NNLayer.cpp @@ -1,8 +1,8 @@ -#include "NNLayer.hpp" +#include "ffnn/layer/NNLayer.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" -#include "NNUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/unit/NNUnit.hpp" // --- Register Unit diff --git a/src/layer/NetworkLayer.cpp b/src/layer/NetworkLayer.cpp index 8453907..0cbc85b 100644 --- a/src/layer/NetworkLayer.cpp +++ b/src/layer/NetworkLayer.cpp @@ -1,6 +1,6 @@ -#include "NetworkLayer.hpp" -#include "OffsetUnit.hpp" -#include "NetworkUnit.hpp" +#include "ffnn/layer/NetworkLayer.hpp" +#include "ffnn/unit/OffsetUnit.hpp" +#include "ffnn/unit/NetworkUnit.hpp" #include #include diff --git a/src/layer/OutputNNLayer.cpp b/src/layer/OutputNNLayer.cpp index df2711c..de630d9 100644 --- a/src/layer/OutputNNLayer.cpp +++ b/src/layer/OutputNNLayer.cpp @@ -1,8 +1,8 @@ -#include "OutputNNLayer.hpp" +#include "ffnn/layer/OutputNNLayer.hpp" -#include "ActivationFunctionInterface.hpp" -#include "ActivationFunctionManager.hpp" -#include "OutputNNUnit.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/unit/OutputNNUnit.hpp" // --- Register Unit diff --git a/src/net/FeedForwardNeuralNetwork.cpp b/src/net/FeedForwardNeuralNetwork.cpp index 902066c..d5d93eb 100644 --- a/src/net/FeedForwardNeuralNetwork.cpp +++ b/src/net/FeedForwardNeuralNetwork.cpp @@ -1,8 +1,8 @@ -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" -#include "NNUnit.hpp" -#include "ActivationFunctionManager.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/unit/NNUnit.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/serial/StringCodeUtilities.cpp b/src/serial/StringCodeUtilities.cpp index ffec457..91a3581 100644 --- a/src/serial/StringCodeUtilities.cpp +++ b/src/serial/StringCodeUtilities.cpp @@ -1,4 +1,4 @@ -#include "StringCodeUtilities.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/src/train/NNTrainer.cpp b/src/train/NNTrainer.cpp index 4db21c1..d5123db 100644 --- a/src/train/NNTrainer.cpp +++ b/src/train/NNTrainer.cpp @@ -1,5 +1,5 @@ -#include "NNTrainer.hpp" -#include "SmartBetaGenerator.hpp" +#include "ffnn/train/NNTrainer.hpp" +#include "ffnn/feed/SmartBetaGenerator.hpp" #include #include diff --git a/src/train/NNTrainerGSL.cpp b/src/train/NNTrainerGSL.cpp index 22fd6aa..371d2c0 100644 --- a/src/train/NNTrainerGSL.cpp +++ b/src/train/NNTrainerGSL.cpp @@ -1,4 +1,4 @@ -#include "NNTrainerGSL.hpp" +#include "ffnn/train/NNTrainerGSL.hpp" #include #include diff --git a/src/unit/ActivationUnit.cpp b/src/unit/ActivationUnit.cpp index 445623f..2d70213 100644 --- a/src/unit/ActivationUnit.cpp +++ b/src/unit/ActivationUnit.cpp @@ -1,6 +1,6 @@ -#include "ActivationUnit.hpp" -#include "StringCodeUtilities.hpp" -#include "ActivationFunctionManager.hpp" +#include "ffnn/unit/ActivationUnit.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" #include diff --git a/src/unit/FedUnit.cpp b/src/unit/FedUnit.cpp index 652dd46..27305a3 100644 --- a/src/unit/FedUnit.cpp +++ b/src/unit/FedUnit.cpp @@ -1,5 +1,5 @@ -#include "FedUnit.hpp" -#include "StringCodeUtilities.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include // for NULL diff --git a/src/unit/InputUnit.cpp b/src/unit/InputUnit.cpp index cbad183..5f8836d 100644 --- a/src/unit/InputUnit.cpp +++ b/src/unit/InputUnit.cpp @@ -1,4 +1,4 @@ -#include "InputUnit.hpp" +#include "ffnn/unit/InputUnit.hpp" // set input data mu and sigma, set shift/scale accordingly void InputUnit::setInputMu(const double &inputMu, const bool &doShift) diff --git a/src/unit/NetworkUnit.cpp b/src/unit/NetworkUnit.cpp index a168b59..22c1845 100644 --- a/src/unit/NetworkUnit.cpp +++ b/src/unit/NetworkUnit.cpp @@ -1,4 +1,4 @@ -#include "NetworkUnit.hpp" +#include "ffnn/unit/NetworkUnit.hpp" #include // for NULL diff --git a/src/unit/OutputNNUnit.cpp b/src/unit/OutputNNUnit.cpp index b81bcab..5a14d0a 100644 --- a/src/unit/OutputNNUnit.cpp +++ b/src/unit/OutputNNUnit.cpp @@ -1,4 +1,4 @@ -#include "OutputNNUnit.hpp" +#include "ffnn/unit/OutputNNUnit.hpp" void OutputNNUnit::setOutputBounds(const double &lbound, const double &ubound) { diff --git a/test/README.md b/test/README.md index 2454c7c..774bd89 100644 --- a/test/README.md +++ b/test/README.md @@ -1,6 +1,7 @@ # LEGEND OF THE UNIT TESTS -Use `make check` either inside test directory (i.e. run all tests) or in a specific unittest folder. +Use `./run.sh` inside the test directory to run the check program and all unit tests +with valgrind or use `make test` inside the build directory (runs without valgrind). ## Unit Test 1 diff --git a/test/common/checkDerivatives.hpp b/test/common/checkDerivatives.hpp index 7d8af8c..ee41d71 100644 --- a/test/common/checkDerivatives.hpp +++ b/test/common/checkDerivatives.hpp @@ -2,7 +2,7 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" void checkDerivatives(FeedForwardNeuralNetwork * const ffnn, const double &TINY) { diff --git a/test/common/checkStoreOnFile.hpp b/test/common/checkStoreOnFile.hpp index 59487ca..c365457 100644 --- a/test/common/checkStoreOnFile.hpp +++ b/test/common/checkStoreOnFile.hpp @@ -2,7 +2,7 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" // expects a neural network without substrates but optionally with connection void checkStoreOnFile(FeedForwardNeuralNetwork * const ffnn, const bool isConnected = false) diff --git a/test/main.cpp b/test/main.cpp index 3c9a284..c8c8679 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -2,7 +2,7 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" void printNNStructure(FeedForwardNeuralNetwork &nn) diff --git a/test/ut1/main.cpp b/test/ut1/main.cpp index 0848b5d..f11b58e 100644 --- a/test/ut1/main.cpp +++ b/test/ut1/main.cpp @@ -1,7 +1,7 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" #include "../common/checkDerivatives.hpp" int main(){ diff --git a/test/ut10/main.cpp b/test/ut10/main.cpp index f2eaaf0..285aaae 100644 --- a/test/ut10/main.cpp +++ b/test/ut10/main.cpp @@ -1,8 +1,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/io/PrintUtilities.hpp" #include "../common/checkDerivatives.hpp" #include "../common/checkStoreOnFile.hpp" diff --git a/test/ut2/main.cpp b/test/ut2/main.cpp index a3eeb73..1d6cc0c 100644 --- a/test/ut2/main.cpp +++ b/test/ut2/main.cpp @@ -1,5 +1,5 @@ -#include "FeedForwardNeuralNetwork.hpp" -#include "ActivationFunctionManager.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" #include "../common/checkStoreOnFile.hpp" diff --git a/test/ut3/main.cpp b/test/ut3/main.cpp index bd18173..3789ebd 100644 --- a/test/ut3/main.cpp +++ b/test/ut3/main.cpp @@ -2,9 +2,9 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "ActivationFunctionManager.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/io/PrintUtilities.hpp" diff --git a/test/ut4/main.cpp b/test/ut4/main.cpp index 3a00032..408fe0d 100644 --- a/test/ut4/main.cpp +++ b/test/ut4/main.cpp @@ -2,9 +2,9 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "ActivationFunctionManager.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/io/PrintUtilities.hpp" diff --git a/test/ut5/main.cpp b/test/ut5/main.cpp index d383ffb..2bdf27b 100644 --- a/test/ut5/main.cpp +++ b/test/ut5/main.cpp @@ -1,5 +1,5 @@ -#include "ActivationFunctionManager.hpp" -#include "ActivationFunctionInterface.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/actf/ActivationFunctionInterface.hpp" #include #include diff --git a/test/ut6/main.cpp b/test/ut6/main.cpp index f96b76a..1a64aa0 100644 --- a/test/ut6/main.cpp +++ b/test/ut6/main.cpp @@ -1,4 +1,4 @@ -#include "StringCodeUtilities.hpp" +#include "ffnn/serial/StringCodeUtilities.hpp" #include #include diff --git a/test/ut7/main.cpp b/test/ut7/main.cpp index d669b95..1b7d3e5 100644 --- a/test/ut7/main.cpp +++ b/test/ut7/main.cpp @@ -5,12 +5,12 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "SmartBetaGenerator.hpp" -#include "ActivationFunctionManager.hpp" -#include "FedUnit.hpp" -#include "FeederInterface.hpp" -#include "PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/feed/SmartBetaGenerator.hpp" +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/unit/FedUnit.hpp" +#include "ffnn/feed/FeederInterface.hpp" +#include "ffnn/io/PrintUtilities.hpp" int main(){ diff --git a/test/ut8/main.cpp b/test/ut8/main.cpp index fbe4eed..9a81e8d 100644 --- a/test/ut8/main.cpp +++ b/test/ut8/main.cpp @@ -1,5 +1,5 @@ -#include "FeedForwardNeuralNetwork.hpp" -#include "NNTrainerGSL.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/train/NNTrainerGSL.hpp" #include #include diff --git a/test/ut9/main.cpp b/test/ut9/main.cpp index 3a4e206..e6b52bb 100644 --- a/test/ut9/main.cpp +++ b/test/ut9/main.cpp @@ -3,8 +3,8 @@ #include #include -#include "FeedForwardNeuralNetwork.hpp" -#include "NNTrainerGSL.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" +#include "ffnn/train/NNTrainerGSL.hpp" using namespace std; using namespace nn_trainer_gsl_details; // to access hidden NNTrainerGSL methods From 6e51a9ebfc583046eef55956c33cf48e9b7686f3 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Thu, 21 Feb 2019 21:12:46 +0100 Subject: [PATCH 10/18] Made build.sh more portable and fixed OpenMP build --- CMakeLists.txt | 2 +- build.sh | 12 ++++++++---- config_template.sh | 2 +- src/CMakeLists.txt | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c302e09..bb8c6ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ message(STATUS "Configured GSL_ROOT_DIR: ${GSL_ROOT_DIR}") if (USE_OPENMP) find_package(OpenMP) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENMP=1") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -DOPENMP=1") message(STATUS "OPENMP_LIBRARY_PATHS: ${OpenMP_CXX_LIBRARY}") message(STATUS "OPENMP_LIBRARIES: ${OpenMP_CXX_LIBRARIES}") endif() diff --git a/build.sh b/build.sh index 34766d9..57bc635 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,11 @@ #!/bin/sh . ./config.sh -mkdir -p build -cd build -cmake -DCMAKE_CXX_COMPILER="${CXX_COMPILER}" -DUSER_CXX_FLAGS="${CXX_FLAGS}" -DUSE_COVERAGE="${USE_COVERAGE}" -DGSL_ROOT_DIR="${GSL_ROOT}" .. -make -j$(nproc) +mkdir -p build && cd build +cmake -DCMAKE_CXX_COMPILER="${CXX_COMPILER}" -DUSER_CXX_FLAGS="${CXX_FLAGS}" -DUSE_COVERAGE="${USE_COVERAGE}" -DUSE_OPENMP="${USE_OPENMP}" -DGSL_ROOT_DIR="${GSL_ROOT}" .. + +if [ "$1" == "" ]; then + make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) +else + make -j$1 +fi diff --git a/config_template.sh b/config_template.sh index 2cbd154..2b17384 100755 --- a/config_template.sh +++ b/config_template.sh @@ -9,7 +9,7 @@ CXX_FLAGS="-O3 -flto -Wall -Wno-unused-function" # add coverage flags USE_COVERAGE=0 -# use MPI for integration +# use OpenMP for parallel propagation USE_OPENMP=0 # GNU Scientific Library diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb30bfa..91ac07e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ file(GLOB SOURCES "*/*.cpp") add_library(ffnn SHARED ${SOURCES}) -target_link_libraries(ffnn "${GSL_LIBRARIES}") # shared libs +target_link_libraries(ffnn "${GSL_LIBRARIES}" "${OpenMP_CXX_LIBRARIES}") # shared libs add_library(ffnn_static STATIC ${SOURCES}) -target_link_libraries(ffnn_static "{$GSL_LIBRARIES}") # static (+ some shared) libs +target_link_libraries(ffnn_static "{$GSL_LIBRARIES}" "${OpenMP_CXX_LIBRARIES}") # static (+ some shared) libs From 21af1aa5b1dd64680a1a94da07590fa89e48dbc2 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Thu, 21 Feb 2019 23:15:22 +0100 Subject: [PATCH 11/18] adapted travis.yml --- .travis.bak | 75 ----------------------------------------- .travis.yml | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 75 deletions(-) delete mode 100644 .travis.bak create mode 100644 .travis.yml diff --git a/.travis.bak b/.travis.bak deleted file mode 100644 index 964421c..0000000 --- a/.travis.bak +++ /dev/null @@ -1,75 +0,0 @@ -sudo: required -dist: trusty -language: c++ -services: -- docker - -matrix: - include: - #- os: linux - # env: - # - MATRIX_EVAL="wget ftp://ftp.gnu.org/gnu/gsl/gsl-2.3.tar.gz && tar -xvf gsl-2.3.tar.gz && cd gsl-2.3 && ./configure && make -j2 && sudo make install && cd ../ && export LDFLAGS=-L/usr/local/lib && export CPPFLAGS=-I/usr/local/include" - # - USE_DOCKER="FALSE" - # - USE_GCOV="FALSE" - - - os: linux // arch linux docker - env: - - USE_DOCKER="TRUE" - - USE_OPENMP="FALSE" - - USE_GCOV="FALSE" - - - os: linux // with enabled openmp - env: - - USE_DOCKER="TRUE" - - USE_OPENMP="TRUE" - - USE_GCOV="FALSE" - - - os: osx - osx_image: xcode8 - env: - - MATRIX_EVAL="brew update && brew install gsl valgrind" - - MYCXX="g++" - - USE_DOCKER="FALSE" - - USE_GCOV="FALSE" - - - os: osx - osx_image: xcode8 - env: - - MATRIX_EVAL="brew update && brew install gsl valgrind" - - MYCXX="clang++" - - USE_DOCKER="FALSE" - - USE_GCOV="TRUE" - -before_install: -- | - if [[ "$USE_DOCKER" == "TRUE" ]]; then - docker pull nnvmc/base; - local configopt="--enable-debug" - if [[ "$USE_OPENMP" == "TRUE" ]]; then configopt="${configopt} --enable-openmp"; fi; - if [[ "$USE_GCOV" == "TRUE" ]]; then configopt="${configopt} --enable-coverage"; fi; - docker run -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "cd /root/repo && ./autogen.sh && ./configure ${configopt}"; - else - eval "${MATRIX_EVAL}" && ${MYCXX} -v; - ./autogen.sh - local configopt="--enable-debug" - if [[ "$USE_GCOV" == "TRUE" ]]; then pip install cpp-coveralls; configopt="${configopt} --enable-coverage"; fi; - ./configure CXX=${MYCXX} ${configopt}; - fi; - -script: -- | - if [[ "$USE_DOCKER" == "TRUE" ]]; then - docker run -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "cd /root/repo && make check" || exit 1; - if [[ "$USE_GCOV" == "TRUE" ]]; then - docker run -e TRAVIS=$TRAVIS -e TRAVIS_JOB_ID=$TRAVIS_JOB_ID -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "pip install cpp-coveralls && cd /root/repo && coveralls -b lib -e test -e benchmark -e include -e lib -e examples -e script -i src --gcov-options '\-lp'"; - fi; - else - make check || exit 1; - if [[ "$USE_GCOV" == "TRUE" ]]; then coveralls -b lib -e test -e benchmark -e include -e lib -e examples -e script -i src --gcov-options '\-lp' ; fi; - fi; -- cat test/test-suite.log test/exe.log test/ut*/exe.log - -notifications: - email: - on_success: change - on_failure: change diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..37b40ca --- /dev/null +++ b/.travis.yml @@ -0,0 +1,96 @@ +dist: xenial +language: c++ +services: +- docker + +addons: + apt: + packages: + - valgrind + - libgsl-dev + + homebrew: + packages: + - valgrind + - gsl + +matrix: + include: + - os: linux // arch linux docker + env: + - MYCXX="g++" + - USE_DOCKER="TRUE" + - USE_GCOV="FALSE" + - USE_OPENMP="TRUE" + + - os: osx + osx_image: xcode10.1 + env: + - MYCXX="g++" + - USE_DOCKER="FALSE" + - USE_GCOV="TRUE" + - USE_OPENMP="FALSE" + + - os: osx + osx_image: xcode10.1 + env: + - MYCXX="clang++" + - USE_DOCKER="FALSE" + - USE_GCOV="FALSE" + - USE_OPENMP="FALSE" + +before_install: +- | + if [[ "$USE_DOCKER" == "TRUE" ]]; then + docker pull nnvmc/base; + else + ${MYCXX} -v; + fi; + echo "CXX_COMPILER=${MYCXX}" >> config.sh; + echo "CXX_FLAGS=\"-O0 -g -Wall -Wno-unused-function ${configopt}\"" >> config.sh; + if [[ "$USE_GCOV" == "TRUE" ]]; then + echo "USE_COVERAGE=1" >> config.sh; + else + echo "USE_COVERAGE=0" >> config.sh; + fi; + if [[ "$USE_OPENMP" == "TRUE" ]]; then + echo "USE_OPENMP=1" >> config.sh; + else + echo "USE_OPENMP=0" >> config.sh; + fi; + echo "GSL_ROOT=" >> config.sh; + +script: +- | + if [[ "$USE_DOCKER" == "TRUE" ]]; then + docker run -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "cd /root/repo && ./build.sh" || exit 1; + else + ./build.sh || exit 1; + fi; + +- | + if [[ "$USE_DOCKER" == "TRUE" ]]; then + if [[ "$USE_OPENMP" == "TRUE" ]]; then + docker run -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "cd /root/repo/build && make test"; + elif [[ "$USE_GCOV" == "TRUE" ]]; then + docker run -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "cd /root/repo/build && make test"; + docker run -e TRAVIS=$TRAVIS -e TRAVIS_JOB_ID=$TRAVIS_JOB_ID -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "pip install cpp-coveralls && cd /root/repo/build && coveralls --verbose -b ./ -r ../ -i include -i src -x .cpp -x .hpp --gcov-options '\-lp'"; + else + docker run -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "cd /root/repo/test && ./run.sh"; + fi; + else + if [[ "$USE_OPENMP" == "TRUE" ]]; then + cd build && make test && cd ..; + elif [[ "$USE_GCOV" == "TRUE" ]]; then + cd build && make test; + sudo pip install cpp-coveralls && coveralls --verbose -b ./ -r ../ -i include -i src -x .cpp -x .hpp --gcov-options '\-lp'; + cd ..; + else + cd test && ./run.sh && cd .. ; + fi; + fi; + +notifications: + email: + on_success: change + on_failure: change From 9e0f84557a2dc0c682b4fea2d958701d5d104771 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Fri, 22 Feb 2019 01:11:36 +0100 Subject: [PATCH 12/18] brought convenient benchmark/profiling functionality back --- .gitignore | 2 ++ benchmark/README.md | 19 ++++++++++--------- benchmark/bench_actfs_derivs/run.sh | 9 --------- benchmark/bench_actfs_ffprop/run.sh | 9 --------- benchmark/run.sh | 14 ++++++++++++++ benchmark/run_prof.sh | 16 ++++++++++++++++ 6 files changed, 42 insertions(+), 27 deletions(-) delete mode 100755 benchmark/bench_actfs_derivs/run.sh delete mode 100755 benchmark/bench_actfs_ffprop/run.sh create mode 100755 benchmark/run.sh create mode 100755 benchmark/run_prof.sh diff --git a/.gitignore b/.gitignore index 89fb9a0..f3e149f 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,8 @@ build config.sh vgcore* +benchmark/*/*.out + doc/*.aux doc/*.dvi doc/*.idx diff --git a/benchmark/README.md b/benchmark/README.md index 9df8ce3..92808c1 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -14,11 +14,11 @@ Currently there are the following benchmarks: # Using the benchmarks -Enter the desired benchmark's directory and execute: - `./run.sh` +Just provide the script `run.sh` the desired benchmark's name, e.g.: + `./run.sh bench_actfs_ffprop` -Each benchmark will write the results to the command line output by default. -If you save it into a file `benchmark_new.out` instead (e.g. via `./run.sh > benchmark_new.out`), you may visualize the result by using: +The benchmark results will be written to a file named `benchmark_new.out` under the respective benchmark folder. +You may visualize the result by entering that directory and using: `python plot.py benchmark_new.out` To let the plot compare the new result versus an older one, you have to provide the old output file like: @@ -28,10 +28,11 @@ You may also change new/old to more meaningful labels, anything like benchmark_* provided labels will be used automatically to create the plot legends. -# Profiling (currently unavailable) +# Profiling -If you want to use the benchmarks for profiling, recompile the library and benchmarks after configuring - `./configure --enable-profiling` +If you want to performance profile the library under execution of a benchmark, +you just need to provide gperftools's libprofiler.so library to `run_prof.sh` as second argument, e.g.: + `./run_prof.sh bench_actfs_ffprop /usr/lib/libprofiler.so` -Then execute a benchmark via make (!) and afterwards view the profile with: - `pprof --text exe exe.prof` +Note that this script does not save any benchmark results. +Also note that for profiling you might want to avoid LTO flags when building the library, to avoid cryptic LTO chunk names in the profile. diff --git a/benchmark/bench_actfs_derivs/run.sh b/benchmark/bench_actfs_derivs/run.sh deleted file mode 100755 index 51059cf..0000000 --- a/benchmark/bench_actfs_derivs/run.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -bench=bench_actfs_derivs - -cd ../../build/benchmark/ -echo -echo "Running benchmark ${bench}..." -./${bench} -echo diff --git a/benchmark/bench_actfs_ffprop/run.sh b/benchmark/bench_actfs_ffprop/run.sh deleted file mode 100755 index 4b78680..0000000 --- a/benchmark/bench_actfs_ffprop/run.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -bench=bench_actfs_ffprop - -cd ../../build/benchmark/ -echo -echo "Running benchmark ${bench}..." -./${bench} -echo diff --git a/benchmark/run.sh b/benchmark/run.sh new file mode 100755 index 0000000..2ce9906 --- /dev/null +++ b/benchmark/run.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +if [ "$1" == "" ]; then + echo "Expected the name of the benchmark to run as first argument." +else + bench=$1 + outfile="$(pwd)/${bench}/benchmark_new.out" + cd ../build/benchmark/ + echo + echo "Running benchmark ${bench}..." + ./${bench} > ${outfile} + cat ${outfile} + echo +fi diff --git a/benchmark/run_prof.sh b/benchmark/run_prof.sh new file mode 100755 index 0000000..2c1b8ba --- /dev/null +++ b/benchmark/run_prof.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +if [ "$1" == "" ]; then + echo "Expected the name of the benchmark to run as first argument." +elif [ "$2" == "" ]; then + echo "Expected the path of libprofiler.so as second argument." +else + bench=$1 + lprof=$2 + cd ../build/benchmark/ + echo + echo "Running benchmark ${bench}..." + LD_PRELOAD=${lprof} CPUPROFILE=${bench}.prof CPUPROFILE_FREQUENCY=10000 CPUPROFILE_REALTIME=1 ./${bench} + pprof --text ${bench} ${bench}.prof + echo +fi From a550e0d0a36dbf0b152ccf0b6db66a75926621c1 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Fri, 22 Feb 2019 13:58:41 +0100 Subject: [PATCH 13/18] Unify READMEs and travis --- .travis.yml | 3 +-- README.md | 32 ++++++++++++++++++++++---------- examples/README.md | 2 +- test/README.md | 4 ++-- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 37b40ca..c31b814 100644 --- a/.travis.yml +++ b/.travis.yml @@ -83,8 +83,7 @@ script: cd build && make test && cd ..; elif [[ "$USE_GCOV" == "TRUE" ]]; then cd build && make test; - sudo pip install cpp-coveralls && coveralls --verbose -b ./ -r ../ -i include -i src -x .cpp -x .hpp --gcov-options '\-lp'; - cd ..; + sudo pip install cpp-coveralls && coveralls --verbose -b ./ -r ../ -i include -i src -x .cpp -x .hpp --gcov-options '\-lp' && cd .. ; else cd test && ./run.sh && cd .. ; fi; diff --git a/README.md b/README.md index 1940429..ff13741 100644 --- a/README.md +++ b/README.md @@ -6,36 +6,48 @@ # FeedForwardNeuralNetwork -C++ Library for building and using a Feed Forward Neural Network. -It includes first and second derivatives in respect to the input values, and first derivatives in respect to the variational parameters. +C++ Library for building and using Feed Forward Neural Networks. +It includes first and second derivatives with respect to the input values, first derivatives with respect to the variational parameters +and mixed derivatives with respect to both input and variational parameters. To get you started, there is a user manual pdf in `doc/` and in `examples/` there are several basic examples. -Most subdirectories come with a `README.md` file, explaining the purpose and what you need to know. +In `test/` you can find the unit tests and benchmarking programs in `benchmark`. +Some subdirectories come with an own `README.md` file which provides further information. # Supported Systems Currently, we automatically test the library on Arch Linux (GCC 8) and MacOS (with clang as well as brewed GCC 8). -However, in principle any system with C++11 supporting compiler should work, at least if you manage to install all dependencies. +However, in principle any system with C++11 supporting compiler should work. +# Requirements -# Build the library +- CMake, to use our build process +- GNU Scientific Library (~2.3+) +- (optional) OpenMP, to use parallelized propagation (make sure that it is beneficial in your case!) +- (optional) valgrind, to run `./run.sh` in `test/` +- (optional) gperftools, ro run `./run_prof.sh` in `benchmark/` +- (optional) pdflatex, to compile the tex file in `doc/` +- (optional) doxygen, to generate doxygen documentation in `doc/doxygen` -Make sure you have a reasonably recent development version (>=2.3?) of the GSL library on your system. Furthermore, we rely on the CMake build system. -Before compiling, copy the config template: - `cp config_template.sh config.sh` +# Build the library -and edit it as needed (especially if you have the GSL library in non-standard paths. +Copy the file `config_template.sh` to `config.sh`, edit it to your liking and then simply execute the command -If you are done, simply use the following script to compile the library and all tests, benchmarks and examples: `./build.sh` Note that we build out-of-tree, so the compiled library and executable files can be found in the directories under `./build/`. + +# First steps + +You may want to read `doc/user_manual.pdf` to get a quick overview of the libraries functionality. However, it is not guaranteed to be perfectly up-to-date and accurate. Therefore, the best way to get your own code started is by studying the examples in `examples/`. See `examples/README.md` for further guidance. + + # Multi-threading: OpenMP This library supports multi-threading computation with a shared memory paradigm, thanks to OpenMP. diff --git a/examples/README.md b/examples/README.md index 9c466ac..974ff41 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,7 +2,7 @@ Make sure the examples are compiled, by running `./build.sh` in the project root folder. Execute an example by switching into one of the example folders and running `./run.sh`. -Note that the actual example executables reside inside the build/ folder under the project's root. +Note that the actual example executables reside inside the `build/examples/` folder under the project's root. Some examples might also contain a `plot.py` script to show a plot. It gets called automatically by `./run.sh` after the executable has terminated, but requires python with matplotlib. diff --git a/test/README.md b/test/README.md index 774bd89..7ccfcd5 100644 --- a/test/README.md +++ b/test/README.md @@ -1,7 +1,7 @@ # LEGEND OF THE UNIT TESTS -Use `./run.sh` inside the test directory to run the check program and all unit tests -with valgrind or use `make test` inside the build directory (runs without valgrind). +Use `./run.sh` inside the test directory to run the check program and unit tests +with valgrind or use `make test` inside the build directory, to run unit tests without valgrind. ## Unit Test 1 From 7b17e3481f69ce36ab3f4321e9372226482fbfcc Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Sat, 23 Feb 2019 19:27:41 +0100 Subject: [PATCH 14/18] small changes to benchmarks/tests and added new benchmark concerning different network sizes --- benchmark/CMakeLists.txt | 1 + benchmark/README.md | 5 + benchmark/bench_actfs_derivs/main.cpp | 28 ++--- benchmark/bench_actfs_ffprop/main.cpp | 13 +- benchmark/bench_nunits_ffprop/main.cpp | 89 ++++++++++++++ benchmark/bench_nunits_ffprop/plot.py | 115 ++++++++++++++++++ ...{FFNNBenchmarks.cpp => FFNNBenchmarks.hpp} | 37 +++--- benchmark/common/{Timer.cpp => Timer.hpp} | 2 +- benchmark/run_all.sh | 6 + test/ut10/main.cpp | 3 +- test/ut5/main.cpp | 18 +-- 11 files changed, 264 insertions(+), 53 deletions(-) create mode 100644 benchmark/bench_nunits_ffprop/main.cpp create mode 100644 benchmark/bench_nunits_ffprop/plot.py rename benchmark/common/{FFNNBenchmarks.cpp => FFNNBenchmarks.hpp} (63%) rename benchmark/common/{Timer.cpp => Timer.hpp} (83%) create mode 100755 benchmark/run_all.sh diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 53f2cd2..4ae054b 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -3,3 +3,4 @@ link_libraries(ffnn) add_executable(bench_actfs_derivs bench_actfs_derivs/main.cpp) add_executable(bench_actfs_ffprop bench_actfs_ffprop/main.cpp) +add_executable(bench_nunits_ffprop bench_nunits_ffprop/main.cpp) diff --git a/benchmark/README.md b/benchmark/README.md index 92808c1..e0f6c5b 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -11,12 +11,17 @@ Currently there are the following benchmarks: `bench_actfs_ffprop`: Benchmark of a FFNN's propagation for various hidden layer activation functions. + `bench_nunits_ffprop`: Benchmark of a FFNN's propagation for different sizes of input and hidden layers. + # Using the benchmarks Just provide the script `run.sh` the desired benchmark's name, e.g.: `./run.sh bench_actfs_ffprop` +Alternatively, you can run all benchmarks sequentially by calling: + `./run_all.sh` + The benchmark results will be written to a file named `benchmark_new.out` under the respective benchmark folder. You may visualize the result by entering that directory and using: `python plot.py benchmark_new.out` diff --git a/benchmark/bench_actfs_derivs/main.cpp b/benchmark/bench_actfs_derivs/main.cpp index 3f451ac..4bb4e00 100644 --- a/benchmark/bench_actfs_derivs/main.cpp +++ b/benchmark/bench_actfs_derivs/main.cpp @@ -5,15 +5,15 @@ #include "ffnn/actf/ActivationFunctionManager.hpp" #include "ffnn/io/PrintUtilities.hpp" -#include "FFNNBenchmarks.cpp" +#include "FFNNBenchmarks.hpp" using namespace std; -void run_single_benchmark(const string &label, const string &actf_id, const double * const indata, const int neval, const int nruns, const bool flag_d1, const bool flag_d2, const bool flag_d3, const bool flag_fad) { +void run_single_benchmark(const string &label, const string &actf_id, const double * const xdata, const int neval, const int nruns, const bool flag_d1, const bool flag_d2, const bool flag_d3, const bool flag_fad) { pair result; const double time_scale = 1000000000.; //nanoseconds - result = sample_benchmark_actf_derivs(std_actf::provideActivationFunction(actf_id), indata, neval, nruns, flag_d1, flag_d2, flag_d3, flag_fad); + result = sample_benchmark_actf_derivs(std_actf::provideActivationFunction(actf_id), xdata, neval, nruns, flag_d1, flag_d2, flag_d3, flag_fad); cout << label << ":" << setw(max(1, 11-(int)label.length())) << setfill(' ') << " " << result.first/neval*time_scale << " +- " << result.second/neval*time_scale << " nanoseconds" << endl; } @@ -24,7 +24,7 @@ int main (void) { const int nactfs = 8; const string actf_ids[nactfs] = {"LGS", "GSS", "ID", "TANS", "SIN", "RELU", "SELU", "SRLU"}; - double * const indata = new double[neval]; // 1d input data for actf bench + double * xdata = new double[neval]; // 1d input data for actf bench // generate some random input random_device rdev; @@ -33,7 +33,7 @@ int main (void) { rgen = mt19937_64(rdev()); rgen.seed(18984687); rd = uniform_real_distribution(-sqrt(3.), sqrt(3.)); // uniform with variance 1 - for (int i=0; i result; const double time_scale = 1000000.; //microseconds @@ -29,8 +29,8 @@ int main (void) { const int nactfs = 8; const string actf_ids[nactfs] = {"LGS", "GSS", "ID", "TANS", "SIN", "RELU", "SELU", "SRLU"}; - double ** const xdata = new double*[neval]; // xndim input data for propagate bench - for (int i=0; i(-sqrt(3.), sqrt(3.)); // uniform with variance 1 - for (int i=0; i +#include +#include + +#include "ffnn/actf/ActivationFunctionManager.hpp" +#include "ffnn/io/PrintUtilities.hpp" +#include "ffnn/net/FeedForwardNeuralNetwork.hpp" + +#include "FFNNBenchmarks.hpp" + +using namespace std; + +void run_single_benchmark(const string &label, FeedForwardNeuralNetwork * const ffnn, const double * const xdata, const int neval, const int nruns) { + pair result; + const double time_scale = 1000000.; //microseconds + + result = sample_benchmark_FFPropagate(ffnn, xdata, neval, nruns); + cout << label << ":" << setw(max(1, 20-(int)label.length())) << setfill(' ') << " " << result.first/neval*time_scale << " +- " << result.second/neval*time_scale << " microseconds" << endl; +} + +int main (void) { + const int neval[3] = {50000, 1000, 20}; + const int nruns = 5; + + const int nhl = 2; + const int yndim = 1; + const int xndim[3] = {6, 24, 96}, nhu1[3] = {12, 48, 192}, nhu2[3] = {6, 24, 96}; + + int ndata[3], ndata_full = 0; + for (int i=0; i<3; ++i) { + ndata[i] = neval[i]*xndim[i]; + ndata_full += ndata[i]; + } + double * xdata = new double[ndata_full]; // xndim input data for propagate bench + + // generate some random input + random_device rdev; + mt19937_64 rgen; + uniform_real_distribution rd; + rgen = mt19937_64(rdev()); + rgen.seed(18984687); + rd = uniform_real_distribution(-sqrt(3.), sqrt(3.)); // uniform with variance 1 + for (int i=0; ipushHiddenLayer(nhu2[inet]); + ffnn->connectFFNN(); + ffnn->assignVariationalParameters(); + + cout << "FFPropagate benchmark with " << nruns << " runs of " << neval[inet] << " FF-Propagations, for a FFNN of shape " << xndim[inet] << "x" << nhu1[inet] << "x" << nhu2[inet] << "x" << yndim << " ." << endl; + cout << "=========================================================================================" << endl << endl; + cout << "NN structure looks like:" << endl << endl; + printFFNNStructure(ffnn, true, 0); + cout << endl; + cout << "Benchmark results (time per propagation):" << endl; + + run_single_benchmark("f", ffnn, xdata+xoffset, neval[inet], nruns); + + ffnn->addFirstDerivativeSubstrate(); + run_single_benchmark("f+d1", ffnn, xdata+xoffset, neval[inet], nruns); + + ffnn->addSecondDerivativeSubstrate(); + run_single_benchmark("f+d1+d2", ffnn, xdata+xoffset, neval[inet], nruns); + + ffnn->addVariationalFirstDerivativeSubstrate(); + run_single_benchmark("f+d1+d2+vd1", ffnn, xdata+xoffset, neval[inet], nruns); + + /* these currently kill 16GB+ of memory on the largest nets */ + //ffnn->addCrossFirstDerivativeSubstrate(); + //run_single_benchmark("f+d1+d2+vd1+cd1", ffnn, xdata+xoffset, neval[inet], nruns); + + //ffnn->addCrossSecondDerivativeSubstrate(); + //run_single_benchmark("f+d1+d2+vd1+cd1+cd2", ffnn, xdata+xoffset, neval[inet], nruns); + + cout << "=========================================================================================" << endl << endl << endl; + + delete ffnn; + xoffset += ndata[inet]; + } + + delete [] xdata; + return 0; +} + diff --git a/benchmark/bench_nunits_ffprop/plot.py b/benchmark/bench_nunits_ffprop/plot.py new file mode 100644 index 0000000..30d7210 --- /dev/null +++ b/benchmark/bench_nunits_ffprop/plot.py @@ -0,0 +1,115 @@ +from pylab import * + +class benchmark_nunits_ffprop: + + def __init__(self, filename, label): + self.label = label + self.data = {} + + bnew = True + with open(filename) as bmfile: + for line in bmfile: + + lsplit = line.split() + + if len(lsplit) < 5: + continue + + if lsplit[0] == 'FFPropagate': + if not bnew: + self.data[net_shape] = net_data # store previous net's data + + net_shape = lsplit[13] + net_data = {} + bnew = False + continue + + if lsplit[0][0:2] == 'f:' or lsplit[0][0:2] == 'f+': + net_data[lsplit[0][:-1]] = (float(lsplit[1]), float(lsplit[3])) + + self.data[net_shape] = net_data # store last net's data + + +def plot_compare_nets(benchmark_list, **kwargs): + nbm = len(benchmark_list) + xlabels = benchmark_list[0].data[list(benchmark_list[0].data.keys())[0]].keys() # get the xlabels from first entry in data dict + + fig = figure() + fig.suptitle('FFPropagate benchmark, comparing different net sizes',fontsize=14) + + itp=0 + for benchmark in benchmark_list: + + itp+=1 + ax = fig.add_subplot(nbm, 1, itp) + for net in benchmark.data.keys(): + values = [v[0] for v in benchmark.data[net].values()] + errors = [v[1] for v in benchmark.data[net].values()] + ax.errorbar(xlabels, values, xerr=None, yerr=errors, **kwargs) + + ax.set_yscale('log') + ax.set_title(benchmark.label + ' version') + ax.set_ylabel('Time per propagation [$\mu s$]') + ax.legend(benchmark.data.keys()) + + return fig + + +def plot_compare_runs(benchmark_list, net_list, width = 0.8, **kwargs): + nbm = len(benchmark_list)-1 + if nbm <= 0: + print('Error: Not enough benchmarks for comparison plot.') + return None + + bwidth = width/float(nbm) + nnet = len(net_list) + if nbm > 1: + ind = arange(len(benchmark_list[0].data[net_list[0]]), 0, -1) + else: + ind = arange(len(benchmark_list[0].data[net_list[0]]), 0, -1) - 0.5*bwidth + xlabels = benchmark_list[0].data[net_list[0]].keys() + + fig = figure() + fig.suptitle('FFPropagate benchmark, comparing against ' + benchmark_list[0].label + ' version',fontsize=14) + + itp = 0 + for ita, net in enumerate(net_list): + + itp+=1 + ax = fig.add_subplot(nnet, 1, itp) + scales = array([100./v[0] for v in benchmark_list[0].data[net].values()]) # we will normalize data to the first benchmark's results + for itb, benchmark in enumerate(benchmark_list[1:]): + values = array([v[0] for v in benchmark.data[net].values()])*scales + errors = array([v[1] for v in benchmark.data[net].values()])*scales + rects = ax.barh(ind - itb*bwidth, values, bwidth, xerr=errors, **kwargs) + for rect in rects: + ax.text(1., rect.get_y() + rect.get_height()/2., '%d' % int(rect.get_width()), ha='left', va='center', fontsize=8) + + ax.set_title(net + ' net') + if ita==len(net_list)-1: + ax.set_xlabel('Time per propagation [%]') + ax.set_xlim([0,200]) + ax.set_yticks(ind - 0.5*(nbm-1)*bwidth) + ax.set_yticklabels(xlabels) + ax.legend([benchmark.label for benchmark in benchmark_list[1:]]) + + return fig + +# Script + +benchmark_list = [] +for benchmark_file in sys.argv[1:]: + try: + benchmark = benchmark_nunits_ffprop(benchmark_file, benchmark_file.split('_')[1].split('.')[0]) + benchmark_list.append(benchmark) + except(OSError): + print("Warning: Couldn't load benchmark file " + benchmark_file + "!") + +if len(benchmark_list)<1: + print("Error: Not even one benchmark loaded!") +else: + fig1 = plot_compare_nets(benchmark_list, fmt='o--') + if len(benchmark_list)>1: + fig2 = plot_compare_runs(benchmark_list, ['6x12x6x1', '24x48x24x1', '96x192x96x1']) + +show() diff --git a/benchmark/common/FFNNBenchmarks.cpp b/benchmark/common/FFNNBenchmarks.hpp similarity index 63% rename from benchmark/common/FFNNBenchmarks.cpp rename to benchmark/common/FFNNBenchmarks.hpp index d11bfbe..42bbe6e 100644 --- a/benchmark/common/FFNNBenchmarks.cpp +++ b/benchmark/common/FFNNBenchmarks.hpp @@ -3,24 +3,22 @@ #include #include "ffnn/net/FeedForwardNeuralNetwork.hpp" -#include "Timer.cpp" +#include "Timer.hpp" -double benchmark_FFPropagate(FeedForwardNeuralNetwork * const ffnn, const double * const * const xdata, const int neval) { - Timer * const timer = new Timer(); - double time; +double benchmark_FFPropagate(FeedForwardNeuralNetwork * const ffnn, const double * const xdata, const int neval) { + Timer timer(1.); + const int ninput = ffnn->getNInput(); - timer->reset(); + timer.reset(); for (int i=0; isetInput(xdata[i]); + ffnn->setInput(xdata+i*ninput); ffnn->FFPropagate(); } - time = timer->elapsed(); - delete timer; - return time; + return timer.elapsed(); } -std::pair sample_benchmark_FFPropagate(FeedForwardNeuralNetwork * ffnn, const double * const * const xdata, const int neval, const int nruns) { +std::pair sample_benchmark_FFPropagate(FeedForwardNeuralNetwork * const ffnn, const double * const xdata, const int neval, const int nruns) { double times[nruns]; double mean = 0., err = 0.; @@ -37,33 +35,30 @@ std::pair sample_benchmark_FFPropagate(FeedForwardNeuralNetwork return result; } -double benchmark_actf_derivs(ActivationFunctionInterface * actf, const double * const xdata, const int neval, const bool flag_d1 = true, const bool flag_d2 = true, const bool flag_d3 = true, const bool flag_fad = true) { - Timer * const timer = new Timer(); - double time, v, v1d, v2d, v3d; +double benchmark_actf_derivs(ActivationFunctionInterface * const actf, const double * const xdata, const int neval, const bool flag_d1 = true, const bool flag_d2 = true, const bool flag_d3 = true, const bool flag_fad = true) { + Timer timer(1.); + double v=0., v1d=0., v2d=0., v3d=0.; if (flag_fad) { - timer->reset(); + timer.reset(); for (int i=0; ifad(xdata[i], v, v1d, v2d, v3d, flag_d1, flag_d2, flag_d3); } - time = timer->elapsed(); + return timer.elapsed(); } else { - timer->reset(); + timer.reset(); for (int i=0; if(xdata[i]); v1d = flag_d1 ? actf->f1d(xdata[i]) : 0.0; v2d = flag_d2 ? actf->f2d(xdata[i]) : 0.0; v3d = flag_d3 ? actf->f3d(xdata[i]) : 0.0; } - time = timer->elapsed(); + return timer.elapsed(); } - - delete timer; - return time; } -std::pair sample_benchmark_actf_derivs(ActivationFunctionInterface * actf, const double * const xdata, const int neval, const int nruns, const bool flag_d1 = true, const bool flag_d2 = true, const bool flag_d3 = true, const bool flag_fad = true) { +std::pair sample_benchmark_actf_derivs(ActivationFunctionInterface * const actf, const double * const xdata, const int neval, const int nruns, const bool flag_d1 = true, const bool flag_d2 = true, const bool flag_d3 = true, const bool flag_fad = true) { double times[nruns]; double mean = 0., err = 0.; diff --git a/benchmark/common/Timer.cpp b/benchmark/common/Timer.hpp similarity index 83% rename from benchmark/common/Timer.cpp rename to benchmark/common/Timer.hpp index 25c0e7f..bf12c5e 100644 --- a/benchmark/common/Timer.cpp +++ b/benchmark/common/Timer.hpp @@ -4,7 +4,7 @@ class Timer { public: - explicit Timer(const double scale = 1.) : _beg(_clock::now()), _scale(scale) {} + explicit Timer(const double scale) : _beg(_clock::now()), _scale(scale) {} void reset() { _beg = _clock::now(); } double elapsed() const { return _scale * std::chrono::duration_cast<_second>(_clock::now() - _beg).count(); } diff --git a/benchmark/run_all.sh b/benchmark/run_all.sh new file mode 100755 index 0000000..f2e1477 --- /dev/null +++ b/benchmark/run_all.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +for bench in bench_*; do + echo "Running ${bench} ..." + ./run.sh $bench +done diff --git a/test/ut10/main.cpp b/test/ut10/main.cpp index 285aaae..1be7171 100644 --- a/test/ut10/main.cpp +++ b/test/ut10/main.cpp @@ -21,7 +21,8 @@ int main() ffnn->pushFeatureMapLayer(4); ffnn->getFeatureMapLayer(1)->setNMaps(1, 1, 0, 1, 0); // we specify only 3 units - ffnn->getFeatureMapLayer(1)->setSize(6); // now the other 2 should be defaulted to IDMU + ffnn->getFeatureMapLayer(1)->setSize(6); // now the other 2 should be defaulted to IDMU (generates warning) + ffnn->getFeatureMapLayer(1)->setNMaps(1, 1, 0, 1, 2); // to suppress further warning on copies //printFFNNStructure(ffnn); diff --git a/test/ut5/main.cpp b/test/ut5/main.cpp index 2bdf27b..d9ed5ed 100644 --- a/test/ut5/main.cpp +++ b/test/ut5/main.cpp @@ -17,10 +17,10 @@ int main(){ for (ActivationFunctionInterface * actf : std_actf::supported_actf){ const double TINY = actf->getIdCode() == "EXP" ? 0.002 : TINY_DEFAULT; - cout << "actf = " << actf->getIdCode() << endl; + // cout << "actf = " << actf->getIdCode() << endl; for (double x : x_to_test){ - cout << " x = " << x << endl; + // cout << " x = " << x << endl; const double f = actf->f(x); @@ -31,8 +31,8 @@ int main(){ const double fdx = actf->f(xdx); const double num_f1d = (fdx - f)/dx; - cout << " f1d = " << f1d << endl; - cout << " num_f1d = " << num_f1d << endl; + // cout << " f1d = " << f1d << endl; + // cout << " num_f1d = " << num_f1d << endl; assert( abs(num_f1d-f1d) < TINY ); @@ -43,8 +43,8 @@ int main(){ const double fmdx = actf->f(xmdx); const double num_f2d = (fdx - 2.*f + fmdx)/(dx*dx); - cout << " f2d = " << f2d << endl; - cout << " num_f2d = " << num_f2d << endl; + // cout << " f2d = " << f2d << endl; + // cout << " num_f2d = " << num_f2d << endl; assert( abs(num_f2d-f2d) < TINY ); @@ -54,8 +54,8 @@ int main(){ const double fdxdx = actf->f(x+dx+dx); const double num_f3d = (fdxdx - 3.*fdx +3*f - fmdx)/(dx*dx*dx); - cout << " f3d = " << f3d << endl; - cout << " num_f3d = " << num_f3d << endl; + // cout << " f3d = " << f3d << endl; + // cout << " num_f3d = " << num_f3d << endl; assert( abs(num_f3d-f3d) < TINY*20 ); @@ -68,7 +68,7 @@ int main(){ assert( abs(fad_f3d-f3d) < TINY ); } - cout << endl; + // cout << endl; } return 0; From 91ccf5bdc0a5c8079e56960ec2b0fdc9b59d130c Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Sat, 23 Feb 2019 22:05:07 +0100 Subject: [PATCH 15/18] improved the way OpenMP is handled --- CMakeLists.txt | 2 +- README.md | 6 ++++-- doc/doxygen/doxygen.conf | 3 ++- include/ffnn/layer/FedLayer.hpp | 3 +++ src/layer/FedLayer.cpp | 23 +++++++++++++++++++++ src/layer/NetworkLayer.cpp | 4 +--- src/net/FeedForwardNeuralNetwork.cpp | 30 ++-------------------------- 7 files changed, 36 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb8c6ca..6352f39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ message(STATUS "Configured GSL_ROOT_DIR: ${GSL_ROOT_DIR}") if (USE_OPENMP) find_package(OpenMP) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -DOPENMP=1") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -DOPENMP") message(STATUS "OPENMP_LIBRARY_PATHS: ${OpenMP_CXX_LIBRARY}") message(STATUS "OPENMP_LIBRARIES: ${OpenMP_CXX_LIBRARIES}") endif() diff --git a/README.md b/README.md index ff13741..dfd4aab 100644 --- a/README.md +++ b/README.md @@ -45,11 +45,13 @@ Note that we build out-of-tree, so the compiled library and executable files can # First steps -You may want to read `doc/user_manual.pdf` to get a quick overview of the libraries functionality. However, it is not guaranteed to be perfectly up-to-date and accurate. Therefore, the best way to get your own code started is by studying the examples in `examples/`. See `examples/README.md` for further guidance. +You may want to read `doc/user_manual.pdf` to get a quick overview of the libraries functionality. However, it is not guaranteed to be perfectly up-to-date and accurate. +Therefore, the best way to get your own code started is by studying the examples in `examples/`. See `examples/README.md` for further guidance. # Multi-threading: OpenMP This library supports multi-threading computation with a shared memory paradigm, thanks to OpenMP. -To activate this feature, set `USE_OPENMP=1` inside your config.sh, before building. Currently it is not recommended to use this, in most cases. +To activate this feature, set `USE_OPENMP=1` inside your config.sh, before building. It is recommended to use this only for larger networks. +You can fine tune performance by setting the `OMP_NUM_THREADS` environment variable. diff --git a/doc/doxygen/doxygen.conf b/doc/doxygen/doxygen.conf index e9f5ca3..aac79e3 100644 --- a/doc/doxygen/doxygen.conf +++ b/doc/doxygen/doxygen.conf @@ -791,7 +791,8 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = "../../src" \ +INPUT = "../../include/ffnn" \ + "../../src" \ "doxygen_stl.cpp" # This tag can be used to specify the character encoding of the source files diff --git a/include/ffnn/layer/FedLayer.hpp b/include/ffnn/layer/FedLayer.hpp index f323948..0728104 100644 --- a/include/ffnn/layer/FedLayer.hpp +++ b/include/ffnn/layer/FedLayer.hpp @@ -42,6 +42,9 @@ class FedLayer: public NetworkLayer virtual FeederInterface * connectUnitOnTopOfLayer(NetworkLayer * nl, const int &i) = 0; // should create and return the feeder for the given unit void connectOnTopOfLayer(NetworkLayer * nl); void disconnect(); + + // --- Computation + void computeValues(); // overriding to add OMP pragma }; #endif diff --git a/src/layer/FedLayer.cpp b/src/layer/FedLayer.cpp index f488033..d3d5eaf 100644 --- a/src/layer/FedLayer.cpp +++ b/src/layer/FedLayer.cpp @@ -113,3 +113,26 @@ void FedLayer::disconnect() _U_fed[i]->setFeeder(NULL); } } + + +// --- Compute Values (with OMP pragma) + +void FedLayer::computeValues() +{ +#ifdef OPENMP + // compile with -DOPENMP -fopenmp flags to use parallelization here + + if (this->getNUnits()>2) { +#pragma omp for schedule(static, 1) + for (std::vector::size_type i=0; i<_U.size(); ++i) _U[i]->computeValues(); + } + else { +#pragma omp single +#endif + + for (std::vector::size_type i=0; i<_U.size(); ++i) _U[i]->computeValues(); + +#ifdef OPENMP + } +#endif +} diff --git a/src/layer/NetworkLayer.cpp b/src/layer/NetworkLayer.cpp index 0cbc85b..8eb5dae 100644 --- a/src/layer/NetworkLayer.cpp +++ b/src/layer/NetworkLayer.cpp @@ -109,8 +109,6 @@ void NetworkLayer::addFirstDerivativeSubstrate(const int &nx0) void NetworkLayer::computeValues() { -#ifdef OPENMP -#pragma omp for schedule(static, 1) -#endif + #pragma omp single // per default (FedLayer overwrites this method with omp for instead) for (std::vector::size_type i=0; i<_U.size(); ++i) _U[i]->computeValues(); } diff --git a/src/net/FeedForwardNeuralNetwork.cpp b/src/net/FeedForwardNeuralNetwork.cpp index d5d93eb..66927ad 100644 --- a/src/net/FeedForwardNeuralNetwork.cpp +++ b/src/net/FeedForwardNeuralNetwork.cpp @@ -12,10 +12,6 @@ #include #include -#ifdef OPENMP -#include //to detect the number of hardware threads on the system -#endif - // --- Beta @@ -420,35 +416,13 @@ void FeedForwardNeuralNetwork::evaluate(const double * in, double * out, double } } -#ifdef OPENMP -bool compare_NUnits(NetworkLayer * A, NetworkLayer * B) { return A->getNUnits()getNUnits(); } -#endif - void FeedForwardNeuralNetwork::FFPropagate() { - _L_in->computeValues(); // OpenMP not worth for input layer - -#ifdef OPENMP -// compile with -DOPENMP -fopenmp flags to use parallelization here - - int nthreads = std::min( (int)std::thread::hardware_concurrency(), (*std::max_element(_L.begin()+1, _L.end(), compare_NUnits))->getNUnits() - 1 ); - if (nthreads>1) { -#pragma omp parallel num_threads(nthreads) - for (std::vector::size_type i=1; i<_L.size(); ++i) - { - _L[i]->computeValues(); // actual omp for inside computeValues -#pragma omp barrier // just to be sure - } - } - else { -#endif - for (std::vector::size_type i=1; i<_L.size(); ++i) + #pragma omp parallel default(none) + for (std::vector::size_type i=0; i<_L.size(); ++i) { _L[i]->computeValues(); } -#ifdef OPENMP - } -#endif } From 7ff054889ffdf2831caa1c52e47eb38fb1d094af Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Sun, 24 Feb 2019 00:09:03 +0100 Subject: [PATCH 16/18] two simple changes for significant speedup & reduced memory consumption for large networks --- include/ffnn/layer/NetworkLayer.hpp | 6 +++--- src/layer/NetworkLayer.cpp | 29 +++++++++++++++++++--------- src/net/FeedForwardNeuralNetwork.cpp | 8 +++++--- src/unit/FedUnit.cpp | 17 +++++++++------- 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/include/ffnn/layer/NetworkLayer.hpp b/include/ffnn/layer/NetworkLayer.hpp index 4edbc65..63afd4f 100644 --- a/include/ffnn/layer/NetworkLayer.hpp +++ b/include/ffnn/layer/NetworkLayer.hpp @@ -62,9 +62,9 @@ class NetworkLayer: public SerializableComponent // --- Values to compute - void addCrossSecondDerivativeSubstrate(const int &nx0, const int &nvp); - void addCrossFirstDerivativeSubstrate(const int &nx0, const int &nvp); - void addVariationalFirstDerivativeSubstrate(const int &nvp); + void addCrossSecondDerivativeSubstrate(const int &nx0); + void addCrossFirstDerivativeSubstrate(const int &nx0); + void addVariationalFirstDerivativeSubstrate(); void addSecondDerivativeSubstrate(const int &nx0); void addFirstDerivativeSubstrate(const int &nx0); diff --git a/src/layer/NetworkLayer.cpp b/src/layer/NetworkLayer.cpp index 8eb5dae..231de14 100644 --- a/src/layer/NetworkLayer.cpp +++ b/src/layer/NetworkLayer.cpp @@ -65,26 +65,35 @@ void NetworkLayer::setSize(const int &nunits) // --- Values to compute -void NetworkLayer::addCrossSecondDerivativeSubstrate(const int &nx0, const int &nvp) +void NetworkLayer::addCrossSecondDerivativeSubstrate(const int &nx0) { - for (std::vector::size_type i=0; i<_U.size(); ++i){ - _U[i]->setCrossSecondDerivativeSubstrate(nx0, nvp); + const int nvp = this->getMaxVariationalParameterIndex()+1; + if (nvp > 0) { + for (std::vector::size_type i=0; i<_U.size(); ++i){ + _U[i]->setCrossSecondDerivativeSubstrate(nx0, nvp); + } } } -void NetworkLayer::addCrossFirstDerivativeSubstrate(const int &nx0, const int &nvp) +void NetworkLayer::addCrossFirstDerivativeSubstrate(const int &nx0) { - for (std::vector::size_type i=0; i<_U.size(); ++i){ - _U[i]->setCrossFirstDerivativeSubstrate(nx0, nvp); + const int nvp = this->getMaxVariationalParameterIndex()+1; + if (nvp > 0) { + for (std::vector::size_type i=0; i<_U.size(); ++i){ + _U[i]->setCrossFirstDerivativeSubstrate(nx0, nvp); + } } } -void NetworkLayer::addVariationalFirstDerivativeSubstrate(const int &nvp) +void NetworkLayer::addVariationalFirstDerivativeSubstrate() { - for (std::vector::size_type i=0; i<_U.size(); ++i){ - _U[i]->setVariationalFirstDerivativeSubstrate(nvp); + const int nvp = this->getMaxVariationalParameterIndex()+1; + if (nvp > 0) { + for (std::vector::size_type i=0; i<_U.size(); ++i){ + _U[i]->setVariationalFirstDerivativeSubstrate(nvp); + } } } @@ -109,6 +118,8 @@ void NetworkLayer::addFirstDerivativeSubstrate(const int &nx0) void NetworkLayer::computeValues() { + #ifdef OPENMP #pragma omp single // per default (FedLayer overwrites this method with omp for instead) + #endif for (std::vector::size_type i=0; i<_U.size(); ++i) _U[i]->computeValues(); } diff --git a/src/net/FeedForwardNeuralNetwork.cpp b/src/net/FeedForwardNeuralNetwork.cpp index 66927ad..79e768c 100644 --- a/src/net/FeedForwardNeuralNetwork.cpp +++ b/src/net/FeedForwardNeuralNetwork.cpp @@ -418,7 +418,9 @@ void FeedForwardNeuralNetwork::evaluate(const double * in, double * out, double void FeedForwardNeuralNetwork::FFPropagate() { + #ifdef OPENMP #pragma omp parallel default(none) + #endif for (std::vector::size_type i=0; i<_L.size(); ++i) { _L[i]->computeValues(); @@ -459,7 +461,7 @@ void FeedForwardNeuralNetwork::addCrossSecondDerivativeSubstrate() // set the substrate in the units for (std::vector::size_type i=0; i<_L.size(); ++i){ - _L[i]->addCrossSecondDerivativeSubstrate(getNInput(), _nvp); + _L[i]->addCrossSecondDerivativeSubstrate(getNInput()); } _flag_c2d = true; @@ -479,7 +481,7 @@ void FeedForwardNeuralNetwork::addCrossFirstDerivativeSubstrate() // set the substrate in the units for (std::vector::size_type i=0; i<_L.size(); ++i) { - _L[i]->addCrossFirstDerivativeSubstrate(getNInput(), _nvp); + _L[i]->addCrossFirstDerivativeSubstrate(getNInput()); } _flag_c1d = true; @@ -493,7 +495,7 @@ void FeedForwardNeuralNetwork::addVariationalFirstDerivativeSubstrate() // set the substrate in the units for (std::vector::size_type i=0; i<_L.size(); ++i) { - _L[i]->addVariationalFirstDerivativeSubstrate(_nvp); + _L[i]->addVariationalFirstDerivativeSubstrate(); } _flag_v1d = true; diff --git a/src/unit/FedUnit.cpp b/src/unit/FedUnit.cpp index 27305a3..28f0335 100644 --- a/src/unit/FedUnit.cpp +++ b/src/unit/FedUnit.cpp @@ -4,11 +4,12 @@ #include #include // for NULL - // --- Computation void FedUnit::computeFeed(){ if (_feeder){ + const int mynvp = _feeder->getMaxVariationalParameterIndex()+1; + // unit value _pv = _feeder->getFeed(); @@ -22,17 +23,17 @@ void FedUnit::computeFeed(){ } if (_first_var_der) { - for (int j=0; j<_nvp; ++j) _first_var_der[j] = _feeder->getVariationalFirstDerivativeFeed(j); + for (int j=0; jgetVariationalFirstDerivativeFeed(j); } if (_cross_first_der) { - for (int j=0; j<_nvp; ++j) { + for (int j=0; jgetCrossFirstDerivativeFeed(i, j); } } if (_cross_second_der) { - for (int j=0; j<_nvp; ++j) { + for (int j=0; jgetCrossSecondDerivativeFeed(i, j); } } @@ -42,6 +43,8 @@ void FedUnit::computeFeed(){ void FedUnit::computeDerivatives(){ if (_feeder) { + const int mynvp = _feeder->getMaxVariationalParameterIndex()+1; + // first derivative if (_v1d){ for (int i=0; i<_nx0; ++i) @@ -58,7 +61,7 @@ void FedUnit::computeDerivatives(){ } // variational first derivative if (_v1vd){ - for (int i=0; i<_nvp; ++i) + for (int i=0; i Date: Sun, 24 Feb 2019 19:36:02 +0100 Subject: [PATCH 17/18] fix cmakelist typo and mini changes to feeders --- src/CMakeLists.txt | 2 +- src/feed/FeederInterface.cpp | 5 +-- src/feed/NNRay.cpp | 66 +++++++++++++++--------------------- src/feed/VariableFeeder.cpp | 5 +-- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 91ac07e..0bd9f8d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,4 +2,4 @@ file(GLOB SOURCES "*/*.cpp") add_library(ffnn SHARED ${SOURCES}) target_link_libraries(ffnn "${GSL_LIBRARIES}" "${OpenMP_CXX_LIBRARIES}") # shared libs add_library(ffnn_static STATIC ${SOURCES}) -target_link_libraries(ffnn_static "{$GSL_LIBRARIES}" "${OpenMP_CXX_LIBRARIES}") # static (+ some shared) libs +target_link_libraries(ffnn_static "${GSL_LIBRARIES}" "${OpenMP_CXX_LIBRARIES}") # static (+ some shared) libs diff --git a/src/feed/FeederInterface.cpp b/src/feed/FeederInterface.cpp index e34c615..dfc26f3 100644 --- a/src/feed/FeederInterface.cpp +++ b/src/feed/FeederInterface.cpp @@ -108,8 +108,5 @@ bool FeederInterface::isVPIndexUsedInSources(const int &id) bool FeederInterface::isVPIndexUsedForFeeder(const int &id) { - if ( isVPIndexUsedInFeeder(id) || isVPIndexUsedInSources(id) ) { - return true; - } - else return false; + return ( isVPIndexUsedInFeeder(id) || isVPIndexUsedInSources(id) ); } diff --git a/src/feed/NNRay.cpp b/src/feed/NNRay.cpp index 969f54b..e09a6df 100644 --- a/src/feed/NNRay.cpp +++ b/src/feed/NNRay.cpp @@ -107,61 +107,49 @@ double NNRay::getSecondDerivativeFeed(const int &i2d){ double NNRay::getVariationalFirstDerivativeFeed(const int &iv1d){ - double feed = 0.; - - if (iv1d < _vp_id_shift+(int)_vp.size()) { + if (iv1d >= _vp_id_shift) { // if the variational parameter with index iv1d is in the ray add the following element - if (iv1d >= _vp_id_shift) { - feed += _sources[ iv1d - _vp_id_shift ]->getValue(); - } - else { - // add source components - for (size_t i=0; i<_map_index_to_sources[iv1d].size(); ++i) { - feed += _beta[_map_index_to_sources[iv1d][i]] * _sources[_map_index_to_sources[iv1d][i]]->getVariationalFirstDerivativeValue(iv1d); - } + return _sources[ iv1d - _vp_id_shift ]->getValue(); + } + else { + // else add source components + double feed = 0.; + for (size_t i=0; i<_map_index_to_sources[iv1d].size(); ++i) { + feed += _beta[_map_index_to_sources[iv1d][i]] * _sources[_map_index_to_sources[iv1d][i]]->getVariationalFirstDerivativeValue(iv1d); } + return feed; } - - return feed; } double NNRay::getCrossFirstDerivativeFeed(const int &i1d, const int &iv1d){ - double feed = 0.; - - if (iv1d < _vp_id_shift+(int)_vp.size()) { + if (iv1d >= _vp_id_shift) { // if the variational parameter with index iv1d is in the ray add the following element - if (iv1d >= _vp_id_shift) { - feed += _sources[ iv1d - _vp_id_shift ]->getFirstDerivativeValue(i1d); - } - else { - // add source components - for (size_t i=0; i<_map_index_to_sources[iv1d].size(); ++i) { - feed += _beta[_map_index_to_sources[iv1d][i]] * _sources[_map_index_to_sources[iv1d][i]]->getCrossFirstDerivativeValue(i1d, iv1d); - } + return _sources[ iv1d - _vp_id_shift ]->getFirstDerivativeValue(i1d); + } + else { + // else add source components + double feed = 0.; + for (size_t i=0; i<_map_index_to_sources[iv1d].size(); ++i) { + feed += _beta[_map_index_to_sources[iv1d][i]] * _sources[_map_index_to_sources[iv1d][i]]->getCrossFirstDerivativeValue(i1d, iv1d); } + return feed; } - - return feed; } double NNRay::getCrossSecondDerivativeFeed(const int &i2d, const int &iv2d){ - double feed = 0.; - - if (iv2d < _vp_id_shift+(int)_vp.size()) { + if (iv2d >= _vp_id_shift) { // if the variational parameter with index iv2d is in the ray add the following element - if (iv2d >= _vp_id_shift) { - feed += _sources[ iv2d - _vp_id_shift ]->getSecondDerivativeValue(i2d); - } - else { - // add source components - for (size_t i=0; i<_map_index_to_sources[iv2d].size(); ++i) { - feed += _beta[_map_index_to_sources[iv2d][i]] * _sources[_map_index_to_sources[iv2d][i]]->getCrossSecondDerivativeValue(i2d, iv2d); - } + return _sources[ iv2d - _vp_id_shift ]->getSecondDerivativeValue(i2d); + } + else { + // else add source components + double feed = 0.; + for (size_t i=0; i<_map_index_to_sources[iv2d].size(); ++i) { + feed += _beta[_map_index_to_sources[iv2d][i]] * _sources[_map_index_to_sources[iv2d][i]]->getCrossSecondDerivativeValue(i2d, iv2d); } + return feed; } - - return feed; } diff --git a/src/feed/VariableFeeder.cpp b/src/feed/VariableFeeder.cpp index ff818a8..ea9abb4 100644 --- a/src/feed/VariableFeeder.cpp +++ b/src/feed/VariableFeeder.cpp @@ -85,9 +85,6 @@ bool VariableFeeder::getVariationalParameterValue(const int &id, double &value){ bool VariableFeeder::isVPIndexUsedInFeeder(const int &id) { - if ( _vp_id_shift <= id && id <_vp_id_shift+(int)_vp.size()) { - return true; - } - else return false; + return ( _vp_id_shift <= id && id <_vp_id_shift+(int)_vp.size() ); } From 3fa5dffac9d6cb689469d0462ba7da0b5f943807 Mon Sep 17 00:00:00 2001 From: Jan Kessler Date: Sun, 24 Feb 2019 21:16:28 +0100 Subject: [PATCH 18/18] codefactor suggestions --- .travis.yml | 2 +- benchmark/run.sh | 2 +- benchmark/run_prof.sh | 4 ++-- build.sh | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index c31b814..a503f0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,7 +68,7 @@ script: ./build.sh || exit 1; fi; -- | +- | if [[ "$USE_DOCKER" == "TRUE" ]]; then if [[ "$USE_OPENMP" == "TRUE" ]]; then docker run -it -v $(pwd):/root/repo nnvmc/base /bin/bash -c "cd /root/repo/build && make test"; diff --git a/benchmark/run.sh b/benchmark/run.sh index 2ce9906..f220260 100755 --- a/benchmark/run.sh +++ b/benchmark/run.sh @@ -1,6 +1,6 @@ #!/bin/sh -if [ "$1" == "" ]; then +if [ "$1" = "" ]; then echo "Expected the name of the benchmark to run as first argument." else bench=$1 diff --git a/benchmark/run_prof.sh b/benchmark/run_prof.sh index 2c1b8ba..6460068 100755 --- a/benchmark/run_prof.sh +++ b/benchmark/run_prof.sh @@ -1,8 +1,8 @@ #!/bin/sh -if [ "$1" == "" ]; then +if [ "$1" = "" ]; then echo "Expected the name of the benchmark to run as first argument." -elif [ "$2" == "" ]; then +elif [ "$2" = "" ]; then echo "Expected the path of libprofiler.so as second argument." else bench=$1 diff --git a/build.sh b/build.sh index 57bc635..e0335e4 100755 --- a/build.sh +++ b/build.sh @@ -4,7 +4,7 @@ mkdir -p build && cd build cmake -DCMAKE_CXX_COMPILER="${CXX_COMPILER}" -DUSER_CXX_FLAGS="${CXX_FLAGS}" -DUSE_COVERAGE="${USE_COVERAGE}" -DUSE_OPENMP="${USE_OPENMP}" -DGSL_ROOT_DIR="${GSL_ROOT}" .. -if [ "$1" == "" ]; then +if [ "$1" = "" ]; then make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) else make -j$1