├── .github └── workflows │ └── main.yml ├── .gitignore ├── .gitmodules ├── .readthedocs.requirements.txt ├── .readthedocs.yml ├── .travis.yml ├── LICENSE ├── Makefile.in ├── NOTICE.txt ├── README.md ├── configure ├── docs ├── Doxyfile ├── Makefile ├── environment.yml ├── make.bat └── source │ ├── _static │ └── main_stylesheet.css │ ├── api │ ├── bfgs.rst │ ├── broyden.rst │ ├── broyden_df.rst │ ├── cg.rst │ ├── constrained_algo_index.rst │ ├── convex_algo_index.rst │ ├── de.rst │ ├── gd.rst │ ├── lbfgs.rst │ ├── metaheuristic_algo_index.rst │ ├── newton.rst │ ├── nm.rst │ ├── pso.rst │ ├── root_finding_algo_index.rst │ ├── simplex_algo_index.rst │ └── sumt.rst │ ├── autodiff.rst │ ├── box_constraints.rst │ ├── conf.py │ ├── examples_and_tests.rst │ ├── images │ ├── ackley_fn_3d.png │ ├── beale_fn_3d.png │ ├── booth_fn_3d.png │ ├── bukin_fn_3d.png │ ├── levi_fn_3d.png │ ├── rastrigin_fn.png │ ├── rosenbrock_fn_3d.png │ ├── sphere_fn.png │ ├── table_fn_3d.png │ └── test_fn_1_3d.png │ ├── index.rst │ ├── installation.rst │ ├── line_search.rst │ ├── settings.rst │ └── test_functions.rst ├── examples ├── autodiff │ ├── autodiff_forward_sphere.cpp │ └── autodiff_reverse_sphere.cpp └── logit_reg.cpp ├── include ├── constrained │ └── sumt.hpp ├── line_search │ └── more_thuente.hpp ├── misc │ ├── bounds_check.hpp │ ├── determine_bounds_type.hpp │ ├── error_reporting.hpp │ ├── error_reporting.ipp │ ├── jacobian_adjust.hpp │ ├── numerical_gradient.hpp │ ├── numerical_hessian.hpp │ ├── optim_misc.hpp │ ├── optim_options.hpp │ ├── optim_structs.hpp │ ├── optim_trace.hpp │ └── transform_vals.hpp ├── optim.hpp ├── stats │ ├── optim_stats.hpp │ └── seed_values.hpp ├── unconstrained │ ├── bfgs.hpp │ ├── cg.hpp │ ├── de.hpp │ ├── de_prmm.hpp │ ├── gd.hpp │ ├── gd.ipp │ ├── lbfgs.hpp │ ├── newton.hpp │ ├── nm.hpp │ ├── optim_unconstrained.hpp │ ├── pso.hpp │ └── pso_dv.hpp └── zeros │ ├── broyden.hpp │ ├── broyden_df.hpp │ └── optim_zeros.hpp ├── src ├── constrained │ └── sumt.cpp ├── line_search │ └── more_thuente.cpp ├── unconstrained │ ├── bfgs.cpp │ ├── cg.cpp │ ├── de.cpp │ ├── de_prmm.cpp │ ├── gd.cpp │ ├── lbfgs.cpp │ ├── newton.cpp │ ├── nm.cpp │ ├── pso.cpp │ └── pso_dv.cpp └── zeros │ ├── broyden.cpp │ └── broyden_df.cpp └── tests ├── constrained └── sumt.cpp ├── misc ├── error_reporting.cpp ├── jacobian_adjust.cpp ├── numerical_gradient.cpp └── numerical_hessian.cpp ├── setup ├── test_fns ├── constr_test_fn_1.hpp ├── constr_test_fn_2.hpp ├── constr_test_fn_3.hpp ├── test_fns.hpp ├── test_solutions.hpp ├── unconstr_test_fn_1.hpp ├── unconstr_test_fn_10.hpp ├── unconstr_test_fn_2.hpp ├── unconstr_test_fn_3.hpp ├── unconstr_test_fn_4.hpp ├── unconstr_test_fn_5.hpp ├── unconstr_test_fn_6.hpp ├── unconstr_test_fn_7.hpp ├── unconstr_test_fn_8.hpp ├── unconstr_test_fn_9.hpp ├── zeros_test_fn_1.hpp └── zeros_test_fn_2.hpp ├── test_setup ├── Makefile.in ├── configure.in ├── cov_check └── run_cov ├── unconstrained ├── bfgs.cpp ├── cg.cpp ├── de.cpp ├── de_prmm.cpp ├── gd.cpp ├── lbfgs.cpp ├── newton.cpp ├── newton_logit_reg.cpp ├── nm.cpp ├── pso.cpp └── pso_dv.cpp └── zeros ├── broyden.cpp └── broyden_df.cpp /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | 2 | # modified version of: 3 | # https://gist.github.com/NickNaso/0d478f1481686d5bcc868cac06620a60 4 | 5 | name: CI 6 | 7 | on: [push, pull_request, release] 8 | 9 | jobs: 10 | build: 11 | name: ${{ matrix.config.name }} 12 | runs-on: ${{ matrix.config.os }} 13 | 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | config: 18 | - { 19 | name: "ubuntu_latest_gcc_arma", 20 | os: ubuntu-latest, 21 | build_type: "Release", 22 | cc: "gcc", 23 | cxx: "g++", 24 | fc: "gfortran", 25 | linalg: "arma" 26 | } 27 | - { 28 | name: "ubuntu_latest_gcc_eigen", 29 | os: ubuntu-latest, 30 | build_type: "Release", 31 | cc: "gcc", 32 | cxx: "g++", 33 | fc: "gfortran", 34 | linalg: "eigen" 35 | } 36 | - { 37 | name: "ubuntu_latest_gcc9_arma", 38 | os: ubuntu-latest, 39 | build_type: "Release", 40 | cc: "gcc-9", 41 | cxx: "g++-9", 42 | fc: "gfortran-9", 43 | linalg: "arma" 44 | } 45 | - { 46 | name: "ubuntu_latest_gcc9_eigen", 47 | os: ubuntu-latest, 48 | build_type: "Release", 49 | cc: "gcc-9", 50 | cxx: "g++-9", 51 | fc: "gfortran-9", 52 | linalg: "eigen" 53 | } 54 | - { 55 | name: "macos_latest_clang_arma", 56 | os: macos-latest, 57 | build_type: "Release", 58 | cc: "clang", 59 | cxx: "clang++", 60 | linalg: "arma" 61 | } 62 | - { 63 | name: "macos_latest_clang_eigen", 64 | os: macos-latest, 65 | build_type: "Release", 66 | cc: "clang", 67 | cxx: "clang++", 68 | linalg: "eigen" 69 | } 70 | 71 | steps: 72 | - uses: actions/checkout@v2 73 | 74 | - name: Print env 75 | run: | 76 | echo github.event.action: ${{ github.event.action }} 77 | echo github.event_name: ${{ github.event_name }} 78 | 79 | - name: Install dependencies on ubuntu 80 | if: startsWith(matrix.config.name, 'ubuntu') 81 | run: | 82 | sudo apt-get update 83 | sudo apt-get install ${{ matrix.config.cc }} ${{ matrix.config.cxx }} ${{ matrix.config.fc }} libblas-dev liblapack-dev 84 | ${{ matrix.config.cc }} --version 85 | 86 | - name: Configure 87 | shell: bash 88 | run: | 89 | export CC=${{ matrix.config.cc }} 90 | export CXX=${{ matrix.config.cxx }} 91 | export FC=${{ matrix.config.fc }} 92 | WDIR=${PWD} 93 | if [[ "${{ matrix.config.linalg }}" == "arma" ]]; then 94 | export OPTIM_TEST_USE_ARMA="y" 95 | mkdir ${WDIR}/arma_tmp 96 | git clone --single-branch https://gitlab.com/conradsnicta/armadillo-code.git ${WDIR}/arma_tmp > /dev/null 2>&1 97 | mv ${WDIR}/arma_tmp/include/* ${WDIR}/include 98 | rm -rf ${WDIR}/arma_tmp 99 | export ARMA_INCLUDE_PATH="${WDIR}/include" 100 | elif [[ "${{ matrix.config.linalg }}" == "eigen" ]]; then 101 | export OPTIM_TEST_USE_EIGEN="y" 102 | mkdir ${WDIR}/eigen_tmp 103 | git clone --single-branch https://gitlab.com/libeigen/eigen.git ${WDIR}/eigen_tmp > /dev/null 2>&1 104 | mv ${WDIR}/eigen_tmp/* ${WDIR}/include 105 | rm -rf ${WDIR}/eigen_tmp 106 | export EIGEN_INCLUDE_PATH="${WDIR}/include" 107 | else 108 | echo -e " \x1B[31m- error: unrecognized linear algebra library.\033[0m" >&2 ; 109 | echo "" 110 | exit 1 111 | fi 112 | # 113 | git submodule update --init 114 | ./configure -c -l ${{ matrix.config.linalg }} 115 | 116 | - name: Build 117 | shell: bash 118 | run: make 119 | 120 | - name: Tests 121 | shell: bash 122 | working-directory: tests 123 | run: | 124 | WDIR=${PWD} 125 | export CXX=${{ matrix.config.cxx }} 126 | if [[ "${{ matrix.config.linalg }}" == "arma" ]]; then 127 | export OPTIM_TEST_USE_ARMA="y" 128 | elif [[ "${{ matrix.config.linalg }}" == "eigen" ]]; then 129 | export OPTIM_TEST_USE_EIGEN="y" 130 | export EIGEN_INCLUDE_PATH="${WDIR}/../include" 131 | else 132 | echo -e " \x1B[31m- error: unrecognized linear algebra library.\033[0m" >&2 ; 133 | echo "" 134 | exit 1 135 | fi 136 | ./setup && ./test_setup/run_cov 137 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .Rproj.user 3 | .Rhistory 4 | Makefile 5 | *.dll 6 | *.exe 7 | *.log 8 | *.lp 9 | *.o 10 | *.so 11 | *.test 12 | *.tmp 13 | *.vscode 14 | 15 | *.gcda 16 | *.gcno 17 | *.gcov 18 | *.dSYM 19 | 20 | !docs/Makefile 21 | docs/build 22 | docs/xml 23 | 24 | header_only_version 25 | include/armadillo* 26 | tests/constrained/configure 27 | tests/constrained/Makefile* 28 | tests/misc/configure 29 | tests/misc/Makefile* 30 | tests/unconstrained/configure 31 | tests/unconstrained/Makefile* 32 | tests/zeros/configure 33 | tests/zeros/Makefile* 34 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "include/BaseMatrixOps"] 2 | path = include/BaseMatrixOps 3 | url = https://github.com/kthohr/BaseMatrixOps.git 4 | -------------------------------------------------------------------------------- /.readthedocs.requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx == 5.1.1 2 | breathe == 4.34.0 3 | sphinx-rtd-theme == 1.0.0 4 | sphinxcontrib-katex == 0.8.6 5 | sphinxcontrib-contentui == 0.2.5 6 | docutils == 0.17.1 -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | requirements_file: .readthedocs.requirements.txt 2 | 3 | conda: 4 | file: docs/environment.yml 5 | 6 | python: 7 | version: "3.8" 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: c++ 3 | sudo: required 4 | 5 | matrix: 6 | include: 7 | - os: linux 8 | dist: trusty 9 | addons: 10 | apt: 11 | packages: 12 | - g++-5 13 | - gfortran-5 14 | sources: &sources 15 | - ubuntu-toolchain-r-test 16 | env: 17 | - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && FC=gfortran-5" 18 | - OPTIM_TEST_USE_ARMA="y" 19 | compiler: gcc 20 | 21 | - os: linux 22 | dist: trusty 23 | addons: 24 | apt: 25 | packages: 26 | - g++-6 27 | - gfortran-6 28 | sources: &sources 29 | - ubuntu-toolchain-r-test 30 | env: 31 | - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && FC=gfortran-6" 32 | - OPTIM_TEST_USE_ARMA="y" 33 | compiler: gcc 34 | 35 | - os: linux 36 | dist: trusty 37 | addons: 38 | apt: 39 | packages: 40 | - g++-7 41 | - gfortran-7 42 | sources: &sources 43 | - ubuntu-toolchain-r-test 44 | env: 45 | - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && FC=gfortran-7" 46 | - OPTIM_TEST_USE_ARMA="y" 47 | compiler: gcc 48 | 49 | - os: linux 50 | dist: trusty 51 | addons: 52 | apt: 53 | packages: 54 | - g++-7 55 | - gfortran-7 56 | sources: &sources 57 | - ubuntu-toolchain-r-test 58 | env: 59 | - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && FC=gfortran-7" 60 | - OPTIM_TEST_USE_EIGEN="y" 61 | compiler: gcc 62 | 63 | - os: linux 64 | dist: trusty 65 | addons: 66 | apt: 67 | packages: 68 | - g++-8 69 | - gfortran-8 70 | sources: &sources 71 | - ubuntu-toolchain-r-test 72 | env: 73 | - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8 && FC=gfortran-8" 74 | - OPTIM_TEST_USE_ARMA="y" 75 | compiler: gcc 76 | 77 | - os: osx 78 | osx_image: xcode9 79 | env: 80 | - MATRIX_EVAL="CC=clang && CXX=clang++" 81 | - OPTIM_TEST_USE_ARMA="y" 82 | compiler: clang 83 | 84 | before_install: 85 | - export FC=gfortran 86 | - eval "${MATRIX_EVAL}" 87 | - echo $FC 88 | 89 | install: 90 | - | 91 | if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then 92 | sudo apt-get update 93 | sudo apt-get install libblas-dev liblapack-dev 94 | # else 95 | # OSX 96 | # brew upgrade gcc || brew install gcc 97 | # export FC=gfortran 98 | fi 99 | 100 | script: 101 | - | 102 | WDIR=${PWD} 103 | if [[ "${OPTIM_TEST_USE_ARMA}" == "y" ]]; then 104 | mkdir ${WDIR}/arma_tmp 105 | git clone --single-branch https://gitlab.com/conradsnicta/armadillo-code.git ${WDIR}/arma_tmp > /dev/null 2>&1 106 | mv ${WDIR}/arma_tmp/include/* ${WDIR}/include 107 | rm -rf ${WDIR}/arma_tmp 108 | export ARMA_INCLUDE_PATH="./include" 109 | ./configure -c -l arma 110 | elif [[ "${OPTIM_TEST_USE_EIGEN}" == "y" ]]; then 111 | mkdir ${WDIR}/eigen_tmp 112 | git clone --single-branch https://gitlab.com/libeigen/eigen.git ${WDIR}/eigen_tmp > /dev/null 2>&1 113 | mv ${WDIR}/eigen_tmp/* ${WDIR}/include 114 | rm -rf ${WDIR}/eigen_tmp 115 | export EIGEN_INCLUDE_PATH="./include" 116 | ./configure -c -l eigen 117 | else 118 | echo -e " \x1B[31m- error: unrecognized linear algebra library.\033[0m" >&2 ; 119 | echo "" 120 | exit 1 121 | fi 122 | - make 123 | - cd ./tests 124 | - ./setup && ./test_setup/run_cov 125 | - cd .. 126 | 127 | after_success: 128 | - | 129 | if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then 130 | bash <(curl -s https://codecov.io/bash) 131 | fi 132 | 133 | after_failure: 134 | - ./travis-tool.sh dump_logs 135 | 136 | notifications: 137 | email: 138 | on_success: change 139 | on_failure: change 140 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | 2 | # core compiling options 3 | 4 | CXX = @CXX@ 5 | 6 | CXX_STD = @OPTIM_CXX_STD@ 7 | OPT_FLAGS = @OPTIM_WARN_FLAGS@ @OPTIM_OPT_FLAGS@ 8 | FPN_FLAGS = -DOPTIM_FPN_TYPE=@OPTIM_FPN_TYPE@ 9 | 10 | OPTIM_MATLIB_FLAGS = @OPTIM_MATLIB_FLAGS@ 11 | OPTIM_MATLIB_INCLUDE_PATH = @OPTIM_MATLIB_INCLUDE_PATH@ 12 | 13 | # install location 14 | INSTALL_PATH=@OPTIM_INSTALL_PATH@ 15 | 16 | # source directories 17 | SDIR = . 18 | OPTIM_DIR = $(SDIR) 19 | OPTIM_SRC_DIR = $(SDIR)/src 20 | OPTIM_HEADER_DIR = $(SDIR)/include 21 | 22 | # shared library name and flags 23 | SHLIB = @OPTIM_SHLIB_NAME@ 24 | SHLIB_FLAGS = $(CXX_STD) @OPTIM_SHLIB_FLAGS@ 25 | 26 | # general flags 27 | CXXFLAGS = $(CXX_STD) $(OPT_FLAGS) $(FPN_FLAGS) $(OPTIM_MATLIB_FLAGS) -I$(OPTIM_MATLIB_INCLUDE_PATH) -I$(OPTIM_HEADER_DIR) 28 | LIBS= @OPTIM_BLAS_LAPACK@ 29 | 30 | # core Optim files 31 | 32 | SOURCES_OPTIM_LS= $(OPTIM_SRC_DIR)/line_search/more_thuente.cpp 33 | OBJECTS_OPTIM_LS= $(SOURCES_OPTIM_LS:.cpp=.o) 34 | 35 | SOURCES_OPTIM_UNCONSTR := $(shell find $(OPTIM_SRC_DIR)/unconstrained -name '*.cpp') 36 | OBJECTS_OPTIM_UNCONSTR := $(SOURCES_OPTIM_UNCONSTR:%.cpp=%.o) 37 | 38 | SOURCES_OPTIM_CONSTR= $(OPTIM_SRC_DIR)/constrained/sumt.cpp 39 | OBJECTS_OPTIM_CONSTR= $(SOURCES_OPTIM_CONSTR:.cpp=.o) 40 | 41 | SOURCES_OPTIM_ZEROS= $(OPTIM_SRC_DIR)/zeros/broyden.cpp $(OPTIM_SRC_DIR)/zeros/broyden_df.cpp 42 | OBJECTS_OPTIM_ZEROS= $(SOURCES_OPTIM_ZEROS:.cpp=.o) 43 | 44 | OBJECTS_OPTIM= $(OBJECTS_OPTIM_LS) $(OBJECTS_OPTIM_UNCONSTR) $(OBJECTS_OPTIM_CONSTR) $(OBJECTS_OPTIM_ZEROS) 45 | 46 | all: $(OPTIM_DIR)/$(SHLIB) $(OBJECTS_OPTIM) 47 | 48 | # 49 | 50 | $(OPTIM_SRC_DIR)/misc/%.o: $(OPTIM_SRC_DIR)/misc/%.cpp 51 | $(CXX) $(CXXFLAGS) $< -c -o $@ 52 | 53 | $(OPTIM_SRC_DIR)/line_search/%.o: $(OPTIM_SRC_DIR)/line_search/%.cpp 54 | $(CXX) $(CXXFLAGS) $< -c -o $@ 55 | 56 | $(OPTIM_SRC_DIR)/unconstrained/%.o: $(OPTIM_SRC_DIR)/unconstrained/%.cpp 57 | $(CXX) $(CXXFLAGS) $< -c -o $@ 58 | 59 | $(OPTIM_SRC_DIR)/constrained/%.o: $(OPTIM_SRC_DIR)/constrained/%.cpp 60 | $(CXX) $(CXXFLAGS) $< -c -o $@ 61 | 62 | $(OPTIM_SRC_DIR)/generic/%.o: $(OPTIM_SRC_DIR)/generic/%.cpp 63 | $(CXX) $(CXXFLAGS) $< -c -o $@ 64 | 65 | $(OPTIM_SRC_DIR)/zeros/%.o: $(OPTIM_SRC_DIR)/zeros/%.cpp 66 | $(CXX) $(CXXFLAGS) $< -c -o $@ 67 | 68 | 69 | # shared library 70 | $(OPTIM_DIR)/$(SHLIB): $(OBJECTS_OPTIM) 71 | $(CXX) $(SHLIB_FLAGS) -o $@ $^ $(LIBS) 72 | 73 | # cleanup and install 74 | .PHONY: clean 75 | clean: 76 | @rm -f *.so ./tests/*/*.test ./tests/*/*.o $(OPTIM_SRC_DIR)/*/*.o ./tests/*/*.tmp $(OPTIM_SRC_DIR)/*/*.tmp \ 77 | $(OPTIM_SRC_DIR)/*/*.gcov $(OPTIM_SRC_DIR)/*/*.gcno $(OPTIM_SRC_DIR)/*/*.gcda $(OPTIM_SRC_DIR)/*/*.dSYM \ 78 | $(OPTIM_SRC_DIR)/*/*/*.o $(OPTIM_SRC_DIR)/*/*/*.gcov $(OPTIM_SRC_DIR)/*/*/*.gcno $(OPTIM_SRC_DIR)/*/*/*.gcda $(OPTIM_SRC_DIR)/*/*/*.dSYM 79 | 80 | .PHONY: vclean 81 | vclean: 82 | @rm -f *.so ./tests/*/*.test ./tests/*/*.o $(OPTIM_SRC_DIR)/*/*.o $(OPTIM_SRC_DIR)/*/*/*.o 83 | @rm -rf ./include/armadillo* 84 | 85 | .PHONY: install 86 | install: $(SHLIB) 87 | @cp $(OPTIM_DIR)/$(SHLIB) $(INSTALL_PATH)/lib/$(SHLIB) 88 | @mkdir -p $(INSTALL_PATH)/include/optim 89 | @cp -r $(OPTIM_DIR)/include/* $(INSTALL_PATH)/include/optim 90 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | OptimLib: A Lightweight C++ Library of Numerical Optimization Methods for Nonlinear Functions 2 | Copyright 2016-2023 Keith O'Hara 3 | 4 | This product includes software developed by Keith O'Hara (http://www.kthohr.com) -------------------------------------------------------------------------------- /docs/Doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = "optimlib" 2 | XML_OUTPUT = xml 3 | INPUT = ../include 4 | GENERATE_LATEX = NO 5 | GENERATE_MAN = NO 6 | GENERATE_RTF = NO 7 | CASE_SENSE_NAMES = NO 8 | GENERATE_HTML = NO 9 | GENERATE_XML = YES 10 | RECURSIVE = YES 11 | QUIET = YES 12 | JAVADOC_AUTOBRIEF = YES 13 | WARN_IF_UNDOCUMENTED = NO 14 | 15 | ENABLE_PREPROCESSING = YES 16 | MACRO_EXPANSION = YES 17 | EXPAND_ONLY_PREDEF = YES 18 | PREDEFINED = "optimlib_inline=inline" \ 19 | "OPTIM_ENABLE_ARMA_WRAPPERS" \ 20 | "OPTIM_ENABLE_EIGEN_WRAPPERS" 21 | -------------------------------------------------------------------------------- /docs/environment.yml: -------------------------------------------------------------------------------- 1 | 2 | name: optimlib-docs 3 | 4 | channels: 5 | - conda-forge 6 | 7 | dependencies: 8 | - doxygen=1.9.3 9 | - pip: 10 | - sphinx==5.1.1 11 | - breathe==4.34.0 12 | - sphinx-rtd-theme==1.0.0 13 | - sphinxcontrib-katex==0.8.6 14 | - sphinxcontrib-contentui==0.2.5 15 | - docutils==0.17.1 -------------------------------------------------------------------------------- /docs/source/_static/main_stylesheet.css: -------------------------------------------------------------------------------- 1 | .wy-nav-content{ 2 | max-width: 1050px !important; 3 | margin: auto; 4 | } 5 | -------------------------------------------------------------------------------- /docs/source/api/constrained_algo_index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | .. raw:: html 8 | 9 | 28 | 29 | Constrained Optimization 30 | ======================== 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | 35 | sumt 36 | 37 | +----------------------------------------+--------------------------------------------------------------+ 38 | | :ref:`sumt ` | Sequential Unconstrained Minimization Technique | 39 | +----------------------------------------+--------------------------------------------------------------+ 40 | | :ref:`sumt ` | Sequential Unconstrained Minimization Technique | 41 | +----------------------------------------+--------------------------------------------------------------+ 42 | -------------------------------------------------------------------------------- /docs/source/api/convex_algo_index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | .. raw:: html 8 | 9 | 28 | 29 | Convex Optimization 30 | =================== 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | 35 | bfgs 36 | 37 | +----------------------------------------+--------------------------------------------------------------+ 38 | | :ref:`bfgs ` | BFGS | 39 | +----------------------------------------+--------------------------------------------------------------+ 40 | | :ref:`bfgs ` | BFGS | 41 | +----------------------------------------+--------------------------------------------------------------+ 42 | 43 | .. toctree:: 44 | :maxdepth: 2 45 | 46 | lbfgs 47 | 48 | +----------------------------------------+--------------------------------------------------------------+ 49 | | :ref:`lbfgs ` | Limited Memory variant of BFGS | 50 | +----------------------------------------+--------------------------------------------------------------+ 51 | | :ref:`lbfgs ` | Limited Memory variant of BFGS | 52 | +----------------------------------------+--------------------------------------------------------------+ 53 | 54 | .. toctree:: 55 | :maxdepth: 2 56 | 57 | cg 58 | 59 | +----------------------------------------+--------------------------------------------------------------+ 60 | | :ref:`cg ` | Conjugate Gradient Method | 61 | +----------------------------------------+--------------------------------------------------------------+ 62 | | :ref:`cg ` | Conjugate Gradient Method | 63 | +----------------------------------------+--------------------------------------------------------------+ 64 | 65 | .. toctree:: 66 | :maxdepth: 2 67 | 68 | gd 69 | 70 | +----------------------------------------+--------------------------------------------------------------+ 71 | | :ref:`gd ` | Gradient Descent | 72 | +----------------------------------------+--------------------------------------------------------------+ 73 | | :ref:`gd ` | Gradient Descent | 74 | +----------------------------------------+--------------------------------------------------------------+ 75 | 76 | .. toctree:: 77 | :maxdepth: 2 78 | 79 | newton 80 | 81 | +----------------------------------------+--------------------------------------------------------------+ 82 | | :ref:`newton ` | Newton | 83 | +----------------------------------------+--------------------------------------------------------------+ 84 | | :ref:`newton ` | Newton | 85 | +----------------------------------------+--------------------------------------------------------------+ 86 | -------------------------------------------------------------------------------- /docs/source/api/metaheuristic_algo_index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | .. raw:: html 8 | 9 | 28 | 29 | Metaheuristic Optimization 30 | ========================== 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | 35 | de 36 | 37 | +----------------------------------------+----------------------------------------------------------------------+ 38 | | :ref:`de ` | Differential Evolution | 39 | +----------------------------------------+----------------------------------------------------------------------+ 40 | | :ref:`de ` | Differential Evolution | 41 | +----------------------------------------+----------------------------------------------------------------------+ 42 | 43 | .. toctree:: 44 | :maxdepth: 2 45 | 46 | de-prmm 47 | 48 | +----------------------------------------+----------------------------------------------------------------------+ 49 | | :ref:`de-prmm ` | DE with Population Reduction and Multiple Mutation (PRMM) Strategies | 50 | +----------------------------------------+----------------------------------------------------------------------+ 51 | | :ref:`de-prmm ` | DE with Population Reduction and Multiple Mutation (PRMM) Strategies | 52 | +----------------------------------------+----------------------------------------------------------------------+ 53 | 54 | 55 | .. toctree:: 56 | :maxdepth: 2 57 | 58 | pso 59 | 60 | +----------------------------------------+----------------------------------------------------------------------+ 61 | | :ref:`pso ` | Particle Swarm Optimization (PSO) | 62 | +----------------------------------------+----------------------------------------------------------------------+ 63 | | :ref:`pso ` | Particle Swarm Optimization (PSO) | 64 | +----------------------------------------+----------------------------------------------------------------------+ 65 | 66 | .. toctree:: 67 | :maxdepth: 2 68 | 69 | pso-dv 70 | 71 | +----------------------------------------+----------------------------------------------------------------------+ 72 | | :ref:`pso-dv ` | PSO with Differentially-Perturbed Velocity (DV) | 73 | +----------------------------------------+----------------------------------------------------------------------+ 74 | | :ref:`pso-dv ` | PSO with Differentially-Perturbed Velocity (DV) | 75 | +----------------------------------------+----------------------------------------------------------------------+ 76 | -------------------------------------------------------------------------------- /docs/source/api/root_finding_algo_index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | .. raw:: html 8 | 9 | 28 | 29 | Root Finding 30 | ============ 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | 35 | broyden 36 | 37 | +------------------------------------------+--------------------------------------------------------------+ 38 | | :ref:`broyden ` | Broyden's method for solving systems of nonlinear equations | 39 | +------------------------------------------+--------------------------------------------------------------+ 40 | | :ref:`broyden ` | Broyden's method for solving systems of nonlinear equations | 41 | +------------------------------------------+--------------------------------------------------------------+ 42 | | :ref:`broyden ` | Broyden's method for solving systems of nonlinear equations | 43 | +------------------------------------------+--------------------------------------------------------------+ 44 | | :ref:`broyden ` | Broyden's method for solving systems of nonlinear equations | 45 | +------------------------------------------+--------------------------------------------------------------+ 46 | 47 | .. toctree:: 48 | :maxdepth: 2 49 | 50 | broyden_df 51 | 52 | +------------------------------------------+--------------------------------------------------------------+ 53 | | :ref:`broyden-df ` | Derivative-free variant of Broyden's method | 54 | +------------------------------------------+--------------------------------------------------------------+ 55 | | :ref:`broyden-df ` | Derivative-free variant of Broyden's method | 56 | +------------------------------------------+--------------------------------------------------------------+ 57 | | :ref:`broyden-df ` | Derivative-free variant of Broyden's method | 58 | +------------------------------------------+--------------------------------------------------------------+ 59 | | :ref:`broyden-df ` | Derivative-free variant of Broyden's method | 60 | +------------------------------------------+--------------------------------------------------------------+ 61 | -------------------------------------------------------------------------------- /docs/source/api/simplex_algo_index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | .. raw:: html 8 | 9 | 28 | 29 | Simplex-based Optimization 30 | ========================== 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | 35 | nm 36 | 37 | +----------------------------------------+--------------------------------------------------------------+ 38 | | :ref:`nm ` | Nelder-Mead | 39 | +----------------------------------------+--------------------------------------------------------------+ 40 | | :ref:`nm ` | Nelder-Mead | 41 | +----------------------------------------+--------------------------------------------------------------+ 42 | -------------------------------------------------------------------------------- /docs/source/api/sumt.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | Sequential Unconstrained Minimization Technique 8 | =============================================== 9 | 10 | **Table of contents** 11 | 12 | .. contents:: :local: 13 | 14 | ---- 15 | 16 | Description 17 | ----------- 18 | 19 | For a general problem 20 | 21 | .. math:: 22 | 23 | \min_x f(x) \text{ subject to } g_k (x) \leq 0, \ \ k \in \{1, \ldots, K \} 24 | 25 | The Sequential Unconstrained Minimization Technique solves: 26 | 27 | .. math:: 28 | 29 | \min_x \left\{ f(x) + c(i) \times \frac{1}{2} \sum_{k=1}^K \left( \max \{ 0, g_k(x) \} \right)^2 \right\} 30 | 31 | The algorithm stops when the error is less than ``err_tol``, or the total number of 'generations' exceeds a desired (or default) value. 32 | 33 | ---- 34 | 35 | Definitions 36 | ----------- 37 | 38 | .. _sumt-func-ref1: 39 | .. doxygenfunction:: sumt(ColVec_t& init_out_vals, std::function opt_objfn, void* opt_data, std::function constr_fn, void* constr_data) 40 | :project: optimlib 41 | 42 | .. _sumt-func-ref2: 43 | .. doxygenfunction:: sumt(ColVec_t& init_out_vals, std::function opt_objfn, void* opt_data, std::function constr_fn, void* constr_data, algo_settings_t& settings) 44 | :project: optimlib 45 | 46 | ---- 47 | 48 | Examples 49 | -------- 50 | 51 | 52 | -------------------------------------------------------------------------------- /docs/source/autodiff.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | Automatic Differentiation 8 | ========================= 9 | 10 | Gradient-based optimization methods in OptimLib (such as BFGS and Gradient Descent) require a user-defined function that returns a gradient vector at each function evaluation. While this is best achieved by knowing the gradient in closed form, OptimLib also provides **experimental support** for automatic differentiation with Eigen-based builds via the `autodiff library `_. 11 | 12 | Requirements: an Eigen-based build of OptimLib, a copy of the ``autodiff`` header files, and a C++17 compatible compiler. 13 | 14 | ---- 15 | 16 | Example 17 | ------- 18 | 19 | The example below uses forward-mode automatic differentiation to compute the gradient of the Sphere function, and the BFGS algorithm to find the input values that minimize the autodiff-enabled function. 20 | 21 | .. code:: cpp 22 | 23 | /* 24 | * Forward-mode autodiff test with Sphere function 25 | */ 26 | 27 | #define OPTIM_ENABLE_EIGEN_WRAPPERS 28 | #include "optim.hpp" 29 | 30 | #include 31 | #include 32 | 33 | // 34 | 35 | autodiff::real 36 | opt_fnd(const autodiff::ArrayXreal& x) 37 | { 38 | return x.cwiseProduct(x).sum(); 39 | } 40 | 41 | double 42 | opt_fn(const Eigen::VectorXd& x, Eigen::VectorXd* grad_out, void* opt_data) 43 | { 44 | autodiff::real u; 45 | autodiff::ArrayXreal xd = x.eval(); 46 | 47 | if (grad_out) { 48 | Eigen::VectorXd grad_tmp = autodiff::gradient(opt_fnd, autodiff::wrt(xd), autodiff::at(xd), u); 49 | 50 | *grad_out = grad_tmp; 51 | } else { 52 | u = opt_fnd(xd); 53 | } 54 | 55 | return u.val(); 56 | } 57 | 58 | int main() 59 | { 60 | Eigen::VectorXd x(5); 61 | x << 1, 2, 3, 4, 5; 62 | 63 | bool success = optim::bfgs(x, opt_fn, nullptr); 64 | 65 | if (success) { 66 | std::cout << "bfgs: forward-mode autodiff test completed successfully.\n" << std::endl; 67 | } else { 68 | std::cout << "bfgs: forward-mode autodiff test completed unsuccessfully.\n" << std::endl; 69 | } 70 | 71 | std::cout << "solution: x = \n" << x << std::endl; 72 | 73 | return 0; 74 | } 75 | 76 | 77 | This example can be compiled using: 78 | 79 | .. code:: bash 80 | 81 | g++ -Wall -std=c++17 -O3 -march=native -ffp-contract=fast -I/path/to/eigen -I/path/to/autodiff -I/path/to/optim/include optim_autodiff_ex.cpp -o optim_autodiff_ex.out -L/path/to/optim/lib -loptim 82 | 83 | 84 | See the ``examples/autodiff`` directory for an example using reverse-mode automatic differentiation. 85 | 86 | ---- 87 | -------------------------------------------------------------------------------- /docs/source/box_constraints.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | Box Constraints 8 | =============== 9 | 10 | This section provides implementation details for how OptimLib handles box constraints. 11 | 12 | The problem is to transform 13 | 14 | .. math:: 15 | 16 | \min_{x \in X} f(x) 17 | 18 | where :math:`X` is a subset of :math:`\mathbb{R}^d`, to 19 | 20 | .. math:: 21 | 22 | \min_{y \in \mathbb{R}^d} f(g^{-1}(y)) 23 | 24 | using a smooth, invertible mapping :math:`g: X \to \mathbb{R}^d`. 25 | 26 | OptimLib allows the user to specify upper and lower bounds for each element of the input vector, :math:`x_j \in [a_j, b_j]`, and uses the following specification for :math:`g`: 27 | 28 | .. math:: 29 | 30 | g(x_j) = \ln \left( \frac{x_j - a_j}{b_j - x_j} \right) 31 | 32 | with corresponding inverse: 33 | 34 | .. math:: 35 | 36 | g^{-1}(y_j) = \frac{a_j + b_j \exp(y_j)}{1 + \exp(y_j)} 37 | 38 | The gradient vector is then: 39 | 40 | .. math:: 41 | 42 | \nabla_y f(g^{-1}(y)) = J(y) [\nabla_{x = g^{-1}(y)} f] 43 | 44 | where :math:`J(y)` is a :math:`d \times d` diagonal matrix with typical element: 45 | 46 | .. math:: 47 | 48 | J_{j,j} = \frac{d}{d y_j} g^{-1}(y_j) = \frac{\exp( y_j ) (b_j - a_j)}{(1 + \exp(y_j))^2} 49 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import subprocess 5 | 6 | on_rtd = os.environ.get('READTHEDOCS', None) == 'True' 7 | 8 | if on_rtd: 9 | subprocess.run(["doxygen", "-v"]) 10 | subprocess.call('cd ..; doxygen', shell=True) 11 | 12 | import sphinx_rtd_theme 13 | 14 | html_theme = "sphinx_rtd_theme" 15 | 16 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 17 | 18 | html_theme_options = { 19 | 'navigation_depth': 4 20 | } 21 | 22 | def setup(app): 23 | app.add_css_file("main_stylesheet.css") 24 | 25 | # extensions = ['breathe','sphinx.ext.mathjax'] 26 | extensions = ['breathe','sphinxcontrib.katex','sphinxcontrib.contentui'] 27 | breathe_projects = { 'optimlib': '../xml' } 28 | templates_path = ['_templates'] 29 | html_static_path = ['_static'] 30 | source_suffix = '.rst' 31 | master_doc = 'index' 32 | project = 'OptimLib' 33 | copyright = '2016-2023 Keith O\'Hara' 34 | author = 'Keith O\'Hara' 35 | 36 | exclude_patterns = [] 37 | highlight_language = 'c++' 38 | pygments_style = 'sphinx' 39 | todo_include_todos = False 40 | htmlhelp_basename = 'optimdoc' 41 | -------------------------------------------------------------------------------- /docs/source/examples_and_tests.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | Examples and Tests 8 | ================== 9 | 10 | .. contents:: :local: 11 | 12 | ---- 13 | 14 | API 15 | --- 16 | 17 | The OptimLib API follows a relatively simple convention, with most algorithms called using the following syntax: 18 | 19 | .. code:: 20 | 21 | algorithm_id(, , ); 22 | 23 | The function inputs, in order, are: 24 | 25 | - A writable vector of initial values to define the starting point of the algorithm, where, in the event of successful completion of the algorithm, the initial values will be overwritten by the latest candidate solution vector. 26 | - The ``objective function`` is a user-defined function to be minimized, or zeroed-out in the case of root finding methods. 27 | - The final input is optional; it is any object that contains additional parameters necessary to evaluate the objective function. 28 | 29 | For example, the BFGS algorithm is called using 30 | 31 | .. code:: cpp 32 | 33 | bfgs(ColVec_t& init_out_vals, std::function opt_objfn, void* opt_data); 34 | 35 | 36 | ---- 37 | 38 | Example 39 | ------- 40 | 41 | The code below uses Differential Evolution to search for the minimum of the :ref:`Ackley function `, a well-known test function with many local minima. 42 | 43 | .. code:: cpp 44 | 45 | #define OPTIM_ENABLE_EIGEN_WRAPPERS 46 | #include "optim.hpp" 47 | 48 | #define OPTIM_PI 3.14159265358979 49 | 50 | double 51 | ackley_fn(const Eigen::VectorXd& vals_inp, Eigen::VectorXd* grad_out, void* opt_data) 52 | { 53 | const double x = vals_inp(0); 54 | const double y = vals_inp(1); 55 | 56 | const double obj_val = 20 + std::exp(1) - 20 * std::exp(-0.2 * std::sqrt(0.5 * (x * x + y * y))) - std::exp( 0.5 * (std::cos(2 * OPTIM_PI * x) + std::cos(2 * OPTIM_PI * y)) ); 57 | 58 | return obj_val; 59 | } 60 | 61 | int main() 62 | { 63 | Eigen::VectorXd x = 2.0 * Eigen::VectorXd::Ones(2); // initial values: (2,2) 64 | 65 | bool success = optim::de(x, ackley_fn, nullptr); 66 | 67 | if (success) { 68 | std::cout << "de: Ackley test completed successfully." << std::endl; 69 | } else { 70 | std::cout << "de: Ackley test completed unsuccessfully." << std::endl; 71 | } 72 | 73 | std::cout << "de: solution to Ackley test:\n" << x << std::endl; 74 | 75 | return 0; 76 | } 77 | 78 | On x86-based computers, this example can be compiled using: 79 | 80 | .. code:: bash 81 | 82 | g++ -Wall -std=c++14 -O3 -march=native -ffp-contract=fast -I/path/to/eigen -I/path/to/optim/include optim_de_ex.cpp -o optim_de_ex.out -L/path/to/optim/lib -loptim 83 | 84 | The Armadillo-based version of this example: 85 | 86 | .. code:: cpp 87 | 88 | #define OPTIM_ENABLE_ARMA_WRAPPERS 89 | #include "optim.hpp" 90 | 91 | // Ackley function 92 | 93 | double ackley_fn(const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data) 94 | { 95 | const double x = vals_inp(0); 96 | const double y = vals_inp(1); 97 | const double pi = arma::datum::pi; 98 | 99 | double obj_val = -20*std::exp( -0.2*std::sqrt(0.5*(x*x + y*y)) ) - std::exp( 0.5*(std::cos(2*pi*x) + std::cos(2*pi*y)) ) + 22.718282L; 100 | 101 | // 102 | 103 | return obj_val; 104 | } 105 | 106 | int main() 107 | { 108 | // initial values: 109 | arma::vec x = arma::ones(2,1) + 1.0; // (2,2) 110 | 111 | // 112 | 113 | std::chrono::time_point start = std::chrono::system_clock::now(); 114 | 115 | bool success = optim::de(x,ackley_fn,nullptr); 116 | 117 | std::chrono::time_point end = std::chrono::system_clock::now(); 118 | std::chrono::duration elapsed_seconds = end-start; 119 | 120 | if (success) { 121 | std::cout << "de: Ackley test completed successfully.\n" 122 | << "elapsed time: " << elapsed_seconds.count() << "s\n"; 123 | } else { 124 | std::cout << "de: Ackley test completed unsuccessfully." << std::endl; 125 | } 126 | 127 | arma::cout << "\nde: solution to Ackley test:\n" << x << arma::endl; 128 | 129 | return 0; 130 | } 131 | 132 | On x86-based computers, compile using: 133 | 134 | .. code:: bash 135 | 136 | g++ -Wall -std=c++11 -O3 -march=native -ffp-contract=fast -I/path/to/armadillo -I/path/to/optim/include optim_de_ex.cpp -o optim_de_ex.out -L/path/to/optim/lib -loptim 137 | 138 | 139 | ---- 140 | 141 | Test suite 142 | ---------- 143 | 144 | You can build the test suite as follows: 145 | 146 | .. code:: bash 147 | 148 | # compile tests 149 | cd ./tests 150 | ./setup 151 | cd ./unconstrained 152 | ./configure -l eigen 153 | make 154 | ./bfgs.test 155 | -------------------------------------------------------------------------------- /docs/source/images/ackley_fn_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/ackley_fn_3d.png -------------------------------------------------------------------------------- /docs/source/images/beale_fn_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/beale_fn_3d.png -------------------------------------------------------------------------------- /docs/source/images/booth_fn_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/booth_fn_3d.png -------------------------------------------------------------------------------- /docs/source/images/bukin_fn_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/bukin_fn_3d.png -------------------------------------------------------------------------------- /docs/source/images/levi_fn_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/levi_fn_3d.png -------------------------------------------------------------------------------- /docs/source/images/rastrigin_fn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/rastrigin_fn.png -------------------------------------------------------------------------------- /docs/source/images/rosenbrock_fn_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/rosenbrock_fn_3d.png -------------------------------------------------------------------------------- /docs/source/images/sphere_fn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/sphere_fn.png -------------------------------------------------------------------------------- /docs/source/images/table_fn_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/table_fn_3d.png -------------------------------------------------------------------------------- /docs/source/images/test_fn_1_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kthohr/optim/5453f48aca695e6fef123677f35cb4d22e356e73/docs/source/images/test_fn_1_3d.png -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | Introduction 8 | ============ 9 | 10 | OptimLib is a lightweight C++ library of numerical optimization methods for nonlinear functions. 11 | 12 | Features: 13 | 14 | - A C++11/14/17 library of local and global optimization algorithms, as well as root finding techniques. 15 | 16 | - Derivative-free optimization using advanced, parallelized metaheuristic methods. 17 | 18 | - Constrained optimization routines to handle simple box constraints, as well as systems of nonlinear constraints. 19 | 20 | - For fast and efficient matrix-based computation, OptimLib supports the following templated linear algebra libraries: 21 | 22 | - `Armadillo `_ 23 | 24 | - `Eigen `_ (version >= 3.4.0) 25 | 26 | - Automatic differentiation functionality is available through use of the `Autodiff library `_ 27 | 28 | - OpenMP-accelerated algorithms for parallel computation. 29 | 30 | - Straightforward linking with parallelized BLAS libraries, such as `OpenBLAS `_. 31 | 32 | - Available as a header-only library, or as a compiled shared library. 33 | 34 | - Released under a permissive, non-GPL license. 35 | 36 | Author: Keith O'Hara 37 | 38 | License: Apache Version 2.0 39 | 40 | ---- 41 | 42 | Installation 43 | ------------ 44 | 45 | The library can be installed on Unix-alike systems via the standard ``./configure && make`` method. 46 | 47 | See the installation page for :ref:`detailed instructions `. 48 | 49 | Algorithms 50 | ---------- 51 | 52 | A list of currently available algorithms includes: 53 | 54 | * Broyden's Method (for root finding) 55 | * Newton's method, BFGS, and L-BFGS 56 | * Gradient descent: basic, momentum, Adam, AdaMax, Nadam, NadaMax, and more 57 | * Nonlinear Conjugate Gradient 58 | * Nelder-Mead 59 | * Differential Evolution (DE) 60 | * Particle Swarm Optimization (PSO) 61 | 62 | ---- 63 | 64 | Contents 65 | -------- 66 | 67 | .. toctree:: 68 | :caption: Guide 69 | :maxdepth: 2 70 | 71 | installation 72 | examples_and_tests 73 | settings 74 | autodiff 75 | 76 | .. toctree:: 77 | :caption: Algorithms 78 | :maxdepth: 2 79 | 80 | api/convex_algo_index 81 | api/simplex_algo_index 82 | api/metaheuristic_algo_index 83 | api/constrained_algo_index 84 | api/root_finding_algo_index 85 | 86 | .. toctree:: 87 | :caption: Appendix 88 | :maxdepth: 2 89 | 90 | box_constraints 91 | line_search 92 | test_functions 93 | -------------------------------------------------------------------------------- /docs/source/installation.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | .. _installation: 8 | 9 | Installation 10 | ============ 11 | 12 | OptimLib is available as a compiled shared library, or as header-only library, for Unix-alike systems only (e.g., popular Linux-based distros, as well as macOS). Note that the use of this library with Windows-based systems, with or without MSVC, **is not supported**. 13 | 14 | 15 | Requirements 16 | ------------ 17 | 18 | OptimLib requires either the Armadillo or Eigen(3) C++ linear algebra libraries. (Note that Eigen version 3.4.0 requires a C++14-compatible compiler.) 19 | 20 | The following options should be declared **before** including the OptimLib header files. 21 | 22 | - OpenMP functionality is enabled by default if the ``_OPENMP`` macro is detected (e.g., by invoking ``-fopenmp`` with GCC or Clang). 23 | 24 | - To explicitly enable OpenMP features, use: 25 | 26 | .. code:: cpp 27 | 28 | #define OPTIM_USE_OPENMP 29 | 30 | - To explicitly disable OpenMP functionality, use: 31 | 32 | .. code:: cpp 33 | 34 | #define OPTIM_DONT_USE_OPENMP 35 | 36 | - To use OptimLib with Armadillo or Eigen: 37 | 38 | .. code:: cpp 39 | 40 | #define OPTIM_ENABLE_ARMA_WRAPPERS 41 | #define OPTIM_ENABLE_EIGEN_WRAPPERS 42 | 43 | Example: 44 | 45 | .. code:: cpp 46 | 47 | #define OPTIM_ENABLE_EIGEN_WRAPPERS 48 | #include "optim.hpp" 49 | 50 | - To use OptimLib with RcppArmadillo or RcppEigen: 51 | 52 | .. code:: cpp 53 | 54 | #define OPTIM_USE_RCPP_ARMADILLO 55 | #define OPTIM_USE_RCPP_EIGEN 56 | 57 | Example: 58 | 59 | .. code:: cpp 60 | 61 | #define OPTIM_USE_RCPP_EIGEN 62 | #include "optim.hpp" 63 | 64 | 65 | ---- 66 | 67 | Installation Method 1: Shared Library 68 | ------------------------------------- 69 | 70 | The library can be installed on Unix-alike systems via the standard ``./configure && make`` method. 71 | 72 | The primary configuration options can be displayed by calling ``./configure -h``, which results in: 73 | 74 | .. code:: bash 75 | 76 | $ ./configure -h 77 | 78 | OptimLib Configuration 79 | 80 | Main options: 81 | -c Code coverage build 82 | (default: disabled) 83 | -d Developmental build 84 | (default: disabled) 85 | -f Floating-point number type 86 | (default: double) 87 | -g Debugging build (optimization flags set to -O0 -g) 88 | (default: disabled) 89 | -h Print help 90 | -i Install path (default: current directory) 91 | Example: /usr/local 92 | -l Choice of linear algebra library 93 | Examples: -l arma or -l eigen 94 | -m Specify the BLAS and Lapack libraries to link against 95 | Examples: -m "-lopenblas" or -m "-framework Accelerate" 96 | -o Compiler optimization options 97 | (default: -O3 -march=native -ffp-contract=fast -flto -DARMA_NO_DEBUG) 98 | -p Enable OpenMP parallelization features 99 | (default: disabled) 100 | 101 | Special options: 102 | --header-only-version Generate a header-only version of OptimLib 103 | 104 | If choosing a shared library build, set (one) of the following environment variables *before* running `configure`: 105 | 106 | .. code:: bash 107 | 108 | export ARMA_INCLUDE_PATH=/path/to/armadillo 109 | export EIGEN_INCLUDE_PATH=/path/to/eigen 110 | 111 | Then, to set the install path to ``/usr/local``, use Armadillo as the linear algebra library, and enable OpenMP features, we would run: 112 | 113 | .. code:: bash 114 | 115 | ./configure -i "/usr/local" -l arma -p 116 | 117 | Following this with the standard ``make && make install`` would build the library and install into ``/usr/local``. 118 | 119 | ---- 120 | 121 | Installation Method 2: Header-only Library 122 | ------------------------------------------ 123 | 124 | OptimLib is also available as a header-only library (i.e., without the need to compile a shared library). Simply run ``configure`` with the ``--header-only-version`` option: 125 | 126 | .. code:: bash 127 | 128 | ./configure --header-only-version 129 | 130 | This will create a new directory, ``header_only_version``, containing a copy of OptimLib, modified to work on an inline basis. 131 | With this header-only version, simply include the header files (``#include "optim.hpp``) and set the include path to the ``head_only_version`` directory (e.g.,``-I/path/to/optimlib/header_only_version``). 132 | -------------------------------------------------------------------------------- /docs/source/line_search.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2016-2023 Keith O'Hara 2 | 3 | Distributed under the terms of the Apache License, Version 2.0. 4 | 5 | The full license is in the file LICENSE, distributed with this software. 6 | 7 | Line Search 8 | =========== 9 | 10 | For effective line search in convex optimization problems, OptimLib uses the method of More and Thuente (1994). 11 | -------------------------------------------------------------------------------- /examples/autodiff/autodiff_forward_sphere.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Forward-mode autodiff test with Sphere function 3 | * 4 | * $CXX -Wall -std=c++17 -mcpu=native -O3 -ffp-contract=fast -I$EIGEN_INCLUDE_PATH -I$AUTODIFF_INCLUDE_PATH -I$OPTIM/include autodiff_forward_sphere.cpp -o autodiff_forward_sphere.test -L$OPTIM -loptim -framework Accelerate 5 | */ 6 | 7 | #define OPTIM_ENABLE_EIGEN_WRAPPERS 8 | #include "optim.hpp" 9 | 10 | #include 11 | #include 12 | 13 | // 14 | 15 | autodiff::real 16 | opt_fnd(const autodiff::ArrayXreal& x) 17 | { 18 | return x.cwiseProduct(x).sum(); 19 | } 20 | 21 | double 22 | opt_fn(const Eigen::VectorXd& x, Eigen::VectorXd* grad_out, void* opt_data) 23 | { 24 | autodiff::real u; 25 | autodiff::ArrayXreal xd = x.eval(); 26 | 27 | if (grad_out) { 28 | Eigen::VectorXd grad_tmp = autodiff::gradient(opt_fnd, autodiff::wrt(xd), autodiff::at(xd), u); 29 | 30 | *grad_out = grad_tmp; 31 | } else { 32 | u = opt_fnd(xd); 33 | } 34 | 35 | return u.val(); 36 | } 37 | 38 | int main() 39 | { 40 | Eigen::VectorXd x(5); 41 | x << 1, 2, 3, 4, 5; 42 | 43 | bool success = optim::bfgs(x, opt_fn, nullptr); 44 | 45 | if (success) { 46 | std::cout << "bfgs: forward-mode autodiff test completed successfully.\n" << std::endl; 47 | } else { 48 | std::cout << "bfgs: forward-mode autodiff test completed unsuccessfully.\n" << std::endl; 49 | } 50 | 51 | std::cout << "solution: x = \n" << x << std::endl; 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /examples/autodiff/autodiff_reverse_sphere.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Reverse-mode autodiff test with Sphere function 3 | * 4 | * $CXX -Wall -std=c++17 -mcpu=native -O3 -ffp-contract=fast -I$EIGEN_INCLUDE_PATH -I$AUTODIFF_INCLUDE_PATH -I$OPTIM/include autodiff_reverse_sphere.cpp -o autodiff_reverse_sphere.test -L$OPTIM -loptim -framework Accelerate 5 | */ 6 | 7 | #define OPTIM_ENABLE_EIGEN_WRAPPERS 8 | #include "optim.hpp" 9 | 10 | #include 11 | #include 12 | 13 | // 14 | 15 | autodiff::var 16 | opt_fnd(const autodiff::ArrayXvar& x) 17 | { 18 | return x.cwiseProduct(x).sum(); 19 | } 20 | 21 | double 22 | opt_fn(const Eigen::VectorXd& x, Eigen::VectorXd* grad_out, void* opt_data) 23 | { 24 | autodiff::ArrayXvar xd = x.eval(); 25 | 26 | autodiff::var y = opt_fnd(xd); 27 | 28 | if (grad_out) { 29 | Eigen::VectorXd grad_tmp = autodiff::gradient(y, xd); 30 | 31 | *grad_out = grad_tmp; 32 | } 33 | 34 | return autodiff::val(y); 35 | } 36 | 37 | int main() 38 | { 39 | Eigen::VectorXd x(5); 40 | x << 1, 2, 3, 4, 5; 41 | 42 | bool success = optim::bfgs(x, opt_fn, nullptr); 43 | 44 | if (success) { 45 | std::cout << "bfgs: reverse-mode autodiff test completed successfully.\n" << std::endl; 46 | } else { 47 | std::cout << "bfgs: reverse-mode autodiff test completed unsuccessfully.\n" << std::endl; 48 | } 49 | 50 | std::cout << "solution: x = \n" << x << std::endl; 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /examples/logit_reg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Newton tests 3 | * 4 | * $CXX -O3 -Wall -std=c++11 -march=native -ffp-contract=fast -I$ARMA_INCLUDE_PATH -I$OPTIM/include logit_reg.cpp -o logit_reg.test -L$OPTIM -loptim -framework Accelerate 5 | */ 6 | 7 | #include "optim.hpp" 8 | 9 | // sigmoid function 10 | 11 | inline 12 | Mat_t sigm(const Mat_t& X) 13 | { 14 | return 1.0 / (1.0 + arma::exp(-X)); 15 | } 16 | 17 | // log-likelihood function data 18 | 19 | struct ll_data_t 20 | { 21 | ColVec_t Y; 22 | Mat_t X; 23 | }; 24 | 25 | // log-likelihood function with hessian 26 | 27 | double ll_fn_whess(const ColVec_t& vals_inp, ColVec_t* grad_out, Mat_t* hess_out, void* opt_data) 28 | { 29 | ll_data_t* objfn_data = reinterpret_cast(opt_data); 30 | 31 | ColVec_t Y = objfn_data->Y; 32 | Mat_t X = objfn_data->X; 33 | 34 | ColVec_t mu = sigm(X*vals_inp); 35 | 36 | const double norm_term = static_cast(Y.n_elem); 37 | 38 | const double obj_val = - arma::accu( Y%arma::log(mu) + (1.0-Y)%arma::log(1.0-mu) ) / norm_term; 39 | 40 | // 41 | 42 | if (grad_out) 43 | { 44 | *grad_out = X.t() * (mu - Y) / norm_term; 45 | } 46 | 47 | // 48 | 49 | if (hess_out) 50 | { 51 | Mat_t S = arma::diagmat( mu%(1.0-mu) ); 52 | *hess_out = X.t() * S * X / norm_term; 53 | } 54 | 55 | // 56 | 57 | return obj_val; 58 | } 59 | 60 | // log-likelihood function for Adam 61 | 62 | double ll_fn(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 63 | { 64 | return ll_fn_whess(vals_inp,grad_out,nullptr,opt_data); 65 | } 66 | 67 | // 68 | 69 | int main() 70 | { 71 | int n_dim = 5; // dimension of parameter vector 72 | int n_samp = 4000; // sample length 73 | 74 | Mat_t X = arma::randn(n_samp,n_dim); 75 | ColVec_t theta_0 = 1.0 + 3.0*arma::randu(n_dim,1); 76 | 77 | ColVec_t mu = sigm(X*theta_0); 78 | 79 | ColVec_t Y(n_samp); 80 | 81 | for (int i=0; i < n_samp; i++) 82 | { 83 | Y(i) = ( arma::as_scalar(arma::randu(1)) < mu(i) ) ? 1.0 : 0.0; 84 | } 85 | 86 | // fn data and initial values 87 | 88 | ll_data_t opt_data; 89 | opt_data.Y = std::move(Y); 90 | opt_data.X = std::move(X); 91 | 92 | ColVec_t x = arma::ones(n_dim,1) + 1.0; // initial values 93 | 94 | // run Adam-based optim 95 | 96 | optim::algo_settings_t settings; 97 | 98 | settings.gd_method = 6; 99 | settings.gd_settings.step_size = 0.1; 100 | 101 | std::chrono::time_point start = std::chrono::system_clock::now(); 102 | 103 | bool success = optim::gd(x,ll_fn,&opt_data,settings); 104 | 105 | std::chrono::time_point end = std::chrono::system_clock::now(); 106 | std::chrono::duration elapsed_seconds = end-start; 107 | 108 | // 109 | 110 | if (success) { 111 | std::cout << "Adam: logit_reg test completed successfully.\n" 112 | << "elapsed time: " << elapsed_seconds.count() << "s\n"; 113 | } else { 114 | std::cout << "Adam: logit_reg test completed unsuccessfully." << std::endl; 115 | } 116 | 117 | arma::cout << "\nAdam: true values vs estimates:\n" << arma::join_rows(theta_0,x) << arma::endl; 118 | 119 | // 120 | // run Newton-based optim 121 | 122 | x = arma::ones(n_dim,1) + 1.0; // initial values 123 | 124 | start = std::chrono::system_clock::now(); 125 | 126 | success = optim::newton(x,ll_fn_whess,&opt_data); 127 | 128 | end = std::chrono::system_clock::now(); 129 | elapsed_seconds = end-start; 130 | 131 | // 132 | 133 | if (success) { 134 | std::cout << "newton: logit_reg test completed successfully.\n" 135 | << "elapsed time: " << elapsed_seconds.count() << "s\n"; 136 | } else { 137 | std::cout << "newton: logit_reg test completed unsuccessfully." << std::endl; 138 | } 139 | 140 | arma::cout << "\nnewton: true values vs estimates:\n" << arma::join_rows(theta_0,x) << arma::endl; 141 | 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /include/constrained/sumt.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Sequential unconstrained minimization technique (SUMT) 23 | */ 24 | 25 | #ifndef _optim_sumt_HPP 26 | #define _optim_sumt_HPP 27 | 28 | /** 29 | * @brief Sequential Unconstrained Minimization Technique 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * @param constr_fn the constraint functions, in vector form, taking three arguments. 38 | * @param constr_data additional data passed to the constraints functions. 39 | * 40 | * @return a boolean value indicating successful completion of the optimization algorithm. 41 | */ 42 | 43 | bool 44 | sumt( 45 | ColVec_t& init_out_vals, 46 | std::function opt_objfn, 47 | void* opt_data, 48 | std::function constr_fn, 49 | void* constr_data 50 | ); 51 | 52 | /** 53 | * @brief Sequential Unconstrained Minimization Technique 54 | * 55 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 56 | * @param opt_objfn the function to be minimized, taking three arguments: 57 | * - \c vals_inp a vector of inputs; 58 | * - \c grad_out a vector to store the gradient; and 59 | * - \c opt_data additional data passed to the user-provided function. 60 | * @param opt_data additional data passed to the user-provided function. 61 | * @param constr_fn the constraint functions, in vector form, taking three arguments. 62 | * @param constr_data additional data passed to the constraints functions. 63 | * @param settings parameters controlling the optimization routine. 64 | * 65 | * @return a boolean value indicating successful completion of the optimization algorithm. 66 | */ 67 | 68 | bool 69 | sumt( 70 | ColVec_t& init_out_vals, 71 | std::function opt_objfn, 72 | void* opt_data, 73 | std::function constr_fn, 74 | void* constr_data, 75 | algo_settings_t& settings 76 | ); 77 | 78 | // 79 | // internal 80 | 81 | namespace internal 82 | { 83 | 84 | struct sumt_data_t { 85 | fp_t c_pen; 86 | }; 87 | 88 | inline 89 | fp_t 90 | mt_sup_norm( 91 | const fp_t a, 92 | const fp_t b, 93 | const fp_t c 94 | ) 95 | { 96 | return std::max( std::max(std::abs(a), std::abs(b)), std::abs(c) ); 97 | } 98 | 99 | bool 100 | sumt_impl( 101 | ColVec_t& init_out_vals, 102 | std::function opt_objfn, 103 | void* opt_data, 104 | std::function constr_fn, 105 | void* constr_data, 106 | algo_settings_t* settings_inp 107 | ); 108 | 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /include/line_search/more_thuente.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Moré and Thuente line search 23 | * 24 | * Based on MINPACK fortran code and Dianne P. O'Leary's Matlab translation of MINPACK 25 | */ 26 | 27 | #ifndef _optim_more_thuente_HPP 28 | #define _optim_more_thuente_HPP 29 | 30 | namespace internal 31 | { 32 | 33 | fp_t 34 | line_search_mt( 35 | fp_t step, 36 | ColVec_t& x, 37 | ColVec_t& grad, 38 | const ColVec_t& direc, 39 | const fp_t* wolfe_cons_1_inp, 40 | const fp_t* wolfe_cons_2_inp, 41 | std::function opt_objfn, 42 | void* opt_data 43 | ); 44 | 45 | // update the 'interval of uncertainty' 46 | 47 | uint_t 48 | mt_step( 49 | fp_t& st_best, 50 | fp_t& f_best, 51 | fp_t& d_best, 52 | fp_t& st_other, 53 | fp_t& f_other, 54 | fp_t& d_other, 55 | fp_t& step, 56 | fp_t& f_step, 57 | fp_t& d_step, 58 | bool& bracket, 59 | fp_t step_min, 60 | fp_t step_max 61 | ); 62 | 63 | fp_t 64 | mt_sup_norm( 65 | const fp_t a, 66 | const fp_t b, 67 | const fp_t c 68 | ); 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /include/misc/bounds_check.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * check and impose sampling bounds for DE and PSO 23 | */ 24 | 25 | inline 26 | void 27 | sampling_bounds_check( 28 | const bool vals_bound, 29 | const size_t n_vals, 30 | const ColVecInt_t bounds_type, 31 | const ColVec_t& hard_lower_bounds, 32 | const ColVec_t& hard_upper_bounds, 33 | ColVec_t& sampling_lower_bounds, 34 | ColVec_t& sampling_upper_bounds 35 | ) 36 | { 37 | if (vals_bound) { 38 | for (size_t i = 0; i < n_vals; ++i) { 39 | if (bounds_type(i) == 4 || bounds_type(i) == 2) { 40 | // lower and upper bound imposed || lower bound only 41 | sampling_lower_bounds(i) = std::max( hard_lower_bounds(i), sampling_lower_bounds(i) ); 42 | } 43 | if (bounds_type(i) == 4 || bounds_type(i) == 3) { 44 | // lower and upper bound imposed || upper bound only 45 | sampling_upper_bounds(i) = std::min( hard_upper_bounds(i), sampling_upper_bounds(i) ); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /include/misc/determine_bounds_type.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Determine the upper-lower bounds combo type 23 | */ 24 | 25 | // note: std::isfinite is not true for NaN, - Inf, or + Inf 26 | 27 | inline 28 | ColVecInt_t 29 | determine_bounds_type( 30 | const bool vals_bound, 31 | const size_t n_vals, 32 | const ColVec_t& lower_bounds, 33 | const ColVec_t& upper_bounds 34 | ) 35 | { 36 | ColVecInt_t ret_vec(n_vals); 37 | 38 | BMO_MATOPS_SET_VALUES_SCALAR(ret_vec, 1); // base case: 1 - no bounds imposed 39 | 40 | if (vals_bound) { 41 | for (size_t i = 0; i < n_vals; ++i) { 42 | if ( std::isfinite(lower_bounds(i)) && std::isfinite(upper_bounds(i)) ) { 43 | // lower and upper bound imposed 44 | ret_vec(i) = 4; 45 | } else if ( std::isfinite(lower_bounds(i)) && !std::isfinite(upper_bounds(i)) ) { 46 | // lower bound only 47 | ret_vec(i) = 2; 48 | } else if ( !std::isfinite(lower_bounds(i)) && std::isfinite(upper_bounds(i)) ) { 49 | // upper bound only 50 | ret_vec(i) = 3; 51 | } 52 | } 53 | } 54 | 55 | // 56 | 57 | return ret_vec; 58 | } 59 | -------------------------------------------------------------------------------- /include/misc/error_reporting.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Error reporting 23 | */ 24 | 25 | #ifndef _optim_error_reporting_HPP 26 | #define _optim_error_reporting_HPP 27 | 28 | void error_reporting( 29 | ColVec_t& out_vals, 30 | const ColVec_t& x_p, 31 | std::function opt_objfn, 32 | void* opt_data, 33 | bool& success, 34 | const fp_t err, 35 | const fp_t err_tol, 36 | const size_t iter, 37 | const size_t iter_max, 38 | const int conv_failure_switch, 39 | algo_settings_t* settings_inp 40 | ); 41 | 42 | void error_reporting(ColVec_t& out_vals, 43 | const ColVec_t& x_p, 44 | std::function opt_objfn, 45 | void* opt_data, 46 | bool& success, 47 | const int conv_failure_switch, 48 | algo_settings_t* settings_inp 49 | ); 50 | 51 | void error_reporting( 52 | ColVec_t& out_vals, 53 | const ColVec_t& x_p, 54 | std::function opt_objfn, 55 | void* opt_data, 56 | bool& success, 57 | const fp_t err, 58 | const fp_t err_tol, 59 | const size_t iter, 60 | const size_t iter_max, 61 | const int conv_failure_switch, 62 | algo_settings_t* settings_inp 63 | ); 64 | 65 | // 66 | 67 | void error_reporting( 68 | ColVec_t& out_vals, 69 | const ColVec_t& x_p, 70 | std::function opt_objfn, 71 | void* opt_data, 72 | bool& success, 73 | const fp_t err, 74 | const fp_t err_tol, 75 | const size_t iter, 76 | const size_t iter_max, 77 | const int conv_failure_switch, 78 | algo_settings_t* settings_inp 79 | ); 80 | 81 | // 82 | 83 | #include "error_reporting.ipp" 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/misc/jacobian_adjust.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Jacobian adjustment 23 | */ 24 | 25 | inline 26 | Mat_t 27 | jacobian_adjust( 28 | const ColVec_t& vals_trans_inp, 29 | const ColVecInt_t& bounds_type, 30 | const ColVec_t& lower_bounds, 31 | const ColVec_t& upper_bounds 32 | ) 33 | { 34 | const size_t n_vals = BMO_MATOPS_SIZE(bounds_type); 35 | 36 | Mat_t ret_mat = BMO_MATOPS_EYE(n_vals); 37 | 38 | for (size_t i = 0; i < n_vals; ++i) { 39 | switch (bounds_type(i)) { 40 | case 2: // lower bound only 41 | ret_mat(i,i) = std::exp(vals_trans_inp(i)); 42 | break; 43 | case 3: // upper bound only 44 | ret_mat(i,i) = std::exp(-vals_trans_inp(i)); 45 | break; 46 | case 4: // upper and lower bounds 47 | // ret_mat(i,i) = std::exp(vals_trans_inp(i))*(upper_bounds(i) - lower_bounds(i)) / std::pow(std::exp(vals_trans_inp(i)) + 1,2); 48 | ret_mat(i,i) = std::exp(vals_trans_inp(i)) * (2*eps_dbl + upper_bounds(i) - lower_bounds(i)) \ 49 | / (std::exp(2 * vals_trans_inp(i)) + 2*std::exp(vals_trans_inp(i)) + 1); 50 | break; 51 | } 52 | } 53 | 54 | return ret_mat; 55 | } 56 | -------------------------------------------------------------------------------- /include/misc/numerical_gradient.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Numerical Gradient, using Abramowitz and Stegun (1972, p. 883, 25.3.21) 23 | */ 24 | 25 | inline 26 | ColVec_t 27 | numerical_gradient( 28 | const ColVec_t& vals_inp, 29 | const fp_t* step_size_inp, 30 | std::function objfn, 31 | void* objfn_data 32 | ) 33 | { 34 | const size_t n_vals = BMO_MATOPS_SIZE(vals_inp); 35 | 36 | const fp_t step_size = (step_size_inp) ? *step_size_inp : 1e-04; 37 | const fp_t step_size_lb_val = std::sqrt(step_size) * std::pow( std::numeric_limits::epsilon(), fp_t(1.0/6.0) ); 38 | const ColVec_t step_size_lb_vec = BMO_MATOPS_CONSTANT_COLVEC(n_vals, step_size_lb_val); 39 | 40 | const ColVec_t step_vec = BMO_MATOPS_MAX( BMO_MATOPS_ABS(vals_inp), step_size_lb_vec ); 41 | 42 | ColVec_t x_orig = vals_inp, x_term_1, x_term_2; 43 | ColVec_t grad_vec = BMO_MATOPS_ZERO_COLVEC(n_vals); 44 | 45 | // 46 | 47 | for (size_t i = 0; i < n_vals; ++i) { 48 | x_term_1 = x_orig; 49 | x_term_2 = x_orig; 50 | 51 | x_term_1(i) += step_vec(i); 52 | x_term_2(i) -= step_vec(i); 53 | 54 | 55 | // 56 | 57 | fp_t term_1 = objfn(x_term_1, nullptr, objfn_data); 58 | fp_t term_2 = -objfn(x_term_2, nullptr, objfn_data); 59 | 60 | fp_t denom_term = fp_t(2.0) * step_vec(i); 61 | 62 | grad_vec(i) = (term_1 + term_2) / denom_term; 63 | } 64 | 65 | // 66 | 67 | return grad_vec; 68 | } 69 | -------------------------------------------------------------------------------- /include/misc/numerical_hessian.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Numerical Hessian, using Abramowitz and Stegun (1972, p. 884, 25.3.24 and 25.3.26) 23 | */ 24 | 25 | inline 26 | Mat_t 27 | numerical_hessian( 28 | const ColVec_t& vals_inp, 29 | const fp_t* step_size_inp, 30 | std::function objfn, 31 | void* objfn_data 32 | ) 33 | { 34 | const size_t n_vals = BMO_MATOPS_SIZE(vals_inp); 35 | 36 | const fp_t step_size = (step_size_inp) ? *step_size_inp : 1e-04; 37 | const fp_t mach_eps = std::numeric_limits::epsilon(); 38 | 39 | // const ColVec_t step_vec = arma::max(arma::abs(vals_inp), std::sqrt(step_size) * std::pow(mach_eps,1.0/6.0) * arma::ones(n_vals,1)); 40 | const ColVec_t step_vec = BMO_MATOPS_MAX( BMO_MATOPS_ABS(vals_inp), std::sqrt(step_size) * std::pow(mach_eps, fp_t(1.0/6.0)) * BMO_MATOPS_ONE_COLVEC(n_vals) ); 41 | 42 | ColVec_t x_orig = vals_inp, x_term_1, x_term_2, x_term_3, x_term_4; 43 | Mat_t hessian_mat = BMO_MATOPS_ZERO_MAT(n_vals,n_vals); 44 | 45 | const fp_t f_orig = - fp_t(30.0) * objfn(x_orig, nullptr, objfn_data); 46 | 47 | // 48 | 49 | for (size_t i = 0; i < n_vals; ++i) { 50 | for (size_t j = i; j < n_vals; ++j) { 51 | x_term_1 = x_orig; 52 | x_term_2 = x_orig; 53 | x_term_3 = x_orig; 54 | x_term_4 = x_orig; 55 | 56 | if (i == j) { 57 | x_term_1(i) += fp_t(2.0) * step_vec(i); 58 | x_term_2(i) += step_vec(i); 59 | x_term_3(i) -= step_vec(i); 60 | x_term_4(i) -= fp_t(2.0) * step_vec(i); 61 | 62 | // 63 | 64 | fp_t term_1 = - objfn(x_term_1, nullptr, objfn_data); 65 | fp_t term_2 = fp_t(16.0) * objfn(x_term_2, nullptr, objfn_data); 66 | fp_t term_3 = fp_t(16.0) * objfn(x_term_3, nullptr, objfn_data); 67 | fp_t term_4 = - objfn(x_term_4, nullptr, objfn_data); 68 | 69 | fp_t denom_term = fp_t(12.0) * step_vec(i) * step_vec(i); 70 | 71 | hessian_mat(i,j) = (term_1 + term_2 + f_orig + term_3 + term_4) / denom_term; 72 | } else { 73 | x_term_1(i) += step_vec(i); 74 | x_term_1(j) += step_vec(j); 75 | 76 | x_term_2(i) += step_vec(i); 77 | x_term_2(j) -= step_vec(j); 78 | 79 | x_term_3(i) -= step_vec(i); 80 | x_term_3(j) += step_vec(j); 81 | 82 | x_term_4(i) -= step_vec(i); 83 | x_term_4(j) -= step_vec(j); 84 | 85 | // 86 | 87 | fp_t term_1 = objfn(x_term_1, nullptr, objfn_data); 88 | fp_t term_2 = -objfn(x_term_2, nullptr, objfn_data); 89 | fp_t term_3 = -objfn(x_term_3, nullptr, objfn_data); 90 | fp_t term_4 = objfn(x_term_4, nullptr, objfn_data); 91 | 92 | fp_t denom_term = fp_t(4.0) * step_vec(i) * step_vec(j); 93 | 94 | hessian_mat(i,j) = (term_1 + term_2 + term_3 + term_4) / denom_term; 95 | hessian_mat(j,i) = hessian_mat(i,j); 96 | } 97 | } 98 | } 99 | 100 | // 101 | 102 | return hessian_mat; 103 | } 104 | -------------------------------------------------------------------------------- /include/misc/optim_misc.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_MISC_INCLUDES 22 | #define OPTIMLIB_MISC_INCLUDES 23 | 24 | // structs 25 | #include "misc/optim_structs.hpp" 26 | 27 | // trace 28 | #include "misc/optim_trace.hpp" 29 | 30 | // utility functions 31 | #include "determine_bounds_type.hpp" 32 | #include "bounds_check.hpp" 33 | #include "error_reporting.hpp" 34 | #include "jacobian_adjust.hpp" 35 | #include "numerical_gradient.hpp" 36 | #include "numerical_hessian.hpp" 37 | #include "transform_vals.hpp" 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/misc/transform_vals.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * transform values 23 | */ 24 | 25 | template 26 | inline 27 | vT 28 | transform( 29 | const vT& vals_inp, 30 | const ColVecInt_t& bounds_type, 31 | const ColVec_t& lower_bounds, 32 | const ColVec_t& upper_bounds 33 | ) 34 | { 35 | const size_t n_vals = BMO_MATOPS_SIZE(bounds_type); 36 | 37 | vT vals_trans_out(n_vals); 38 | 39 | for (size_t i = 0; i < n_vals; ++i) { 40 | switch (bounds_type(i)) { 41 | case 1: // no bounds 42 | vals_trans_out(i) = vals_inp(i); 43 | break; 44 | case 2: // lower bound only 45 | vals_trans_out(i) = std::log(vals_inp(i) - lower_bounds(i) + eps_dbl); 46 | break; 47 | case 3: // upper bound only 48 | vals_trans_out(i) = - std::log(upper_bounds(i) - vals_inp(i) + eps_dbl); 49 | break; 50 | case 4: // upper and lower bounds 51 | vals_trans_out(i) = std::log(vals_inp(i) - lower_bounds(i) + eps_dbl) - std::log(upper_bounds(i) - vals_inp(i) + eps_dbl); 52 | break; 53 | } 54 | } 55 | 56 | // 57 | 58 | return vals_trans_out; 59 | } 60 | 61 | template 62 | inline 63 | vT 64 | inv_transform( 65 | const vT& vals_trans_inp, 66 | const ColVecInt_t& bounds_type, 67 | const ColVec_t& lower_bounds, 68 | const ColVec_t& upper_bounds 69 | ) 70 | { 71 | const size_t n_vals = BMO_MATOPS_SIZE(bounds_type); 72 | 73 | vT vals_out(n_vals); 74 | 75 | for (size_t i = 0; i < n_vals; ++i) { 76 | switch (bounds_type(i)) { 77 | case 1: // no bounds 78 | vals_out(i) = vals_trans_inp(i); 79 | break; 80 | case 2: // lower bound only 81 | if (!std::isfinite(vals_trans_inp(i))) { 82 | vals_out(i) = lower_bounds(i) + eps_dbl; 83 | } else { 84 | vals_out(i) = lower_bounds(i) + eps_dbl + std::exp(vals_trans_inp(i)); 85 | } 86 | break; 87 | case 3: // upper bound only 88 | if (!std::isfinite(vals_trans_inp(i))) { 89 | vals_out(i) = upper_bounds(i) - eps_dbl; 90 | } else { 91 | vals_out(i) = upper_bounds(i) - eps_dbl - std::exp(-vals_trans_inp(i)); 92 | } 93 | break; 94 | case 4: // upper and lower bounds 95 | if (!std::isfinite(vals_trans_inp(i))) { 96 | if (std::isnan(vals_trans_inp(i))) { 97 | vals_out(i) = (upper_bounds(i) - lower_bounds(i)) / 2; 98 | } 99 | else if (vals_trans_inp(i) < 0.0) { 100 | vals_out(i) = lower_bounds(i) + eps_dbl; 101 | } else { 102 | vals_out(i) = upper_bounds(i) - eps_dbl; 103 | } 104 | } else { 105 | vals_out(i) = ( lower_bounds(i) - eps_dbl + (upper_bounds(i) + eps_dbl)*std::exp(vals_trans_inp(i)) ) \ 106 | / ( 1.0 + std::exp(vals_trans_inp(i)) ); 107 | 108 | if (!std::isfinite(vals_out(i))) { 109 | vals_out(i) = upper_bounds(i) - eps_dbl; 110 | } 111 | } 112 | break; 113 | } 114 | } 115 | 116 | // 117 | 118 | return vals_out; 119 | } 120 | -------------------------------------------------------------------------------- /include/optim.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_INCLUDES 22 | #define OPTIMLIB_INCLUDES 23 | 24 | #include "misc/optim_options.hpp" 25 | 26 | namespace optim 27 | { 28 | // misc/utility files 29 | #include "misc/optim_misc.hpp" 30 | 31 | // stats/rng files 32 | #include "stats/optim_stats.hpp" 33 | 34 | // line search 35 | #include "line_search/more_thuente.hpp" 36 | 37 | // unconstrained optimization 38 | #include "unconstrained/optim_unconstrained.hpp" 39 | 40 | // constrained optimization 41 | #include "constrained/sumt.hpp" 42 | 43 | // solving systems of nonlinear equations 44 | #include "zeros/optim_zeros.hpp" 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/stats/optim_stats.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_STATS_INCLUDES 22 | #define OPTIMLIB_STATS_INCLUDES 23 | 24 | #include "seed_values.hpp" 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/stats/seed_values.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_STATS_SEED_VALUES 22 | #define OPTIMLIB_STATS_SEED_VALUES 23 | 24 | inline 25 | size_t 26 | generate_seed_value(const int ind_inp, const int n_threads, rand_engine_t& rand_engine) 27 | { 28 | return static_cast( (bmo::stats::runif(rand_engine) + ind_inp + n_threads) * 1000 ); 29 | // return static_cast( (ind_inp + n_threads) * 1000 ); 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/unconstrained/bfgs.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * BFGS method for quasi-Newton-based non-linear optimization 23 | */ 24 | 25 | #ifndef _optim_bfgs_HPP 26 | #define _optim_bfgs_HPP 27 | 28 | /** 29 | * @brief The Broyden–Fletcher–Goldfarb–Shanno (BFGS) Quasi-Newton Optimization Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | bfgs( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief The Broyden–Fletcher–Goldfarb–Shanno (BFGS) Quasi-Newton Optimization Algorithm 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | bfgs( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | bfgs_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp 82 | ); 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/unconstrained/de.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Differential Evolution (DE) optimization 23 | */ 24 | 25 | #ifndef _optim_de_HPP 26 | #define _optim_de_HPP 27 | 28 | /** 29 | * @brief The Differential Evolution (DE) Optimization Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | de( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief The Differential Evolution (DE) Optimization Algorithm 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | de( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | de_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp 82 | ); 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/unconstrained/de_prmm.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Differential Evolution (DE) with Population Reduction and Multiple Mutation Strategies 23 | */ 24 | 25 | #ifndef _optim_de_prmm_HPP 26 | #define _optim_de_prmm_HPP 27 | 28 | /** 29 | * @brief The Differential Evolution (DE) with Population Reduction and Multiple Mutation Strategies (PRMM) Optimization Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | de_prmm( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief The Differential Evolution (DE) with Population Reduction and Multiple Mutation Strategies (PRMM) Optimization Algorithm 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | de_prmm( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | de_prmm_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp 82 | ); 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/unconstrained/gd.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Gradient Descent (GD) 23 | */ 24 | 25 | #ifndef _optim_gd_HPP 26 | #define _optim_gd_HPP 27 | 28 | /** 29 | * @brief The Gradient Descent Optimization Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | gd( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief The Gradient Descent Optimization Algorithm 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | gd( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | gd_basic_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp); 82 | 83 | } 84 | 85 | #include "gd.ipp" 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/unconstrained/lbfgs.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * L-BFGS method for quasi-Newton-based non-linear optimization 23 | */ 24 | 25 | #ifndef _optim_lbfgs_HPP 26 | #define _optim_lbfgs_HPP 27 | 28 | /** 29 | * @brief The Limited Memory Variant of the BFGS Optimization Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | lbfgs( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief The Limited Memory Variant of the BFGS Optimization Algorithm 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | lbfgs( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | lbfgs_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp 82 | ); 83 | 84 | // algorithm 7.4 of Nocedal and Wright (2006) 85 | inline 86 | ColVec_t 87 | lbfgs_recur( 88 | ColVec_t q, 89 | const Mat_t& s_mat, 90 | const Mat_t& y_mat, 91 | const uint_t M 92 | ) 93 | { 94 | ColVec_t alpha_vec(M); 95 | 96 | // forwards 97 | 98 | // fp_t rho = 1.0; 99 | 100 | for (size_t i = 0; i < M; ++i) { 101 | fp_t rho = 1.0 / BMO_MATOPS_DOT_PROD(y_mat.col(i),s_mat.col(i)); 102 | alpha_vec(i) = rho * BMO_MATOPS_DOT_PROD(s_mat.col(i),q); 103 | 104 | q -= alpha_vec(i)*y_mat.col(i); 105 | } 106 | 107 | ColVec_t r = q * ( BMO_MATOPS_DOT_PROD(s_mat.col(0),y_mat.col(0)) / BMO_MATOPS_DOT_PROD(y_mat.col(0),y_mat.col(0)) ); 108 | 109 | // backwards 110 | 111 | // fp_t beta = 1.0; 112 | 113 | for (int i = M - 1; i >= 0; i--) { 114 | fp_t rho = 1.0 / BMO_MATOPS_DOT_PROD(y_mat.col(i),s_mat.col(i)); 115 | fp_t beta = rho * BMO_MATOPS_DOT_PROD(y_mat.col(i),r); 116 | 117 | r += (alpha_vec(i) - beta)*s_mat.col(i); 118 | } 119 | 120 | return r; 121 | } 122 | 123 | } 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /include/unconstrained/newton.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Newton's method for non-linear optimization 23 | */ 24 | 25 | #ifndef _optim_newton_HPP 26 | #define _optim_newton_HPP 27 | 28 | /** 29 | * @brief Newton's Nonlinear Optimization Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking four arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; 35 | * - \c hess_out a matrix to store the Hessian; and 36 | * - \c opt_data additional data passed to the user-provided function. 37 | * @param opt_data additional data passed to the user-provided function. 38 | * 39 | * @return a boolean value indicating successful completion of the optimization algorithm. 40 | */ 41 | 42 | bool 43 | newton( 44 | ColVec_t& init_out_vals, 45 | std::function opt_objfn, 46 | void* opt_data 47 | ); 48 | 49 | /** 50 | * @brief Newton's Nonlinear Optimization Algorithm 51 | * 52 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 53 | * @param opt_objfn the function to be minimized, taking four arguments: 54 | * - \c vals_inp a vector of inputs; 55 | * - \c grad_out a vector to store the gradient; 56 | * - \c hess_out a matrix to store the Hessian; and 57 | * - \c opt_data additional data passed to the user-provided function. 58 | * @param opt_data additional data passed to the user-provided function. 59 | * @param settings parameters controlling the optimization routine. 60 | * 61 | * @return a boolean value indicating successful completion of the optimization algorithm. 62 | */ 63 | 64 | bool 65 | newton( 66 | ColVec_t& init_out_vals, 67 | std::function opt_objfn, 68 | void* opt_data, 69 | algo_settings_t& settings 70 | ); 71 | 72 | // 73 | // internal 74 | 75 | namespace internal 76 | { 77 | 78 | bool 79 | newton_impl( 80 | ColVec_t& init_out_vals, 81 | std::function opt_objfn, 82 | void* opt_data, 83 | algo_settings_t* settings_inp 84 | ); 85 | 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /include/unconstrained/nm.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Nelder-Mead 23 | */ 24 | 25 | #ifndef _optim_nm_HPP 26 | #define _optim_nm_HPP 27 | 28 | /** 29 | * @brief The Nelder-Mead Simplex-based Optimization Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | nm( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief The Nelder-Mead Simplex-based Optimization Algorithm 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | nm( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | nm_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp 82 | ); 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/unconstrained/optim_unconstrained.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_UNCONSTRAINED_INCLUDES 22 | #define OPTIMLIB_UNCONSTRAINED_INCLUDES 23 | 24 | #include "bfgs.hpp" 25 | #include "lbfgs.hpp" 26 | #include "newton.hpp" 27 | #include "cg.hpp" 28 | #include "gd.hpp" 29 | #include "de.hpp" 30 | #include "de_prmm.hpp" 31 | #include "nm.hpp" 32 | #include "pso.hpp" 33 | #include "pso_dv.hpp" 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/unconstrained/pso.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Particle Swarm Optimization (PSO) 23 | */ 24 | 25 | #ifndef _optim_pso_HPP 26 | #define _optim_pso_HPP 27 | 28 | /** 29 | * @brief Particle Swarm Optimization (PSO) Algorithm 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | pso( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief Particle Swarm Optimization (PSO) Algorithm 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | pso( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | pso_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp 82 | ); 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/unconstrained/pso_dv.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Particle Swarm Optimization (PSO) with Differentially-Perturbed Velocity (DV) 23 | */ 24 | 25 | #ifndef _optim_pso_dv_HPP 26 | #define _optim_pso_dv_HPP 27 | 28 | /** 29 | * @brief Particle Swarm Optimization (PSO) with Differentially-Perturbed Velocity (DV) 30 | * 31 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 32 | * @param opt_objfn the function to be minimized, taking three arguments: 33 | * - \c vals_inp a vector of inputs; 34 | * - \c grad_out a vector to store the gradient; and 35 | * - \c opt_data additional data passed to the user-provided function. 36 | * @param opt_data additional data passed to the user-provided function. 37 | * 38 | * @return a boolean value indicating successful completion of the optimization algorithm. 39 | */ 40 | 41 | bool 42 | pso_dv( 43 | ColVec_t& init_out_vals, 44 | std::function opt_objfn, 45 | void* opt_data 46 | ); 47 | 48 | /** 49 | * @brief Particle Swarm Optimization (PSO) with Differentially-Perturbed Velocity (DV) 50 | * 51 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 52 | * @param opt_objfn the function to be minimized, taking three arguments: 53 | * - \c vals_inp a vector of inputs; 54 | * - \c grad_out a vector to store the gradient; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | pso_dv( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // internal 72 | 73 | namespace internal 74 | { 75 | 76 | bool 77 | pso_dv_impl( 78 | ColVec_t& init_out_vals, 79 | std::function opt_objfn, 80 | void* opt_data, 81 | algo_settings_t* settings_inp 82 | ); 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/zeros/broyden.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Broyden's method for solving systems of nonlinear equations 23 | */ 24 | 25 | #ifndef _optim_broyden_HPP 26 | #define _optim_broyden_HPP 27 | 28 | // without jacobian 29 | 30 | /** 31 | * @brief Broyden's method for solving systems of nonlinear equations, without Jacobian 32 | * 33 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 34 | * @param opt_objfn the function to be minimized, taking three arguments: 35 | * - \c vals_inp a vector of inputs; and 36 | * - \c opt_data additional data passed to the user-provided function. 37 | * @param opt_data additional data passed to the user-provided function. 38 | * 39 | * @return a boolean value indicating successful completion of the optimization algorithm. 40 | */ 41 | 42 | bool 43 | broyden( 44 | ColVec_t& init_out_vals, 45 | std::function opt_objfn, 46 | void* opt_data 47 | ); 48 | 49 | /** 50 | * @brief Broyden's method for solving systems of nonlinear equations, without Jacobian 51 | * 52 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 53 | * @param opt_objfn the function to be minimized, taking three arguments: 54 | * - \c vals_inp a vector of inputs; and 55 | * - \c opt_data additional data passed to the user-provided function. 56 | * @param opt_data additional data passed to the user-provided function. 57 | * @param settings parameters controlling the optimization routine. 58 | * 59 | * @return a boolean value indicating successful completion of the optimization algorithm. 60 | */ 61 | 62 | bool 63 | broyden( 64 | ColVec_t& init_out_vals, 65 | std::function opt_objfn, 66 | void* opt_data, 67 | algo_settings_t& settings 68 | ); 69 | 70 | // 71 | // with jacobian 72 | 73 | /** 74 | * @brief Broyden's method for solving systems of nonlinear equations, with Jacobian 75 | * 76 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 77 | * @param opt_objfn the function to be minimized, taking three arguments: 78 | * - \c vals_inp a vector of inputs; and 79 | * - \c opt_data additional data passed to the user-provided function. 80 | * @param opt_data additional data passed to the user-provided function. 81 | * @param jacob_objfn a function to calculate the Jacobian matrix, taking two arguments: 82 | * - \c vals_inp a vector of inputs; and 83 | * - \c jacob_data additional data passed to the Jacobian function. 84 | * @param jacob_data additional data passed to the Jacobian function. 85 | * 86 | * @return a boolean value indicating successful completion of the optimization algorithm. 87 | */ 88 | 89 | bool 90 | broyden( 91 | ColVec_t& init_out_vals, 92 | std::function opt_objfn, 93 | void* opt_data, 94 | std::function jacob_objfn, 95 | void* jacob_data 96 | ); 97 | 98 | /** 99 | * @brief Broyden's method for solving systems of nonlinear equations, with Jacobian 100 | * 101 | * @param init_out_vals a column vector of initial values, which will be replaced by the solution upon successful completion of the optimization algorithm. 102 | * @param opt_objfn the function to be minimized, taking three arguments: 103 | * - \c vals_inp a vector of inputs; and 104 | * - \c opt_data additional data passed to the user-provided function. 105 | * @param opt_data additional data passed to the user-provided function. 106 | * @param jacob_objfn a function to calculate the Jacobian matrix, taking two arguments: 107 | * - \c vals_inp a vector of inputs; and 108 | * - \c jacob_data additional data passed to the Jacobian function. 109 | * @param jacob_data additional data passed to the Jacobian function. 110 | * @param settings parameters controlling the optimization routine. 111 | * 112 | * @return a boolean value indicating successful completion of the optimization algorithm. 113 | */ 114 | 115 | bool 116 | broyden(ColVec_t& init_out_vals, 117 | std::function opt_objfn, 118 | void* opt_data, 119 | std::function jacob_objfn, 120 | void* jacob_data, 121 | algo_settings_t& settings 122 | ); 123 | 124 | // 125 | // internal functions 126 | 127 | namespace internal 128 | { 129 | 130 | bool 131 | broyden_impl( 132 | ColVec_t& init_out_vals, 133 | std::function opt_objfn, 134 | void* opt_data, 135 | algo_settings_t* settings_inp 136 | ); 137 | 138 | 139 | bool 140 | broyden_impl( 141 | ColVec_t& init_out_vals, 142 | std::function opt_objfn, 143 | void* opt_data, 144 | std::function jacob_objfn, 145 | void* jacob_data, 146 | algo_settings_t* settings_inp 147 | ); 148 | 149 | } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /include/zeros/optim_zeros.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_ZEROS_INCLUDES 22 | #define OPTIMLIB_ZEROS_INCLUDES 23 | 24 | #include "broyden.hpp" 25 | #include "broyden_df.hpp" 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/constrained/sumt.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Sequential unconstrained minimization technique (SUMT) 23 | */ 24 | 25 | #include "optim.hpp" 26 | 27 | // [OPTIM_BEGIN] 28 | optimlib_inline 29 | bool 30 | optim::internal::sumt_impl( 31 | ColVec_t& init_out_vals, 32 | std::function opt_objfn, 33 | void* opt_data, 34 | std::function constr_fn, 35 | void* constr_data, 36 | algo_settings_t* settings_inp 37 | ) 38 | { 39 | // notation: 'p' stands for '+1'. 40 | 41 | bool success = false; 42 | 43 | // settings 44 | 45 | algo_settings_t settings; 46 | 47 | if (settings_inp) { 48 | settings = *settings_inp; 49 | } 50 | 51 | const int conv_failure_switch = settings.conv_failure_switch; 52 | const size_t iter_max = settings.iter_max; 53 | const fp_t rel_sol_change_tol = settings.rel_sol_change_tol; 54 | 55 | const fp_t par_eta = settings.sumt_settings.par_eta; // growth of penalty parameter 56 | 57 | // lambda function that combines the objective function with the constraints 58 | 59 | std::function sumt_objfn \ 60 | = [opt_objfn, opt_data, constr_fn, constr_data] (const ColVec_t& vals_inp, ColVec_t* grad_out, void* sumt_data) \ 61 | -> fp_t 62 | { 63 | sumt_data_t *d = reinterpret_cast(sumt_data); 64 | fp_t c_pen = d->c_pen; 65 | 66 | const size_t n_vals = BMO_MATOPS_SIZE(vals_inp); 67 | 68 | ColVec_t grad_obj(n_vals); 69 | Mat_t jacob_constr; 70 | 71 | // 72 | 73 | fp_t ret = 1E08; 74 | 75 | ColVec_t constr_vals = constr_fn(vals_inp, &jacob_constr, constr_data); 76 | ColVec_t tmp_vec = constr_vals; 77 | 78 | bmo::reset_negative_values(tmp_vec, constr_vals); 79 | bmo::reset_negative_rows(tmp_vec, jacob_constr); 80 | 81 | // 82 | 83 | fp_t constr_valsq = BMO_MATOPS_DOT_PROD(constr_vals,constr_vals); 84 | 85 | if (constr_valsq > 0) { 86 | ret = opt_objfn(vals_inp,&grad_obj,opt_data) + c_pen*(constr_valsq / 2.0); 87 | 88 | if (grad_out) { 89 | *grad_out = grad_obj + c_pen * BMO_MATOPS_TRANSPOSE( BMO_MATOPS_COLWISE_SUM(jacob_constr) ); 90 | } 91 | } else { 92 | ret = opt_objfn(vals_inp, &grad_obj, opt_data); 93 | 94 | if (grad_out) { 95 | *grad_out = grad_obj; 96 | } 97 | } 98 | 99 | // 100 | 101 | return ret; 102 | }; 103 | 104 | // initialization 105 | 106 | ColVec_t x = init_out_vals; 107 | 108 | sumt_data_t sumt_data; 109 | sumt_data.c_pen = 1.0; 110 | 111 | ColVec_t x_p = x; 112 | 113 | // begin loop 114 | 115 | size_t iter = 0; 116 | fp_t rel_sol_change = 2*rel_sol_change_tol; 117 | 118 | while (rel_sol_change > rel_sol_change_tol && iter < iter_max) { 119 | ++iter; 120 | 121 | // 122 | 123 | bfgs(x_p, sumt_objfn, &sumt_data, settings); 124 | 125 | if (iter % 10 == 0) { 126 | rel_sol_change = BMO_MATOPS_L1NORM( BMO_MATOPS_ARRAY_DIV_ARRAY((x_p - x), (BMO_MATOPS_ARRAY_ADD_SCALAR(BMO_MATOPS_ABS(x), OPTIM_FPN_SMALL_NUMBER)) ) ); 127 | } 128 | 129 | // 130 | 131 | sumt_data.c_pen = par_eta * sumt_data.c_pen; // increase penalization parameter value 132 | x = x_p; 133 | } 134 | 135 | // 136 | 137 | error_reporting(init_out_vals, x_p, opt_objfn, opt_data, 138 | success, rel_sol_change, rel_sol_change_tol, 139 | iter, iter_max, conv_failure_switch, settings_inp); 140 | 141 | return success; 142 | } 143 | 144 | optimlib_inline 145 | bool 146 | optim::sumt( 147 | ColVec_t& init_out_vals, 148 | std::function opt_objfn, 149 | void* opt_data, 150 | std::function constr_fn, 151 | void* constr_data 152 | ) 153 | { 154 | return internal::sumt_impl(init_out_vals, opt_objfn, opt_data, constr_fn, constr_data, nullptr); 155 | } 156 | 157 | optimlib_inline 158 | bool 159 | optim::sumt( 160 | ColVec_t& init_out_vals, 161 | std::function opt_objfn, 162 | void* opt_data, 163 | std::function constr_fn, 164 | void* constr_data, 165 | algo_settings_t& settings 166 | ) 167 | { 168 | return internal::sumt_impl(init_out_vals, opt_objfn, opt_data, constr_fn, constr_data, &settings); 169 | } 170 | -------------------------------------------------------------------------------- /src/unconstrained/newton.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Newton's method for non-linear optimization 23 | */ 24 | 25 | #include "optim.hpp" 26 | 27 | // [OPTIM_BEGIN] 28 | optimlib_inline 29 | bool 30 | optim::internal::newton_impl( 31 | ColVec_t& init_out_vals, 32 | std::function opt_objfn, 33 | void* opt_data, 34 | algo_settings_t* settings_inp 35 | ) 36 | { 37 | // notation: 'p' stands for '+1'. 38 | 39 | bool success = false; 40 | 41 | const size_t n_vals = BMO_MATOPS_SIZE(init_out_vals); 42 | 43 | // settings 44 | 45 | algo_settings_t settings; 46 | 47 | if (settings_inp) { 48 | settings = *settings_inp; 49 | } 50 | 51 | const int print_level = settings.print_level; 52 | 53 | const uint_t conv_failure_switch = settings.conv_failure_switch; 54 | const size_t iter_max = settings.iter_max; 55 | const fp_t grad_err_tol = settings.grad_err_tol; 56 | const fp_t rel_sol_change_tol = settings.rel_sol_change_tol; 57 | 58 | // initialization 59 | 60 | ColVec_t x = init_out_vals; 61 | ColVec_t x_p = x; 62 | 63 | if (! BMO_MATOPS_IS_FINITE(x) ) { 64 | printf("newton error: non-finite initial value(s).\n"); 65 | return false; 66 | } 67 | 68 | Mat_t H(n_vals, n_vals); // hessian matrix 69 | ColVec_t grad(n_vals); // gradient vector 70 | ColVec_t d = BMO_MATOPS_ZERO_COLVEC(n_vals); // direction vector 71 | 72 | opt_objfn(x_p, &grad, &H, opt_data); 73 | 74 | fp_t grad_err = BMO_MATOPS_L2NORM(grad); 75 | 76 | OPTIM_NEWTON_TRACE(-1, grad_err, 0.0, x_p, d, grad, H); 77 | 78 | if (grad_err <= grad_err_tol) { 79 | return true; 80 | } 81 | 82 | // if ||gradient(initial values)|| > tolerance, then continue 83 | 84 | d = - BMO_MATOPS_SOLVE(H, grad); // Newton direction 85 | 86 | x_p += d; // no line search used here 87 | 88 | opt_objfn(x_p, &grad, &H, opt_data); 89 | 90 | grad_err = BMO_MATOPS_L2NORM(grad); 91 | fp_t rel_sol_change = BMO_MATOPS_L1NORM( BMO_MATOPS_ARRAY_DIV_ARRAY( (x_p - x), (BMO_MATOPS_ARRAY_ADD_SCALAR(BMO_MATOPS_ABS(x), OPTIM_FPN_SMALL_NUMBER)) ) ); 92 | 93 | OPTIM_NEWTON_TRACE(0, grad_err, rel_sol_change, x_p, d, grad, H); 94 | 95 | if (grad_err <= grad_err_tol) { 96 | init_out_vals = x_p; 97 | return true; 98 | } 99 | 100 | x = x_p; 101 | 102 | // begin loop 103 | 104 | size_t iter = 0; 105 | 106 | while (grad_err > grad_err_tol && rel_sol_change > rel_sol_change_tol && iter < iter_max) { 107 | ++iter; 108 | 109 | // 110 | 111 | d = - BMO_MATOPS_SOLVE(H,grad); 112 | x_p += d; 113 | 114 | opt_objfn(x_p, &grad, &H, opt_data); 115 | 116 | // 117 | 118 | grad_err = BMO_MATOPS_L2NORM(grad); 119 | rel_sol_change = BMO_MATOPS_L1NORM( BMO_MATOPS_ARRAY_DIV_ARRAY( (x_p - x), (BMO_MATOPS_ARRAY_ADD_SCALAR(BMO_MATOPS_ABS(x), OPTIM_FPN_SMALL_NUMBER)) ) ); 120 | 121 | // 122 | 123 | x = x_p; 124 | 125 | OPTIM_NEWTON_TRACE(iter, grad_err, rel_sol_change, x_p, d, grad, H); 126 | } 127 | 128 | // 129 | 130 | error_reporting(init_out_vals, x_p, opt_objfn, opt_data, 131 | success, grad_err, grad_err_tol, iter, iter_max, 132 | conv_failure_switch, settings_inp); 133 | 134 | return success; 135 | } 136 | 137 | optimlib_inline 138 | bool 139 | optim::newton( 140 | ColVec_t& init_out_vals, 141 | std::function opt_objfn, 142 | void* opt_data 143 | ) 144 | { 145 | return internal::newton_impl(init_out_vals,opt_objfn,opt_data,nullptr); 146 | } 147 | 148 | optimlib_inline 149 | bool 150 | optim::newton( 151 | ColVec_t& init_out_vals, 152 | std::function opt_objfn, 153 | void* opt_data, 154 | algo_settings_t& settings 155 | ) 156 | { 157 | return internal::newton_impl(init_out_vals,opt_objfn,opt_data,&settings); 158 | } 159 | -------------------------------------------------------------------------------- /tests/constrained/sumt.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // SUMT test 23 | // 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | // 31 | 32 | ColVec_t x_1 = BMO_MATOPS_ONE_COLVEC(2); 33 | 34 | bool success_1 = optim::sumt(x_1,constr_test_objfn_1,nullptr,constr_test_constrfn_1,nullptr); 35 | 36 | if (success_1) { 37 | std::cout << "sumt: test_1 completed successfully." << std::endl; 38 | } else { 39 | std::cout << "sumt: test_1 completed unsuccessfully." << std::endl; 40 | } 41 | 42 | BMO_MATOPS_COUT << "sumt: solution to test_1:\n" << x_1 << "\n"; 43 | 44 | // 45 | 46 | ColVec_t x_2 = BMO_MATOPS_ONE_COLVEC(2); 47 | 48 | bool success_2 = optim::sumt(x_2,constr_test_objfn_2,nullptr,constr_test_constrfn_2,nullptr); 49 | 50 | if (success_2) { 51 | std::cout << "sumt: test_2 completed successfully." << std::endl; 52 | } else { 53 | std::cout << "sumt: test_2 completed unsuccessfully." << std::endl; 54 | } 55 | 56 | BMO_MATOPS_COUT << "sumt: solution to test_2:\n" << x_2 << "\n"; 57 | 58 | // this is particularly troublesome 59 | 60 | ColVec_t x_3 = BMO_MATOPS_ARRAY_ADD_SCALAR(BMO_MATOPS_ZERO_COLVEC(2), 1.2); 61 | 62 | bool success_3 = optim::sumt(x_3,constr_test_objfn_3,nullptr,constr_test_constrfn_3,nullptr); 63 | 64 | if (success_3) { 65 | std::cout << "sumt: test_3 completed successfully." << std::endl; 66 | } else { 67 | std::cout << "sumt: test_3 completed unsuccessfully." << std::endl; 68 | } 69 | 70 | BMO_MATOPS_COUT << "sumt: solution to test_3:\n" << x_3 << "\n"; 71 | 72 | // 73 | // coverage tests 74 | 75 | optim::algo_settings_t settings; 76 | 77 | optim::sumt(x_1,constr_test_objfn_1,nullptr,constr_test_constrfn_1,nullptr); 78 | optim::sumt(x_1,constr_test_objfn_1,nullptr,constr_test_constrfn_1,nullptr,settings); 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /tests/misc/error_reporting.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // coverage tests for error_reporting 23 | // 24 | 25 | #include "optim.hpp" 26 | 27 | double 28 | optim_simple_fn_1(const optim::ColVec_t& vals_inp, optim::ColVec_t* grad_out, void* opt_data) 29 | { 30 | return 1.0; 31 | } 32 | 33 | optim::ColVec_t 34 | optim_simple_fn_2(const optim::ColVec_t& vals_inp, void* opt_data) 35 | { 36 | int n = BMO_MATOPS_SIZE(vals_inp); 37 | optim::ColVec_t ret_vec = BMO_MATOPS_ZERO_COLVEC(n); 38 | return ret_vec; 39 | } 40 | 41 | int main() 42 | { 43 | 44 | optim::ColVec_t out_vals = BMO_MATOPS_ONE_COLVEC(2); 45 | optim::ColVec_t x_p = BMO_MATOPS_ONE_COLVEC(2); 46 | 47 | bool success = false; 48 | 49 | double err_1 = 0.5; 50 | double err_2 = 1.5; 51 | double err_tol = 1.0; 52 | 53 | size_t iter_1 = 1; 54 | size_t iter_2 = 3; 55 | size_t iter_max = 2; 56 | 57 | optim::algo_settings_t settings; 58 | 59 | std::cout << "\n ***** Begin ERROR_REPORTING tests. ***** \n" << std::endl; 60 | 61 | // 62 | // error_reporting_1 63 | 64 | int conv_failure_switch = 0; 65 | 66 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 67 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,&settings); 68 | 69 | conv_failure_switch = 1; 70 | 71 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 72 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,&settings); 73 | 74 | conv_failure_switch = 2; 75 | 76 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 77 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,&settings); 78 | 79 | conv_failure_switch = 3; // error 80 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 81 | 82 | // 83 | // error_reporting_2 84 | 85 | conv_failure_switch = 0; 86 | 87 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,conv_failure_switch,&settings); 88 | 89 | conv_failure_switch = 2; 90 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,conv_failure_switch,&settings); 91 | 92 | conv_failure_switch = 3; // error 93 | optim::error_reporting(out_vals,x_p,optim_simple_fn_1,nullptr,success,conv_failure_switch,&settings); 94 | 95 | // 96 | // error_reporting_3 97 | 98 | conv_failure_switch = 0; 99 | 100 | optim::error_reporting(out_vals,x_p,optim_simple_fn_2,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 101 | optim::error_reporting(out_vals,x_p,optim_simple_fn_2,nullptr,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,&settings); 102 | 103 | conv_failure_switch = 1; 104 | 105 | optim::error_reporting(out_vals,x_p,optim_simple_fn_2,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 106 | optim::error_reporting(out_vals,x_p,optim_simple_fn_2,nullptr,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,&settings); 107 | 108 | conv_failure_switch = 2; 109 | 110 | optim::error_reporting(out_vals,x_p,optim_simple_fn_2,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 111 | optim::error_reporting(out_vals,x_p,optim_simple_fn_2,nullptr,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,&settings); 112 | 113 | conv_failure_switch = 3; // error 114 | optim::error_reporting(out_vals,x_p,optim_simple_fn_2,nullptr,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,&settings); 115 | 116 | // done 117 | 118 | std::cout << "\n ***** End ERROR_REPORTING tests. ***** \n" << std::endl; 119 | 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /tests/misc/jacobian_adjust.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * unit test 23 | */ 24 | 25 | #include "optim.hpp" 26 | 27 | int main() 28 | { 29 | 30 | std::cout << "\n ***** Begin JACOBIAN tests. ***** \n" << std::endl; 31 | 32 | // 33 | 34 | const bool vals_bound = true; 35 | const int n_vals = 4; 36 | 37 | optim::ColVec_t lb(n_vals); 38 | lb(0) = 0; 39 | lb(1) = 0; 40 | lb(2) = -std::numeric_limits::infinity(); 41 | lb(3) = -std::numeric_limits::infinity(); 42 | 43 | optim::ColVec_t ub(n_vals); 44 | ub(0) = 2; 45 | ub(1) = std::numeric_limits::infinity(); 46 | ub(2) = 2; 47 | ub(3) = std::numeric_limits::infinity(); 48 | 49 | optim::ColVecInt_t bounds_type = optim::determine_bounds_type(vals_bound,n_vals,lb,ub); 50 | 51 | optim::ColVec_t initial_vals = BMO_MATOPS_ONE_COLVEC(n_vals); 52 | 53 | optim::ColVec_t vals_trans = optim::transform(initial_vals,bounds_type,lb,ub); 54 | 55 | optim::Mat_t j_mat = optim::jacobian_adjust(vals_trans,bounds_type,lb,ub); 56 | 57 | optim::ColVec_t vals_inv_trans = optim::inv_transform(vals_trans,bounds_type,lb,ub); 58 | 59 | // 60 | 61 | std::cout << "\n ***** END JACOBIAN tests. ***** \n" << std::endl; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /tests/misc/numerical_gradient.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // numerical gradient tests 23 | // 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | 31 | std::cout << "\n ***** Begin numerical_gradient tests. ***** \n" << std::endl; 32 | 33 | // 34 | // test 1 35 | optim::ColVec_t x_1 = BMO_MATOPS_ONE_COLVEC(2); 36 | 37 | optim::ColVec_t grad_vec_1 = optim::numerical_gradient(x_1,nullptr,unconstr_test_fn_1,nullptr); 38 | 39 | BMO_MATOPS_COUT << "gradient 1:\n" << grad_vec_1 << BMO_MATOPS_ENDL; 40 | 41 | // 42 | // test 2 43 | 44 | optim::ColVec_t x_2 = BMO_MATOPS_ONE_COLVEC(2); 45 | 46 | optim::ColVec_t grad_vec_2 = optim::numerical_gradient(x_2,nullptr,unconstr_test_fn_2,nullptr); 47 | 48 | BMO_MATOPS_COUT << "gradient 2:\n" << grad_vec_2 << BMO_MATOPS_ENDL; 49 | 50 | // 51 | // test 3 52 | 53 | optim::ColVec_t x_3 = BMO_MATOPS_ONE_COLVEC(2); 54 | 55 | optim::ColVec_t grad_vec_3 = optim::numerical_gradient(x_3,nullptr,unconstr_test_fn_3,nullptr); 56 | 57 | BMO_MATOPS_COUT << "gradient 3:\n" << grad_vec_3 << BMO_MATOPS_ENDL; 58 | 59 | // 60 | // test 4 61 | 62 | optim::ColVec_t x_4 = BMO_MATOPS_ONE_COLVEC(2); 63 | 64 | optim::ColVec_t grad_vec_4 = optim::numerical_gradient(x_4,nullptr,unconstr_test_fn_4,nullptr); 65 | 66 | BMO_MATOPS_COUT << "gradient 4:\n" << grad_vec_4 << BMO_MATOPS_ENDL; 67 | 68 | // 69 | // test 5 70 | 71 | optim::ColVec_t x_5 = BMO_MATOPS_ONE_COLVEC(2); 72 | 73 | optim::ColVec_t grad_vec_5 = optim::numerical_gradient(x_5,nullptr,unconstr_test_fn_5,nullptr); 74 | 75 | BMO_MATOPS_COUT << "gradient 5:\n" << grad_vec_5 << BMO_MATOPS_ENDL; 76 | 77 | // 78 | 79 | std::cout << "\n ***** end numerical_gradient tests. ***** \n" << std::endl; 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /tests/misc/numerical_hessian.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // numerical hessian tests 23 | // 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | 31 | std::cout << "\n ***** Begin numerical_hessian tests. ***** \n" << std::endl; 32 | 33 | // 34 | // test 1 35 | optim::ColVec_t x_1 = BMO_MATOPS_ONE_COLVEC(2); 36 | 37 | optim::Mat_t hess_mat_1 = optim::numerical_hessian(x_1,nullptr,unconstr_test_fn_1,nullptr); 38 | 39 | BMO_MATOPS_COUT << "hessian 1:\n" << hess_mat_1 << BMO_MATOPS_ENDL; 40 | 41 | // 42 | // test 2 43 | 44 | optim::ColVec_t x_2 = BMO_MATOPS_ONE_COLVEC(2); 45 | 46 | optim::Mat_t hess_mat_2 = optim::numerical_hessian(x_2,nullptr,unconstr_test_fn_2,nullptr); 47 | 48 | BMO_MATOPS_COUT << "hessian 2:\n" << hess_mat_2 << BMO_MATOPS_ENDL; 49 | 50 | // 51 | // test 3 52 | 53 | optim::ColVec_t x_3 = BMO_MATOPS_ONE_COLVEC(2); 54 | 55 | optim::Mat_t hess_mat_3 = optim::numerical_hessian(x_3,nullptr,unconstr_test_fn_3,nullptr); 56 | 57 | BMO_MATOPS_COUT << "hessian 3:\n" << hess_mat_3 << BMO_MATOPS_ENDL; 58 | 59 | // 60 | // test 4 61 | 62 | optim::ColVec_t x_4 = BMO_MATOPS_ONE_COLVEC(2); 63 | 64 | optim::Mat_t hess_mat_4 = optim::numerical_hessian(x_4,nullptr,unconstr_test_fn_4,nullptr); 65 | 66 | BMO_MATOPS_COUT << "hessian 4:\n" << hess_mat_4 << BMO_MATOPS_ENDL; 67 | 68 | // 69 | // test 5 70 | 71 | optim::ColVec_t x_5 = BMO_MATOPS_ONE_COLVEC(2); 72 | 73 | optim::Mat_t hess_mat_5 = optim::numerical_hessian(x_5,nullptr,unconstr_test_fn_5,nullptr); 74 | 75 | BMO_MATOPS_COUT << "hessian 5:\n" << hess_mat_5 << BMO_MATOPS_ENDL; 76 | 77 | // 78 | 79 | std::cout << "\n ***** end numerical_hessian tests. ***** \n" << std::endl; 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /tests/setup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # OptimLib test setup 3 | 4 | function print_help 5 | { 6 | echo "" ; 7 | echo -e "\x1B[32mOptimLib Test setup options:\033[0m" >&2 ; 8 | echo "-c Clean binary files" ; 9 | echo "-h Print help" ; 10 | echo "" ; 11 | } 12 | 13 | while getopts hcdgi:m:o:p option; do 14 | case "${option}" in 15 | h) print_help; exit 2;; 16 | c) OPTIM_TEST_SETUP_CLEAN="y";; 17 | ?) print_help; exit 2;; 18 | esac 19 | done 20 | 21 | # 22 | 23 | declare -a DIRS=("constrained" "misc" "unconstrained" "zeros") 24 | 25 | # 26 | 27 | if [[ "${OPTIM_TEST_SETUP_CLEAN}" == "y" ]]; then 28 | for i in "${DIRS[@]}"; do 29 | rm -rf ./"$i"/*.dSYM 30 | rm -f ./"$i"/*.o 31 | rm -f ./"$i"/*.test 32 | rm -f ./"$i"/configure 33 | rm -f ./"$i"/Makefile 34 | rm -f ./"$i"/Makefile.in 35 | done 36 | else 37 | for i in "${DIRS[@]}"; do 38 | rm -f ./"$i"/configure 39 | rm -f ./"$i"/Makefile.in 40 | 41 | cp test_setup/configure.in ./"$i"/configure 42 | cp test_setup/Makefile.in ./"$i"/Makefile.in 43 | done 44 | fi 45 | -------------------------------------------------------------------------------- /tests/test_fns/constr_test_fn_1.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // simple constrained optim problem 23 | // 24 | // f(x) = (x_1 - 5)^2 + (x_2 - 4)^2 25 | // g(x) = -2*x_1 - x_2 + 14 <= 0 26 | // 27 | // solution is: (5,4) 28 | // 29 | 30 | #ifndef _optim_constr_test_fn_1_HPP 31 | #define _optim_constr_test_fn_1_HPP 32 | 33 | double 34 | constr_test_objfn_1(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 35 | { 36 | double x_1 = vals_inp(0); 37 | double x_2 = vals_inp(1); 38 | 39 | double obj_val = std::pow(x_1 - 5.0,2) + std::pow(x_2 - 4.0,2); 40 | // 41 | if (grad_out) { 42 | (*grad_out)(0) = 2.0*(x_1 - 5.0); 43 | (*grad_out)(1) = 2.0*(x_2 - 4.0); 44 | } 45 | // 46 | return obj_val; 47 | } 48 | 49 | ColVec_t 50 | constr_test_constrfn_1(const ColVec_t& vals_inp, Mat_t* jacob_out, void* opt_data) 51 | { 52 | double x_1 = vals_inp(0); 53 | double x_2 = vals_inp(1); 54 | 55 | ColVec_t constr_vals(1); 56 | constr_vals(0) = -2*x_1 - x_2 + 14.0; 57 | 58 | if (jacob_out) { 59 | BMO_MATOPS_SET_SIZE_POINTER(jacob_out,1,2); 60 | 61 | (*jacob_out)(0,0) = -2.0; 62 | (*jacob_out)(0,1) = -1.0; 63 | } 64 | 65 | return constr_vals; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /tests/test_fns/constr_test_fn_2.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // simple constrained optim problem 23 | // 24 | // f(x) = (x_1 - 5)^2 + (x_2 - 4)^2 25 | // g_1(x) = -2*x_1 - x_2 + 14 <= 0 26 | // g_2(x) = x_1 + x_2 - 9 <= 0 27 | // 28 | // solution is: (5,4) 29 | // 30 | 31 | #ifndef _optim_constr_test_fn_2_HPP 32 | #define _optim_constr_test_fn_2_HPP 33 | 34 | double 35 | constr_test_objfn_2(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 36 | { 37 | double x_1 = vals_inp(0); 38 | double x_2 = vals_inp(1); 39 | 40 | double obj_val = std::pow(x_1 - 5.0,2) + std::pow(x_2 - 4.0,2); 41 | // 42 | if (grad_out) { 43 | (*grad_out)(0) = 2.0*(x_1 - 5.0); 44 | (*grad_out)(1) = 2.0*(x_2 - 4.0); 45 | } 46 | // 47 | return obj_val; 48 | } 49 | 50 | ColVec_t 51 | constr_test_constrfn_2(const ColVec_t& vals_inp, Mat_t* jacob_out, void* opt_data) 52 | { 53 | double x_1 = vals_inp(0); 54 | double x_2 = vals_inp(1); 55 | 56 | ColVec_t constr_vals(2); 57 | constr_vals(0) = -2*x_1 - x_2 + 14.0; 58 | constr_vals(1) = x_1 + x_2 - 9.0; 59 | 60 | if (jacob_out) { 61 | BMO_MATOPS_SET_SIZE_POINTER(jacob_out,2,2); 62 | 63 | (*jacob_out)(0,0) = -2.0; 64 | (*jacob_out)(0,1) = -1.0; 65 | (*jacob_out)(1,0) = 1.0; 66 | (*jacob_out)(1,1) = 1.0; 67 | } 68 | 69 | return constr_vals; 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /tests/test_fns/constr_test_fn_3.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Rosenbrock function constrained with a cubic and a line 26 | // 27 | // f(x) = (1 - x)^2 + 100(y - x^2)^2 28 | // g_1(x) = (x - 1)^3 - y + 1 <= 0 29 | // g_2(x) = x + y - 2 <= 0 30 | // 31 | // solution is: (1,1) 32 | // 33 | 34 | #ifndef _optim_constr_test_fn_3_HPP 35 | #define _optim_constr_test_fn_3_HPP 36 | 37 | double 38 | constr_test_objfn_3(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 39 | { 40 | double x = vals_inp(0); 41 | double y = vals_inp(1); 42 | 43 | double obj_val = std::pow(1.0 - x,2) + 100*std::pow(y - x*x,2); 44 | // 45 | if (grad_out) { 46 | (*grad_out)(0) = - 2*(1.0 - x) - 200*(y - x*x)*2*x; 47 | (*grad_out)(1) = 200*(y - x*x); 48 | } 49 | // 50 | return obj_val; 51 | } 52 | 53 | ColVec_t 54 | constr_test_constrfn_3(const ColVec_t& vals_inp, Mat_t* jacob_out, void* opt_data) 55 | { 56 | double x = vals_inp(0); 57 | double y = vals_inp(1); 58 | 59 | ColVec_t constr_vals(2); 60 | constr_vals(0) = std::pow(x - 1.0,3) - y + 1.0; 61 | constr_vals(1) = x + y - 2.0; 62 | 63 | if (jacob_out) { 64 | BMO_MATOPS_SET_SIZE_POINTER(jacob_out,2,2); 65 | 66 | (*jacob_out)(0,0) = 3*std::pow(x - 1.0,2); 67 | (*jacob_out)(0,1) = -1.0; 68 | (*jacob_out)(1,0) = 1.0; 69 | (*jacob_out)(1,1) = 1.0; 70 | } 71 | 72 | return constr_vals; 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /tests/test_fns/test_fns.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_TEST_INCLUDES 22 | #define OPTIMLIB_TEST_INCLUDES 23 | 24 | using optim::ColVec_t; 25 | using optim::Mat_t; 26 | 27 | #define OPTIM_PI 3.14159265358979 28 | 29 | #include "unconstr_test_fn_1.hpp" 30 | #include "unconstr_test_fn_2.hpp" 31 | #include "unconstr_test_fn_3.hpp" 32 | #include "unconstr_test_fn_4.hpp" 33 | #include "unconstr_test_fn_5.hpp" 34 | #include "unconstr_test_fn_6.hpp" 35 | #include "unconstr_test_fn_7.hpp" 36 | #include "unconstr_test_fn_8.hpp" 37 | #include "unconstr_test_fn_9.hpp" 38 | #include "unconstr_test_fn_10.hpp" 39 | 40 | #include "constr_test_fn_1.hpp" 41 | #include "constr_test_fn_2.hpp" 42 | #include "constr_test_fn_3.hpp" 43 | 44 | #include "zeros_test_fn_1.hpp" 45 | #include "zeros_test_fn_2.hpp" 46 | 47 | #include "test_solutions.hpp" 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /tests/test_fns/test_solutions.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | #ifndef OPTIMLIB_TEST_SOLUTIONS 22 | #define OPTIMLIB_TEST_SOLUTIONS 23 | 24 | namespace unconstr_test_sols 25 | { 26 | 27 | ColVec_t test_1() 28 | { 29 | ColVec_t ret(2); 30 | 31 | ret(0) = 2.25; 32 | ret(1) = -4.75; 33 | 34 | return ret; 35 | } 36 | 37 | // 38 | 39 | ColVec_t test_2() 40 | { 41 | return BMO_MATOPS_ONE_COLVEC(2); 42 | } 43 | 44 | // 45 | 46 | ColVec_t test_3(const int n) 47 | { 48 | return BMO_MATOPS_ZERO_COLVEC(n); 49 | } 50 | 51 | // 52 | 53 | ColVec_t test_4() 54 | { 55 | ColVec_t ret(2); 56 | 57 | ret(0) = 3.0; 58 | ret(1) = 0.5; 59 | 60 | return ret; 61 | } 62 | 63 | // 64 | 65 | ColVec_t test_5() 66 | { 67 | ColVec_t ret(2); 68 | 69 | ret(0) = 1.0; 70 | ret(1) = 3.0; 71 | 72 | return ret; 73 | } 74 | 75 | // 76 | 77 | ColVec_t test_6() 78 | { 79 | return BMO_MATOPS_ZERO_COLVEC(2); 80 | } 81 | 82 | // 83 | 84 | ColVec_t test_7() 85 | { 86 | return BMO_MATOPS_ZERO_COLVEC(2); 87 | } 88 | 89 | // 90 | 91 | ColVec_t test_8() 92 | { 93 | return BMO_MATOPS_ONE_COLVEC(2); 94 | } 95 | 96 | // 97 | 98 | ColVec_t test_9() 99 | { 100 | ColVec_t ret(2); 101 | 102 | ret(0) = -10.0; 103 | ret(1) = 1.0; 104 | 105 | return ret; 106 | } 107 | 108 | } 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_1.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from Matlab's help page 23 | // https://www.mathworks.com/help/optim/ug/fminunc.html 24 | // 25 | // f(x) = 3*x_1^2 + 2*x_1*x_2 + x_2^2 − 4*x_1 + 5*x_2 26 | // 27 | // solution is: (2.25,-4.75) 28 | // 29 | 30 | #ifndef _optim_test_fn_1_HPP 31 | #define _optim_test_fn_1_HPP 32 | 33 | inline 34 | double 35 | unconstr_test_fn_1_whess(const ColVec_t& vals_inp, ColVec_t* grad_out, Mat_t* hess_out, void* opt_data) 36 | { 37 | const double x_1 = vals_inp(0); 38 | const double x_2 = vals_inp(1); 39 | 40 | double obj_val = 3*x_1*x_1 + 2*x_1*x_2 + x_2*x_2 - 4*x_1 + 5*x_2; 41 | 42 | if (grad_out) { 43 | (*grad_out)(0) = 6*x_1 + 2*x_2 - 4; 44 | (*grad_out)(1) = 2*x_1 + 2*x_2 + 5; 45 | } 46 | 47 | if (hess_out) { 48 | (*hess_out)(0,0) = 6.0; 49 | (*hess_out)(0,1) = 2.0; 50 | (*hess_out)(1,0) = 2.0; 51 | (*hess_out)(1,1) = 2.0; 52 | } 53 | 54 | // 55 | 56 | return obj_val; 57 | } 58 | 59 | inline 60 | double 61 | unconstr_test_fn_1(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 62 | { 63 | return unconstr_test_fn_1_whess(vals_inp, grad_out, nullptr, opt_data); 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_10.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Table function: 26 | // 27 | // f(x,y) = -abs( sin(x)cos(y)exp( abs(1 - sqrt(x^2 + y^2)/pi) ) ) 28 | // -10 <= x,y <= 10 29 | // 30 | // there are four solutions: (8.05502,9.66459), (-8.05502,9.66459), (8.05502,-9.66459), (-8.05502,-9.66459) 31 | // 32 | 33 | #ifndef _optim_test_fn_10_HPP 34 | #define _optim_test_fn_10_HPP 35 | 36 | inline 37 | double 38 | unconstr_test_fn_10(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 39 | { 40 | const double x = vals_inp(0); 41 | const double y = vals_inp(1); 42 | 43 | double obj_val = - std::abs( std::sin(x)*std::cos(y)*std::exp( std::abs( 1.0 - std::sqrt(x*x + y*y) / OPTIM_PI ) ) ); 44 | 45 | return obj_val; 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_2.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // Rosenbrock's function: 23 | // f(x) = 100*(x_2 - x_1^2)^2 + (1-x_1)^2 24 | // 25 | // solution is: (1.00,1.00) 26 | // 27 | 28 | #ifndef _optim_test_fn_2_HPP 29 | #define _optim_test_fn_2_HPP 30 | 31 | inline 32 | double 33 | unconstr_test_fn_2_whess(const ColVec_t& vals_inp, ColVec_t* grad_out, Mat_t* hess_out, void* opt_data) 34 | { 35 | const double x_1 = vals_inp(0); 36 | const double x_2 = vals_inp(1); 37 | 38 | const double x1sq = x_1 * x_1; 39 | 40 | // 41 | 42 | double obj_val = 100*std::pow(x_2 - x1sq,2) + std::pow(1-x_1,2); 43 | 44 | if (grad_out) { 45 | (*grad_out)(0) = -400*(x_2 - x1sq)*x_1 - 2*(1-x_1); 46 | (*grad_out)(1) = 200*(x_2 - x1sq); 47 | } 48 | 49 | if (hess_out) { 50 | (*hess_out)(0,0) = 1200 * x1sq - 400 * x_2 + 2; 51 | (*hess_out)(0,1) = - 400 * x_1; 52 | (*hess_out)(1,0) = - 400 * x_1; 53 | (*hess_out)(1,1) = 200; 54 | } 55 | 56 | return obj_val; 57 | } 58 | 59 | inline 60 | double 61 | unconstr_test_fn_2(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 62 | { 63 | return unconstr_test_fn_2_whess(vals_inp, grad_out, nullptr, opt_data); 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_3.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Sphere function: 26 | // 27 | // f(x) = x_1^2 + x_2^2 + ... + x_n^2 28 | // 29 | // solution is: (0,0,...,0) 30 | // 31 | 32 | #ifndef _optim_test_fn_3_HPP 33 | #define _optim_test_fn_3_HPP 34 | 35 | inline 36 | double 37 | unconstr_test_fn_3(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 38 | { 39 | const double obj_val = BMO_MATOPS_DOT_PROD(vals_inp,vals_inp); 40 | 41 | if (grad_out) { 42 | *grad_out = 2.0*vals_inp; 43 | } 44 | 45 | return obj_val; 46 | } 47 | 48 | inline 49 | double 50 | unconstr_test_fn_3_whess(const ColVec_t& vals_inp, ColVec_t* grad_out, Mat_t* hess_out, void* opt_data) 51 | { 52 | const int n_vals = BMO_MATOPS_SIZE(vals_inp); 53 | const double obj_val = BMO_MATOPS_DOT_PROD(vals_inp,vals_inp); 54 | 55 | if (grad_out) { 56 | *grad_out = 2.0*vals_inp; 57 | } 58 | 59 | if (hess_out) { 60 | *hess_out = 2.0 * BMO_MATOPS_EYE(n_vals); 61 | } 62 | 63 | return obj_val; 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_4.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Beale's function: 26 | // 27 | // f(x) = (1.5 - x_1 + x_1*x_2)^2 + (2.25 - x_1 + x_1*x_2^2)^2 + (2.625 - x_1 + x_1*x_2^3)^2 28 | // -4.5 <= x_1, x_2 <= 4.5 29 | // 30 | // solution is: (3.0, 0.5) 31 | // 32 | 33 | #ifndef _optim_test_fn_4_HPP 34 | #define _optim_test_fn_4_HPP 35 | 36 | inline 37 | double 38 | unconstr_test_fn_4_whess(const ColVec_t& vals_inp, ColVec_t* grad_out, Mat_t* hess_out, void* opt_data) 39 | { 40 | const double x_1 = vals_inp(0); 41 | const double x_2 = vals_inp(1); 42 | 43 | // compute some terms only once 44 | 45 | const double x1sq = x_1 * x_1; 46 | const double x2sq = x_2 * x_2; 47 | const double x2cb = x2sq * x_2; 48 | const double x1x2 = x_1*x_2; 49 | 50 | // 51 | 52 | double obj_val = std::pow(1.5 - x_1 + x1x2, 2) + std::pow(2.25 - x_1 + x_1*x2sq, 2) + std::pow(2.625 - x_1 + x_1*x2cb, 2); 53 | 54 | if (grad_out) { 55 | // 2 x_1 x_2^6 + 2 x_1 x_2^4 - 4 x_1 x_2^3 - 2 x_1 x_2^2 - 4 x_1 x_2 + 6 x_1 + 5.25 x_2^3 + 4.5 x_2^2 + 3 x_2 - 12.75 56 | (*grad_out)(0) = (2 * x_1 * x2cb * x2cb) + (2 * x_1 * x2sq * x2sq) - (4 * x_1 * x2cb) - (2 * x_1 * x2sq) - (4 * x1x2) + (6 * x_1) + (5.25 * x2cb) + (4.5 * x2sq) + (3 * x_2) - 12.75; 57 | // 6 x_1^2 x_2^5 + 4 x_1^2 x_2^3 - 6 x_1^2 x_2^2 - 2 x_1^2 x_2 - 2 x_1^2 + 15.75 x_1 x_2^2 + 9 x_1 x_2 + 3 x_1 58 | (*grad_out)(1) = (6 * x1sq * x2sq * x2cb) + (4 * x1sq * x2cb) - (6 * x1sq * x2sq) - (2 * x1sq * x_2) - (2 * x1sq) + (15.75 * x_1 * x2sq) + (9 * x1x2) + (3 * x_1); 59 | } 60 | 61 | if (hess_out) { 62 | // 2 x_2^6 + 2 x_2^4 - 4 x_2^3 - 2 x_2^2 - 4 x_2 + 6 63 | (*hess_out)(0,0) = (2 * x2cb * x2cb) + (2 * x2sq * x2sq) - (4*x2cb) - (2*x2sq) - (4*x_2) + 6; 64 | 65 | // 12 x_1 x_2^5 + 8 x_1 x_2^3 - 12 x_1 x_2^2 - 4 x_1 x_2 - 4 x_1 + 15.75 x_2^2 + 9 x_2 + 3 66 | double H12 = (12 * x_1 * x2sq * x2cb) + (8 * x_1 * x2cb) - (12 * x_1 * x2sq) - (4 * x1x2) - (4 * x_1) + (15.75 * x2sq) + (9 * x_2) + 3; 67 | (*hess_out)(0,1) = H12; 68 | (*hess_out)(1,0) = H12; 69 | 70 | // 30 x_1^2 x_2^4 + 12 x_1^2 x_2^2 - 12 x_1^2 x_2 - 2 x_1^2 + 31.5 x_1 x_2 + 9 x_1 71 | (*hess_out)(1,1) = (30 * x1sq * (x2sq*x2sq)) + (12 * x1sq * x2sq) - (12 * x1sq * x_2) - (2*x1sq) + (31.5 * x1x2) + (9 * x_1); 72 | } 73 | 74 | return obj_val; 75 | } 76 | 77 | inline 78 | double 79 | unconstr_test_fn_4(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 80 | { 81 | return unconstr_test_fn_4_whess(vals_inp, grad_out, nullptr, opt_data); 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_5.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Booth's function: 26 | // 27 | // f(x) = (x_1 + 2*x_2 - 7)^2 + (2*x_1 + x_2 - 5)^2 28 | // s.t. -10 <= x_1, x_2 <= 10 29 | // 30 | // solution: f(1,3) = 0 31 | // 32 | 33 | #ifndef _optim_test_fn_5_HPP 34 | #define _optim_test_fn_5_HPP 35 | 36 | inline 37 | double 38 | unconstr_test_fn_5_whess(const ColVec_t& vals_inp, ColVec_t* grad_out, Mat_t* hess_out, void* opt_data) 39 | { 40 | double x_1 = vals_inp(0); 41 | double x_2 = vals_inp(1); 42 | 43 | double obj_val = std::pow(x_1 + 2*x_2 - 7.0, 2) + std::pow(2*x_1 + x_2 - 5.0, 2); 44 | 45 | if (grad_out) { 46 | // (*grad_out)(0) = 2*(x_1 + 2*x_2 - 7.0) + 2*(2*x_1 + x_2 - 5.0)*2; 47 | (*grad_out)(0) = 10*x_1 + 8*x_2 - 34; 48 | // (*grad_out)(1) = 2*(x_1 + 2*x_2 - 7.0)*2 + 2*(2*x_1 + x_2 - 5.0); 49 | (*grad_out)(1) = 8*x_1 + 10*x_2 - 38; 50 | } 51 | 52 | if (hess_out) { 53 | (*hess_out)(0,0) = 10.0; 54 | (*hess_out)(0,1) = 8.0; 55 | (*hess_out)(1,0) = 8.0; 56 | (*hess_out)(1,1) = 10.0; 57 | } 58 | 59 | return obj_val; 60 | } 61 | 62 | inline 63 | double 64 | unconstr_test_fn_5(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 65 | { 66 | return unconstr_test_fn_5_whess(vals_inp, grad_out, nullptr, opt_data); 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_6.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Rastrigin function: 26 | // 27 | // f(x) = A*n + sum_{i=1}^n (x_i^2 - A cos(2*pi*x_i)) 28 | // where A = 10 29 | // 30 | // solution is: (0,0) 31 | // 32 | 33 | #ifndef _optim_test_fn_6_HPP 34 | #define _optim_test_fn_6_HPP 35 | 36 | struct unconstr_test_fn_6_data { 37 | double A; 38 | }; 39 | 40 | inline 41 | double 42 | unconstr_test_fn_6(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 43 | { 44 | const int n = BMO_MATOPS_SIZE(vals_inp); 45 | 46 | unconstr_test_fn_6_data* objfn_data = reinterpret_cast(opt_data); 47 | const double A = objfn_data->A; 48 | 49 | double obj_val = A*n + BMO_MATOPS_ACCU( BMO_MATOPS_POW(vals_inp,2) - A*BMO_MATOPS_COS(2 * OPTIM_PI * vals_inp) ); 50 | // 51 | // if (grad_out) { 52 | // *grad_out = 2*vals_inp + A*2*arma::datum::pi*arma::sin(2*arma::datum::pi*vals_inp); 53 | // } 54 | // 55 | return obj_val; 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_7.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Ackley's function: 26 | // 27 | // f(x) = -20*exp(-0.2*sqrt(0.5*(x^2 + y^2))) - exp(0.5*(cos(2*pi*x) + cos(2*pi*y))) + exp(1) + 20 28 | // 29 | // solution is: (0,0) 30 | // 31 | 32 | #ifndef _optim_test_fn_7_HPP 33 | #define _optim_test_fn_7_HPP 34 | 35 | inline 36 | double 37 | unconstr_test_fn_7(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 38 | { 39 | const double x = vals_inp(0); 40 | const double y = vals_inp(1); 41 | 42 | double obj_val = 20 + std::exp(1) - 20*std::exp( -0.2*std::sqrt(0.5*(x*x + y*y)) ) - std::exp( 0.5*(std::cos(2 * OPTIM_PI * x) + std::cos(2 * OPTIM_PI * y)) ); 43 | 44 | return obj_val; 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_8.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Levi function: 26 | // 27 | // f(x) = (sin(3*pi*x))^2 + (x-1)^2 (1 + (sin(3*pi*y))^2) + (y-1)^2 (1 + (sin(2*pi*x))^2) 28 | // 29 | // solution is: (1,1) 30 | // 31 | 32 | #ifndef _optim_test_fn_8_HPP 33 | #define _optim_test_fn_8_HPP 34 | 35 | inline 36 | double 37 | unconstr_test_fn_8(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 38 | { 39 | const double x = vals_inp(0); 40 | const double y = vals_inp(1); 41 | const double pi = OPTIM_PI; 42 | 43 | double obj_val = std::pow( std::sin(3*pi*x), 2) + std::pow(x-1,2)*(1 + std::pow( std::sin(3 * OPTIM_PI * y), 2)) + std::pow(y-1,2)*(1 + std::pow( std::sin(2 * OPTIM_PI * x), 2)); 44 | 45 | return obj_val; 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /tests/test_fns/unconstr_test_fn_9.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from 23 | // https://en.wikipedia.org/wiki/Test_functions_for_optimization 24 | // 25 | // Bukin function N.6: 26 | // 27 | // f(x) = 100*sqrt(abs(y - 0.01*x^2)) + 0.01*abs(x + 10) 28 | // -15 <= x <= -5 29 | // - 3 <= y <= 3 30 | // 31 | // solution is: (-10,1) 32 | // 33 | 34 | #ifndef _optim_test_fn_9_HPP 35 | #define _optim_test_fn_9_HPP 36 | 37 | inline 38 | double 39 | unconstr_test_fn_9(const ColVec_t& vals_inp, ColVec_t* grad_out, void* opt_data) 40 | { 41 | const double x = vals_inp(0); 42 | const double y = vals_inp(1); 43 | 44 | double obj_val = 100*std::sqrt(std::abs(y - 0.01*x*x)) + 0.01*std::abs(x + 10); 45 | 46 | return obj_val; 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /tests/test_fns/zeros_test_fn_1.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // this example is from Matlab's help page 23 | // https://www.mathworks.com/help/optim/ug/fsolve.html 24 | // 25 | // F(x) = [exp(-exp(-(x_1+x_2))) - x_2*(1+x_1^2); 26 | // x_1*cos(x_2) + x_2*sin(x_1) - 0.5 ] 27 | // 28 | // solution is: (0.3532,0.6061) 29 | // 30 | 31 | #ifndef _optim_zeros_test_fn_1_HPP 32 | #define _optim_zeros_test_fn_1_HPP 33 | 34 | ColVec_t 35 | zeros_test_objfn_1(const ColVec_t& vals_inp, void* opt_data) 36 | { 37 | double x_1 = vals_inp(0); 38 | double x_2 = vals_inp(1); 39 | 40 | // 41 | 42 | ColVec_t ret(2); 43 | 44 | ret(0) = std::exp(-std::exp(-(x_1+x_2))) - x_2*(1 + std::pow(x_1,2)); 45 | ret(1) = x_1*std::cos(x_2) + x_2*std::sin(x_1) - 0.5; 46 | 47 | // 48 | 49 | return ret; 50 | } 51 | 52 | Mat_t 53 | zeros_test_jacob_1(const ColVec_t& vals_inp, void* opt_data) 54 | { 55 | double x_1 = vals_inp(0); 56 | double x_2 = vals_inp(1); 57 | 58 | // 59 | 60 | Mat_t ret(2,2); 61 | 62 | ret(0,0) = std::exp(-std::exp(-(x_1+x_2))-(x_1+x_2)) - 2*x_1*x_1; 63 | ret(0,1) = std::exp(-std::exp(-(x_1+x_2))-(x_1+x_2)) - x_1*x_1 - 1.0; 64 | ret(1,0) = std::cos(x_2) + x_2*std::cos(x_1); 65 | ret(1,1) = -x_1*std::sin(x_2) + std::cos(x_1); 66 | 67 | // 68 | 69 | return ret; 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /tests/test_fns/zeros_test_fn_2.hpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | // 22 | // F(x) = [ 2*x_1 - x_2 - exp(-x_1); 23 | // - x_1 + 2*x_2 - exp(-x_2)] 24 | // 25 | // solution is: (2.25,-4.75) 26 | // 27 | 28 | #ifndef _optim_zeros_test_fn_2_HPP 29 | #define _optim_zeros_test_fn_2_HPP 30 | 31 | ColVec_t 32 | zeros_test_objfn_2(const ColVec_t& vals_inp, void* opt_data) 33 | { 34 | double x_1 = vals_inp(0); 35 | double x_2 = vals_inp(1); 36 | 37 | // 38 | 39 | ColVec_t ret(2); 40 | 41 | ret(0) = 2*x_1 - x_2 - std::exp(-x_1); 42 | ret(1) = - x_1 + 2*x_2 - std::exp(-x_2); 43 | 44 | // 45 | 46 | return ret; 47 | } 48 | 49 | Mat_t 50 | zeros_test_jacob_2(const ColVec_t& vals_inp, void* opt_data) 51 | { 52 | double x_1 = vals_inp(0); 53 | double x_2 = vals_inp(1); 54 | 55 | // 56 | 57 | Mat_t ret(2,2); 58 | 59 | ret(0,0) = 2 + std::exp(-x_1); 60 | ret(0,1) = - 1.0; 61 | ret(1,0) = - 1.0; 62 | ret(1,1) = 2 + std::exp(-x_2); 63 | 64 | // 65 | 66 | return ret; 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /tests/test_setup/Makefile.in: -------------------------------------------------------------------------------- 1 | 2 | # core compiling options 3 | CXX = @CXX@ 4 | 5 | CXX_STD = @OPTIM_CXX_STD@ 6 | OPT_FLAGS = @OPTIM_WARN_FLAGS@ @OPTIM_OPT_FLAGS@ 7 | 8 | OPTIM_MATLIB_FLAGS = @OPTIM_MATLIB_FLAGS@ 9 | OPTIM_MATLIB_INCLUDE_PATH = @OPTIM_MATLIB_INCLUDE_PATH@ 10 | 11 | # install location 12 | INSTALL_PATH=@OPTIM_INSTALL_PATH@ 13 | 14 | # source directories 15 | OPTIM_HEADER_DIR = @OPTIM_INCLUDE_PATH@ 16 | OPTIM_TEST_DIR = . 17 | 18 | # general flags 19 | CXXFLAGS = $(CXX_STD) $(OPT_FLAGS) $(OPTIM_MATLIB_FLAGS) -I$(OPTIM_MATLIB_INCLUDE_PATH) -I$(OPTIM_HEADER_DIR) 20 | LIBS= -L@OPTIM_INSTALL_PATH@ -l@OPTIM_SHLIB_NAME@ @OPTIM_BLAS_LAPACK@ 21 | 22 | # Optim Test Files 23 | SOURCES_OPTIM := $(shell find $(OPTIM_TEST_DIR) -name '*.cpp') 24 | OBJECTS_OPTIM := $(addprefix $(OPTIM_TEST_DIR)/,$(SOURCES_OPTIM:%.cpp=%.test)) 25 | 26 | all: $(OBJECTS_OPTIM) 27 | 28 | # core Optim files 29 | $(OPTIM_TEST_DIR)/%.test: $(OPTIM_TEST_DIR)/%.cpp 30 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 31 | 32 | # cleanup and install 33 | .PHONY: clean 34 | clean: 35 | @rm -rf *.so ./*.gcov ./*.gcno ./*.gcda ./*.dSYM ./*.test -------------------------------------------------------------------------------- /tests/test_setup/cov_check: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z ${CXXCOV+x} ]; then 4 | CXXCOV=gcov 5 | fi 6 | 7 | for t in ./*.test; do 8 | "$t" 9 | done 10 | 11 | for t in ./*.cpp; do 12 | $CXXCOV "$t" > /dev/null 2>&1 13 | done 14 | -------------------------------------------------------------------------------- /tests/test_setup/run_cov: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | WDIR=${PWD} 4 | 5 | cd .. 6 | 7 | export CXXCOV=gcov 8 | export LD_LIBRARY_PATH="$PWD":$LD_LIBRARY_PATH 9 | 10 | cd tests 11 | 12 | # 13 | 14 | declare -a DIRS=("constrained" "misc" "unconstrained" "zeros") 15 | 16 | for i in "${DIRS[@]}"; do 17 | cd "$WDIR"/"$i" 18 | 19 | if [[ "${OPTIM_TEST_USE_ARMA}" == "y" ]]; then 20 | ./configure -c -l arma 21 | elif [[ "${OPTIM_TEST_USE_EIGEN}" == "y" ]]; then 22 | ./configure -c -l eigen 23 | else 24 | echo -e " \x1B[31m- tests error: unrecognized linear algebra library.\033[0m" >&2 ; 25 | echo "" 26 | exit 1 27 | fi 28 | 29 | make 30 | sh ./../test_setup/cov_check 31 | done 32 | -------------------------------------------------------------------------------- /tests/unconstrained/bfgs.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * BFGS tests 23 | */ 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | 31 | std::cout << "\n ***** Begin BFGS tests. ***** \n" << std::endl; 32 | 33 | // 34 | // test 1 35 | 36 | ColVec_t x_1 = BMO_MATOPS_ONE_COLVEC(2); 37 | 38 | bool success_1 = optim::bfgs(x_1, unconstr_test_fn_1, nullptr); 39 | 40 | if (success_1) { 41 | std::cout << "bfgs: test_1 completed successfully." << std::endl; 42 | } else { 43 | std::cout << "bfgs: test_1 completed unsuccessfully." << std::endl; 44 | } 45 | 46 | std::cout << "Distance from the actual solution to test_1:\n" \ 47 | << BMO_MATOPS_L2NORM(x_1 - unconstr_test_sols::test_1()) << std::endl; 48 | 49 | // 50 | // test 2 51 | 52 | ColVec_t x_2 = BMO_MATOPS_ZERO_COLVEC(2); 53 | 54 | bool success_2 = optim::bfgs(x_2,unconstr_test_fn_2,nullptr); 55 | 56 | if (success_2) { 57 | std::cout << "\nbfgs: test_2 completed successfully." << std::endl; 58 | } else { 59 | std::cout << "\nbfgs: test_2 completed unsuccessfully." << std::endl; 60 | } 61 | 62 | std::cout << "Distance from the actual solution to test_2:\n" \ 63 | << BMO_MATOPS_L2NORM(x_2 - unconstr_test_sols::test_2()) << std::endl; 64 | 65 | // 66 | // test 3 67 | 68 | int test_3_dim = 5; 69 | ColVec_t x_3 = BMO_MATOPS_ONE_COLVEC(test_3_dim); 70 | 71 | bool success_3 = optim::bfgs(x_3,unconstr_test_fn_3,nullptr); 72 | 73 | if (success_3) { 74 | std::cout << "\nbfgs: test_3 completed successfully." << std::endl; 75 | } else { 76 | std::cout << "\nbfgs: test_3 completed unsuccessfully." << std::endl; 77 | } 78 | 79 | std::cout << "Distance from the actual solution to test_3:\n" \ 80 | << BMO_MATOPS_L2NORM(x_3 - unconstr_test_sols::test_3(test_3_dim)) << std::endl; 81 | 82 | // 83 | // test 4 84 | 85 | ColVec_t x_4 = BMO_MATOPS_ONE_COLVEC(2); 86 | 87 | bool success_4 = optim::bfgs(x_4,unconstr_test_fn_4,nullptr); 88 | 89 | if (success_4) { 90 | std::cout << "\nbfgs: test_4 completed successfully." << std::endl; 91 | } else { 92 | std::cout << "\nbfgs: test_4 completed unsuccessfully." << std::endl; 93 | } 94 | 95 | std::cout << "Distance from the actual solution to test_4:\n" \ 96 | << BMO_MATOPS_L2NORM(x_4 - unconstr_test_sols::test_4()) << std::endl; 97 | 98 | // 99 | // test 5 100 | 101 | ColVec_t x_5 = BMO_MATOPS_ZERO_COLVEC(2); 102 | 103 | bool success_5 = optim::bfgs(x_5,unconstr_test_fn_5,nullptr); 104 | 105 | if (success_5) { 106 | std::cout << "\nbfgs: test_5 completed successfully." << std::endl; 107 | } else { 108 | std::cout << "\nbfgs: test_5 completed unsuccessfully." << std::endl; 109 | } 110 | 111 | std::cout << "Distance from the actual solution to test_5:\n" \ 112 | << BMO_MATOPS_L2NORM(x_5 - unconstr_test_sols::test_5()) << std::endl; 113 | 114 | // 115 | // for coverage 116 | 117 | optim::algo_settings_t settings; 118 | 119 | optim::bfgs(x_1, unconstr_test_fn_1, nullptr); 120 | optim::bfgs(x_1, unconstr_test_fn_1, nullptr,settings); 121 | 122 | settings.vals_bound = true; 123 | settings.lower_bounds = BMO_MATOPS_ARRAY_ADD_SCALAR(BMO_MATOPS_ZERO_COLVEC(2), - 4.5); 124 | settings.upper_bounds = BMO_MATOPS_ARRAY_ADD_SCALAR(BMO_MATOPS_ZERO_COLVEC(2), + 4.5); 125 | 126 | x_4 = BMO_MATOPS_ONE_COLVEC(2); 127 | 128 | success_4 = optim::bfgs(x_4, unconstr_test_fn_4, nullptr, settings); 129 | 130 | if (success_4) { 131 | std::cout << "\nbfgs with box constraints: test_4 completed successfully." << std::endl; 132 | } else { 133 | std::cout << "\nbfgs with box constraints: test_4 completed unsuccessfully." << std::endl; 134 | } 135 | 136 | std::cout << "Distance from the actual solution to test_4:\n" \ 137 | << BMO_MATOPS_L2NORM(x_4 - unconstr_test_sols::test_4()) << std::endl; 138 | 139 | // 140 | 141 | std::cout << "\n ***** End BFGS tests. ***** \n" << std::endl; 142 | 143 | return 0; 144 | } 145 | -------------------------------------------------------------------------------- /tests/unconstrained/lbfgs.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * L-BFGS tests 23 | */ 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | 31 | std::cout << "\n ***** Begin L-BFGS tests. ***** \n" << std::endl; 32 | 33 | optim::algo_settings_t settings; 34 | 35 | // 36 | // test 1 37 | 38 | ColVec_t x_1 = BMO_MATOPS_ONE_COLVEC(2); 39 | 40 | bool success_1 = optim::lbfgs(x_1, unconstr_test_fn_1, nullptr); 41 | 42 | if (success_1) { 43 | std::cout << "lbfgs: test_1 completed successfully." << std::endl; 44 | } else { 45 | std::cout << "lbfgs: test_1 completed unsuccessfully." << std::endl; 46 | } 47 | 48 | std::cout << "Distance from the actual solution to test_1:\n" \ 49 | << BMO_MATOPS_L2NORM(x_1 - unconstr_test_sols::test_1()) << std::endl; 50 | 51 | // 52 | // test 2 53 | 54 | // settings.print_level = 3; 55 | 56 | ColVec_t x_2 = BMO_MATOPS_ZERO_COLVEC(2); 57 | 58 | bool success_2 = optim::lbfgs(x_2, unconstr_test_fn_2, nullptr, settings); 59 | 60 | if (success_2) { 61 | std::cout << "\nlbfgs: test_2 completed successfully." << std::endl; 62 | } else { 63 | std::cout << "\nlbfgs: test_2 completed unsuccessfully." << std::endl; 64 | } 65 | 66 | std::cout << "Distance from the actual solution to test_2:\n" \ 67 | << BMO_MATOPS_L2NORM(x_2 - unconstr_test_sols::test_2()) << std::endl; 68 | 69 | // 70 | // test 3 71 | 72 | int test_3_dim = 5; 73 | ColVec_t x_3 = BMO_MATOPS_ONE_COLVEC(test_3_dim); 74 | 75 | bool success_3 = optim::lbfgs(x_3, unconstr_test_fn_3, nullptr); 76 | 77 | if (success_3) { 78 | std::cout << "\nlbfgs: test_3 completed successfully." << std::endl; 79 | } else { 80 | std::cout << "\nlbfgs: test_3 completed unsuccessfully." << std::endl; 81 | } 82 | 83 | std::cout << "Distance from the actual solution to test_3:\n" \ 84 | << BMO_MATOPS_L2NORM(x_3 - unconstr_test_sols::test_3(test_3_dim)) << std::endl; 85 | 86 | // 87 | // test 4 88 | 89 | optim::algo_settings_t settings_4; 90 | 91 | // settings_4.rel_sol_change_tol = -1.0; 92 | // settings_4.print_level = 4; 93 | 94 | ColVec_t x_4 = BMO_MATOPS_ONE_COLVEC(2); 95 | x_4(0) = 4.0; 96 | x_4(1) = 0.0; 97 | 98 | bool success_4 = optim::lbfgs(x_4, unconstr_test_fn_4, nullptr, settings_4); 99 | 100 | if (success_4) { 101 | std::cout << "\nlbfgs: test_4 completed successfully." << std::endl; 102 | } else { 103 | std::cout << "\nlbfgs: test_4 completed unsuccessfully." << std::endl; 104 | } 105 | 106 | std::cout << "Distance from the actual solution to test_4:\n" \ 107 | << BMO_MATOPS_L2NORM(x_4 - unconstr_test_sols::test_4()) << std::endl; 108 | 109 | // 110 | // test 5 111 | 112 | ColVec_t x_5 = BMO_MATOPS_ZERO_COLVEC(2); 113 | 114 | bool success_5 = optim::lbfgs(x_5, unconstr_test_fn_5, nullptr); 115 | 116 | if (success_5) { 117 | std::cout << "\nlbfgs: test_5 completed successfully." << std::endl; 118 | } else { 119 | std::cout << "\nlbfgs: test_5 completed unsuccessfully." << std::endl; 120 | } 121 | 122 | std::cout << "Distance from the actual solution to test_5:\n" \ 123 | << BMO_MATOPS_L2NORM(x_5 - unconstr_test_sols::test_5()) << std::endl; 124 | 125 | // 126 | // for coverage 127 | 128 | // optim::algo_settings_t settings; 129 | 130 | optim::lbfgs(x_1, unconstr_test_fn_1, nullptr); 131 | optim::lbfgs(x_1, unconstr_test_fn_1 ,nullptr, settings); 132 | 133 | settings.vals_bound = true; 134 | settings.lower_bounds = BMO_MATOPS_ARRAY_ADD_SCALAR( BMO_MATOPS_ZERO_COLVEC(2), - 4.5); 135 | settings.upper_bounds = BMO_MATOPS_ARRAY_ADD_SCALAR( BMO_MATOPS_ZERO_COLVEC(2), + 4.5); 136 | 137 | x_4 = BMO_MATOPS_ONE_COLVEC(2); 138 | 139 | success_4 = optim::lbfgs(x_4, unconstr_test_fn_4, nullptr, settings); 140 | 141 | if (success_4) { 142 | std::cout << "\nlbfgs with box constraints: test_4 completed successfully." << std::endl; 143 | } else { 144 | std::cout << "\nlbfgs with box constraints: test_4 completed unsuccessfully." << std::endl; 145 | } 146 | 147 | std::cout << "Distance from the actual solution to test_4:\n" \ 148 | << BMO_MATOPS_L2NORM(x_4 - unconstr_test_sols::test_4()) << std::endl; 149 | 150 | std::cout << "\n ***** End L-BFGS tests. ***** \n" << std::endl; 151 | 152 | return 0; 153 | } 154 | -------------------------------------------------------------------------------- /tests/unconstrained/newton.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Newton tests 23 | */ 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | std::cout << "\n ***** Begin Newton tests. ***** \n" << std::endl; 31 | 32 | // 33 | // test 1 34 | 35 | ColVec_t x_1 = BMO_MATOPS_ZERO_COLVEC(2); 36 | 37 | bool success_1 = optim::newton(x_1, unconstr_test_fn_1_whess, nullptr); 38 | 39 | if (success_1) { 40 | std::cout << "\nnewton: test_1 completed successfully." << std::endl; 41 | } else { 42 | std::cout << "\nnewton: test_1 completed unsuccessfully." << std::endl; 43 | } 44 | 45 | std::cout << "Distance from the actual solution to test_1:\n" \ 46 | << BMO_MATOPS_L2NORM(x_1 - unconstr_test_sols::test_1()) << std::endl; 47 | 48 | // 49 | // test 2 50 | 51 | ColVec_t x_2 = BMO_MATOPS_ZERO_COLVEC(2); 52 | 53 | bool success_2 = optim::newton(x_2, unconstr_test_fn_2_whess, nullptr); 54 | 55 | if (success_2) { 56 | std::cout << "\nnewton: test_2 completed successfully." << std::endl; 57 | } else { 58 | std::cout << "\nnewton: test_2 completed unsuccessfully." << std::endl; 59 | } 60 | 61 | std::cout << "Distance from the actual solution to test_2:\n" \ 62 | << BMO_MATOPS_L2NORM(x_2 - unconstr_test_sols::test_2()) << std::endl; 63 | 64 | // 65 | // test 3 66 | 67 | int test_3_dim = 5; 68 | ColVec_t x_3 = BMO_MATOPS_ONE_COLVEC(test_3_dim); 69 | 70 | bool success_3 = optim::newton(x_3, unconstr_test_fn_3_whess, nullptr); 71 | 72 | if (success_3) { 73 | std::cout << "\nnewton: test_3 completed successfully." << std::endl; 74 | } else { 75 | std::cout << "\nnewton: test_3 completed unsuccessfully." << std::endl; 76 | } 77 | 78 | std::cout << "Distance from the actual solution to test_3:\n" \ 79 | << BMO_MATOPS_L2NORM(x_3 - unconstr_test_sols::test_3(test_3_dim)) << std::endl; 80 | 81 | 82 | // 83 | // test 5 84 | 85 | // optim::algo_settings_t settings; 86 | // settings.err_tol = 1.0e-12; 87 | // settings.print_level = 4; 88 | 89 | ColVec_t x_5 = BMO_MATOPS_ZERO_COLVEC(2); 90 | x_5(0) = 2.0; 91 | x_5(1) = 2.0; 92 | 93 | bool success_5 = optim::newton(x_5, unconstr_test_fn_5_whess, nullptr); 94 | 95 | if (success_5) { 96 | std::cout << "\nnewton: test_5 completed successfully." << std::endl; 97 | } else { 98 | std::cout << "\nnewton: test_5 completed unsuccessfully." << std::endl; 99 | } 100 | 101 | std::cout << "Distance from the actual solution to test_5:\n" \ 102 | << BMO_MATOPS_L2NORM(x_5 - unconstr_test_sols::test_5()) << std::endl; 103 | 104 | // 105 | 106 | std::cout << "\n ***** End Newton tests. ***** \n" << std::endl; 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /tests/unconstrained/newton_logit_reg.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Newton test - logit regression 23 | */ 24 | 25 | #include "optim.hpp" 26 | 27 | using optim::ColVec_t; 28 | using optim::Mat_t; 29 | 30 | // sigmoid function 31 | 32 | inline 33 | Mat_t 34 | sigm(const Mat_t& X) 35 | { 36 | return BMO_MATOPS_SCALAR_DIV_ARRAY(1.0, ( BMO_MATOPS_ARRAY_ADD_SCALAR(BMO_MATOPS_EXP(-X), 1.0) )); 37 | } 38 | 39 | // log-likelihood function 40 | 41 | struct ll_data_t { 42 | ColVec_t Y; 43 | Mat_t X; 44 | }; 45 | 46 | double ll_fn(const ColVec_t& vals_inp, ColVec_t* grad_out, Mat_t* hess_out, void* opt_data) 47 | { 48 | ll_data_t* objfn_data = reinterpret_cast(opt_data); 49 | 50 | ColVec_t Y = objfn_data->Y; 51 | Mat_t X = objfn_data->X; 52 | 53 | ColVec_t mu = sigm(X*vals_inp); 54 | 55 | double norm_term = static_cast( BMO_MATOPS_SIZE(Y) ); 56 | 57 | #ifndef OPTIM_LOGIT_EX_LL_TERM_1 58 | #define OPTIM_LOGIT_EX_LL_TERM_1 BMO_MATOPS_HADAMARD_PROD(Y, BMO_MATOPS_LOG(mu)) 59 | #endif 60 | 61 | #ifndef OPTIM_LOGIT_EX_LL_TERM_2 62 | #define OPTIM_LOGIT_EX_LL_TERM_2 BMO_MATOPS_HADAMARD_PROD( BMO_MATOPS_ARRAY_ADD_SCALAR(-Y,1.0), BMO_MATOPS_LOG( BMO_MATOPS_ARRAY_ADD_SCALAR(-mu,1.0) )) 63 | #endif 64 | 65 | const double obj_val = - BMO_MATOPS_ACCU( OPTIM_LOGIT_EX_LL_TERM_1 + OPTIM_LOGIT_EX_LL_TERM_2 ) / norm_term; 66 | 67 | // 68 | 69 | if (grad_out) { 70 | *grad_out = BMO_MATOPS_TRANSPOSE(X) * (mu - Y) / norm_term; 71 | } 72 | 73 | if (hess_out) { 74 | Mat_t S = BMO_MATOPS_DIAGMAT( BMO_MATOPS_HADAMARD_PROD(mu, BMO_MATOPS_ARRAY_ADD_SCALAR(-mu,1.0)) ); 75 | *hess_out = BMO_MATOPS_TRANSPOSE(X) * S * X / norm_term; 76 | } 77 | 78 | // 79 | 80 | return obj_val; 81 | } 82 | 83 | // 84 | 85 | int main() 86 | { 87 | int n_dim = 5; // dimension of theta 88 | int n_samp = 1000; // sample length 89 | 90 | Mat_t X = bmo::stats::rsnorm_mat(n_samp,n_dim); 91 | ColVec_t theta_0 = BMO_MATOPS_ARRAY_ADD_SCALAR(3.0 * BMO_MATOPS_RANDU_VEC(n_dim), 1.0); 92 | 93 | BMO_MATOPS_COUT << "\nTrue theta:\n" << theta_0 << "\n"; 94 | 95 | ColVec_t mu = sigm(X*theta_0); 96 | 97 | ColVec_t Y(n_samp); 98 | 99 | for (int i = 0; i < n_samp; ++i) { 100 | Y(i) = ( BMO_MATOPS_AS_SCALAR(BMO_MATOPS_RANDU_VEC(1)) < mu(i) ) ? 1.0 : 0.0; 101 | } 102 | 103 | // fn data and initial values 104 | 105 | ll_data_t opt_data; 106 | opt_data.Y = std::move(Y); 107 | opt_data.X = std::move(X); 108 | 109 | ColVec_t x = BMO_MATOPS_ARRAY_ADD_SCALAR( BMO_MATOPS_ONE_COLVEC(n_dim), 1.0 ); // (2,2) 110 | 111 | std::chrono::time_point start = std::chrono::system_clock::now(); 112 | 113 | bool success = optim::newton(x, ll_fn, &opt_data); 114 | 115 | std::chrono::time_point end = std::chrono::system_clock::now(); 116 | std::chrono::duration elapsed_seconds = end-start; 117 | 118 | if (success) { 119 | std::cout << "newton: logit_reg test completed successfully.\n" 120 | << "elapsed time: " << elapsed_seconds.count() << "s\n"; 121 | } else { 122 | std::cout << "newton: logit_reg test completed unsuccessfully." << std::endl; 123 | } 124 | 125 | BMO_MATOPS_COUT << "\nnewton: solution to logit_reg test:\n" << x << "\n"; 126 | 127 | return 0; 128 | } -------------------------------------------------------------------------------- /tests/zeros/broyden.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Broyden tests 23 | */ 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | 31 | std::cout << "\n ***** Begin Broyden tests. ***** \n" << std::endl; 32 | 33 | // 34 | // test 1 35 | 36 | optim::algo_settings_t settings_1; 37 | // settings_1.print_level = 4; 38 | 39 | ColVec_t x_1 = BMO_MATOPS_ZERO_COLVEC(2); 40 | 41 | bool success_1 = optim::broyden(x_1, zeros_test_objfn_1, nullptr, settings_1); 42 | 43 | if (success_1) { 44 | std::cout << "broyden: test_1 completed successfully." << std::endl; 45 | } else { 46 | std::cout << "broyden: test_1 completed unsuccessfully." << std::endl; 47 | } 48 | 49 | BMO_MATOPS_COUT << "broyden: solution to test_1:\n" << x_1 << "\n"; 50 | 51 | // 52 | // test 2 53 | 54 | ColVec_t x_2 = BMO_MATOPS_ZERO_COLVEC(2); 55 | 56 | bool success_2 = optim::broyden(x_2, zeros_test_objfn_2, nullptr); 57 | 58 | if (success_2) { 59 | std::cout << "broyden: test_2 completed successfully." << std::endl; 60 | } else { 61 | std::cout << "broyden: test_2 completed unsuccessfully." << std::endl; 62 | } 63 | 64 | BMO_MATOPS_COUT << "broyden: solution to test_2:\n" << x_2 << "\n"; 65 | 66 | // 67 | // coverage tests 68 | 69 | optim::algo_settings_t settings; 70 | 71 | optim::broyden(x_1,zeros_test_objfn_1,nullptr); 72 | optim::broyden(x_1,zeros_test_objfn_1,nullptr,settings); 73 | 74 | // 75 | // test 1 76 | 77 | x_1 = BMO_MATOPS_ZERO_COLVEC(2); 78 | 79 | success_1 = optim::broyden(x_1, zeros_test_objfn_1, nullptr, zeros_test_jacob_1, nullptr); 80 | 81 | if (success_1) { 82 | std::cout << "broyden with jacobian: test_1 completed successfully." << std::endl; 83 | } else { 84 | std::cout << "broyden with jacobian: test_1 completed unsuccessfully." << std::endl; 85 | } 86 | 87 | BMO_MATOPS_COUT << "broyden with jacobian: solution to test_1:\n" << x_1 << "\n"; 88 | 89 | // 90 | // test 2 91 | 92 | x_2 = BMO_MATOPS_ZERO_COLVEC(2); 93 | 94 | success_2 = optim::broyden(x_2,zeros_test_objfn_2,nullptr,zeros_test_jacob_2,nullptr); 95 | 96 | if (success_2) { 97 | std::cout << "broyden with jacobian: test_2 completed successfully." << std::endl; 98 | } else { 99 | std::cout << "broyden with jacobian: test_2 completed unsuccessfully." << std::endl; 100 | } 101 | 102 | BMO_MATOPS_COUT << "broyden with jacobian: solution to test_2:\n" << x_2 << "\n"; 103 | 104 | // 105 | // coverage tests 106 | 107 | optim::broyden(x_1,zeros_test_objfn_1,nullptr,zeros_test_jacob_1,nullptr); 108 | optim::broyden(x_1,zeros_test_objfn_1,nullptr,zeros_test_jacob_1,nullptr,settings); 109 | 110 | // 111 | 112 | std::cout << "\n ***** End Broyden tests. ***** \n" << std::endl; 113 | 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /tests/zeros/broyden_df.cpp: -------------------------------------------------------------------------------- 1 | /*################################################################################ 2 | ## 3 | ## Copyright (C) 2016-2023 Keith O'Hara 4 | ## 5 | ## This file is part of the OptimLib C++ library. 6 | ## 7 | ## Licensed under the Apache License, Version 2.0 (the "License"); 8 | ## you may not use this file except in compliance with the License. 9 | ## You may obtain a copy of the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in writing, software 14 | ## distributed under the License is distributed on an "AS IS" BASIS, 15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | ## See the License for the specific language governing permissions and 17 | ## limitations under the License. 18 | ## 19 | ################################################################################*/ 20 | 21 | /* 22 | * Broyden tests 23 | */ 24 | 25 | #include "optim.hpp" 26 | #include "./../test_fns/test_fns.hpp" 27 | 28 | int main() 29 | { 30 | 31 | std::cout << "\n ***** Begin DF Broyden tests. ***** \n" << std::endl; 32 | 33 | // 34 | // test 1 35 | 36 | optim::algo_settings_t settings_1; 37 | // settings_1.print_level = 4; 38 | 39 | ColVec_t x_1 = BMO_MATOPS_ZERO_COLVEC(2); 40 | 41 | bool success_1 = optim::broyden_df(x_1,zeros_test_objfn_1,nullptr,settings_1); 42 | 43 | if (success_1) { 44 | std::cout << "broyden_df: test_1 completed successfully." << std::endl; 45 | } else { 46 | std::cout << "broyden_df: test_1 completed unsuccessfully." << std::endl; 47 | } 48 | 49 | BMO_MATOPS_COUT << "broyden_df: solution to test_1:\n" << x_1 << "\n"; 50 | 51 | // 52 | // test 2 53 | 54 | ColVec_t x_2 = BMO_MATOPS_ZERO_COLVEC(2); 55 | 56 | bool success_2 = optim::broyden_df(x_2,zeros_test_objfn_2,nullptr); 57 | 58 | if (success_2) { 59 | std::cout << "broyden_df: test_2 completed successfully." << std::endl; 60 | } else { 61 | std::cout << "broyden_df: test_2 completed unsuccessfully." << std::endl; 62 | } 63 | 64 | BMO_MATOPS_COUT << "broyden_df: solution to test_2:\n" << x_2 << "\n"; 65 | 66 | // 67 | // coverage tests 68 | 69 | optim::algo_settings_t settings; 70 | 71 | optim::broyden_df(x_1,zeros_test_objfn_1,nullptr); 72 | optim::broyden_df(x_1,zeros_test_objfn_1,nullptr,settings); 73 | 74 | // 75 | // test 1 76 | 77 | x_1 = BMO_MATOPS_ZERO_COLVEC(2); 78 | 79 | success_1 = optim::broyden_df(x_1,zeros_test_objfn_1,nullptr,zeros_test_jacob_1,nullptr); 80 | 81 | if (success_1) { 82 | std::cout << "broyden_df w jacobian: test_1 completed successfully." << std::endl; 83 | } else { 84 | std::cout << "broyden_df w jacobian: test_1 completed unsuccessfully." << std::endl; 85 | } 86 | 87 | BMO_MATOPS_COUT << "broyden_df w jacobian: solution to test_1:\n" << x_1 << "\n"; 88 | 89 | // 90 | // test 2 91 | 92 | x_2 = BMO_MATOPS_ZERO_COLVEC(2); 93 | 94 | success_2 = optim::broyden_df(x_2,zeros_test_objfn_2,nullptr,zeros_test_jacob_2,nullptr); 95 | 96 | if (success_2) { 97 | std::cout << "broyden_df w jacobian: test_2 completed successfully." << std::endl; 98 | } else { 99 | std::cout << "broyden_df w jacobian: test_2 completed unsuccessfully." << std::endl; 100 | } 101 | 102 | BMO_MATOPS_COUT << "broyden_df w jacobian: solution to test_2:\n" << x_2 << "\n"; 103 | 104 | // 105 | // coverage tests 106 | 107 | optim::broyden_df(x_1,zeros_test_objfn_1,nullptr,zeros_test_jacob_1,nullptr); 108 | optim::broyden_df(x_1,zeros_test_objfn_1,nullptr,zeros_test_jacob_1,nullptr,settings); 109 | 110 | // 111 | 112 | std::cout << "\n ***** End DF Broyden tests. ***** \n" << std::endl; 113 | 114 | return 0; 115 | } 116 | --------------------------------------------------------------------------------