From a18672760352dcca81fb1c4e74f79d8c02cba2cc Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm <philipp@uvos.xyz> Date: Mon, 11 Mar 2024 16:11:40 +0100 Subject: [PATCH] fvalueEq: handle eadge case at 0 where epsilon is zero --- basicmath.cpp | 4 ++-- eisgenerator/eistype.h | 3 ++- eisgenerator/model.h | 22 +++++++++++++++++++++- eistype.cpp | 14 ++++++++++++++ model.cpp | 34 ++++++++++++++++++++++++++++++++-- 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/basicmath.cpp b/basicmath.cpp index 74cfcc9..f08bff2 100644 --- a/basicmath.cpp +++ b/basicmath.cpp @@ -248,7 +248,7 @@ void eis::removeDuplicates(std::vector<eis::DataPoint>& data) bool eis::fvalueEq(fvalue a, fvalue b, unsigned int ulp) { fvalue epsilon = std::numeric_limits<fvalue>::epsilon()*std::fabs(a+b)*ulp; - return a - epsilon < b && a + epsilon > b; + return a - epsilon <= b && a + epsilon >= b; } static std::pair<std::vector<eis::DataPoint>::const_iterator, std::vector<eis::DataPoint>::const_iterator> @@ -412,7 +412,7 @@ std::vector<eis::DataPoint> eis::fitToFrequencies(std::vector<fvalue> omegas, co return out; } -void difference(std::vector<eis::DataPoint>& a, const std::vector<eis::DataPoint>& b) +void eis::difference(std::vector<eis::DataPoint>& a, const std::vector<eis::DataPoint>& b) { assert(a.size() == b.size()); for(size_t i = 0; i < a.size(); ++i) diff --git a/eisgenerator/eistype.h b/eisgenerator/eistype.h index ebb0557..d151162 100644 --- a/eisgenerator/eistype.h +++ b/eisgenerator/eistype.h @@ -445,9 +445,10 @@ public: /** * @brief Returns the a vector of DataPoints as a pair of valarrays. * +* @param data the data to transform to valarrays * @return A pair of valarrays, first the real part and second the imaginary part. */ -std::pair<std::valarray<fvalue>, std::valarray<fvalue>> eisToValarrays(const std::vector<eis::DataPoint>& b); +std::pair<std::valarray<fvalue>, std::valarray<fvalue>> eisToValarrays(const std::vector<eis::DataPoint>& data); /** * @brief Returns the mean l2 element wise distance of the given spectra. diff --git a/eisgenerator/model.h b/eisgenerator/model.h index 2f053da..e5f9dce 100644 --- a/eisgenerator/model.h +++ b/eisgenerator/model.h @@ -52,7 +52,7 @@ private: static size_t paramSkipIndex(const std::string& str, size_t index); static void addComponantToFlat(Componant* componant, std::vector<Componant*>* flatComponants); - static void sweepThreadFn(std::vector<std::vector<DataPoint>>* data, Model* model, size_t start, size_t stop, const Range& omega); + static void sweepThreadFn(std::vector<std::vector<DataPoint>>* data, Model* model, size_t start, size_t stop, const std::vector<fvalue>& omega); size_t getActiveParameterCount(); @@ -118,6 +118,26 @@ public: */ std::vector<DataPoint> executeSweep(const std::vector<fvalue>& omega, size_t index = 0); + /** + * @brief Executes a frequency and parameter sweep at the given parameter indecies + * + * @param omega The range along which to execute the frequency sweep. + * @param indecies the parameter indecies to include in the sweep + * @param parallel if this is set to true, the parameter sweep is executed in parallel + * @return A vector of vectors of DataPoint structs containing the impedance at every frequency sweep and parameter index. + */ + std::vector<std::vector<DataPoint>> executeSweeps(const Range& omega, const std::vector<size_t>& indecies, bool parallel = false); + + /** + * @brief Executes a frequency and parameter sweep at the given parameter indecies + * + * @param omega A vector of frequencies in rad/s to calculate the impedance at. + * @param indecies the parameter indecies to include in the sweep + * @param parallel if this is set to true, the parameter sweep is executed in parallel + * @return A vector of vectors of DataPoint structs containing the impedance at every frequency sweep and parameter index. + */ + std::vector<std::vector<DataPoint>> executeSweeps(const std::vector<fvalue>& omega, const std::vector<size_t>& indecies, bool parallel = false); + /** * @brief Executes a frequency sweep with the given omega values for each parameter combination in the applied parameter sweep. * diff --git a/eistype.cpp b/eistype.cpp index 5900750..5d499f8 100644 --- a/eistype.cpp +++ b/eistype.cpp @@ -44,6 +44,20 @@ EisSpectra eis::loadFromDisk(const std::filesystem::path& path) return EisSpectra(path); } +std::pair<std::valarray<fvalue>, std::valarray<fvalue>> eis::eisToValarrays(const std::vector<eis::DataPoint>& data) +{ + std::valarray<fvalue> real(data.size()); + std::valarray<fvalue> imag(data.size()); + + for(size_t i = 0; i < data.size(); ++i) + { + real[i] = data[i].im.real(); + imag[i] = data[i].im.imag(); + } + + return {real, imag}; +} + void eis::Range::print(int level) const { Log(static_cast<Log::Level>(level))<<"Range "<<start<<'-'<<end<<' '<<count<<" steps"<<(log ? " Log" : ""); diff --git a/model.cpp b/model.cpp index 62eab45..c172bff 100644 --- a/model.cpp +++ b/model.cpp @@ -372,7 +372,37 @@ std::vector<DataPoint> Model::executeSweep(const std::vector<fvalue>& omega, siz return results; } -void Model::sweepThreadFn(std::vector<std::vector<DataPoint>>* data, Model* model, size_t start, size_t stop, const Range& omega) +std::vector<std::vector<DataPoint>> Model::executeSweeps(const Range& omega, const std::vector<size_t>& indecies, bool parallel) +{ + return executeSweeps(omega.getRangeVector(), indecies, parallel); +} + +std::vector<std::vector<DataPoint>> Model::executeSweeps(const std::vector<fvalue>& omega, const std::vector<size_t>& indecies, bool parallel) +{ + unsigned int threadsCount = parallel ? std::thread::hardware_concurrency() : 1; + + if(indecies.size() < threadsCount*10) + threadsCount = 1; + + size_t countPerThread = indecies.size()/threadsCount; + std::vector<std::thread> threads(threadsCount); + std::vector<Model> models(threadsCount, *this); + + std::vector<std::vector<DataPoint>> data(indecies.size()); + + for(size_t i = 0; i < threadsCount; ++i) + { + size_t start = i*countPerThread; + size_t stop = i < threadsCount-1 ? (i+1)*countPerThread : indecies.size(); + threads[i] = std::thread(sweepThreadFn, &data, &models[i], start, stop, omega); + } + for(size_t i = 0; i < threadsCount; ++i) + threads[i].join(); + + return data; +} + +void Model::sweepThreadFn(std::vector<std::vector<DataPoint>>* data, Model* model, size_t start, size_t stop, const std::vector<fvalue>& omega) { for(size_t i = start; i < stop; ++i) { @@ -396,7 +426,7 @@ std::vector<std::vector<DataPoint>> Model::executeAllSweeps(const Range& omega) { size_t start = i*countPerThread; size_t stop = i < threadsCount-1 ? (i+1)*countPerThread : count; - threads[i] = std::thread(sweepThreadFn, &data, &models[i], start, stop, std::ref(omega)); + threads[i] = std::thread(sweepThreadFn, &data, &models[i], start, stop, omega.getRangeVector()); } for(size_t i = 0; i < threadsCount; ++i) threads[i].join(); -- GitLab