diff --git a/componant/paralellseriel.cpp b/componant/paralellseriel.cpp index bd4a275822c13f3c6ba63d25051bee45adb54b6a..4139f1d901441aa59006d8253f091b150032fe15 100644 --- a/componant/paralellseriel.cpp +++ b/componant/paralellseriel.cpp @@ -20,9 +20,19 @@ #include "componant/paralellseriel.h" #include "componant/componant.h" +#include "type.h" using namespace eis; +std::vector<bool> ParallelSerial::contributes(fvalue omega, fvalue threshold) +{ + std::vector<fvalue> ratios = contributionRatio(omega); + std::vector<bool> out(ratios.size()); + for(size_t i = 0; i < ratios.size(); ++i) + out[i] = ratios[i] > threshold; + return out; +} + Parallel::Parallel(std::vector<Componant*> componantsIn): componants(componantsIn) { } @@ -108,6 +118,17 @@ std::string Parallel::getTorchScript(std::vector<std::string>& parameters) return out; } +std::vector<fvalue> Parallel::contributionRatio(fvalue omega) +{ + std::vector<fvalue> out(componants.size()); + for(size_t i = 0; i < componants.size(); ++i) + out[i] = std::abs(componants[i]->execute(omega)); + fvalue max = *std::min_element(out.begin(), out.end()); + for(fvalue& val : out) + val = max / val; + return out; +} + Serial::Serial(std::vector<Componant*> componantsIn): componants(componantsIn) { } @@ -195,3 +216,14 @@ std::string Serial::getTorchScript(std::vector<std::string>& parameters) out.push_back(')'); return out; } + +std::vector<fvalue> Serial::contributionRatio(fvalue omega) +{ + std::vector<fvalue> out(componants.size()); + for(size_t i = 0; i < componants.size(); ++i) + out[i] = std::abs(componants[i]->execute(omega)); + fvalue max = *std::max_element(out.begin(), out.end()); + for(fvalue& val : out) + val = val / max; + return out; +} diff --git a/eisgenerator/componant/paralellseriel.h b/eisgenerator/componant/paralellseriel.h index 914e127909e265938bb29f40bf45f9458bb6ddab..3071737529087c814a49978f4ede64421ce8cb06 100644 --- a/eisgenerator/componant/paralellseriel.h +++ b/eisgenerator/componant/paralellseriel.h @@ -26,7 +26,14 @@ namespace eis { -class Parallel: public Componant +class ParallelSerial: public Componant +{ +public: + virtual std::vector<fvalue> contributionRatio(fvalue omega) = 0; + std::vector<bool> contributes(fvalue omega, fvalue threshold = 0.01); +}; + +class Parallel: public ParallelSerial { public: std::vector<Componant*> componants; @@ -43,9 +50,10 @@ public: virtual bool compileable() override; virtual std::string getCode(std::vector<std::string>& parameters) override; virtual std::string getTorchScript(std::vector<std::string>& parameters) override; + virtual std::vector<fvalue> contributionRatio(fvalue omega) override; }; -class Serial: public Componant +class Serial: public ParallelSerial { public: std::vector<Componant*> componants; @@ -62,6 +70,7 @@ public: virtual bool compileable() override; virtual std::string getCode(std::vector<std::string>& parameters) override; virtual std::string getTorchScript(std::vector<std::string>& parameters) override; + virtual std::vector<fvalue> contributionRatio(fvalue omega) override; }; } diff --git a/eisgenerator/model.h b/eisgenerator/model.h index 65cd099fdc6357bfb945653c4aadd6d749f8816c..0c5d1c4501077442aa9f197e7c1d69b028cbf4ef 100644 --- a/eisgenerator/model.h +++ b/eisgenerator/model.h @@ -309,6 +309,23 @@ public: */ std::vector<size_t> getRecommendedParamIndices(eis::Range omegaRange, double distance, bool threaded = false); + /** + * @brief Attempts to check if all elements contribute to the result + + * @param threashold contribution ratio below which the contribution is considered irrelivant + * @param omegaRange range of frequencies to consider + * @return True if all Contribute false otherwise + */ + bool allElementsContribute(eis::Range omegaRange, fvalue threashold = 0.01); + + /** + * @brief Checks if all elements in series with one another dont have too similar impedance + + * @param threashold contribution ratio below which the contribution is considered irrelivant + * @param omegaRange range of frequencies to consider + * @return True if all series have a difference false otherwise. + */ + bool hasSeriesDifference(eis::Range omegaRange, fvalue threashold = 0.1); /** * @brief Removes the series reistance from a model string (if any) diff --git a/kissplotcsv b/kissplotcsv index d608fcf489917fcf00c399e3ba5654f3a6a27990..a823e495e33786bd2ac8fa0f4617c55a30d7dbf9 100755 --- a/kissplotcsv +++ b/kissplotcsv @@ -124,5 +124,5 @@ set tics font \"Sans,12\"; \ set xlabel font \"Sans,15\"; \ set ylabel font \"Sans,15\"; \ set datafile separator ','; \ -plot '-' using $mode skip 3 notitle w l; +plot '-' using $mode skip 5 notitle w l; " diff --git a/main.cpp b/main.cpp index a724bfd86d25b38ae80c33390d21847dd4215251..6152ebd88df6f37edfeec871143b8610c95ee1a8 100644 --- a/main.cpp +++ b/main.cpp @@ -308,8 +308,7 @@ static void findRanges(const Config& config, eis::Model& model) static void outputRanges(const Config& config, eis::Model& model) { - std::vector<size_t> indices; - getRangeValuesForModel(config, model, &indices); + std::vector<size_t> indices = model.getRecommendedParamIndices(config.omegaRange, config.rangeDistance, config.threaded); if(indices.empty()) { diff --git a/model.cpp b/model.cpp index eb61a2acad1b797eef530fcacf3e83ffa0ff9147..27593f9d2390e7f255582596331e23bf51ba48f3 100644 --- a/model.cpp +++ b/model.cpp @@ -590,14 +590,6 @@ std::vector<size_t> Model::getRecommendedParamIndices(eis::Range omegaRange, dou continue; } - fvalue nonConstantess = std::abs(pearsonCorrelation(data)); - if(nonConstantess < 0.1) - { - eis::Log(eis::Log::DEBUG)<<"skipping output for step "<<i - <<" as data is too constant: "<<nonConstantess; - continue; - } - std::vector<std::vector<eis::DataPoint>>::iterator search; if(threaded) { @@ -622,8 +614,23 @@ std::vector<size_t> Model::getRecommendedParamIndices(eis::Range omegaRange, dou std::cout<<std::flush; } } + + std::vector<size_t> out; + out.reserve(indices.size()); + for(size_t candidate : indices) + { + resolveSteps(candidate); + if(!allElementsContribute(omegaRange)) + eis::Log(eis::Log::DEBUG)<<"skipping "<<candidate<<" as not all elements contribute"; + else if(!hasSeriesDifference(omegaRange)) + eis::Log(eis::Log::DEBUG)<<"skipping "<<candidate<<" as not all elements in series are different"; + else + out.push_back(candidate); + + } + eis::Log(eis::Log::INFO, false)<<'\n'; - return indices; + return out; } size_t Model::getUuid() const @@ -761,3 +768,84 @@ void Model::removeSeriesResitance(std::string& model) } } } + +bool Model::allElementsContribute(eis::Range omegaRange, fvalue threashold) +{ + std::vector<Componant*> componants = getFlatComponants(); + componants.push_back(_model); + std::vector<ParallelSerial*> combiners; + for(Componant* componant : componants) + { + ParallelSerial* candidate = dynamic_cast<ParallelSerial*>(componant); + if(candidate) + combiners.push_back(candidate); + } + + std::vector<bool> contributesGlobal; + for(fvalue omega : omegaRange.getRangeVector()) + { + std::vector<bool> contributes; + for(ParallelSerial* combiner : combiners) + { + std::vector<bool> contributesLocal = combiner->contributes(omega); + contributes.insert(contributes.end(), contributesLocal.begin(), contributesLocal.end()); + } + if(contributesGlobal.empty()) + { + contributesGlobal = contributes; + } + else + { + for(size_t i = 0; i < contributesGlobal.size(); ++i) + contributesGlobal[i] = contributes[i] || contributesGlobal[i]; + } + + if(std::find(contributesGlobal.begin(), contributesGlobal.end(), false) == contributesGlobal.end()) + break; + } + + return std::find(contributesGlobal.begin(), contributesGlobal.end(), false) == contributesGlobal.end(); +} + + +bool Model::hasSeriesDifference(eis::Range omegaRange, fvalue threashold) +{ + std::vector<Componant*> componants = getFlatComponants(); + componants.push_back(_model); + std::vector<Serial*> serials; + for(Componant* componant : componants) + { + Serial* candidate = dynamic_cast<Serial*>(componant); + if(candidate) + serials.push_back(candidate); + } + + std::vector<bool> isDifferentGlobal; + for(fvalue omega : omegaRange.getRangeVector()) + { + bool allContribute = true; + for(Serial* serial : serials) + { + std::vector<std::complex<fvalue>> impedances; + for(Componant* componant : serial->componants) + impedances.push_back(componant->execute(omega)); + for(size_t i = 0; i < impedances.size() && allContribute; ++i) + { + for(size_t j = i+1; j < impedances.size(); ++j) + { + if(std::abs(impedances[i] - impedances[j])/std::abs(impedances[i]) < threashold) + { + allContribute = false; + break; + } + } + } + if(!allContribute) + break; + } + if(allContribute) + return true; + } + + return false; +} diff --git a/test.cpp b/test.cpp index 0d5f026ff558a06dc9c3f1925a086112a1b24cd9..b7214182f1e54ea22ce73bd6baef6d7a90edb6c8 100644 --- a/test.cpp +++ b/test.cpp @@ -545,6 +545,67 @@ bool testResize() return true; } +bool testContribution() +{ + eis::Range omega(1, 1e6, 50, true); + eis::Model model("r{0.001}c{1e-10~0.0001L}", 100, true); + + bool contributes = model.allElementsContribute(omega); + if(contributes) + { + eis::Log(eis::Log::ERROR)<<__func__<<" expected 0 got "<<contributes; + return false; + } + + model = eis::Model("r{1000}c{1e-10~0.0001L}", 100, true); + contributes = model.allElementsContribute(omega); + if(!contributes) + { + eis::Log(eis::Log::ERROR)<<__func__<<" expected 1 got "<<contributes; + return false; + } + + model = eis::Model("r{1}-r{1000}", 100, true); + contributes = model.allElementsContribute(omega); + if(contributes) + { + eis::Log(eis::Log::ERROR)<<__func__<<" expected 0 got "<<contributes; + return false; + } + + model = eis::Model("r{10}-r{10}", 100, true); + contributes = model.allElementsContribute(omega); + if(!contributes) + { + eis::Log(eis::Log::ERROR)<<__func__<<" expected 1 got "<<contributes; + return false; + } + + return true; +} + +bool testSeriesContribution() +{ + eis::Range omega(1, 1e6, 50, true); + eis::Model model("r{10}c{1e-5}-r{10}c{1e-5}", 100, true); + + bool contributes = model.hasSeriesDifference(omega); + if(contributes) + { + eis::Log(eis::Log::ERROR)<<__func__<<" expected 0 got "<<contributes; + return false; + } + + model = eis::Model("r{10}c{1e-5}-r{10}p{1e-5, 0.8}", 100, true); + contributes = model.hasSeriesDifference(omega); + if(!contributes) + { + eis::Log(eis::Log::ERROR)<<__func__<<" expected 1 got "<<contributes; + return false; + } + return true; +} + int main(int argc, char** argv) { eis::Log::headers = true; @@ -616,5 +677,11 @@ int main(int argc, char** argv) if(!testResize()) return 22; + if(!testContribution()) + return 23; + + if(!testSeriesContribution()) + return 24; + return 0; }