From 9a225439cf2802bae58484c15f1256fb195e65b5 Mon Sep 17 00:00:00 2001 From: Iason Date: Thu, 18 Feb 2021 15:33:31 +0200 Subject: [PATCH] main optimizes a pair of patterns of which the filepath is given as cl arguments. The user can additionally define the number of function calls and the directory in which the program should export the results. --- src/main.cpp | 274 ++++++---------------------------- src/reducedmodeloptimizer.hpp | 72 ++++++--- 2 files changed, 99 insertions(+), 247 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b4cad26..fbbc4ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,245 +16,61 @@ #include #include -void exportOptimizationResults( - const ReducedModelOptimizer::Results &optimizationResults, - const std::filesystem::path &optimizationDirectory, - const ReducedModelOptimizer::Settings &settings_optimization, - csvFile &statistics, - const std::pair patternPair) { - std::filesystem::path saveToPath(std::filesystem::path(optimizationDirectory) - .append(patternPair.first->getLabel() + - "@" + - patternPair.second->getLabel())); - std::filesystem::create_directories(std::filesystem::path(saveToPath)); - - optimizationResults.save(saveToPath.string()); - statistics << patternPair.first->getLabel() + "@" + - patternPair.second->getLabel(); - statistics << optimizationResults.objectiveValue; - for (const double &optimalX : optimizationResults.x) { - statistics << optimalX; - } - - for (int unusedXVarCounter = 0; - unusedXVarCounter < - settings_optimization.xRanges.size() - optimizationResults.x.size(); - unusedXVarCounter++) { - statistics << "-"; - } - - statistics << optimizationResults.time; - if (optimizationResults.numberOfSimulationCrashes == 0) { - statistics << "No crashes"; - } else { - statistics << optimizationResults.numberOfSimulationCrashes; - } - statistics << endrow; -} - -void optimizeTestSet( - const std::vector> patternPairs, - const ReducedModelOptimizer::Settings &settings_optimization, - const std::string &saveTo) { - const std::string optimizationSettingsString = - settings_optimization.toString(); - std::filesystem::path thisOptimizationDirectory( - std::filesystem::path(saveTo).append(optimizationSettingsString)); - //.append("Results")); - std::filesystem::create_directories(thisOptimizationDirectory); - std::cout << optimizationSettingsString << std::endl; - csvFile csv_settings(std::filesystem::path(thisOptimizationDirectory) - .append("settings.csv") - .string(), - true); - settings_optimization.writeTo(csv_settings); - csvFile statistics(std::filesystem::path(thisOptimizationDirectory) - .append("statistics.csv") - .string(), - false); - - // Write header to csv - statistics << "FullPattern@ReducedPattern" - << "Obj value"; - for (const ReducedModelOptimizer::xRange &range : - settings_optimization.xRanges) { - statistics << range.label; - } - statistics << "Time(s)"; - statistics << "#Crashes"; - statistics << endrow; - - double totalError = 0; - int totalNumberOfSimulationCrashes = 0; - std::vector optimizationResults_testSet( - patternPairs.size()); - auto start = std::chrono::high_resolution_clock::now(); - int pairsOptimized = 0; -#pragma omp parallel for - for (int patternPairIndex = 0; patternPairIndex < patternPairs.size(); - patternPairIndex++) { - const std::pair &patternPair = - patternPairs[patternPairIndex]; - std::cout << "Optimizing " << patternPair.first->getLabel() << "@" - << patternPair.second->getLabel() << std::endl; - const std::vector numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1}; - ReducedModelOptimizer optimizer(numberOfNodesPerSlot); - optimizer.initializePatterns(*patternPair.first, *patternPair.second, {}); - ReducedModelOptimizer::Results optimizationResults = - optimizer.optimize(settings_optimization); - - totalError += optimizationResults.objectiveValue; - optimizationResults_testSet[patternPairIndex] = optimizationResults; - totalNumberOfSimulationCrashes += - optimizationResults.numberOfSimulationCrashes; - - std::cout << "Optimized " << ++pairsOptimized << "/" << patternPairs.size() - << std::endl; -#pragma omp critical - { - exportOptimizationResults(optimizationResults, thisOptimizationDirectory, - settings_optimization, statistics, patternPair); - optimizationResults.draw(); - } - } - - // for (int patternPairIndex = 0; patternPairIndex < patternPairs.size(); - // patternPairIndex++) { - // const std::pair &patternPair = - // patternPairs[patternPairIndex]; - // const ReducedModelOptimizer::Results optimizationResults = - // optimizationResults_testSet[patternPairIndex]; - // // Save results - // std::filesystem::path saveToPath( - // std::filesystem::path(thisOptimizationDirectory) - // .append(patternPair.first->getLabel() + "@" + - // patternPair.second->getLabel())); - // std::filesystem::create_directories(std::filesystem::path(saveToPath)); - // optimizationResults.save(saveToPath.string()); - - // // Save statistics - // statistics << patternPair.first->getLabel() + "@" + - // patternPair.second->getLabel(); - // statistics << optimizationResults.objectiveValue; - // for (const double &optimalX : optimizationResults.x) { - // statistics << optimalX; - // } - - // for (int unusedXVarCounter = 0; - // unusedXVarCounter < - // settings_optimization.xRanges.size() - - // optimizationResults.x.size(); unusedXVarCounter++) { - // statistics << "-"; - // } - - // statistics << optimizationResults.time; - // if (optimizationResults.numberOfSimulationCrashes == 0) { - // statistics << "No crashes"; - // } else { - // statistics << optimizationResults.numberOfSimulationCrashes; - // } - // statistics << endrow; - // } -} - int main(int argc, char *argv[]) { - // Create reduced models - // FormFinder::runUnitTests(); - const std::vector numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1}; - std::vector singleBarReducedModelEdges{vcg::Point2i(0, 3)}; - FlatPattern singleBarReducedModel(numberOfNodesPerSlot, - singleBarReducedModelEdges); - singleBarReducedModel.setLabel("SingleBar_reduced"); - singleBarReducedModel.savePly(singleBarReducedModel.getLabel()); - singleBarReducedModel.scale(0.03); + if (argc < 4) { + std::cerr << "Specify the pattern pair to be optimized." << std::endl; + std::terminate(); + } + // Populate the pattern pair to be optimized + ////Full pattern + const std::string filepath_fullPattern = argv[1]; + FlatPattern fullPattern(filepath_fullPattern); + fullPattern.setLabel( + std::filesystem::path(filepath_fullPattern).stem().string()); + fullPattern.scale(0.03); + ////Reduced pattern + const std::string filepath_reducedPattern = argv[2]; + FlatPattern reducedPattern(filepath_reducedPattern); + reducedPattern.setLabel( + std::filesystem::path(filepath_reducedPattern).stem().string()); + reducedPattern.scale(0.03); - std::vector CWreducedModelEdges{vcg::Point2i(1, 5), - vcg::Point2i(3, 5)}; - FlatPattern CWReducedModel(numberOfNodesPerSlot, CWreducedModelEdges); - CWReducedModel.setLabel("CW_reduced"); - CWReducedModel.scale(0.03); - - std::vector CCWreducedModelEdges{vcg::Point2i(1, 5), - vcg::Point2i(3, 1)}; - FlatPattern CCWReducedModel(numberOfNodesPerSlot, CCWreducedModelEdges); - CCWReducedModel.setLabel("CCW_reduced"); - CCWReducedModel.savePly(CWReducedModel.getLabel()); - CCWReducedModel.scale(0.03); - - std::vector reducedModels{&singleBarReducedModel, - &CWReducedModel, &CCWReducedModel}; - - // Define the ranges that the optimizer will use + // Set the optization settings ReducedModelOptimizer::xRange beamWidth{"B", 0.5, 1.5}; ReducedModelOptimizer::xRange beamDimensionsRatio{"bOverh", 0.7, 1.3}; ReducedModelOptimizer::xRange beamE{"E", 0.1, 1.9}; ReducedModelOptimizer::xRange innerHexagonSize{"HS", 0.1, 0.9}; - // Test set of full patterns - std::string fullPatternsTestSetDirectory = "../TestSet"; - if (!std::filesystem::exists( - std::filesystem::path(fullPatternsTestSetDirectory))) { - std::cerr << "Full pattern directory does not exist: " - << fullPatternsTestSetDirectory << std::endl; - return 1; - } - // "/home/iason/Documents/PhD/Research/Approximating shapes with flat " - // "patterns/Pattern_enumerator/Results/1v_0v_2e_1e_1c_6fan/3/Valid"; - std::vector> patternPairs; - for (const auto &entry : - filesystem::directory_iterator(fullPatternsTestSetDirectory)) { - const auto filepath = - // std::filesystem::path(fullPatternsTestSetDirectory).append("305.ply"); - entry.path(); - const std::string filepathString = filepath.string(); - const std::string tiledSuffix = "_tiled.ply"; - if (filepathString.compare(filepathString.size() - tiledSuffix.size(), - tiledSuffix.size(), tiledSuffix) == 0) { - continue; - } - - FlatPattern fullPattern(filepathString); - fullPattern.setLabel(filepath.stem().string()); - fullPattern.scale(0.03); - // for (int reducedPatternIndex = 0; - // reducedPatternIndex < reducedModels.size(); - // reducedPatternIndex++) { - FlatPattern *pFullPattern = new FlatPattern(); - pFullPattern->copy(fullPattern); - FlatPattern *pReducedPattern = new FlatPattern(); - // pReducedPattern->copy(*reducedModels[reducedPatternIndex]); - pReducedPattern->copy(*reducedModels[0]); - patternPairs.push_back(std::make_pair(pFullPattern, pReducedPattern)); - // } - } - - // for (double rangeOffset = 0.15; rangeOffset <= 0.95; rangeOffset += 0.05) - // { ReducedModelOptimizer::Settings settings_optimization; settings_optimization.xRanges = {beamWidth, beamDimensionsRatio, beamE, innerHexagonSize}; + const bool input_numberOfFunctionCallsDefined = argc >= 4; + settings_optimization.numberOfFunctionCalls = + input_numberOfFunctionCallsDefined ? std::atoi(argv[3]) : 100; + // Optimize pair + const std::string pairName = + fullPattern.getLabel() + "@" + reducedPattern.getLabel(); + std::cout << "Optimizing " << pairName << std::endl; + const std::vector numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1}; + ReducedModelOptimizer optimizer(numberOfNodesPerSlot); + optimizer.initializePatterns(fullPattern, reducedPattern, {}); + ReducedModelOptimizer::Results optimizationResults = + optimizer.optimize(settings_optimization); + // Export results + const bool input_resultDirectoryDefined = argc >= 5; + std::string optimiziationResultsDirectory = + input_resultDirectoryDefined ? argv[4] : "OptimizationResults"; + std::filesystem::path dirPath_thisOptimization( + std::filesystem::path(optimiziationResultsDirectory).append(pairName)); + std::filesystem::create_directories(dirPath_thisOptimization); + csvFile csv_results(std::filesystem::path(dirPath_thisOptimization) + .append("results.csv") + .string(), + false); + settings_optimization.writeTo(csv_results); + optimizationResults.writeTo(settings_optimization, csv_results); + optimizationResults.save(dirPath_thisOptimization.string()); - // for (settings_optimization.numberOfFunctionCalls = 100; - // settings_optimization.numberOfFunctionCalls < 5000; - // settings_optimization.numberOfFunctionCalls += 100) { - std::string optimiziationResultsDirectory = "OptimizationResults"; - if (argc < 2) { - settings_optimization.numberOfFunctionCalls = 100; - } else if (argc == 2) { - settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]); - } else if (argc == 3) { - settings_optimization.numberOfFunctionCalls = std::atoi(argv[1]); - optimiziationResultsDirectory = argv[2]; - } - // settings_optimization.normalizeObjectiveValue = false; - // optimizeTestSet(patternPairs, settings_optimization, - // optimiziationResultsDirectory); - settings_optimization.normalizeObjectiveValue = true; - optimizeTestSet(patternPairs, settings_optimization, - optimiziationResultsDirectory); + // optimizationResults.draw(); - for (auto &patternPair : patternPairs) { - delete patternPair.first; - delete patternPair.second; - } return 0; } diff --git a/src/reducedmodeloptimizer.hpp b/src/reducedmodeloptimizer.hpp index 0cd4ce1..5bdf3f6 100644 --- a/src/reducedmodeloptimizer.hpp +++ b/src/reducedmodeloptimizer.hpp @@ -47,7 +47,7 @@ public: std::vector xRanges; int numberOfFunctionCalls{100}; double solutionAccuracy{1e-2}; - bool normalizeObjectiveValue{ true }; + bool normalizeObjectiveValue{true}; std::string toString() const { std::string settingsString; @@ -59,23 +59,25 @@ public: settingsString += xRangesString; } settingsString += "FuncCalls=" + std::to_string(numberOfFunctionCalls) + - " Accuracy=" + std::to_string(solutionAccuracy)+" Norm="+(normalizeObjectiveValue ? "yes" : "no"); + " Accuracy=" + std::to_string(solutionAccuracy) + + " Norm=" + (normalizeObjectiveValue ? "yes" : "no"); return settingsString; } - void writeTo(csvFile &csv) const { + void writeTo(csvFile &csv, const bool writeHeader = true) const { // Create settings csv header - if (!xRanges.empty()) { - for (const xRange &range : xRanges) { - csv << range.label + " max"; - csv << range.label + " min"; + if (writeHeader) { + if (!xRanges.empty()) { + for (const xRange &range : xRanges) { + csv << range.label + " max"; + csv << range.label + " min"; + } } + csv << "Function Calls"; + csv << "Solution Accuracy"; + csv << endrow; } - csv << "Function Calls"; - csv << "Solution Accuracy"; - csv << "Normalize obj value"; - csv << endrow; if (!xRanges.empty()) { for (const xRange &range : xRanges) { @@ -85,7 +87,6 @@ public: } csv << numberOfFunctionCalls; csv << solutionAccuracy; - csv <<(normalizeObjectiveValue ? "yes" : "no"); csv << endrow; } }; @@ -149,7 +150,8 @@ public: &reducedToFullInterfaceViMap); static double computeError(const std::vector &reducedPatternResults, - const std::vector &fullPatternResults,const double& interfaceDisplacementNormSum, + const std::vector &fullPatternResults, + const double &interfaceDisplacementNormSum, const std::unordered_map &reducedToFullInterfaceViMap); @@ -250,10 +252,9 @@ struct ReducedModelOptimizer::Results { const std::shared_ptr &pReducedPatternSimulationJob = reducedPatternSimulationJobs[simulationJobIndex]; const auto reducedPatternDirectoryPath = - std::filesystem::path(simulationJobFolderPath) - .append("Reduced"); + std::filesystem::path(simulationJobFolderPath).append("Reduced"); if (!std::filesystem::exists(reducedPatternDirectoryPath)) { - std::filesystem::create_directory(reducedPatternDirectoryPath); + std::filesystem::create_directory(reducedPatternDirectoryPath); } pReducedPatternSimulationJob->save(reducedPatternDirectoryPath.string()); } @@ -264,10 +265,12 @@ struct ReducedModelOptimizer::Results { for (const auto &directoryEntry : filesystem::directory_iterator(loadFromPath)) { const auto simulationScenarioPath = directoryEntry.path(); + if (!std::filesystem::is_directory(simulationScenarioPath)) { + continue; + } // Load reduced pattern files for (const auto &fileEntry : filesystem::directory_iterator( - std::filesystem::path(simulationScenarioPath) - .append("Full"))) { + std::filesystem::path(simulationScenarioPath).append("Full"))) { const auto filepath = fileEntry.path(); if (filepath.extension() == ".json") { SimulationJob job; @@ -291,6 +294,39 @@ struct ReducedModelOptimizer::Results { } } } + + void writeTo(const ReducedModelOptimizer::Settings &settings_optimization, + csvFile &csv, const bool writeHeader = true) const { + if (writeHeader) { + //// Write header to csv + csv << "Obj value"; + for (const ReducedModelOptimizer::xRange &range : + settings_optimization.xRanges) { + csv << range.label; + } + csv << "Time(s)"; + csv << "#Crashes"; + csv << endrow; + } + csv << objectiveValue; + for (const double &optimalX : x) { + csv << optimalX; + } + + for (int unusedXVarCounter = 0; + unusedXVarCounter < settings_optimization.xRanges.size() - x.size(); + unusedXVarCounter++) { + csv << "-"; + } + + csv << time; + if (numberOfSimulationCrashes == 0) { + csv << "No crashes"; + } else { + csv << numberOfSimulationCrashes; + } + csv << endrow; + } }; #endif // REDUCEDMODELOPTIMIZER_HPP