diff --git a/eisgenerator/model.h b/eisgenerator/model.h index 908823d37322c7d5266b7765536dc428453a2d6f..7e53901e53f48581b8cbc32692312741705deeff 100644 --- a/eisgenerator/model.h +++ b/eisgenerator/model.h @@ -21,6 +21,10 @@ public: double end; size_t count; + double stepSize() const + { + return (end-start)/count; + } Range(double startI, double endI, size_t countI): start(startI), end(endI), count(countI){} Range() = default; }; @@ -45,10 +49,15 @@ public: Model& operator=(const Model& in); ~Model(); DataPoint execute(double omaga); - std::vector<DataPoint> sweep(const Range& omega); - bool sweepParams(const std::vector<Range>& componantRanges, const Range& omega, std::function<void(std::vector<DataPoint>&, const std::vector<double>&)> dataCb); + std::vector<DataPoint> executeSweep(const Range& omega); + bool executeParamSweep(const std::vector<Range>& componantRanges, const Range& omega, std::function<void(std::vector<DataPoint>&, const std::vector<double>&)> dataCb); + std::vector<DataPoint> executeParamByIndex(const std::vector<Range>& componantRanges, const Range& omega, size_t index); + std::string getModelStr(); std::vector<Componant*> getFlatComponants(); size_t getFlatParametersCount(); bool setFlatParameters(const std::vector<double>& parameters); + + static std::vector<double> getSweepParamByIndex(const std::vector<Range>& componantRanges, size_t index); + static size_t getRequiredStepsForSweeps(const std::vector<Range>& componantRanges); }; diff --git a/main.cpp b/main.cpp index 4c554b8789d64a4c88800d152ba0f457a35a9034..417fa70860ee94d32a62cbe55775e3796e7faf82 100644 --- a/main.cpp +++ b/main.cpp @@ -27,7 +27,7 @@ void runSingle() Model::Range omega(0, 1e6, 50); auto start = std::chrono::high_resolution_clock::now(); - results = model.sweep(omega); + results = model.executeSweep(omega); auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); @@ -35,7 +35,7 @@ void runSingle() std::cout<<"omega: "<<res.omega<<" real = "<<res.im.real()<<" im = "<<res.im.imag()<<'\n'; Model modelCopy(model); - results = modelCopy.sweep(omega); + results = modelCopy.executeSweep(omega); for(const Model::DataPoint& res : results) std::cout<<"omega: "<<res.omega<<" real = "<<res.im.real()<<" im = "<<res.im.imag()<<'\n'; @@ -67,7 +67,7 @@ void runSweep() Model::Range omega(0, 1e6, 25); auto start = std::chrono::high_resolution_clock::now(); - model.sweepParams(parameters, omega, &sweepCb); + model.executeParamSweep(parameters, omega, &sweepCb); auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); diff --git a/model.cpp b/model.cpp index 7b7bfb854c8b72f682ba38be7ddbba4413fd351a..da2bf5cf90e2c6d2efb038e9daa538a11d5b8f1e 100644 --- a/model.cpp +++ b/model.cpp @@ -230,7 +230,7 @@ std::vector<Componant*> Model::getFlatComponants() return getFlatComponants(); } -std::vector<Model::DataPoint> Model::sweep(const Range& omega) +std::vector<Model::DataPoint> Model::executeSweep(const Range& omega) { double step = (omega.end - omega.start)/omega.count; double currOmega = omega.start; @@ -245,7 +245,40 @@ std::vector<Model::DataPoint> Model::sweep(const Range& omega) return results; } -bool Model::sweepParams(const std::vector<Range>& componantRanges, const Range& omega, std::function<void(std::vector<DataPoint>&, const std::vector<double>&)> dataCb) +std::vector<Model::DataPoint> Model::executeParamByIndex(const std::vector<Range>& componantRanges, const Range& omega, size_t index) +{ + assert(setFlatParameters(getSweepParamByIndex(componantRanges, index))); + + return executeSweep(omega); +} + +size_t Model::getRequiredStepsForSweeps(const std::vector<Range>& componantRanges) +{ + size_t stepsRequired = 1; + for(size_t i = 0; i < componantRanges.size(); ++i) + stepsRequired *= componantRanges[i].count; + return stepsRequired; +} + +std::vector<double> Model::getSweepParamByIndex(const std::vector<Range>& componantRanges, size_t index) +{ + size_t parametersCount = componantRanges.size(); + std::vector<size_t> parameterIndexies(parametersCount, 0); + for(size_t i = 0; i < parametersCount && index > 0; ++i) + { + index = i > 0 ? index/componantRanges[i-1].count : index; + parameterIndexies[i] = index % componantRanges[i].count; + index -= parameterIndexies[i]; + } + + std::vector<double> parameters(parametersCount, 0); + for(size_t i = 0; i < parametersCount; ++i) + parameters[i] = parameterIndexies[i]*componantRanges[i].stepSize(); + return parameters; +} + +bool Model::executeParamSweep(const std::vector<Range>& componantRanges, const Range& omega, + std::function<void(std::vector<DataPoint>&, const std::vector<double>&)> dataCb) { size_t parametersCount = getFlatParametersCount(); if(componantRanges.size() != parametersCount) @@ -268,31 +301,18 @@ bool Model::sweepParams(const std::vector<Range>& componantRanges, const Range& } } - size_t stepsRequired = 1; - for(size_t i = 0; i < parametersCount; ++i) - stepsRequired*=componantRanges[i].count; + size_t stepsRequired = getRequiredStepsForSweeps(componantRanges); std::vector<double> currentParam(parametersCount, 0); - std::vector<double> stepSize(parametersCount, 0); for(size_t i = 0; i < parametersCount; ++i) - { currentParam[i] = componantRanges[i].start; - stepSize[i] = (componantRanges[i].end - componantRanges[i].start)/componantRanges[i].count; - } std::cout<<"Executing sweep. Steps requried: "<<stepsRequired<<std::endl; for(size_t i = 0; i < stepsRequired; ++i) { - for(size_t i = 0; i < parametersCount; ++i) - { - currentParam[i] += stepSize[i]; - if(currentParam[i] > componantRanges[i].end) - currentParam[i] = componantRanges[i].start; - else - break; - } - std::vector<DataPoint> result = sweep(omega); + setFlatParameters(getSweepParamByIndex(componantRanges, i)); + std::vector<DataPoint> result = executeSweep(omega); dataCb(result, currentParam); }