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.
This commit is contained in:
parent
ae645b27d2
commit
9a225439cf
274
src/main.cpp
274
src/main.cpp
|
@ -16,245 +16,61 @@
|
|||
#include <string>
|
||||
#include <vcg/complex/algorithms/update/position.h>
|
||||
|
||||
void exportOptimizationResults(
|
||||
const ReducedModelOptimizer::Results &optimizationResults,
|
||||
const std::filesystem::path &optimizationDirectory,
|
||||
const ReducedModelOptimizer::Settings &settings_optimization,
|
||||
csvFile &statistics,
|
||||
const std::pair<FlatPattern *, FlatPattern *> 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<std::pair<FlatPattern *, FlatPattern *>> 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<ReducedModelOptimizer::Results> 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<FlatPattern *, FlatPattern *> &patternPair =
|
||||
patternPairs[patternPairIndex];
|
||||
std::cout << "Optimizing " << patternPair.first->getLabel() << "@"
|
||||
<< patternPair.second->getLabel() << std::endl;
|
||||
const std::vector<size_t> 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<FlatPattern *, FlatPattern *> &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<size_t> numberOfNodesPerSlot{1, 0, 0, 2, 1, 2, 1};
|
||||
std::vector<vcg::Point2i> 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<vcg::Point2i> CWreducedModelEdges{vcg::Point2i(1, 5),
|
||||
vcg::Point2i(3, 5)};
|
||||
FlatPattern CWReducedModel(numberOfNodesPerSlot, CWreducedModelEdges);
|
||||
CWReducedModel.setLabel("CW_reduced");
|
||||
CWReducedModel.scale(0.03);
|
||||
|
||||
std::vector<vcg::Point2i> 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<FlatPattern *> 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<std::pair<FlatPattern *, FlatPattern *>> 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<size_t> 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;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
std::vector<xRange> 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<Vector6d> &reducedPatternResults,
|
||||
const std::vector<Vector6d> &fullPatternResults,const double& interfaceDisplacementNormSum,
|
||||
const std::vector<Vector6d> &fullPatternResults,
|
||||
const double &interfaceDisplacementNormSum,
|
||||
const std::unordered_map<ReducedPatternVertexIndex,
|
||||
FullPatternVertexIndex>
|
||||
&reducedToFullInterfaceViMap);
|
||||
|
@ -250,10 +252,9 @@ struct ReducedModelOptimizer::Results {
|
|||
const std::shared_ptr<SimulationJob> &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
|
||||
|
|
Loading…
Reference in New Issue