Unverified Commit 55eccf5c authored by Dmitry Bagaev's avatar Dmitry Bagaev Committed by GitHub
Browse files

Optimizer module [WIP] (#34)

* WIP: ttsp optimizer draft

* 2prev

* WIP: Update optimizer logic

* 2prev

* WIP: TTSP Solve update, series added

* Alternating optimizer added

* WIP: Noop optimizer added & some fixes

* WIP: Annealing optimizer

* TTSP Optimizer alpha M.1

* WIP: update

* WIP: 2prev

* WIP: some improvments

* WIP: Minor refactoring

* upd

* temp fix for GeRa

* update structure

* minor fix

* Refactoring. Improvments.

* Major bug fixes

* Global optimizers feature

* upd

* upd

* upd

* upd2

* bayesian method

* bayesian opt added

* update

* bayesian update

* bayesian update

* 2prev

* 22prev

* 222prev

* Bayesian optimizaer properties added

* new example added

* more options to optimizers

* bug fixed

* update

* multiple parameters update support

* multiple parameters update support

* some updates

* upd

* bayesian opt tuning

* b upd

* b upd2

* upd

* k3biilu2 new version added

* upd ttsp examples

* bupdate

* cmake FindNLOPT

* k3d added

* 2prev

* 2prev

* K3 block removed from CMakeLists.txt

* TTSP -> Optimizer rename

* TTSP module added

* ttsp fixes

* 2prev

* update ttsp

* 2prev

* 22prev
parent 30570c97
......@@ -8,12 +8,13 @@ SyncToy*
.idea/
Source/Solver/solver_fcbiilu2/fcbiilu2.cpp
Source/Solver/solver_fcbiilu2/fcbiilu2_nosign.cpp
Source/Solver/solver_k3biilu2/k3d.cpp
Source/Solver/solver_k3biilu2/k3d.h
Source/Solver/solver_k3biilu2/k3d.cpp
Source/Solver/solver_k3biilu2/k3d_block.cxx
Source/Solver/solver_k3biilu2/k3d_block.hxx
.vscode/*
......
......@@ -35,6 +35,8 @@ option(USE_SOLVER_MONDRIAAN "Use Mondriaan for matrix reordering" OFF)
option(USE_SOLVER_PETSC "Use PETSc solvers" OFF)
option(USE_SOLVER_TRILINOS "Use Trilinos solvers" OFF)
option(USE_SOLVER_SUPERLU "Use SuperLU solver" OFF)
option(USE_OPTIMIZER "Use Optimization toolkit" OFF)
option(USE_OPTIMIZER_BAYESIAN "Compile Optimization module against Limbo library to provide Bayesian optimization algorithm" OFF)
#option(USE_AUTODIFF_ASMJIT "Use AsmJit for automatic differentiation" OFF)
#option(USE_AUTODIFF_EXPRESSION_TEMPLATES "Use c++ expression templates for automatic differentiation" OFF)
......@@ -75,6 +77,21 @@ if(TEST_FORTRAN_ANI3D)
endif()
if(USE_OPTIMIZER_BAYESIAN)
include_directories(/Users/bvdmitri/Projects/CXX/limbo/src)
target_link_libraries(inmost /Users/bvdmitri/Projects/CXX/limbo/build/src/liblimbo.a)
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
find_package(NLOPT)
include_directories(${NLOPT_INCLUDE_DIRS})
target_link_libraries(inmost ${NLOPT_LIBRARIES})
find_package(boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(inmost ${Boost_LIBRARIES})
endif()
if(USE_MPI)
find_package(MPI)
......@@ -330,6 +347,7 @@ set(INMOST_INSTALL_HEADERS Source/Headers/inmost.h
Source/Headers/inmost_xml.h
Source/Headers/inmost_variable.h
Source/Headers/inmost_block_variable.h
Source/Headers/inmost_optimizer.h
Source/Headers/container.hpp)
#if( COMPILE_EXAMPLES )
......@@ -375,6 +393,7 @@ set_property(TARGET inmost PROPERTY PUBLIC_HEADER
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_variable.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_block_variable.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_xml.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/inmost_optimizer.h"
"${PROJECT_SOURCE_DIR}/Source/Headers/container.hpp")
#if( COMPILE_EXAMPLES )
......
if(USE_MESH)
add_subdirectory(AdaptiveMesh)
add_subdirectory(DrawGrid)
add_subdirectory(DrawGridTests)
add_subdirectory(GridGen)
add_subdirectory(GridTools)
endif(USE_MESH)
if(USE_SOLVER)
add_subdirectory(DrawMatrix)
add_subdirectory(MatSolve)
endif(USE_SOLVER)
if(USE_SOLVER AND USE_MESH)
add_subdirectory(FVDiscr)
add_subdirectory(Solver)
endif(USE_SOLVER AND USE_MESH)
if(USE_AUTODIFF AND USE_SOLVER AND USE_MESH)
add_subdirectory(ADFVDiscr)
add_subdirectory(ADMFD)
add_subdirectory(ADVDIFF)
add_subdirectory(TestSuite)
add_subdirectory(MFD-ES)
endif(USE_AUTODIFF AND USE_SOLVER AND USE_MESH)
if (USE_MESH)
add_subdirectory(AdaptiveMesh)
add_subdirectory(DrawGrid)
add_subdirectory(DrawGridTests)
add_subdirectory(GridGen)
add_subdirectory(GridTools)
endif (USE_MESH)
if (USE_OPTIMIZER)
add_subdirectory(OptimizerSolve)
add_subdirectory(OptimizerFunction)
endif ()
if (USE_SOLVER)
add_subdirectory(DrawMatrix)
add_subdirectory(MatSolve)
endif (USE_SOLVER)
if (USE_SOLVER AND USE_MESH)
add_subdirectory(FVDiscr)
add_subdirectory(Solver)
endif (USE_SOLVER AND USE_MESH)
if (USE_AUTODIFF AND USE_SOLVER AND USE_MESH)
add_subdirectory(ADFVDiscr)
add_subdirectory(ADMFD)
add_subdirectory(ADVDIFF)
add_subdirectory(TestSuite)
add_subdirectory(MFD-ES)
endif (USE_AUTODIFF AND USE_SOLVER AND USE_MESH)
#add_subdirectory(OctreeCutcell)
if(USE_MESH AND USE_PARTITIONER)
#add_subdirectory(Octree)
endif(USE_MESH AND USE_PARTITIONER)
if(USE_ANI_INMOST_EXAMPLES)
if(DEFINED ENV{ANI_DIR})
message("ANI_DIR is defined")
add_subdirectory(Ani_Inmost)
else()
MESSAGE("ANI_DIR IS NOT_DEFINED. Compilation of ani_inmost_examples failed")
endif()
endif()
if (USE_MESH AND USE_PARTITIONER)
#add_subdirectory(Octree)
endif (USE_MESH AND USE_PARTITIONER)
if (USE_ANI_INMOST_EXAMPLES)
if (DEFINED ENV{ANI_DIR})
message("ANI_DIR is defined")
add_subdirectory(Ani_Inmost)
else ()
MESSAGE("ANI_DIR IS NOT_DEFINED. Compilation of ani_inmost_examples failed")
endif ()
endif ()
......@@ -339,7 +339,7 @@ int main(int argc, char **argv) {
}
mat.Load(matrixFileName, ENUMUNDEF, ENUMUNDEF, orderingFileName);
} else {
mat.Load(matrixFileName); //if interval parameters not set, matrix will be divided automatically
mat.Load(matrixFileName); //ifinterval parameters not set, matrix will be divided automatically
}
if (processorsCount == 1) {
ps_inmost(mat, "a.ps"); //db !IK!
......
project(OptimizerFunction)
set(SOURCE main.cpp)
add_subdirectory(function)
include_directories(function)
add_executable(OptimizerFunction ${SOURCE})
target_link_libraries(OptimizerFunction inmost)
if(USE_MPI)
message("linking OptimizerFunction with MPI")
target_link_libraries(OptimizerFunction ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(OptimizerFunction PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
install(TARGETS OptimizerFunction EXPORT inmost-targets RUNTIME DESTINATION bin)
set(SOURCE ${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/static_sin.cpp
${CMAKE_CURRENT_SOURCE_DIR}/static_sin_r2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_x2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_r2.cpp)
set(HEADER ${HEADER}
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_function.h
${CMAKE_CURRENT_SOURCE_DIR}/static_sin.h
${CMAKE_CURRENT_SOURCE_DIR}/static_sin_r2.h
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_x2.h
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_r2.h)
set(HEADER ${HEADER} PARENT_SCOPE)
set(SOURCE ${SOURCE} PARENT_SCOPE)
\ No newline at end of file
//
// Created by Dmitri Bagaev on 2019-03-25.
//
#ifndef INMOST_DYNAMIC_FUNCTION_H
#define INMOST_DYNAMIC_FUNCTION_H
#include <utility>
#include <inmost_optimizer.h>
class DynamicFunction {
public:
virtual double invoke(double x, double y, int iteration) const noexcept = 0;
virtual double GetMinimumValue(int iteration) const noexcept = 0;
virtual std::pair<double, double> GetMinimumPoint(int iteration) const noexcept = 0;
virtual std::pair<double, double> GetXRange() const noexcept = 0;
virtual std::pair<double, double> GetYRange() const noexcept = 0;
virtual INMOST::OptimizationParameterType GetXParameterType() const noexcept {
return INMOST::OptimizationParameterType::PARAMETER_TYPE_DEFAULT;
}
virtual INMOST::OptimizationParameterType GetYParameterType() const noexcept {
return INMOST::OptimizationParameterType::PARAMETER_TYPE_DEFAULT;
}
};
#endif //INMOST_DYNAMIC_FUNCTION_H
//
// Created by Dmitri Bagaev on 2019-04-13.
//
#include "dynamic_r2.h"
DynamicR2::DynamicR2() : distribution(-0.04, 0.04) {
unsigned int seed = static_cast<unsigned int>(time(NULL));
generator.seed(seed);
}
double DynamicR2::invoke(double x, double y, int iteration) const noexcept {
std::pair<double, double> min_point = GetMinimumPoint(iteration);
double mx = min_point.first;
double my = min_point.second;
double tmp1 = std::log10(x / mx);
double tmp2 = (17.5 * (y - my)) / (7.5 + y - my);
double f = ((16.0 / 25.0) * (tmp1 * tmp1) + 1) * ((1.0 / 25.0) * (tmp2 * tmp2) + 1);
return f * (1 + distribution(generator));
}
double DynamicR2::GetMinimumValue(int iteration) const noexcept {
return 1.0;
}
std::pair<double, double> DynamicR2::GetMinimumPoint(int iteration) const noexcept {
double kx = 200;
double ky = 800;
// double x = std::pow(10, -2 - std::cos((2 * M_PI * iteration) / kx));
double x = 1.0 / (1.0 / (std::pow(10, -3) - std::pow(10, -1)) - ((double) iteration / 20.0)) + std::pow(10, -1);
double y = 2 + std::cos((2 * M_PI * iteration) / ky);
return std::make_pair(x, y);
}
std::pair<double, double> DynamicR2::GetXRange() const noexcept {
return std::make_pair(-3.5, -0.5);
}
std::pair<double, double> DynamicR2::GetYRange() const noexcept {
return std::make_pair(0, 4);
}
INMOST::OptimizationParameterType DynamicR2::GetXParameterType() const noexcept {
return INMOST::OptimizationParameterType::PARAMETER_TYPE_EXPONENT;
}
//
// Created by Dmitri Bagaev on 2019-04-13.
//
#ifndef INMOST_DYNAMIC_R2_H
#define INMOST_DYNAMIC_R2_H
#include "dynamic_function.h"
#include <random>
class DynamicR2 : public DynamicFunction {
private:
mutable std::mt19937 generator;
mutable std::uniform_real_distribution<> distribution;
public:
DynamicR2();
double invoke(double x, double y, int iteration) const noexcept override;
double GetMinimumValue(int iteration) const noexcept override;
std::pair<double, double> GetMinimumPoint(int iteration) const noexcept override;
std::pair<double, double> GetXRange() const noexcept override;
std::pair<double, double> GetYRange() const noexcept override;
INMOST::OptimizationParameterType GetXParameterType() const noexcept override;
};
#endif //INMOST_DYNAMIC_R2_H
//
// Created by Dmitri Bagaev on 2019-03-25.
//
#include "dynamic_x2.h"
#include <cmath>
DynamicX2::DynamicX2() : distribution(-0.04, 0.04) {
unsigned int seed = static_cast<unsigned int>(time(NULL));
generator.seed(seed);
}
double DynamicX2::invoke(double x, double y, int iteration) const noexcept {
double xm = GetMinimumPoint(iteration).first;
double f = 0.0;
if (x <= xm) {
double a = 10.0 / (xm * xm);
double b = -20.0 / xm;
double c = 10.0;
f = a * x * x + b * x + c;
} else {
double a = 10.0 / (xm * xm - 8.0 * xm + 16);
double b = -2.0 * a * xm;
double c = b * b / (4.0 * a);
f = a * x * x + b * x + c;
}
return f + 1 + f * distribution(generator);
}
double DynamicX2::GetMinimumValue(int iteration) const noexcept {
return 1.0;
}
std::pair<double, double> DynamicX2::GetMinimumPoint(int iteration) const noexcept {
return std::make_pair(2 + std::sin(iteration / 150.0), 0.0);
}
std::pair<double, double> DynamicX2::GetXRange() const noexcept {
return std::make_pair(0, 4);
}
std::pair<double, double> DynamicX2::GetYRange() const noexcept {
return std::make_pair(0, 1); // unused
}
//
// Created by Dmitri Bagaev on 2019-03-25.
//
#ifndef INMOST_DYNAMIC_X2_H
#define INMOST_DYNAMIC_X2_H
#include "dynamic_function.h"
#include <random>
class DynamicX2 : public DynamicFunction {
private:
mutable std::mt19937 generator;
mutable std::uniform_real_distribution<> distribution;
public:
DynamicX2();
double invoke(double x, double y, int iteration) const noexcept override;
double GetMinimumValue(int iteration) const noexcept override;
std::pair<double, double> GetMinimumPoint(int iteration) const noexcept override;
std::pair<double, double> GetXRange() const noexcept override;
std::pair<double, double> GetYRange() const noexcept override;
};
#endif //INMOST_DYNAMIC_X2_H
//
// Created by Dmitri Bagaev on 2019-03-25.
//
#include "static_sin.h"
#include <cmath>
double StaticSin::invoke(double x, double y, int iteration) const noexcept {
return 1.0 - std::sin(x);
}
std::pair<double, double> StaticSin::GetXRange() const noexcept {
return std::make_pair(0, M_PI);
}
std::pair<double, double> StaticSin::GetYRange() const noexcept {
return std::make_pair(0, M_PI);
}
double StaticSin::GetMinimumValue(int iteration) const noexcept {
return 0;
}
std::pair<double, double> StaticSin::GetMinimumPoint(int iteration) const noexcept {
return std::make_pair(M_PI / 2, 0.0);
}
//
// Created by Dmitri Bagaev on 2019-03-25.
//
#ifndef INMOST_DYNAMIC_SIN_H
#define INMOST_DYNAMIC_SIN_H
#include "dynamic_function.h"
class StaticSin : public DynamicFunction {
public:
double GetMinimumValue(int iteration) const noexcept override;
std::pair<double, double> GetMinimumPoint(int iteration) const noexcept override;
std::pair<double, double> GetXRange() const noexcept override;
std::pair<double, double> GetYRange() const noexcept override;
double invoke(double x, double y, int iteration) const noexcept override;
};
#endif //INMOST_DYNAMIC_SIN_H
//
// Created by Dmitri Bagaev on 2019-03-29.
//
#include "static_sin_r2.h"
#include <cmath>
double StaticSinR2::invoke(double x, double y, int iteration) const noexcept {
return -1.0 * std::sin(x) * std::cos(y) + 1.0;
}
double StaticSinR2::GetMinimumValue(int iteration) const noexcept {
return 0;
}
std::pair<double, double> StaticSinR2::GetMinimumPoint(int iteration) const noexcept {
return std::make_pair(M_PI / 2.0, 0);
}
std::pair<double, double> StaticSinR2::GetXRange() const noexcept {
return std::make_pair(0, M_PI);
}
std::pair<double, double> StaticSinR2::GetYRange() const noexcept {
return std::make_pair(-M_PI / 2.0, M_PI / 2.0);
}
//
// Created by Dmitri Bagaev on 2019-03-29.
//
#ifndef INMOST_STATIC_SIN_R2_H
#define INMOST_STATIC_SIN_R2_H
#include "dynamic_function.h"
class StaticSinR2 : public DynamicFunction {
public:
double invoke(double x, double y, int iteration) const noexcept override;
double GetMinimumValue(int iteration) const noexcept override;
std::pair<double, double> GetMinimumPoint(int iteration) const noexcept override;
std::pair<double, double> GetXRange() const noexcept override;
std::pair<double, double> GetYRange() const noexcept override;
};
#endif //INMOST_STATIC_SIN_R2_H
#include <iostream>
#include <dynamic_function.h>
#include <static_sin.h>
#include <static_sin_r2.h>
#include <dynamic_x2.h>
#include <dynamic_r2.h>
#include <inmost_optimizer.h>
using namespace INMOST;
int main(int argc, char **argv) {
#if defined(USE_MPI)
MPI_Init(&argc, &argv);
#endif
bool use_second_parameter = false;
int max_iterations = 500;
double x_default = 0.0;
double y_default = 0.0;
bool x_default_found = false;
bool y_default_found = false;
int x_steps = 40;
int y_steps = 40;
std::string optimizer_type = "noop";
std::string function_type = "sin1d";
std::string out_folder = "";
//Parse argv parameters
if (argc == 1) goto help_message;
int i;
for (i = 1; i < argc; i++) {
//Print help message and exit
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
help_message:
std::cout << "Help message: " << std::endl;
std::cout << "Command line options: " << std::endl;
std::cout << "Required: " << std::endl;
std::cout << "-o, --optimizer <Optimizer type>" << std::endl;
std::cout << "Optional: " << std::endl;
std::cout << "-f, --function <function type>" << std::endl;
std::cout << "-usp, -y, --use-second-parameter" << std::endl;
std::cout << "-xd, --x-default <x default value>" << std::endl;
std::cout << "-yd, --y-default <y default value>" << std::endl;
std::cout << "-xs, --x-step <x step>" << std::endl;
std::cout << "-ys, --y-step <y step>" << std::endl;
std::cout << "-mi, --max-iterations <max iterations>" << std::endl;
std::cout << "-of, --out-folder <out folder path>" << std::endl;
std::cout << "-w, --wait" << std::endl;
std::cout << " Available optimizers:" << std::endl;
std::vector<std::string> availableOptimizers = INMOST::Optimizers::GetAvailableOptimizers();
for (auto it = availableOptimizers.begin(); it != availableOptimizers.end(); ++it) {
std::cout << " " << *it << std::endl;
}
return 0;
}
if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--optimizer") == 0) {
optimizer_type = std::string(argv[i + 1]);
i++;
continue;
}
if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--function") == 0) {
function_type = std::string(argv[i + 1]);
i++;
continue;
}
if (strcmp(argv[i], "-mi") == 0 || strcmp(argv[i], "--max-iterations") == 0) {
max_iterations = std::atoi(argv[i + 1]);
i++;
continue;
}
if (strcmp(argv[i], "-y") == 0 || strcmp(argv[i], "-usp") == 0 || strcmp(argv[i], "--use-second-parameter") == 0) {
use_second_parameter = true;
continue;
}
if (strcmp(argv[i], "-xd") == 0 || strcmp(argv[i], "--x-default") == 0) {
x_default_found = true;
x_default = std::atoi(argv[i + 1]);
i++;
continue;
}
if (strcmp(argv[i], "-yd") == 0 || strcmp(argv[i], "--y-default") == 0) {
y_default_found = true;
y_default = std::atoi(argv[i + 1]);
i++;
continue;
}
if (strcmp(argv[i], "-xs") == 0 || strcmp(argv[i], "--x-step") == 0) {
x_steps = std::atoi(argv[i + 1]);
i++;
continue;
}
if (strcmp(argv[i], "-ys") == 0 || strcmp(argv[i], "--y-step") == 0) {
y_steps = std::atoi(argv[i + 1]);