From 76f09c9fe1df737460d24f3f093ffd374d352d8d Mon Sep 17 00:00:00 2001 From: Walter Van Herck <w.van.herck@fz-juelich.de> Date: Fri, 3 Feb 2017 18:12:52 +0100 Subject: [PATCH] Refactor: ScalarFresnelMap now maintains a cache (hash map) of calculated Fresnel coefficients --- Core/Computation/MainComputation.cpp | 2 +- Core/Computation/MainComputation.h | 2 +- Core/Multilayer/HashKVector.cpp | 22 +++++++++++++++++++ Core/Multilayer/HashKVector.h | 33 ++++++++++++++++++++++++++++ Core/Multilayer/ScalarFresnelMap.cpp | 17 +++++++++++--- Core/Multilayer/ScalarFresnelMap.h | 8 +++++-- 6 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 Core/Multilayer/HashKVector.cpp create mode 100644 Core/Multilayer/HashKVector.h diff --git a/Core/Computation/MainComputation.cpp b/Core/Computation/MainComputation.cpp index eb763f1954b..d657a339f96 100644 --- a/Core/Computation/MainComputation.cpp +++ b/Core/Computation/MainComputation.cpp @@ -92,7 +92,7 @@ void MainComputation::runProtected() } IFresnelMap* MainComputation::createFresnelMap(const MultiLayer* p_multilayer, - const MultiLayer* p_inverted_multilayer) + const MultiLayer* p_inverted_multilayer) { if (!p_multilayer->requiresMatrixRTCoefficients()) return new ScalarFresnelMap(p_multilayer); diff --git a/Core/Computation/MainComputation.h b/Core/Computation/MainComputation.h index f7959257c38..1b60f584387 100644 --- a/Core/Computation/MainComputation.h +++ b/Core/Computation/MainComputation.h @@ -55,7 +55,7 @@ public: private: void runProtected(); static IFresnelMap* createFresnelMap(const MultiLayer* p_multilayer, - const MultiLayer* p_inverted_multilayer); + const MultiLayer* p_inverted_multilayer); std::unique_ptr<MultiLayer> mP_multi_layer; std::unique_ptr<MultiLayer> mP_inverted_multilayer; diff --git a/Core/Multilayer/HashKVector.cpp b/Core/Multilayer/HashKVector.cpp new file mode 100644 index 00000000000..706690ba9cb --- /dev/null +++ b/Core/Multilayer/HashKVector.cpp @@ -0,0 +1,22 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file Core/Computation/HashKVector.cpp +//! @brief Implements class HashKVector. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2017 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors J. Burle, J. M. Fisher, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "HashKVector.h" + +// Simple exclusive or of the std::hash<double> of its components +size_t HashKVector::operator()(kvector_t kvec) const noexcept +{ + return m_double_hash(kvec.x()) ^ m_double_hash(kvec.y()) ^ m_double_hash(kvec.z()); +} diff --git a/Core/Multilayer/HashKVector.h b/Core/Multilayer/HashKVector.h new file mode 100644 index 00000000000..5e76a968fb1 --- /dev/null +++ b/Core/Multilayer/HashKVector.h @@ -0,0 +1,33 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file Core/Computation/HashKVector.h +//! @brief Defines class HashKVector. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2017 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors J. Burle, J. M. Fisher, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef HASHKVECTOR_H +#define HASHKVECTOR_H + +#include "Vectors3D.h" +#include <functional> + +class HashKVector +{ +public: + HashKVector() {} + ~HashKVector() {} + + size_t operator()(kvector_t kvec) const noexcept; +private: + std::hash<double> m_double_hash; +}; + +#endif // HASHKVECTOR_H diff --git a/Core/Multilayer/ScalarFresnelMap.cpp b/Core/Multilayer/ScalarFresnelMap.cpp index 8d4c3fcc2d8..8edb9ba0830 100644 --- a/Core/Multilayer/ScalarFresnelMap.cpp +++ b/Core/Multilayer/ScalarFresnelMap.cpp @@ -23,6 +23,9 @@ ScalarFresnelMap::ScalarFresnelMap(const MultiLayer* multilayer) : mp_multilayer(multilayer) {} +ScalarFresnelMap::~ScalarFresnelMap() +{} + const ILayerRTCoefficients* ScalarFresnelMap::getOutCoefficients( const SimulationElement& sim_element, size_t layer_index) const { @@ -38,7 +41,15 @@ const ILayerRTCoefficients* ScalarFresnelMap::getInCoefficients( const ScalarRTCoefficients* ScalarFresnelMap::getCoefficients( kvector_t kvec, size_t layer_index) const { - SpecularMatrix::MultiLayerCoeff_t coeffs; - SpecularMatrix::execute(*mp_multilayer, kvec, coeffs); - return new ScalarRTCoefficients(coeffs[layer_index]); + ScalarRTCoefficients* result; + auto it = m_hash_table.find(kvec); + if (it != m_hash_table.end()) + result = new ScalarRTCoefficients(it->second[layer_index]); + else { + std::vector<ScalarRTCoefficients> coeffs; + SpecularMatrix::execute(*mp_multilayer, kvec, coeffs); + result = new ScalarRTCoefficients(coeffs[layer_index]); + m_hash_table[kvec] = std::move(coeffs); + } + return result; } diff --git a/Core/Multilayer/ScalarFresnelMap.h b/Core/Multilayer/ScalarFresnelMap.h index 1a021daf3f3..fd3b7e1e290 100644 --- a/Core/Multilayer/ScalarFresnelMap.h +++ b/Core/Multilayer/ScalarFresnelMap.h @@ -16,8 +16,10 @@ #ifndef SCALARFRESNELMAP_H #define SCALARFRESNELMAP_H +#include "HashKVector.h" #include "IFresnelMap.h" -#include "Vectors3D.h" +#include <unordered_map> +#include <vector> class MultiLayer; class ILayerRTCoefficients; @@ -31,7 +33,7 @@ class BA_CORE_API_ ScalarFresnelMap : public IFresnelMap { public: ScalarFresnelMap(const MultiLayer* multilayer); - ~ScalarFresnelMap() final {} + ~ScalarFresnelMap() final; //! Retrieves the amplitude coefficients for the given angles const ILayerRTCoefficients* getOutCoefficients ( @@ -44,6 +46,8 @@ public: private: const MultiLayer* mp_multilayer; const ScalarRTCoefficients* getCoefficients(kvector_t kvec, size_t layer_index) const; + mutable std::unordered_map<kvector_t, std::vector<ScalarRTCoefficients>, + HashKVector> m_hash_table; }; #endif // SCALARFRESNELMAP_H -- GitLab