├── .github └── workflows │ ├── deploy_docs.yml │ ├── deploy_pypi.yml │ └── python_package.yml ├── .gitignore ├── README.md ├── docs └── sphinx │ └── manual │ ├── _static │ └── logo.png │ ├── _templates │ └── versions.html │ ├── en │ ├── Makefile │ └── source │ │ ├── acknowledgement.rst │ │ ├── algorithm.rst │ │ ├── api │ │ ├── modules.rst │ │ ├── physbo.blm.basis.fourier.rst │ │ ├── physbo.blm.basis.rst │ │ ├── physbo.blm.core.model.rst │ │ ├── physbo.blm.core.rst │ │ ├── physbo.blm.inf.exact.rst │ │ ├── physbo.blm.inf.rst │ │ ├── physbo.blm.lik.gauss.rst │ │ ├── physbo.blm.lik.linear.rst │ │ ├── physbo.blm.lik.rst │ │ ├── physbo.blm.predictor.rst │ │ ├── physbo.blm.prior.gauss.rst │ │ ├── physbo.blm.prior.rst │ │ ├── physbo.blm.rst │ │ ├── physbo.gp.core.learning.rst │ │ ├── physbo.gp.core.model.rst │ │ ├── physbo.gp.core.prior.rst │ │ ├── physbo.gp.core.rst │ │ ├── physbo.gp.cov.gauss.rst │ │ ├── physbo.gp.cov.rst │ │ ├── physbo.gp.inf.exact.rst │ │ ├── physbo.gp.inf.rst │ │ ├── physbo.gp.lik.gauss.rst │ │ ├── physbo.gp.lik.rst │ │ ├── physbo.gp.mean.const.rst │ │ ├── physbo.gp.mean.rst │ │ ├── physbo.gp.mean.zero.rst │ │ ├── physbo.gp.predictor.rst │ │ ├── physbo.gp.rst │ │ ├── physbo.misc.centering.rst │ │ ├── physbo.misc.gauss_elim.rst │ │ ├── physbo.misc.rst │ │ ├── physbo.misc.set_config.rst │ │ ├── physbo.opt.adam.rst │ │ ├── physbo.opt.rst │ │ ├── physbo.predictor.rst │ │ ├── physbo.rst │ │ ├── physbo.search.discrete.policy.rst │ │ ├── physbo.search.discrete.results.rst │ │ ├── physbo.search.discrete.rst │ │ ├── physbo.search.rst │ │ ├── physbo.search.score.rst │ │ ├── physbo.search.utility.rst │ │ └── physbo.variable.rst │ │ ├── conf.py │ │ ├── contact.rst │ │ ├── index.rst │ │ ├── install.rst │ │ ├── introduction.rst │ │ └── notebook │ │ ├── data │ │ └── s5-210.csv │ │ ├── index.rst │ │ ├── tutorial_Gaussian_process.ipynb │ │ ├── tutorial_basic.ipynb │ │ ├── tutorial_basic_org.ipynb │ │ ├── tutorial_interactive_mode.ipynb │ │ ├── tutorial_multi_objective.ipynb │ │ ├── tutorial_multi_probe.ipynb │ │ └── tutorial_once_mode.ipynb │ └── ja │ ├── Makefile │ ├── make.bat │ ├── scan.sh │ └── source │ ├── .gitignore │ ├── acknowledgement.rst │ ├── algorithm.rst │ ├── conf.py │ ├── contact.rst │ ├── index.rst │ ├── install.rst │ ├── introduction.rst │ └── notebook │ ├── data │ └── s5-210.csv │ ├── index.rst │ ├── tutorial_Gaussian_process.ipynb │ ├── tutorial_basic.ipynb │ ├── tutorial_interactive_mode.ipynb │ ├── tutorial_multi_objective.ipynb │ ├── tutorial_multi_probe.ipynb │ ├── tutorial_once_mode.ipynb │ └── tutorial_simulator.ipynb ├── examples ├── grain_bound │ ├── .gitignore │ ├── data │ │ └── s5-210.csv │ ├── tutorial.ipynb │ ├── tutorial_interactive_mode.ipynb │ └── tutorial_multi_probe.ipynb ├── multiple.py ├── multiple_score.py ├── sfs.py ├── simple.py ├── simple_score.py └── simple_time.py ├── make_wheels.sh ├── physbo ├── .gitignore ├── __init__.py ├── blm │ ├── __init__.py │ ├── basis │ │ ├── __init__.py │ │ └── fourier.py │ ├── core │ │ ├── __init__.py │ │ └── model.py │ ├── inf │ │ ├── __init__.py │ │ └── exact.py │ ├── lik │ │ ├── __init__.py │ │ ├── _src │ │ │ ├── __init__.py │ │ │ └── cov.py │ │ ├── gauss.py │ │ └── linear.py │ ├── predictor.py │ └── prior │ │ ├── __init__.py │ │ └── gauss.py ├── gp │ ├── __init__.py │ ├── core │ │ ├── __init__.py │ │ ├── learning.py │ │ ├── model.py │ │ └── prior.py │ ├── cov │ │ ├── __init__.py │ │ ├── _src │ │ │ ├── __init__.py │ │ │ └── enhance_gauss.pyx │ │ └── gauss.py │ ├── inf │ │ ├── __init__.py │ │ └── exact.py │ ├── lik │ │ ├── __init__.py │ │ └── gauss.py │ ├── mean │ │ ├── __init__.py │ │ ├── const.py │ │ └── zero.py │ └── predictor.py ├── misc │ ├── __init__.py │ ├── _src │ │ ├── __init__.py │ │ ├── cholupdate.pyx │ │ ├── diagAB.pyx │ │ ├── logsumexp.pyx │ │ └── traceAB.pyx │ ├── centering.py │ ├── gauss_elim.py │ └── set_config.py ├── opt │ ├── __init__.py │ └── adam.py ├── predictor.py ├── search │ ├── __init__.py │ ├── discrete │ │ ├── __init__.py │ │ ├── policy.py │ │ └── results.py │ ├── discrete_multi │ │ ├── __init__.py │ │ ├── policy.py │ │ └── results.py │ ├── pareto.py │ ├── score.py │ ├── score_multi.py │ └── utility.py └── variable.py ├── pyproject.toml ├── setup.cfg ├── setup.py ├── tests ├── README.md ├── integrated │ ├── __init__.py │ ├── test_gp.py │ ├── test_interactive_example.py │ ├── test_multi_objective.py │ └── test_simple_example.py └── unit │ ├── __init__.py │ ├── test_gp.py │ ├── test_misc.py │ ├── test_policy.py │ ├── test_search.py │ └── test_variable.py └── tox.ini /.github/workflows/deploy_docs.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - develop 8 | - '!gh-pages' 9 | - changedocs 10 | tags: '*' 11 | 12 | jobs: 13 | deploy: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Inject slug/short variables 17 | uses: rlespinasse/github-slug-action@v4.x 18 | 19 | - name: Checkout 20 | uses: actions/checkout@v4 21 | with: 22 | path: main 23 | fetch-depth: 0 24 | 25 | - name: Checkout gh-pages 26 | uses: actions/checkout@v4 27 | with: 28 | ref: gh-pages 29 | path: gh-pages 30 | 31 | - name: Set up Python 32 | uses: actions/setup-python@v5 33 | with: 34 | python-version: '3.10' 35 | 36 | - name: Install dependencies 37 | run: | 38 | sudo apt update 39 | sudo apt install pandoc 40 | python -m pip install --upgrade pip setuptools wheel 41 | pip install tox tox-gh-actions 42 | 43 | - name: Build docs with tox 44 | env: 45 | TARGET_NAME: ${{ env.GITHUB_REF_SLUG }} 46 | run: | 47 | cd main 48 | tox run -e docs 49 | cd ../ 50 | 51 | - name: Deploy Configuration 52 | run: | 53 | mkdir ~/.ssh 54 | ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts 55 | echo "${{ secrets.GH_ACTIONS_DEPLOY_KEY }}" > ~/.ssh/id_rsa 56 | chmod 400 ~/.ssh/id_rsa 57 | 58 | - name: Push 59 | env: 60 | GIT_USER: "PHYSBO Developers" 61 | GIT_EMAIL: "physbo-dev@issp.u-tokyo.ac.jp" 62 | TARGET_NAME: ${{ env.GITHUB_REF_SLUG }} 63 | run: | 64 | cd ${GITHUB_WORKSPACE} 65 | for lang in ja en; do 66 | rm -rf "gh-pages/manual/${TARGET_NAME}/${lang}" 67 | mkdir -p "gh-pages/manual/${TARGET_NAME}" 68 | cp -r "main/.tox/docs_out/manual/${lang}" "gh-pages/manual/${TARGET_NAME}/" 69 | done 70 | cd gh-pages 71 | git config --local user.name "${GIT_USER}" 72 | git config --local user.email "${GIT_EMAIL}" 73 | git remote set-url origin git@github.com:${GITHUB_REPOSITORY}.git 74 | git add manual 75 | if git commit -m "Deploy docs to ${TARGET_NAME} by GitHub Actions triggered by ${GITHUB_SHA}" 76 | then 77 | git push origin gh-pages 78 | else 79 | echo "Nothing to deploy" 80 | fi 81 | -------------------------------------------------------------------------------- /.github/workflows/deploy_pypi.yml: -------------------------------------------------------------------------------- 1 | name: Deploy python package to PyPI 2 | 3 | on: 4 | push: 5 | tags: ['*'] 6 | 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | environment: 11 | name: pypi 12 | url: https://pypi.org/p/physbo 13 | permissions: 14 | id-token: write # IMPORTANT: this permission is mandatory for trusted publishing 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up Python 20 | uses: actions/setup-python@v5 21 | with: 22 | python-version: '3.10' 23 | 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install -U pip 27 | python -m pip install build 28 | 29 | - name: Build 30 | run: python -m build --sdist 31 | 32 | - name: Publish 33 | uses: pypa/gh-action-pypi-publish@release/v1 34 | with: 35 | skip-existing: true 36 | -------------------------------------------------------------------------------- /.github/workflows/python_package.yml: -------------------------------------------------------------------------------- 1 | name: Test python package 2 | 3 | on: 4 | push: 5 | pull_request: 6 | schedule: 7 | - cron: '0 0 1,15 * *' # JST 9:00 AM, 1st and 15th of every month 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-22.04 12 | strategy: 13 | fail-fast: false 14 | max-parallel: 3 15 | matrix: 16 | python-version: ['3.8', '3.9', '3.10', '3.11'] 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | - name: Set up Python ${{ matrix.python-version }} 21 | uses: actions/setup-python@v5 22 | with: 23 | python-version: ${{ matrix.python-version }} 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install --upgrade pip setuptools wheel 27 | pip install tox tox-gh-actions 28 | - name: Test with tox 29 | run: tox run 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # optimization tools for PHYsics based on Bayesian Optimization ( PHYSBO ) 2 | 3 | Bayesian optimization has been proven as an effective tool in accelerating scientific discovery. 4 | A standard implementation (e.g., scikit-learn), however, can accommodate only small training data. 5 | PHYSBO is highly scalable due to an efficient protocol that employs Thompson sampling, random feature maps, one-rank Cholesky update and automatic hyperparameter tuning. Technical features are described in [COMBO's document](https://github.com/tsudalab/combo/blob/master/docs/combo_document.pdf) and [PHYSBO's report](https://doi.org/10.1016/j.cpc.2022.108405) (open access). 6 | PHYSBO was developed based on [COMBO](https://github.com/tsudalab/combo) for academic use. 7 | 8 | ## Documentation 9 | 10 | - Stable (master branch) 11 | - [English](https://issp-center-dev.github.io/PHYSBO/manual/master/en/index.html) 12 | - [日本語](https://issp-center-dev.github.io/PHYSBO/manual/master/ja/index.html) 13 | - Latest (develop branch) 14 | - [English](https://issp-center-dev.github.io/PHYSBO/manual/develop/en/index.html) 15 | - [日本語](https://issp-center-dev.github.io/PHYSBO/manual/develop/ja/index.html) 16 | 17 | ## Dependencies 18 | 19 | - Python >= 3.6 20 | - No longer tested with Python 3.6 21 | - NumPy < 2.0.0 22 | - SciPy 23 | 24 | ## Install 25 | 26 | - From PyPI (recommended) 27 | 28 | ```bash 29 | python3 -m pip install physbo 30 | ``` 31 | 32 | - From source (for developers) 33 | 1. Update pip (>= 19.0) 34 | 35 | ```bash 36 | python3 -m pip install -U pip 37 | ``` 38 | 39 | 1. Download or clone the github repository 40 | 41 | ``` 42 | git clone https://github.com/issp-center-dev/PHYSBO 43 | ``` 44 | 45 | 1. Install via pip 46 | 47 | ``` bash 48 | # ./PHYSBO is the root directory of PHYSBO 49 | # pip install options such as --user are avaiable 50 | 51 | python3 -m pip install ./PHYSBO 52 | ``` 53 | 54 | 1. Note: Do not `import physbo` at the root directory of the repository because `import physbo` does not try to import the installed PHYSBO but one in the repository, which includes Cython codes not compiled. 55 | 56 | ## Uninstall 57 | 58 | ```bash 59 | python3 -m pip uninstall physbo 60 | ``` 61 | 62 | ## Usage 63 | 64 | For an introductory tutorial please consult the documentation. ([English](https://issp-center-dev.github.io/PHYSBO/manual/master/en/notebook/tutorial_basic.html) / [日本語](https://issp-center-dev.github.io/PHYSBO/manual/develop/ja/install.html#id2)) 65 | 66 | ['examples/simple.py'](./examples/simple.py) is a simple example. 67 | 68 | ## Data repository 69 | 70 | A tutorial and a dataset of a paper about PHYSBO can be found in [PHYSBO Gallery](http://isspns-container.issp.u-tokyo.ac.jp/repo/12). 71 | 72 | ## License 73 | 74 | PHYSBO was developed based on [COMBO](https://github.com/tsudalab/COMBO) for academic use. 75 | PHYSBO v2 is distributed under Mozilla Public License version 2.0 (MPL v2). 76 | We hope that you cite the following reference when you publish the results using PHYSBO: 77 | 78 | [“Bayesian optimization package: PHYSBO”, Yuichi Motoyama, Ryo Tamura, Kazuyoshi Yoshimi, Kei Terayama, Tsuyoshi Ueno, Koji Tsuda, Computer Physics Communications Volume 278, September 2022, 108405.](https://doi.org/10.1016/j.cpc.2022.108405) 79 | 80 | Bibtex 81 | 82 | ``` 83 | @misc{@article{MOTOYAMA2022108405, 84 | title = {Bayesian optimization package: PHYSBO}, 85 | journal = {Computer Physics Communications}, 86 | volume = {278}, 87 | pages = {108405}, 88 | year = {2022}, 89 | issn = {0010-4655}, 90 | doi = {https://doi.org/10.1016/j.cpc.2022.108405}, 91 | author = {Yuichi Motoyama and Ryo Tamura and Kazuyoshi Yoshimi and Kei Terayama and Tsuyoshi Ueno and Koji Tsuda}, 92 | keywords = {Bayesian optimization, Multi-objective optimization, Materials screening, Effective model estimation} 93 | } 94 | ``` 95 | 96 | ### Copyright 97 | 98 | © *2020- The University of Tokyo. All rights reserved.* 99 | This software was developed with the support of \"*Project for advancement of software usability in materials science*\" of The Institute for Solid State Physics, The University of Tokyo. 100 | -------------------------------------------------------------------------------- /docs/sphinx/manual/_static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/issp-center-dev/PHYSBO/79ce6a2c012ae2e5a3384a295c381564feec1acd/docs/sphinx/manual/_static/logo.png -------------------------------------------------------------------------------- /docs/sphinx/manual/_templates/versions.html: -------------------------------------------------------------------------------- 1 | {# The original version of this file is a part of sphinx_rtd_theme v0.5.0, which is distributed under the MIT license #} 2 | {# https://github.com/readthedocs/sphinx_rtd_theme #} 3 | 4 | {# Add rst-badge after rst-versions for small badge style. #} 5 | {% if ENABLE_VERSIONING == "true" %} 6 |
7 | 8 | Read the Docs 9 | v: {{ current_version }} 10 | 11 | 12 |
13 |
14 |
{{ _('Languages') }}
15 | {% for lang in languages %} 16 | {% set root_dir = pathto("../..", 1)%} 17 |
18 | {% if lang == current_lang %}{% endif %} 19 | {{ lang }} 20 | {% if lang == current_lang %}{% endif %} 21 |
22 | {% endfor %} 23 | 24 |
{{ _('Branches') }}
25 | {% for name in branches %} 26 | {% set root_dir = pathto("../..", 1)%} 27 |
28 | {% if name == current_version %}{% endif %} 29 | {{ name }} 30 | {% if name == current_version %}{% endif %} 31 |
32 | {% endfor %} 33 | 34 |
{{ _('Tags') }}
35 | {% for name in tags %} 36 | {% set root_dir = pathto("../..", 1)%} 37 |
38 | {% if name == current_version %}{% endif %} 39 | {{ name }} 40 | {% if name == current_version %}{% endif %} 41 |
42 | {% endfor %} 43 | 44 |
45 |
46 |
47 | {% endif %} {# endif ENABLE_VERSIONING #} 48 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = python -msphinx 7 | SPHINXPROJ = pyMC 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | sh ./scan.sh 21 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -t "tag-$@" 22 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/acknowledgement.rst: -------------------------------------------------------------------------------- 1 | *************************** 2 | Acknowledgement 3 | *************************** 4 | We would like to thank the support from “Project for advancement of software usability in materials science” by The Institute for Solid State Physics, The University of Tokyo, for development of PHYSBO. 5 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/modules.rst: -------------------------------------------------------------------------------- 1 | physbo 2 | ====== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | physbo 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.basis.fourier.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.basis.fourier module 2 | =============================== 3 | 4 | .. automodule:: physbo.blm.basis.fourier 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.basis.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.basis package 2 | ======================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.blm.basis.fourier 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.blm.basis 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.core.model.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.core.model module 2 | ============================ 3 | 4 | .. automodule:: physbo.blm.core.model 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.core.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.core package 2 | ======================= 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.blm.core.model 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.blm.core 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.inf.exact.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.inf.exact module 2 | =========================== 3 | 4 | .. automodule:: physbo.blm.inf.exact 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.inf.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.inf package 2 | ====================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.blm.inf.exact 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.blm.inf 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.lik.gauss.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.lik.gauss module 2 | =========================== 3 | 4 | .. automodule:: physbo.blm.lik.gauss 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.lik.linear.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.lik.linear module 2 | ============================ 3 | 4 | .. automodule:: physbo.blm.lik.linear 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.lik.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.lik package 2 | ====================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.blm.lik.gauss 11 | physbo.blm.lik.linear 12 | 13 | Module contents 14 | --------------- 15 | 16 | .. automodule:: physbo.blm.lik 17 | :members: 18 | :undoc-members: 19 | :show-inheritance: 20 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.predictor.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.predictor module 2 | =========================== 3 | 4 | .. automodule:: physbo.blm.predictor 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.prior.gauss.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.prior.gauss module 2 | ============================= 3 | 4 | .. automodule:: physbo.blm.prior.gauss 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.prior.rst: -------------------------------------------------------------------------------- 1 | physbo.blm.prior package 2 | ======================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.blm.prior.gauss 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.blm.prior 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.blm.rst: -------------------------------------------------------------------------------- 1 | physbo.blm package 2 | ================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.blm.basis 11 | physbo.blm.core 12 | physbo.blm.inf 13 | physbo.blm.lik 14 | physbo.blm.prior 15 | 16 | Submodules 17 | ---------- 18 | 19 | .. toctree:: 20 | :maxdepth: 4 21 | 22 | physbo.blm.predictor 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: physbo.blm 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.core.learning.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.core.learning module 2 | ============================== 3 | 4 | .. automodule:: physbo.gp.core.learning 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.core.model.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.core.model module 2 | =========================== 3 | 4 | .. automodule:: physbo.gp.core.model 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.core.prior.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.core.prior module 2 | =========================== 3 | 4 | .. automodule:: physbo.gp.core.prior 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.core.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.core package 2 | ====================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.gp.core.learning 11 | physbo.gp.core.model 12 | physbo.gp.core.prior 13 | 14 | Module contents 15 | --------------- 16 | 17 | .. automodule:: physbo.gp.core 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.cov.gauss.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.cov.gauss module 2 | ========================== 3 | 4 | .. automodule:: physbo.gp.cov.gauss 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.cov.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.cov package 2 | ===================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.gp.cov.gauss 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.gp.cov 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.inf.exact.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.inf.exact module 2 | ========================== 3 | 4 | .. automodule:: physbo.gp.inf.exact 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.inf.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.inf package 2 | ===================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.gp.inf.exact 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.gp.inf 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.lik.gauss.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.lik.gauss module 2 | ========================== 3 | 4 | .. automodule:: physbo.gp.lik.gauss 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.lik.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.lik package 2 | ===================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.gp.lik.gauss 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.gp.lik 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.mean.const.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.mean.const module 2 | =========================== 3 | 4 | .. automodule:: physbo.gp.mean.const 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.mean.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.mean package 2 | ====================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.gp.mean.const 11 | physbo.gp.mean.zero 12 | 13 | Module contents 14 | --------------- 15 | 16 | .. automodule:: physbo.gp.mean 17 | :members: 18 | :undoc-members: 19 | :show-inheritance: 20 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.mean.zero.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.mean.zero module 2 | ========================== 3 | 4 | .. automodule:: physbo.gp.mean.zero 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.predictor.rst: -------------------------------------------------------------------------------- 1 | physbo.gp.predictor module 2 | ========================== 3 | 4 | .. automodule:: physbo.gp.predictor 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.gp.rst: -------------------------------------------------------------------------------- 1 | physbo.gp package 2 | ================= 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.gp.core 11 | physbo.gp.cov 12 | physbo.gp.inf 13 | physbo.gp.lik 14 | physbo.gp.mean 15 | 16 | Submodules 17 | ---------- 18 | 19 | .. toctree:: 20 | :maxdepth: 4 21 | 22 | physbo.gp.predictor 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: physbo.gp 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.misc.centering.rst: -------------------------------------------------------------------------------- 1 | physbo.misc.centering module 2 | ============================ 3 | 4 | .. automodule:: physbo.misc.centering 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.misc.gauss_elim.rst: -------------------------------------------------------------------------------- 1 | physbo.misc.gauss\_elim module 2 | ============================== 3 | 4 | .. automodule:: physbo.misc.gauss_elim 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.misc.rst: -------------------------------------------------------------------------------- 1 | physbo.misc package 2 | =================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.misc.centering 11 | physbo.misc.gauss_elim 12 | physbo.misc.set_config 13 | 14 | Module contents 15 | --------------- 16 | 17 | .. automodule:: physbo.misc 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.misc.set_config.rst: -------------------------------------------------------------------------------- 1 | physbo.misc.set\_config module 2 | ============================== 3 | 4 | .. automodule:: physbo.misc.set_config 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.opt.adam.rst: -------------------------------------------------------------------------------- 1 | physbo.opt.adam module 2 | ====================== 3 | 4 | .. automodule:: physbo.opt.adam 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.opt.rst: -------------------------------------------------------------------------------- 1 | physbo.opt package 2 | ================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.opt.adam 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: physbo.opt 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.predictor.rst: -------------------------------------------------------------------------------- 1 | physbo.predictor module 2 | ======================= 3 | 4 | .. automodule:: physbo.predictor 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.rst: -------------------------------------------------------------------------------- 1 | physbo package 2 | ============== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.blm 11 | physbo.gp 12 | physbo.misc 13 | physbo.opt 14 | physbo.search 15 | 16 | Submodules 17 | ---------- 18 | 19 | .. toctree:: 20 | :maxdepth: 4 21 | 22 | physbo.predictor 23 | physbo.variable 24 | 25 | Module contents 26 | --------------- 27 | 28 | .. automodule:: physbo 29 | :members: 30 | :undoc-members: 31 | :show-inheritance: 32 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.search.discrete.policy.rst: -------------------------------------------------------------------------------- 1 | physbo.search.discrete.policy module 2 | ==================================== 3 | 4 | .. automodule:: physbo.search.discrete.policy 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.search.discrete.results.rst: -------------------------------------------------------------------------------- 1 | physbo.search.discrete.results module 2 | ===================================== 3 | 4 | .. automodule:: physbo.search.discrete.results 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.search.discrete.rst: -------------------------------------------------------------------------------- 1 | physbo.search.discrete package 2 | ============================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.search.discrete.policy 11 | physbo.search.discrete.results 12 | 13 | Module contents 14 | --------------- 15 | 16 | .. automodule:: physbo.search.discrete 17 | :members: 18 | :undoc-members: 19 | :show-inheritance: 20 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.search.rst: -------------------------------------------------------------------------------- 1 | physbo.search package 2 | ===================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | physbo.search.discrete 11 | physbo.search.discrete_multi 12 | 13 | Submodules 14 | ---------- 15 | 16 | .. toctree:: 17 | :maxdepth: 4 18 | 19 | physbo.search.pareto 20 | physbo.search.score 21 | physbo.search.score_multi 22 | physbo.search.utility 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: physbo.search 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.search.score.rst: -------------------------------------------------------------------------------- 1 | physbo.search.score module 2 | ========================== 3 | 4 | .. automodule:: physbo.search.score 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.search.utility.rst: -------------------------------------------------------------------------------- 1 | physbo.search.utility module 2 | ============================ 3 | 4 | .. automodule:: physbo.search.utility 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/api/physbo.variable.rst: -------------------------------------------------------------------------------- 1 | physbo.variable module 2 | ====================== 3 | 4 | .. automodule:: physbo.variable 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/contact.rst: -------------------------------------------------------------------------------- 1 | Contact 2 | ========================================= 3 | 4 | - Bug Reports 5 | 6 | Please report all problems and bugs on the github `Issues `_ page. 7 | 8 | To resolve bugs early, follow these guidelines when reporting: 9 | 10 | 1. Please specify the version of PHYSBO you are using. 11 | 12 | 2. If there are problems for installation, please inform us about your operating system and the compiler. 13 | 14 | 3. If a problem occurs during execution, enter the input file used for execution and its output. 15 | 16 | Thank you for your cooperation. 17 | 18 | - Others 19 | 20 | If you have any questions about your research that are difficult to consult at Issues on GitHub, please send an e-mail to the following address: 21 | 22 | E-mail: ``physbo-dev__at__issp.u-tokyo.ac.jp`` (replace _at_ by @) 23 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/index.rst: -------------------------------------------------------------------------------- 1 | .. PHYSBO documentation master file, created by 2 | sphinx-quickstart on Tue May 26 18:44:52 2020. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to PHYSBO's documentation! 7 | ================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | introduction 14 | install 15 | notebook/index 16 | algorithm 17 | API Reference 18 | acknowledgement 19 | contact 20 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/install.rst: -------------------------------------------------------------------------------- 1 | Basic usage 2 | ===================== 3 | 4 | Install 5 | --------------------- 6 | 7 | Required Packages 8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 | 10 | * Python >= 3.6 11 | * numpy < 2.0.0 12 | * scipy 13 | 14 | Download and Install 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 | 17 | - From ``PyPI`` (recommended) :: 18 | 19 | $ pip3 install physbo 20 | 21 | - Required packages such as NumPy will also be installed at the same time. 22 | 23 | - If you add the ``--user`` option, it will be installed under the user's home directory :: 24 | 25 | $ pip3 install --user physbo 26 | 27 | 28 | - From source (for developers) 29 | 30 | #. Download or clone the github repository 31 | 32 | $ git clone https://github.com/issp-center-dev/PHYSBO 33 | 34 | #. Update ``pip`` to 19.0 or higher :: 35 | 36 | $ pip3 install -U pip 37 | 38 | - If you don't have ``pip3``, you can install it with ``python3 -m ensurepip``. 39 | 40 | #. Install :: 41 | 42 | $ cd PHYSBO 43 | $ pip3 install --user ./ 44 | 45 | Uninstall 46 | ~~~~~~~~~~~~~~~~~~~~~~~~ 47 | 48 | #. Execute the following command. :: 49 | 50 | $ pip uninstall physbo 51 | 52 | 53 | Basic structures 54 | -------------------------- 55 | 56 | PHYSBO has the following structure (shown up to the second level). 57 | 58 | .. 59 | |--physbo 60 | | |--blm 61 | | |--gp 62 | | |--misc 63 | | |--opt 64 | | |--search 65 | | |--predictor.py 66 | | |--variable.py 67 | 68 | Each module is created with the following structure. 69 | 70 | - ``blm`` :Module for Baysean linear model 71 | - ``gp`` :Module for Gaussian Process 72 | - ``opt`` :Module for optimazation 73 | - ``search`` :Module for searching for optimal solutions 74 | - ``predictor.py`` :Abstract class for predictors 75 | - ``variable.py`` :Class defined for variable associations used in physbo 76 | - ``misc`` : Others (e.g., modules for normalizing the search space) 77 | 78 | For more information about each module, please refer to the API reference. 79 | 80 | Calculation flow 81 | -------------------------- 82 | 83 | Bayesian optimization is well suited for optimization problems such as complex simulations or real-world experimental tasks where the objective function is very costly to evaluate. 84 | In PHYSBO, the following steps are used to perform the optimization (please refer to the tutorial and API reference for details on each). 85 | 86 | 1. Defining the search space 87 | 88 | Define each parameter set (d-dimensional vector) as a search candidate, where N: the number of search candidates , d: the number of input parameter dimensions. The parameter set should list all the candidates. 89 | 90 | 2. Defining the simulator 91 | 92 | For searching candidates defined above, define a simulator that gives the objective function values (values to be optimized, such as material property values) for each search candidate. In PHYSBO, the direction of optimization is to maximize the objective function, so if you want to minimize the objective function, you can do so by applying a negative value to the value returned by the simulator. 93 | 94 | 3. Performing optimization 95 | 96 | First, set the optimization policy (the search space is passed to policy as an argument at this stage). You can choose between the following two optimization methods. 97 | 98 | - ``random_search`` 99 | - ``bayes_search`` 100 | 101 | In ``random_search``, we randomly select parameters from the search space and search for the largest objective function among them. It is used to prepare an initial set of parameters as a preprocessing step for Bayesian optimization. ``bayes_search`` performs Bayesian optimization. The type of score (acquisition function) in Bayesian optimization can be one of the following. 102 | 103 | - TS (Thompson Sampling): Sample one regression function from the posterior probability distribution of the learned Gaussian process, and select the point where the predicetd value becomes maximum as a next candidate. 104 | - EI (Expected Improvement): Select the point where the expected value of the difference between the predicted value by the Gaussian process and the maximum value in the current situation becomes the maximum as a next candidate. 105 | - PI (Probability of Improvement): Select the point with the highest probability of exceeding the current maximum of the current acquisition function as a next candidate. 106 | 107 | Details of Gaussian processes are described in :ref:`chap_algorithm` . For other details of each method, please see `this reference `_ . 108 | If you specify the simulator and the number of search steps in these methods, the following loop will rotate by the number of search steps. 109 | 110 | i). Select the next parameter to be executed from the list of candidate parameters. 111 | 112 | ii). Run the simulator with the selected parameters. 113 | 114 | The number of parameter returned in i) is one by default, but it is possible to return multiple parameters in one step. For more details, please refer to the "Exploring multiple candidates at once" section of the tutorial. Also, instead of running the above loop inside PHYSBO, it is possible to control i) and ii) separately from the outside. In other words, it is possible to propose the next parameter to be executed from PHYSBO, evaluate its objective function value in some way outside PHYSBO (e.g., by experiment rather than numerical calculation), and register the evaluated value in PHYSBO. For more details, please refer to the "Running Interactively" section of the tutorial. 115 | 116 | 4. Check numerical results 117 | 118 | The search result ``res`` is returned as an object of the ``history`` class ( ``physbo.search.discrete.results.history`` ). The following is a reference to the search results. 119 | 120 | - ``res.fx``: The logs of evaluation values for simulator (objective function) simulator. 121 | - ``res.chosen_actions``: The logs of the action ID (parameter) when the simulator has executed. 122 | - ``fbest, best_action= res.export_all_sequence_best_fx()``: The logs of the best values and their action IDs (parameters) at each step where the simulator has executed. 123 | - ``res.total_num_search``: Total number steps where the simulator has executed. 124 | 125 | The search results can be saved to an external file using the ``save`` method, and the output results can be loaded using the ``load`` method. See the tutorial for details on how to use it. 126 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/introduction.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ===================== 3 | 4 | About PHYSBO 5 | ---------------------- 6 | 7 | PHYSBO (optimization tools for PHYSics based on Bayesian Optimization) is a Python library for fast and scalable Bayesian optimization. It is based on COMBO (Common Bayesian Optimization) and has been developed mainly for researchers in the materials science field. There are many attempts to accelerate scientific discovery through data-driven design-of-experiment algorithms in the fields of physics, chemistry, and materials. Bayesian optimization is an effective tool for accelerating these scientific discoveries. Bayesian optimization is a technique that can be used for complex simulations and real-world experimental tasks where the evaluation of objective function values (e.g., characteristic values) is very costly. In other words, the problem solved by Bayesian optimization is to find a parameter (e.g., material composition, structure, process and simulation parameters) with a better objective function value (e.g., material properties) in as few experiments and simulations as possible. In Bayesian optimization, the candidate parameters to be searched for are listed in advance, and the candidate with the largest objective function value is selected from among the candidates by making good use of machine learning (using Gaussian process regression) prediction. Experiments and simulations are performed on the candidates and the objective function values are evaluated. By repeating the process of selection by machine learning and evaluation by experimental simulation, we can reduce the number of times of optimization. On the other hand, Bayesian optimization is generally computationally expensive, and standard implementations such as scikit-learn are difficult to handle a large amount of data. PHYSBO achieves high scalability due to the following features 8 | 9 | - Thompson Sampling 10 | - random feature map 11 | - one-rank Cholesky update 12 | - automatic hyperparameter tuning 13 | 14 | Please see `this reference `_ for technical details. 15 | 16 | Citation 17 | ---------------------- 18 | 19 | When citing PHYSBO, please cite the following reference: 20 | 21 | Yuichi Motoyama, Ryo Tamura, Kazuyoshi Yoshimi, Kei Terayama, Tsuyoshi Ueno, Koji Tsuda, 22 | Bayesian optimization package: PHYSBO, 23 | Computer Physics Communications Volume 278, September 2022, 108405. Available from https://www.sciencedirect.com/science/article/pii/S0010465522001242?via%3Dihub (open access). 24 | 25 | Bibtex is given as follows: :: 26 | 27 | @misc{@article{MOTOYAMA2022108405, 28 | title = {Bayesian optimization package: PHYSBO}, 29 | journal = {Computer Physics Communications}, 30 | volume = {278}, 31 | pages = {108405}, 32 | year = {2022}, 33 | issn = {0010-4655}, 34 | doi = {https://doi.org/10.1016/j.cpc.2022.108405}, 35 | author = {Yuichi Motoyama and Ryo Tamura and Kazuyoshi Yoshimi and Kei Terayama and Tsuyoshi Ueno and Koji Tsuda}, 36 | keywords = {Bayesian optimization, Multi-objective optimization, Materials screening, Effective model estimation} 37 | } 38 | 39 | Main Developers 40 | ---------------------- 41 | 42 | - ver. 1.0- 43 | 44 | - Ryo Tamura (International Center for Materials Nanoarchitectonics, National Institute for Materials Science) 45 | - Tsuyoshi Ueno (Magne-Max Capital Management Company) 46 | - Kei Terayama (Graduate School of Medical Life Science, Yokohama City University) 47 | - Koji Tsuda (Graduate School of Frontier Sciences, The University of Tokyo) 48 | - Yuichi Motoyama (The Institute for Solid State Physics, The University of Tokyo) 49 | - Kazuyoshi Yoshimi (The Institute for Solid State Physics, The University of Tokyo) 50 | - Naoki Kawashima (The Institute for Solid State Physics, The University of Tokyo) 51 | 52 | License 53 | ---------------------- 54 | 55 | PHYSBO v2 is distributed under `the Mozilla Public License version 2.0 (MPL v2) `_. 56 | 57 | Copyright (c) <2020-> The University of Tokyo. All rights reserved. 58 | 59 | Part of this software is developed under the support of "Project for advancement of software usability in materials science" by The Institute for Solid State Physics, The University of Tokyo. 60 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/notebook/index.rst: -------------------------------------------------------------------------------- 1 | Tutorials 2 | ================================== 3 | Here, the usage of PHYSBO is introduced through tutorials. 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | :caption: Contents: 8 | 9 | tutorial_basic 10 | tutorial_Gaussian_process 11 | tutorial_interactive_mode 12 | tutorial_once_mode 13 | tutorial_multi_probe 14 | tutorial_multi_objective 15 | -------------------------------------------------------------------------------- /docs/sphinx/manual/en/source/notebook/tutorial_once_mode.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Restart calculations by reading existing calculation results\n", 8 | "\n", 9 | "You can read existing action IDs (parameters) and their evaluation values and run PHYSBO in the following flow. \n", 10 | "\n", 11 | "1. Load an external file and read the existing action IDs (parameters) and their evaluation values. \n", 12 | "2. Register the action ID (parameter) and evaluation value to PHYSBO. \n", 13 | "3. Get the parameters for the next execution from PHYSBO.\n", 14 | "\n", 15 | "This can be used in cases where PHYSBO cannot be left open for a long time due to time constraints, and thus cannot be executed interactively.\n", 16 | "\n", 17 | "## Prepare the search candidate data\n", 18 | "\n", 19 | "As the previous tutorials, save the dataset file [s5-210.csv](https://raw.githubusercontent.com/issp-center-dev/PHYSBO/master/examples/grain_bound/data/s5-210.csv) into the subdirectory `data`, and load dataset from this file as the following:" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": { 26 | "ExecuteTime": { 27 | "end_time": "2020-12-04T06:17:28.657314Z", 28 | "start_time": "2020-12-04T06:17:27.967614Z" 29 | } 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "import physbo\n", 34 | "\n", 35 | "import numpy as np\n", 36 | "\n", 37 | "\n", 38 | "def load_data():\n", 39 | " A = np.asarray(np.loadtxt('data/s5-210.csv',skiprows=1, delimiter=',') )\n", 40 | " X = A[:,0:3]\n", 41 | " t = -A[:,3]\n", 42 | " return X, t\n", 43 | "\n", 44 | "X, t = load_data()\n", 45 | "X = physbo.misc.centering(X)" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "## Preparing the precomputed data\n", 53 | "\n", 54 | "In the `load_data` function above, all X and t are stored. Here, as precomputed, we get a random list of 20 actoin IDs and their evaluation values." 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 4, 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "[12623, 13781, 1326, 8484, 16753, 15922, 13268, 9938, 15617, 11732, 7157, 16537, 4563, 9235, 4579, 3107, 8208, 17451, 4815, 10162]\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "import random\n", 72 | "random.seed(0)\n", 73 | "calculated_ids = random.sample(range(t.size), 20)\n", 74 | "print(calculated_ids)\n", 75 | "t_initial = t[calculated_ids]" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "## Register action ID (parameter) and evaluation value to PHYSBO.\n", 83 | "\n", 84 | "Register `calculated_ids` and `t[calculated_ids]` as a list in the initial variable `initial_data` of policy." 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 5, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "# set policy \n", 94 | "policy = physbo.search.discrete.policy(test_X=X, initial_data=[calculated_ids, t_initial])\n", 95 | "\n", 96 | "# set seed \n", 97 | "policy.set_seed( 0 )" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "## Get the next parameter to be executed from PHYSBO\n", 105 | "\n", 106 | "Perform Bayesian optimization to obtain the next candidate point." 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 6, 112 | "metadata": { 113 | "ExecuteTime": { 114 | "end_time": "2020-12-04T06:17:28.674407Z", 115 | "start_time": "2020-12-04T06:17:28.669875Z" 116 | } 117 | }, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "Start the initial hyper parameter searching ...\n", 124 | "Done\n", 125 | "\n", 126 | "Start the hyper parameter learning ...\n", 127 | "0 -th epoch marginal likelihood -20.09302189053099\n", 128 | "50 -th epoch marginal likelihood -23.11964735598211\n", 129 | "100 -th epoch marginal likelihood -24.83020118385076\n", 130 | "150 -th epoch marginal likelihood -25.817906570042602\n", 131 | "200 -th epoch marginal likelihood -26.42342027124426\n", 132 | "250 -th epoch marginal likelihood -26.822598600211865\n", 133 | "300 -th epoch marginal likelihood -27.10872736571494\n", 134 | "350 -th epoch marginal likelihood -27.331572599126865\n", 135 | "400 -th epoch marginal likelihood -27.517235815448124\n", 136 | "450 -th epoch marginal likelihood -27.67892333553869\n", 137 | "500 -th epoch marginal likelihood -27.82299469827059\n", 138 | "Done\n", 139 | "\n", 140 | "[73] [[-1.6680279 -1.46385011 1.68585446]]\n" 141 | ] 142 | } 143 | ], 144 | "source": [ 145 | "actions = policy.bayes_search(max_num_probes=1, simulator=None, score=\"TS\", interval=0, num_rand_basis = 5000)\n", 146 | "print(actions, X[actions])" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "Perform external calculations on the obtained candidate points, and register the actions and their scores in a file. The process of reading the file again, running the Bayesian optimization, and obtaining the next candidate point is repeated to advance the Bayesian optimization." 154 | ] 155 | } 156 | ], 157 | "metadata": { 158 | "kernelspec": { 159 | "display_name": "Python 3", 160 | "language": "python", 161 | "name": "python3" 162 | }, 163 | "language_info": { 164 | "codemirror_mode": { 165 | "name": "ipython", 166 | "version": 3 167 | }, 168 | "file_extension": ".py", 169 | "mimetype": "text/x-python", 170 | "name": "python", 171 | "nbconvert_exporter": "python", 172 | "pygments_lexer": "ipython3", 173 | "version": "3.8.5" 174 | } 175 | }, 176 | "nbformat": 4, 177 | "nbformat_minor": 1 178 | } 179 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | sh ./scan.sh 21 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -t "tag-$@" $(SPHINXOPTS) $(O) 22 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/scan.sh: -------------------------------------------------------------------------------- 1 | rm -rf source/api 2 | rm -rf build/doctrees 3 | sphinx-apidoc -f -e -o source/api ../../../../physbo 4 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/.gitignore: -------------------------------------------------------------------------------- 1 | api -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/acknowledgement.rst: -------------------------------------------------------------------------------- 1 | *************************** 2 | 謝辞 3 | *************************** 4 | PHYSBOは東京大学物性研究所 ソフトウェア高度化プロジェクト (2020 年度) の支援を受け開発されました。この場を借りて感謝します。 5 | 6 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | import sys 18 | import os 19 | 20 | sys.path.insert(0, os.path.abspath("../../../../../physbo")) 21 | 22 | # -- Project information ----------------------------------------------------- 23 | 24 | project = "PHYSBO" 25 | copyright = "2020-, PHYSBO developers" 26 | author = "PHYSBO developers" 27 | 28 | # The short X.Y version. 29 | version = "2.2" 30 | # The full version, including alpha/beta/rc tags. 31 | release = "2.2.0" 32 | 33 | # -- General configuration --------------------------------------------------- 34 | 35 | # Add any Sphinx extension module names here, as strings. They can be 36 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 37 | # ones. 38 | extensions = [ 39 | "sphinx.ext.autodoc", 40 | "sphinx.ext.intersphinx", 41 | "sphinx.ext.todo", 42 | "sphinx.ext.coverage", 43 | "sphinx.ext.mathjax", 44 | "sphinx.ext.ifconfig", 45 | "sphinx.ext.viewcode", 46 | "sphinx.ext.napoleon", 47 | "nbsphinx", 48 | ] 49 | 50 | numfig = True 51 | 52 | # Add any paths that contain templates here, relative to this directory. 53 | templates_path = ["../../_templates"] 54 | 55 | # The language for content autogenerated by Sphinx. Refer to documentation 56 | # for a list of supported languages. 57 | # 58 | # This is also used if you do content translation via gettext catalogs. 59 | # Usually you set "language" from the command line for these cases. 60 | language = "ja" 61 | 62 | # List of patterns, relative to source directory, that match files and 63 | # directories to ignore when looking for source files. 64 | # This pattern also affects html_static_path and html_extra_path. 65 | exclude_patterns = ["_build", "**.ipynb_checkpoints"] 66 | for t in ("tag-latex", "tag-latexpdf", "tag-latexpdfja"): 67 | if t in tags: 68 | exclude_patterns.append("api") 69 | 70 | # The suffix of source filenames. 71 | source_suffix = [".rst", ".md"] 72 | 73 | from recommonmark.parser import CommonMarkParser 74 | 75 | source_parsers = { 76 | ".md": CommonMarkParser, 77 | } 78 | 79 | pygments_style = "sphinx" 80 | 81 | nbsphinx_execute = "never" 82 | 83 | # -- Options for HTML output ------------------------------------------------- 84 | 85 | # The theme to use for HTML and HTML Help pages. See the documentation for 86 | # a list of builtin themes. 87 | # 88 | # html_theme = "alabaster" 89 | html_theme = "sphinx_rtd_theme" 90 | html_log = "logo.png" 91 | html_theme_options = {"logo_only": True} 92 | 93 | # Add any paths that contain custom static files (such as style sheets) here, 94 | # relative to this directory. They are copied after the builtin static files, 95 | # so a file named "default.css" will overwrite the builtin "default.css". 96 | html_static_path = ["../../_static"] 97 | 98 | master_doc = "index" 99 | 100 | # Grouping the document tree into LaTeX files. List of tuples 101 | # (source start file, target name, title, 102 | # author, documentclass [howto, manual, or own class]). 103 | latex_engine = 'uplatex' 104 | # latex_docclass = {"manual": "jsbook"} 105 | latex_logo = "../../_static/logo.png" 106 | 107 | 108 | # -- configuring _template/version.html ------------------------------------- 109 | 110 | html_context = {} 111 | 112 | html_context["ENABLE_VERSIONING"] = os.environ.get("CI", "false") 113 | 114 | html_context["languages"] = [("en"), ("ja")] 115 | html_context["current_lang"] = language 116 | 117 | current_version = os.environ.get("TARGET_NAME", "") 118 | if not current_version: 119 | current_version = release 120 | html_context["current_version"] = current_version 121 | 122 | html_context["branches"] = ["develop", "master"] 123 | html_context["tags"] = [] 124 | exclude_tags = ["v0.1.0", "v0.2.0", "v0.3.0"] 125 | 126 | try: 127 | import git 128 | 129 | repo = git.Repo(search_parent_directories=True) 130 | tags = list(map(str, repo.tags)) 131 | tags.sort(reverse=True) 132 | for tag in tags: 133 | if tag not in exclude_tags: 134 | html_context["tags"].append(tag) 135 | except: 136 | pass 137 | 138 | if current_version not in html_context["branches"]: 139 | if current_version not in html_context["tags"]: 140 | html_context["branches"].append(current_version) 141 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/contact.rst: -------------------------------------------------------------------------------- 1 | お問い合わせ 2 | ========================================= 3 | 4 | PHYSBO に関するお問い合わせはこちらにお寄せください。 5 | 6 | - バグ報告 7 | 8 | PHYSBO のバグ関連の報告は `GitHubのIssues `_ で受け付けています。 9 | 10 | バグを早期に解決するため、報告時には次のガイドラインに従ってください。 11 | 12 | - 使用している PHYSBO のバージョンを指定してください。 13 | 14 | - インストールに問題がある場合には、使用しているオペレーティングシステムとコンパイラの情報についてお知らせください。 15 | 16 | - 実行に問題が生じた場合は、実行に使用した入力ファイルとその出力を記載してください。 17 | 18 | - その他 19 | 20 | 研究に関連するトピックなどGitHubのIssuesで相談しづらいことを問い合わせる際には、以下の連絡先にコンタクトをしてください。 21 | 22 | E-mail: ``physbo-dev__at__issp.u-tokyo.ac.jp`` (_at_を@に変更してください) 23 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/index.rst: -------------------------------------------------------------------------------- 1 | .. PHYSBO documentation master file, created by 2 | sphinx-quickstart on Tue May 26 18:44:52 2020. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to PHYSBO's documentation! 7 | ================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | introduction 14 | install 15 | notebook/index 16 | algorithm 17 | API Reference 18 | acknowledgement 19 | contact 20 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/install.rst: -------------------------------------------------------------------------------- 1 | 基本的な使用方法 2 | ===================== 3 | 4 | インストール 5 | --------------------- 6 | 7 | 実行環境・必要なパッケージ 8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 | PHYSBOの実行環境・必要なパッケージは以下の通りです。 10 | 11 | * Python >= 3.6 12 | * numpy < 2.0.0 13 | * scipy 14 | 15 | 16 | .. `Anaconda `_ 環境を利用すると、numpy, scipy, Cython がデフォルトでインストールされているため、COMBO をすぐに実行することが可能です。 17 | 依存パッケージを手動でインストールする場合は、以下の手順によりまとめてインストールすることができます。 18 | 19 | #. 以下をコピーして、'requirements.txt' というファイル名で保存します (setup.py と同じディレクトリ内に保存します) :: 20 | 21 | ## To install these requirements, run 22 | ## pip install -U -r requirements.txt 23 | ## (the -U option also upgrades packages; from the second time on, 24 | ## just run 25 | ## pip install -r requirements.txt 26 | ## 27 | ## NOTE: before running the command above, you need to install a recent version 28 | ## of pip from the website, and then possibly install/upgrade setuptools using 29 | ## sudo pip install --upgrade setuptools 30 | ## numpy 31 | numpy >=1.10 32 | 33 | ## scipy 34 | scipy >= 0.16 35 | 36 | ## 37 | Cython >= 0.22.1 38 | 39 | ## mpi4py 40 | mpi4py >= 2.0 (optional) 41 | 42 | #. 以下のコマンドを実行します。 :: 43 | 44 | > pip install -U -r requirements.txt 45 | 46 | ダウンロード・インストール 47 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 48 | 49 | - ``PyPI`` からのインストール(推奨) :: 50 | 51 | $ pip3 install physbo 52 | 53 | - NumPy などの依存パッケージも同時にインストールされます。 54 | 55 | - ``--user`` オプションを追加するとユーザのホームディレクトリ以下にインストールされます。 :: 56 | 57 | $ pip3 install --user physbo 58 | 59 | 60 | - ソースコードからのインストール(開発者向け) 61 | 62 | #. 本体のダウンロード 63 | 64 | ソースファイルをダウンロードするか、以下のように github レポジトリをクローンしてください。 :: 65 | 66 | $ git clone https://github.com/issp-center-dev/PHYSBO 67 | 68 | #. pip を 19.0 以上に更新 :: 69 | 70 | $ pip3 install -U pip 71 | 72 | - ここで ``pip3`` が入っていない場合には ``python3 -m ensurepip`` でインストール可能です 73 | 74 | #. インストール :: 75 | 76 | $ cd PHYSBO 77 | $ pip3 install --user ./ 78 | 79 | アンインストール 80 | ~~~~~~~~~~~~~~~~~~~~~~~~ 81 | 82 | #. 以下のコマンドを実行します。 :: 83 | 84 | $ pip uninstall physbo 85 | 86 | 87 | PHYSBOの基本構造 88 | -------------------------- 89 | 90 | PHYSBOは以下のような構成になっています(第2階層まで表示)。 91 | 92 | .. 93 | |--physbo 94 | | |--blm 95 | | |--gp 96 | | |--misc 97 | | |--opt 98 | | |--search 99 | | |--predictor.py 100 | | |--variable.py 101 | 102 | 各モジュールは以下のような構成で作成されています。 103 | 104 | - ``blm`` :Baysean linear modelに関するモジュール 105 | - ``gp`` :Gaussian Processに関するモジュール 106 | - ``opt`` :最適化に関するモジュール 107 | - ``search`` :最適解を探索するためのモジュール 108 | - ``predictor.py`` :predictorの抽象クラス 109 | - ``variable.py`` :physboで用いる変数関連について定義されたクラス 110 | - ``misc`` : その他(探索空間を正規化するためのモジュールなど) 111 | 112 | 各モジュールの詳細についてはAPIリファレンスを参考にしてください。 113 | 114 | 計算の流れ 115 | -------------------------- 116 | 117 | ベイズ最適化は、複雑なシミュレーションや、実世界における実験タスクなど、目的関数の評価に大きなコストがかかるような最適化問題に適しています。 118 | PHYSBO では以下の手順により最適化を実行します(それぞれの詳細はチュートリアルおよびAPIリファレンスを参考にしてください)。 119 | 120 | 1. 探索空間の定義 121 | 122 | N: 探索候補の数 , d: 入力パラメータの次元数 とした時、探索候補である各パラメータセット (d 次元のベクトル) を定義します。パラメータセットは全ての候補をリストアップしておく必要があります。 123 | 124 | 2. simulator の定義 125 | 126 | 上で定義した探索候補に対して、各探索候補の目的関数値(材料特性値など最適化したい値)を与えるsimulatorを定義します。PHYSBOでは、最適化の方向は「目的関数の最大化」になります。そのため,目的関数を最小化したい場合、simulatorから返す値にマイナスをかけることで実行できます。 127 | 128 | 3. 最適化の実行 129 | 130 | 最初に、最適化の policy をセットします(探索空間はこの段階で引数としてpolicyに渡されます)。最適化方法は、以下の2種類から選択します。 131 | 132 | - ``random_search`` 133 | - ``bayes_search`` 134 | 135 | ``random_search`` では、探索空間からランダムにパラメータを選び、その中で最大となる目的関数を探します。ベイズ最適化を行うための前処理として初期パラメータ群を用意するために使用します。 ``bayes_search`` は、ベイズ最適化を行います。ベイズ最適化でのscore: 獲得関数(acquisition function) の種類は、以下のいずれかから指定します。 136 | 137 | - TS (Thompson Sampling): 学習されたガウス過程の事後確率分布から回帰関数を1つサンプリングし、それを用いた予測が最大となる点を候補として選択します。 138 | - EI (Expected Improvement): ガウス過程による予測値と現状での最大値との差の期待値が最大となる点を候補として選択します。 139 | - PI (Probability of Improvement): 現状での最大値を超える確率が最大となる点を候補として選択します。 140 | 141 | ガウス過程に関する詳細については :ref:`chap_algorithm` に記載してあります。その他、各手法の詳細については、`こちらの文献 `_ およびその参考文献を参照して下さい。 142 | 143 | これらのメソッドに先ほど定義した simulator と探索ステップ数を指定すると、探索ステップ数だけ以下のループが回ります。 144 | 145 | i). パラメータ候補の中から次に実行するパラメータを選択 146 | 147 | ii). 選択されたパラメータで simulator を実行 148 | 149 | i)で返されるパラメータはデフォルトでは1つですが、1ステップで複数のパラメータを返すことも可能です。詳しくはチュートリアルの「複数候補を一度に探索する」の項目を参照してください。また、上記のループを PHYSBO の中で回すのではなく、i) と ii) を別個に外部から制御することも可能です。つまり、PHYSBO から次に実行するパラメータを提案し、その目的関数値をPHYSBOの外部で何らかの形で評価し(例えば、数値計算ではなく、実験による評価など)、それをPHYSBOの外部で何らかの形で提案し、評価値をPHYSBOに登録する、という手順が可能です。詳しくは、チュートリアルの「インタラクティブに実行する」の項目を参照してください。 150 | 151 | 152 | 4. 結果の確認 153 | 154 | 探索結果 res は history クラスのオブジェクト (physbo.search.discrete.results.history) として返されます。以下より探索結果を参照します。 155 | 156 | - res.fx : simulator (目的関数) の評価値の履歴。 157 | - res.chosen_actions: simulator を評価したときのaction ID(パラメータ)の履歴。 158 | - fbest, best_action= res.export_all_sequence_best_fx(): simulator を評価した全タイミングにおけるベスト値とそのaction ID(パラメータ)の履歴。 159 | - res.total_num_search: simulator のトータル評価数。 160 | 161 | また、探索結果は save メソッドにより外部ファイルに保存でき、load メソッドを用いて出力した結果をロードすることができます。使用方法の詳細はチュートリアルをご覧ください。 162 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/introduction.rst: -------------------------------------------------------------------------------- 1 | はじめに 2 | ===================== 3 | 4 | PHYSBO とは 5 | ---------------------- 6 | 7 | PHYSBO(optimization tool for PHYSics based on Bayesian Optimization)は、高速でスケーラブルなベイズ最適化 (Bayesian optimization) のためのPythonライブラリです。 8 | COMBO(COMmon Baysian Optimization)をもとに、主に物性分野の研究者をターゲットに開発されました。 9 | 物理、化学、材料分野において、データ駆動的な実験計画アルゴリズムによって科学的発見を加速する、という試みが多く行われています。 10 | ベイズ最適化は、このような科学的発見を加速するために有効なツールです。 11 | ベイズ最適化は、複雑なシミュレーションや、実世界における実験タスクなど、目的関数値(特性値など)の評価に大きなコストがかかるような場合に利用できる手法です。つまり、「できるだけ少ない実験・シミュレーション回数でより良い目的関数値(材料特性など)を持つパラメータ(材料の組成、構造、プロセスやシミュレーションパラメータなど)を見つけ出す」ことが、ベイズ最適化によって解かれる問題です。ベイズ最適化では、探索するパラメータの候補をあらかじめリストアップし、候補の中から目的関数値が最大と考えられる候補を機械学習(ガウス過程回帰を利用)による予測をうまく利用することで選定します。その候補に対して実験・シミュレーションを行い目的関数値を評価します。機械学習による選定・実験シミュレーションによる評価を繰り返すことにより、少ない回数での最適化が可能となります。 12 | 一方で、一般的にベイズ最適化は計算コストが高く、scikit-learn 等のスタンダードな実装では、多くのデータを扱うことが困難です。 13 | PHYSBOでは以下の特徴により、高いスケーラビリティを実現しています。 14 | 15 | * Thompson Sampling 16 | * random feature map 17 | * one-rank Cholesky update 18 | * automatic hyperparameter tuning 19 | 20 | 技術的な詳細については、`こちらの文献 `_ を参照して下さい。 21 | 22 | 23 | PHYSBO の引用 24 | ---------------------- 25 | 26 | PHYSBOを引用する際には、以下の文献を引用してください、 27 | 28 | 29 | Yuichi Motoyama, Ryo Tamura, Kazuyoshi Yoshimi, Kei Terayama, Tsuyoshi Ueno, Koji Tsuda, 30 | Bayesian optimization package: PHYSBO, 31 | Computer Physics Communications Volume 278, September 2022, 108405. Available from https://www.sciencedirect.com/science/article/pii/S0010465522001242?via%3Dihub (open access). 32 | 33 | Bibtexは以下の通りです。 :: 34 | 35 | @misc{@article{MOTOYAMA2022108405, 36 | title = {Bayesian optimization package: PHYSBO}, 37 | journal = {Computer Physics Communications}, 38 | volume = {278}, 39 | pages = {108405}, 40 | year = {2022}, 41 | issn = {0010-4655}, 42 | doi = {https://doi.org/10.1016/j.cpc.2022.108405}, 43 | author = {Yuichi Motoyama and Ryo Tamura and Kazuyoshi Yoshimi and Kei Terayama and Tsuyoshi Ueno and Koji Tsuda}, 44 | keywords = {Bayesian optimization, Multi-objective optimization, Materials screening, Effective model estimation} 45 | } 46 | 47 | 主な開発者 48 | ---------------------- 49 | - ver. 1.0- 50 | 51 | - 田村 亮 (物質・材料研究機構 国際ナノアーキテクトニクス研究拠点) 52 | - 寺山 慧 (横浜市立大学大学院 生命医科学研究科) 53 | - 津田 宏治 (東京大学大学院 新領域創成科学研究科) 54 | - 植野 剛 (株式会社 Magne-Max Capital Management) 55 | - 本山 裕一 (東京大学 物性研究所) 56 | - 吉見 一慶 (東京大学 物性研究所) 57 | - 川島 直輝 (東京大学 物性研究所) 58 | 59 | 60 | - ver. 0.1-0.3 61 | 62 | - 田村 亮 (物質・材料研究機構 国際ナノアーキテクトニクス研究拠点) 63 | - 寺山 慧 (横浜市立大学大学院 生命医科学研究科) 64 | - 津田 宏治 (東京大学大学院 新領域創成科学研究科) 65 | - 本山 裕一 (東京大学 物性研究所) 66 | - 吉見 一慶 (東京大学 物性研究所) 67 | - 川島 直輝 (東京大学 物性研究所) 68 | 69 | ライセンス 70 | ---------------------- 71 | 72 | PHYSBO v2 のソースコードは `Mozilla Public License version 2.0(MPL v2) `_ (`日本語訳 `_) のもとで公開・頒布されています。 73 | 74 | Copyright (c) <2020-> The University of Tokyo. All rights reserved. 75 | 76 | 本ソフトウェアは2020年度 東京大学物性研究所 ソフトウェア高度化プロジェクトの支援を受け開発されました。 77 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/notebook/index.rst: -------------------------------------------------------------------------------- 1 | チュートリアル 2 | ================================== 3 | ここでは、PHYSBOのチュートリアルを通してその使用方法を紹介します。 4 | 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | :caption: Contents: 9 | 10 | tutorial_basic 11 | tutorial_Gaussian_process 12 | tutorial_interactive_mode 13 | tutorial_once_mode 14 | tutorial_multi_probe 15 | tutorial_multi_objective 16 | 17 | -------------------------------------------------------------------------------- /docs/sphinx/manual/ja/source/notebook/tutorial_once_mode.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 既存の計算結果を読み込んで実行する\n", 8 | "\n", 9 | "以下の流れで、既存のaction ID(パラメータ)とその評価値を読み込み、PHYSBO を実行することができます。\n", 10 | "\n", 11 | "1. 外部ファイルを読み込み、既存のaction ID(パラメータ)と評価値を読み込む。\n", 12 | "2. action ID(パラメータ)と評価値をPHYSBOに登録する。\n", 13 | "3. PHYSBO から次に実行するパラメータを得る。\n", 14 | "\n", 15 | "時間制限の関係上、PHYSBO をずっと開いたままにできないため、インタラクティブに実行できないといった場合に、利用することができます。\n", 16 | "\n", 17 | "## 探索候補データの準備\n", 18 | "\n", 19 | "これまでのチュートリアルと同様、データセットファイル [s5-210.csv](https://raw.githubusercontent.com/issp-center-dev/PHYSBO/master/examples/grain_bound/data/s5-210.csv) を `data` ディレクトリ以下に保存し、次のように読み出します。" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "metadata": { 26 | "ExecuteTime": { 27 | "end_time": "2020-12-04T06:17:28.657314Z", 28 | "start_time": "2020-12-04T06:17:27.967614Z" 29 | } 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "import physbo\n", 34 | "\n", 35 | "import numpy as np\n", 36 | "\n", 37 | "\n", 38 | "def load_data():\n", 39 | " A = np.asarray(np.loadtxt('data/s5-210.csv',skiprows=1, delimiter=',') )\n", 40 | " X = A[:,0:3]\n", 41 | " t = -A[:,3]\n", 42 | " return X, t\n", 43 | "\n", 44 | "X, t = load_data()\n", 45 | "X = physbo.misc.centering(X)" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "## 事前に計算したデータの用意\n", 53 | "\n", 54 | "上述の `load_data` 関数では全てのXとtが格納されています。ここでは事前に計算したとして、actoin IDのリストをランダムに20個取得し、その評価値を得ます。" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "[12623, 13781, 1326, 8484, 16753, 15922, 13268, 9938, 15617, 11732, 7157, 16537, 4563, 9235, 4579, 3107, 8208, 17451, 4815, 10162]\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "import random\n", 72 | "random.seed(0)\n", 73 | "calculated_ids = random.sample(range(t.size), 20)\n", 74 | "print(calculated_ids)\n", 75 | "t_initial = t[calculated_ids]" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "## action ID(パラメータ)と評価値をPHYSBOに登録\n", 83 | "\n", 84 | "policyの初期変数 `initial_data` に `calculated_ids` と `t[calculated_ids]` をリストとして登録します。" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 3, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "# policy のセット \n", 94 | "policy = physbo.search.discrete.policy(test_X=X, initial_data=[calculated_ids, t_initial])\n", 95 | "\n", 96 | "# シード値のセット \n", 97 | "policy.set_seed( 0 )" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "## PHYSBO から次に実行するパラメータを取得\n", 105 | "\n", 106 | "ベイズ最適化を行い、次の候補点を得ます。" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 4, 112 | "metadata": { 113 | "ExecuteTime": { 114 | "end_time": "2020-12-04T06:17:28.674407Z", 115 | "start_time": "2020-12-04T06:17:28.669875Z" 116 | } 117 | }, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "Start the initial hyper parameter searching ...\n", 124 | "Done\n", 125 | "\n", 126 | "Start the hyper parameter learning ...\n", 127 | "0 -th epoch marginal likelihood -20.09302189053099\n", 128 | "50 -th epoch marginal likelihood -23.11964735598211\n", 129 | "100 -th epoch marginal likelihood -24.83020118385076\n", 130 | "150 -th epoch marginal likelihood -25.817906570042602\n", 131 | "200 -th epoch marginal likelihood -26.42342027124426\n", 132 | "250 -th epoch marginal likelihood -26.822598600211865\n", 133 | "300 -th epoch marginal likelihood -27.10872736571494\n", 134 | "350 -th epoch marginal likelihood -27.331572599126865\n", 135 | "400 -th epoch marginal likelihood -27.517235815448124\n", 136 | "450 -th epoch marginal likelihood -27.67892333553869\n", 137 | "500 -th epoch marginal likelihood -27.82299469827059\n", 138 | "Done\n", 139 | "\n", 140 | "[73] [[-1.6680279 -1.46385011 1.68585446]]\n" 141 | ] 142 | } 143 | ], 144 | "source": [ 145 | "actions = policy.bayes_search(max_num_probes=1, simulator=None, score=\"TS\", interval=0, num_rand_basis = 5000)\n", 146 | "print(actions, X[actions])" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "得られた候補点について外部で計算を行い、ファイルにactionsとそのスコアを登録する。再びファイルを読み込み、ベイズ最適化を実行し次の候補点を得るというプロセスを繰り返すことで、ベイズ最適化を進めることができます。" 154 | ] 155 | } 156 | ], 157 | "metadata": { 158 | "kernelspec": { 159 | "display_name": "Python 3", 160 | "language": "python", 161 | "name": "python3" 162 | }, 163 | "language_info": { 164 | "codemirror_mode": { 165 | "name": "ipython", 166 | "version": 3 167 | }, 168 | "file_extension": ".py", 169 | "mimetype": "text/x-python", 170 | "name": "python", 171 | "nbconvert_exporter": "python", 172 | "pygments_lexer": "ipython3", 173 | "version": "3.8.5" 174 | } 175 | }, 176 | "nbformat": 4, 177 | "nbformat_minor": 1 178 | } 179 | -------------------------------------------------------------------------------- /examples/grain_bound/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *~ 3 | build/ 4 | installed 5 | .pyc 6 | .ipynb_checkpoints 7 | BLM_EI 8 | BLM_TS 9 | GP_EI 10 | random 11 | res 12 | data 13 | describe_graph.ipynb 14 | run_random.py 15 | script.py 16 | script_random.py 17 | -------------------------------------------------------------------------------- /examples/multiple.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import itertools 9 | 10 | import numpy as np 11 | import physbo 12 | 13 | # Make a set of candidates, test_X 14 | D = 2 # The number of params (the dimension of parameter space) 15 | Nx = 11 # The number of candidates 16 | N = Nx * Nx 17 | 18 | # score = "HVPI" 19 | score = "EHVI" 20 | 21 | a = np.linspace(-2, 2, Nx) 22 | test_X = np.array(list(itertools.product(a, a))) 23 | 24 | 25 | def vlmop2_minus(x): 26 | n = x.shape[1] 27 | y1 = 1 - np.exp(-1 * np.sum((x - 1 / np.sqrt(n)) ** 2, axis=1)) 28 | y2 = 1 - np.exp(-1 * np.sum((x + 1 / np.sqrt(n)) ** 2, axis=1)) 29 | 30 | return np.c_[-y1, -y2] 31 | 32 | 33 | class simulator(object): 34 | def __init__(self, X): 35 | self.t = vlmop2_minus(X) 36 | 37 | def __call__(self, action): 38 | return self.t[action] 39 | 40 | 41 | sim = simulator(test_X) 42 | 43 | policy = physbo.search.discrete_multi.policy(test_X, num_objectives=2) 44 | policy.set_seed(0) 45 | # Random search (10 times) 46 | policy.random_search(max_num_probes=10, simulator=sim) 47 | 48 | # Bayesian search (40 times) 49 | # score function (acquition function): expectation of improvement (EI) 50 | policy.bayes_search(max_num_probes=40, simulator=sim, score=score, interval=0) 51 | 52 | print("Pareto fronts:") 53 | res = policy.history 54 | front, front_index = res.export_pareto_front() 55 | for fr, ifr in zip(front, front_index): 56 | print(" action: ", ifr) 57 | print(" X: ", test_X[ifr, :]) 58 | print(" f: ", fr) 59 | print() 60 | -------------------------------------------------------------------------------- /examples/multiple_score.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import itertools 9 | 10 | import numpy as np 11 | import physbo 12 | 13 | # Make a set of candidates, test_X 14 | D = 2 # The number of params (the dimension of parameter space) 15 | Nx = 11 # The number of candidates 16 | N = Nx * Nx 17 | 18 | # score = "HVPI" 19 | score = "EHVI" 20 | 21 | a = np.linspace(-2, 2, Nx) 22 | test_X = np.array(list(itertools.product(a, a))) 23 | 24 | 25 | def vlmop2_minus(x): 26 | n = x.shape[1] 27 | y1 = 1 - np.exp(-1 * np.sum((x - 1 / np.sqrt(n)) ** 2, axis=1)) 28 | y2 = 1 - np.exp(-1 * np.sum((x + 1 / np.sqrt(n)) ** 2, axis=1)) 29 | 30 | return np.c_[-y1, -y2] 31 | 32 | 33 | class simulator(object): 34 | def __init__(self, X): 35 | self.t = vlmop2_minus(X) 36 | 37 | def __call__(self, action): 38 | return self.t[action] 39 | 40 | 41 | sim = simulator(test_X) 42 | 43 | policy = physbo.search.discrete_multi.policy(test_X, num_objectives=2) 44 | policy.set_seed(0) 45 | # Random search (10 times) 46 | policy.random_search(max_num_probes=10, simulator=sim) 47 | 48 | # Bayesian search (40 times) 49 | # score function (acquisition function): expectation of improvement (EI) 50 | policy.bayes_search(max_num_probes=40, simulator=sim, score=score, interval=0) 51 | 52 | print("Mean values of prediction") 53 | scores = policy.get_post_fmean(xs=test_X) 54 | print(scores) 55 | print() 56 | 57 | print("Standard deviations of prediction") 58 | scores = policy.get_post_fcov(xs=test_X) 59 | print(np.sqrt(scores)) 60 | print() 61 | 62 | print("Acquisition function") 63 | scores = policy.get_score(mode=score, xs=test_X) 64 | print(scores) 65 | -------------------------------------------------------------------------------- /examples/sfs.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import physbo 3 | from physbo.misc import set_config 4 | from mlxtend.feature_selection import SequentialFeatureSelector as SFS 5 | import matplotlib.pyplot as plt 6 | 7 | 8 | # 1. Generate data 9 | def generate_data(n_samples=2000, n_features=5): 10 | """Generate artificial dataset""" 11 | # Generate features 12 | X = np.random.uniform(-10, 10, (n_samples, n_features)) 13 | 14 | # Define objective function 15 | def target_function(x): 16 | # Function where x1, x2, x5 are important features 17 | return ( 18 | (100 - x[4]) ** 2 19 | + (10 - x[0]) ** 2 20 | + (1 - x[1]) ** 2 21 | + x[3] 22 | + (1000 - x[0] * x[1]) 23 | + np.random.normal(0, 1) 24 | ) 25 | 26 | # Calculate target variable 27 | y = np.array([target_function(x) for x in X]) 28 | 29 | return X, y 30 | 31 | 32 | # 2. GP model setup 33 | def setup_gp_model(input_dim): 34 | """Setup GP model""" 35 | # Set kernel (covariance function) 36 | cov = physbo.gp.cov.gauss(input_dim, ard=False) 37 | 38 | # Set mean function 39 | mean = physbo.gp.mean.const() 40 | 41 | # Set likelihood function 42 | lik = physbo.gp.lik.gauss() 43 | 44 | # Prepare configuration 45 | config = set_config() 46 | 47 | # Create GP model 48 | gp = physbo.gp.sfs(lik=lik, mean=mean, cov=cov, config=config) 49 | 50 | return gp 51 | 52 | 53 | def main(): 54 | # 1. Generate data 55 | X, y = generate_data() 56 | print("Dataset shape:", X.shape) 57 | 58 | # 2. Setup GP model 59 | gp = setup_gp_model(X.shape[1]) 60 | 61 | # 3. Configure Sequential Feature Selector 62 | sfs = SFS( 63 | estimator=gp, 64 | k_features=3, # Number of features to select 65 | forward=True, # Use forward selection 66 | floating=True, # Use Floating search 67 | scoring="r2", # Evaluation metric 68 | cv=3, # Number of cross-validation splits 69 | n_jobs=-1, # Number of parallel jobs 70 | ) 71 | 72 | # 4. Execute feature selection 73 | sfs.fit(X, y) 74 | 75 | # 5. Display results 76 | print("\nSelected features:") 77 | print(sfs.subsets_) 78 | 79 | # 6. Visualize results 80 | plt.figure(figsize=(10, 6)) 81 | from mlxtend.plotting import plot_sequential_feature_selection as plot_sfs 82 | 83 | fig = plot_sfs(sfs.get_metric_dict(), kind="std_err") 84 | plt.title("Sequential Forward Selection (w/ SFFS)") 85 | plt.grid() 86 | plt.show() 87 | 88 | 89 | if __name__ == "__main__": 90 | main() 91 | -------------------------------------------------------------------------------- /examples/simple.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | import physbo 10 | 11 | # Make a set of candidates, test_X 12 | D = 3 # The number of params (the dimension of parameter space) 13 | N = 1000 # The number of candidates 14 | test_X = np.random.randn(N, D) # Generated from Gaussian 15 | test_X[0, :] = 0.0 # true solution 16 | 17 | 18 | def simulator(actions: np.ndarray) -> np.ndarray: 19 | """Objective function 20 | 21 | Quadratic function, -Σ_i x_i^2 22 | Receives an array of actions (indices of candidates) and returns the corresponding results as an array 23 | """ 24 | return -np.sum(test_X[actions, :] ** 2, axis=1) 25 | 26 | 27 | policy = physbo.search.discrete.policy(test_X) 28 | policy.set_seed(12345) 29 | 30 | # Random search (10 times) 31 | policy.random_search(max_num_probes=10, simulator=simulator) 32 | 33 | # Bayesian search (40 times) 34 | # score function (acquition function): expectation of improvement (EI) 35 | policy.bayes_search(max_num_probes=40, simulator=simulator, score="EI") 36 | 37 | # Print the best result 38 | # best_actions[i] and best_fx[i] stores the best action and value up to the i-th search (random + bayes) 39 | best_fx, best_actions = policy.history.export_sequence_best_fx() 40 | print(f"best_fx: {best_fx[-1]} at {test_X[best_actions[-1], :]}") 41 | -------------------------------------------------------------------------------- /examples/simple_score.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | import physbo 10 | 11 | # Make a set of candidates, test_X 12 | D = 3 # The number of params (the dimension of parameter space) 13 | N = 100 # The number of candidates 14 | test_X = np.random.randn(N, D) # Generated from Gaussian 15 | test_X[0, :] # true solution 16 | score = "EI" 17 | 18 | 19 | def simulator(actions: np.ndarray) -> np.ndarray: 20 | """Objective function 21 | 22 | Quadratic function, -Σ_i x_i^2 23 | Receives an array of actions (indices of candidates) and returns the corresponding results as an array 24 | """ 25 | return -np.sum(test_X[actions, :] ** 2, axis=1) 26 | 27 | 28 | policy = physbo.search.discrete.policy(test_X) 29 | policy.set_seed(12345) 30 | 31 | # Random search (10 times) 32 | policy.random_search(max_num_probes=10, simulator=simulator) 33 | 34 | # Bayesian search (40 times) 35 | # score function (acquisition function): expectation of improvement (EI) 36 | policy.bayes_search(max_num_probes=40, simulator=simulator, score=score) 37 | 38 | print("Mean values of prediction") 39 | scores = policy.get_post_fmean(xs=test_X) 40 | print(scores) 41 | print() 42 | 43 | print("Standard deviations of prediction") 44 | scores = policy.get_post_fcov(xs=test_X) 45 | print(np.sqrt(scores)) 46 | print() 47 | 48 | print("Acquisition function") 49 | scores = policy.get_score(mode=score, xs=test_X) 50 | print(scores) 51 | -------------------------------------------------------------------------------- /examples/simple_time.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | ### This example describes how to save elapsed time 9 | 10 | 11 | import numpy as np 12 | import matplotlib.pyplot as plt 13 | import physbo 14 | 15 | 16 | # Make a set of candidates, test_X 17 | D = 3 # The number of params (the dimension of parameter space) 18 | N = 1000 # The number of candidates 19 | test_X = np.random.randn(N, D) # Generated from Gaussian 20 | test_X[0, :] = 0.0 # true solution 21 | 22 | 23 | def simulator(actions: np.ndarray) -> np.ndarray: 24 | """Objective function 25 | 26 | Quadratic function, -Σ_i x_i^2 27 | Receives an array of actions (indices of candidates) and returns the corresponding results as an array 28 | """ 29 | return -np.sum(test_X[actions, :] ** 2, axis=1) 30 | 31 | 32 | policy = physbo.search.discrete.policy(test_X) 33 | policy.set_seed(12345) 34 | 35 | # Random search (10 times) 36 | policy.random_search(max_num_probes=10, simulator=simulator) 37 | 38 | # Bayesian search (40 times) 39 | # score function (acquition function): expectation of improvement (EI) 40 | policy.bayes_search(max_num_probes=40, simulator=simulator, score="EI") 41 | 42 | # Print the best result 43 | # best_actions[i] and best_fx[i] stores the best action and value up to the i-th search (random + bayes) 44 | best_fx, best_actions = policy.history.export_sequence_best_fx() 45 | print(f"best_fx: {best_fx[-1]} at {test_X[best_actions[-1], :]}") 46 | 47 | fig, ax = plt.subplots() 48 | ax.plot(policy.history.time_total, marker="o") 49 | fig.savefig("time_total.pdf") 50 | ax.clear() 51 | 52 | ax.plot(policy.history.time_update_predictor, marker="o") 53 | fig.savefig("time_update_predictor.pdf") 54 | ax.clear() 55 | 56 | ax.plot(policy.history.time_get_action, marker="o") 57 | fig.savefig("time_get_action.pdf") 58 | ax.clear() 59 | 60 | ax.plot(policy.history.time_run_simulator, marker="o") 61 | fig.savefig("time_run_simulator.pdf") 62 | ax.clear() 63 | -------------------------------------------------------------------------------- /make_wheels.sh: -------------------------------------------------------------------------------- 1 | # This file is for the package maintainer 2 | 3 | rm -rf build dist *.egg-info 4 | 5 | ret=0 6 | python setup.py sdist || ret=$? 7 | echo 8 | echo 9 | 10 | if [ $ret -ne 0 ];then 11 | echo "Failed to make source distribution" 12 | exit 1 13 | fi 14 | python setup.py bdist_wheel || ret=$? 15 | 16 | echo 17 | echo 18 | 19 | if [ $ret -ne 0 ];then 20 | echo "Failed to make platform wheel" 21 | exit 1 22 | fi 23 | 24 | echo 'To upload to PyPI:' 25 | echo 'twine upload --repository pypi dist/*' 26 | -------------------------------------------------------------------------------- /physbo/.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | .idea 3 | -------------------------------------------------------------------------------- /physbo/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from . import gp 9 | from . import opt 10 | from . import blm 11 | from . import misc 12 | from . import search 13 | from . import predictor 14 | from .predictor import base_predictor 15 | from .variable import variable 16 | 17 | __version__ = "2.2.0" 18 | -------------------------------------------------------------------------------- /physbo/blm/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | """ Bayesian Linear Model 9 | """ 10 | 11 | from . import basis 12 | from . import prior 13 | from . import lik 14 | from . import inf 15 | 16 | from .core import model 17 | from .predictor import predictor 18 | -------------------------------------------------------------------------------- /physbo/blm/basis/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .fourier import fourier 9 | -------------------------------------------------------------------------------- /physbo/blm/basis/fourier.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | # -*- coding:utf-8 -*- 9 | import numpy as np 10 | 11 | 12 | class fourier: 13 | """ 14 | random feature maps 15 | ``Psi(X; W,b) = cos[X * Wt + b] * alpha`` 16 | where 17 | 18 | - X: input, N-by-d matrix 19 | - W: weight, l-by-d matrix 20 | - Wt: transpose of W 21 | - b: bias, 1-by-l matrix 22 | - alpha: coefficient 23 | 24 | and 25 | 26 | - N: number of data 27 | - d: dimension of input 28 | - l: number of basis 29 | 30 | Attributes 31 | ========== 32 | params: Tuple 33 | W, b, alpha 34 | nbasis: int 35 | number of basis 36 | 37 | References 38 | ========== 39 | A. Rahimi and B. Recht, "Random features for large-scale kernel machines," 40 | in "Advances in neural information processing systems," 2007, pp. 1177-1184. 41 | """ 42 | 43 | def __init__(self, params): 44 | """ 45 | Parameters 46 | ---------- 47 | params: Tuple 48 | W, b, alpha 49 | """ 50 | self._check_params(params) 51 | self._check_len_params(params) 52 | self.params = params 53 | self.nbasis = self.params[1].shape[0] 54 | 55 | def get_basis(self, X, params=None): 56 | """ 57 | compute the value of basis 58 | 59 | Parameters 60 | ========== 61 | X: numpy.ndarray 62 | input 63 | params: Tuple 64 | W, b, alpha 65 | (default: self.params) 66 | 67 | Returns 68 | ======= 69 | Psi(X; W,b): numpy.ndarray 70 | N-by-l matrix 71 | 72 | ``cos[X * Wt + b] * alpha`` 73 | 74 | where ``Wt`` is the transpose of ``W``. 75 | """ 76 | if params is None: 77 | params = self.params 78 | 79 | self._check_params(params) 80 | self._check_len_params(params) 81 | 82 | return np.cos(np.dot(X, params[0].transpose()) + params[1]) * params[2] 83 | 84 | def set_params(self, params): 85 | """ 86 | update basis parameters 87 | 88 | Parameters 89 | ========== 90 | params: tuple 91 | W, b, alpha 92 | 93 | """ 94 | self._check_params(params) 95 | self._check_len_params(params) 96 | self.params = params 97 | 98 | def show(self): 99 | """ 100 | print parameters 101 | """ 102 | print("W = ", self.params[0]) 103 | print("b = ", self.params[1]) 104 | print("alpha = ", self.params[2]) 105 | 106 | def _check_params(self, params): 107 | """ 108 | Parameters 109 | ========== 110 | params: tuple 111 | W, b, alpha 112 | 113 | Raises 114 | ====== 115 | ValueError 116 | if ``params`` is not a 3-dimensional tuple 117 | """ 118 | if not isinstance(params, tuple): 119 | raise ValueError("The variable < params > must be a tuple.") 120 | 121 | if len(params) != 3: 122 | raise ValueError("The variable < params > must be 3-dimensional tuple.") 123 | 124 | def _check_len_params(self, params): 125 | """ 126 | Parameters 127 | ========== 128 | params: tuple 129 | W, b, alpha 130 | 131 | 132 | Raises 133 | ====== 134 | ValueError 135 | when dim of W and b are mismatch 136 | or alpha is not a scalar 137 | """ 138 | if params[0].shape[0] != params[1].shape[0]: 139 | raise ValueError( 140 | "The length of 0-axis of W must be same as the length of b." 141 | ) 142 | 143 | if hasattr(params[2], "__len__"): 144 | if len(params[2]) != 1: 145 | raise ValueError("The third entry of must be a scalar.") 146 | else: 147 | if isinstance(params[2], str): 148 | raise ValueError("The third entry of must be a scalar.") 149 | -------------------------------------------------------------------------------- /physbo/blm/core/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .model import model 9 | -------------------------------------------------------------------------------- /physbo/blm/inf/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from . import exact 9 | -------------------------------------------------------------------------------- /physbo/blm/inf/exact.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | import scipy 10 | 11 | import physbo.misc as misc 12 | 13 | 14 | def prepare(blm, X, t, Psi=None): 15 | """ 16 | initializes auxiaialy parameters for quick sampling 17 | 18 | ``blm.stats`` will be updated. 19 | 20 | Parameters 21 | ========== 22 | blm: physbo.blm.core.model 23 | model 24 | X: numpy.ndarray 25 | inputs 26 | t: numpy.ndarray 27 | target (label) 28 | Psi: 29 | feature maps (default: blm.lik.get_basis(X)) 30 | """ 31 | if Psi is None: 32 | Psi = blm.lik.get_basis(X) 33 | PsiT = Psi.transpose() 34 | G = np.dot(PsiT, Psi) * blm.lik.cov.prec 35 | A = G + blm.prior.get_prec() 36 | U = scipy.linalg.cholesky(A, check_finite=False) 37 | b = PsiT.dot(t - blm.lik.linear.bias) 38 | alpha = misc.gauss_elim(U, b) 39 | blm.stats = (U, b, alpha) 40 | 41 | 42 | def update_stats(blm, x, t, psi=None): 43 | """ 44 | calculates new auxiaialy parameters for quick sampling by fast-update 45 | 46 | Parameters 47 | ========== 48 | blm: physbo.blm.core.model 49 | model 50 | x: numpy.ndarray 51 | input 52 | t: numpy.ndarray 53 | target (label) 54 | psi: 55 | feature map (default: blm.lik.get_basis(X)) 56 | 57 | Returns 58 | ======= 59 | (U, b, alpha): Tuple 60 | new auxially parameters 61 | 62 | Notes 63 | ===== 64 | ``blm.stats[0]`` (U) will be mutated while the others not. 65 | """ 66 | if psi is None: 67 | psi = blm.lik.get_basis(x) 68 | U = blm.stats[0] 69 | b = blm.stats[1] + (t - blm.lik.linear.bias) * psi 70 | misc.cholupdate(U, psi * np.sqrt(blm.lik.cov.prec)) 71 | alpha = misc.gauss_elim(U, b) 72 | return (U, b, alpha) 73 | 74 | 75 | def sampling(blm, w_mu=None, N=1, alpha=1.0): 76 | """ 77 | draws samples of weights 78 | 79 | Parameters 80 | ========== 81 | blm: physbo.blm.core.model 82 | model 83 | w_mu: numpy.ndarray 84 | mean of weight 85 | N: int 86 | the number of samples 87 | (default: 1) 88 | alpha: float 89 | noise for sampling source 90 | (default: 1.0) 91 | 92 | Returns 93 | ======= 94 | numpy.ndarray 95 | samples of weights 96 | """ 97 | if w_mu is None: 98 | w_mu = get_post_params_mean(blm) 99 | if N == 1: 100 | z = np.random.randn(blm.nbasis) * alpha 101 | else: 102 | z = np.random.randn(blm.nbasis, N) * alpha 103 | 104 | U = blm.stats[0] 105 | invUz = scipy.linalg.solve_triangular( 106 | U, z, lower=False, overwrite_b=False, check_finite=False 107 | ) 108 | return (invUz.transpose() + w_mu).transpose() 109 | 110 | 111 | def get_post_params_mean(blm): 112 | """ 113 | calculates mean of weight 114 | 115 | Parameters 116 | ========== 117 | blm: physbo.blm.core.model 118 | 119 | Returns 120 | ======= 121 | numpy.ndarray 122 | """ 123 | return blm.stats[2] * blm.lik.cov.prec 124 | 125 | 126 | def get_post_fmean(blm, X, Psi=None, w=None): 127 | """ 128 | calculates posterior mean of model 129 | 130 | Parameters 131 | ========== 132 | blm: physbo.blm.core.model 133 | X: numpy.ndarray 134 | inputs 135 | Psi: numpy.ndarray 136 | feature maps 137 | (default: blm.lik.linear.basis.get_basis(X)) 138 | w: numpy.ndarray 139 | weights 140 | (default: get_post_params_mean(blm)) 141 | 142 | Returns 143 | ======= 144 | numpy.ndarray 145 | """ 146 | if Psi is None: 147 | Psi = blm.lik.linear.basis.get_basis(X) 148 | 149 | if w is None: 150 | w = get_post_params_mean(blm) 151 | return Psi.dot(w) + blm.lik.linear.bias 152 | 153 | 154 | def get_post_fcov(blm, X, Psi=None, diag=True): 155 | """ 156 | calculates posterior covariance of model 157 | 158 | Parameters 159 | ========== 160 | blm: physbo.blm.core.model 161 | X: numpy.ndarray 162 | inputs 163 | Psi: numpy.ndarray 164 | feature maps 165 | (default: blm.lik.linear.basis.get_basis(X)) 166 | diag: bool 167 | if True, returns only variances as a diagonal matrix 168 | (default: True) 169 | 170 | Returns 171 | ======= 172 | numpy.ndarray 173 | Returned shape is (num_points) if diag=true, (num_points, num_points) if diag=false, 174 | where num_points is the number of points in X. 175 | """ 176 | if Psi is None: 177 | Psi = blm.lik.linear.basis.get_basis(X) 178 | 179 | U = blm.stats[0] 180 | R = scipy.linalg.solve_triangular( 181 | U.transpose(), 182 | Psi.transpose(), 183 | lower=True, 184 | overwrite_b=False, 185 | check_finite=False, 186 | ) 187 | RT = R.transpose() 188 | 189 | if diag is True: 190 | fcov = misc.diagAB(RT, R) 191 | else: 192 | fcov = np.dot(RT, R) 193 | 194 | return fcov 195 | -------------------------------------------------------------------------------- /physbo/blm/lik/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from ._src import cov 9 | from .linear import linear 10 | from .gauss import gauss 11 | -------------------------------------------------------------------------------- /physbo/blm/lik/_src/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .cov import cov 9 | -------------------------------------------------------------------------------- /physbo/blm/lik/_src/cov.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class cov: 12 | """ 13 | Covariance 14 | 15 | Attributes 16 | ========== 17 | params: float 18 | half of log of variance 19 | nparams: int 20 | number of parameters 21 | sigma2: float 22 | variance 23 | prec: float 24 | inv. of variance 25 | """ 26 | 27 | def __init__(self, params=None): 28 | self.params = params 29 | if self.params is None: 30 | self.params = np.log(1) 31 | self.nparams = 1 32 | self.sigma2, self.prec = self._trans_params(params) 33 | 34 | def get_cov(self, N, params=None): 35 | """ 36 | compute the covariance of prior 37 | 38 | Parameters 39 | ========== 40 | N: int 41 | dimension 42 | params: 43 | half of log of variance 44 | (default: self.params) 45 | 46 | Returns 47 | ======= 48 | numpy.ndarray 49 | NxN covariance matrix 50 | """ 51 | if params is None: 52 | params = self.params 53 | 54 | sigma2, prec = self._trans_params(params) 55 | return np.identity(N) * sigma2 56 | 57 | def get_prec(self, N, params=None): 58 | """ 59 | compute the precision of prior 60 | 61 | Parameters 62 | ========== 63 | N: int 64 | dimension 65 | params: 66 | half of log of variance 67 | (default: self.params) 68 | 69 | Returns 70 | ======= 71 | numpy.ndarray 72 | inverse of covariance matrix 73 | """ 74 | if params is None: 75 | params = self.params 76 | sigma2, prec = self._trans_params(params) 77 | return np.identity(N) * prec 78 | 79 | def set_params(self, params): 80 | """ 81 | set the parameter 82 | 83 | Parameters 84 | ========== 85 | params: float 86 | half of log of variance 87 | """ 88 | self.params = params 89 | self.sigma2, self.prec = self._trans_params(params) 90 | 91 | def _trans_params(self, params=None): 92 | """ 93 | transform the parameter into variance and precision 94 | 95 | Parameters 96 | ========== 97 | params: float 98 | half of log of variance 99 | (default: self.params) 100 | 101 | Returns 102 | ======= 103 | sigma2: float 104 | variance 105 | prec: float 106 | precision (inv. of variance) 107 | """ 108 | if params is None: 109 | params = np.copy(self.params) 110 | 111 | sigma2 = np.exp(2 * params) 112 | prec = 1 / sigma2 113 | return sigma2, prec 114 | -------------------------------------------------------------------------------- /physbo/blm/lik/gauss.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class gauss: 12 | """ 13 | Gaussian 14 | 15 | Attributes 16 | ========== 17 | linear 18 | cov: blm.lik.cov 19 | covariance 20 | stats 21 | """ 22 | 23 | def __init__(self, linear, cov): 24 | self.linear = linear 25 | self.cov = cov 26 | self.stats = () 27 | 28 | def get_cov(self, N, params=None): 29 | """ 30 | Returns covariance matrix 31 | 32 | Parameters 33 | ========== 34 | N: int 35 | dimension 36 | params: float 37 | half of log of variance 38 | (default: self.cov.params) 39 | 40 | Returns 41 | ======= 42 | numpy.ndarray 43 | NxN covariance matrix 44 | """ 45 | if params is None: 46 | params = np.copy(self.cov.params) 47 | 48 | return self.cov.get_cov(N, params) 49 | 50 | def get_prec(self, N, params=None): 51 | """ 52 | Returns precision matrix 53 | 54 | Parameters 55 | ========== 56 | N: int 57 | dimension 58 | params: float 59 | half of log of variance 60 | (default: self.cov.params) 61 | 62 | Returns 63 | ======= 64 | numpy.ndarray 65 | NxN precision matrix 66 | """ 67 | 68 | if params is None: 69 | params = np.copy(self.cov.params) 70 | 71 | return self.cov.get_cov(N, params) 72 | 73 | def get_basis(self, X): 74 | """ 75 | calculates value of basis function at input 76 | 77 | Parameters 78 | ========== 79 | X: numpy.ndarray 80 | input 81 | 82 | See also 83 | ======== 84 | blm.basis.fourier.get_basis 85 | """ 86 | return self.linear.basis.get_basis(X) 87 | 88 | def get_mean(self, X, Psi=None, params=None, bias=None): 89 | """ 90 | calculates mean value 91 | 92 | Parameters 93 | ========== 94 | X: numpy.ndarray 95 | raw input 96 | Psi: numpy.ndarray 97 | value of feature maps 98 | params: numpy.ndarray 99 | weight 100 | bias: float 101 | bias 102 | 103 | See also 104 | ======== 105 | blm.basis.fourier.get_mean 106 | """ 107 | return self.linear.get_mean(X, Psi, params, bias) 108 | 109 | def set_params(self, params): 110 | """ 111 | sets parameters 112 | """ 113 | self.linear.set_params(params) 114 | 115 | def set_bias(self, bias): 116 | """ 117 | sets bias 118 | """ 119 | self.linear.set_bias(bias) 120 | 121 | def sampling(self, fmean): 122 | """ 123 | draws samples 124 | 125 | Parameters 126 | ========== 127 | fmean: numpy.ndarray 128 | means of samples 129 | 130 | Returns 131 | ======= 132 | samples: numpy.ndarray 133 | """ 134 | num_data = fmean.shape[0] 135 | eps = np.sqrt(self.cov.sigma2) * np.random.randn(num_data) 136 | return fmean + eps 137 | -------------------------------------------------------------------------------- /physbo/blm/lik/linear.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class linear: 12 | """ 13 | 14 | Attributes 15 | ========== 16 | basis: 17 | basis for random feature map 18 | nbasis: int 19 | number of basis 20 | bias: 21 | params: 22 | _init_params: 23 | initial value of the parameter 24 | """ 25 | 26 | def __init__(self, basis, params=None, bias=None): 27 | self.basis = basis 28 | self.nbasis = basis.nbasis 29 | self._init_params = params 30 | self.bias = bias 31 | self.params = params 32 | 33 | if params is None: 34 | self.params = np.zeros(self.nbasis) 35 | self.nparams = self.nbasis 36 | 37 | def get_mean(self, X, Psi=None, params=None, bias=None): 38 | """ 39 | calculate mean values 40 | 41 | Parameters 42 | ========== 43 | X: numpy.ndarray 44 | input as an N-by-d matrix 45 | Psi: numpy.ndarray 46 | feature maps ``Psi(X)`` as an N-by-l matrix 47 | (default: self.get_basis(X)) 48 | params: numpy.ndarray 49 | weight as a vector with size l 50 | (default: self.params) 51 | bias: float 52 | (default: self.bias) 53 | 54 | Returns 55 | ======= 56 | numpy.ndarray 57 | Psi * params + bias 58 | 59 | """ 60 | if params is None: 61 | params = np.copy(self.params) 62 | 63 | if bias is None: 64 | bias = np.copy(self.bias) 65 | 66 | if Psi is None: 67 | Psi = self.get_basis(X) 68 | 69 | return Psi.dot(params) + bias 70 | 71 | def set_params(self, params): 72 | """ 73 | set parameters 74 | 75 | Parameters 76 | ========== 77 | params: np.ndarray 78 | """ 79 | self.params = params 80 | 81 | def set_bias(self, bias): 82 | """ 83 | set bias 84 | 85 | Parameters 86 | ========== 87 | bias: float 88 | """ 89 | self.bias = bias 90 | 91 | def _init_params(self, params): 92 | """ 93 | initialize parameters 94 | 95 | Parameters 96 | ========== 97 | params: np.ndarray 98 | (default: numpy.zeros(self.nbasis)) 99 | """ 100 | if params is None: 101 | self.params = np.zeros(self.nbasis) 102 | 103 | self.params = params 104 | 105 | def _init_bias(self, bias): 106 | """ 107 | initialize bias 108 | 109 | Parameters 110 | ========== 111 | bias: float 112 | (default: 0) 113 | """ 114 | if bias is None: 115 | self.bias = 0 116 | 117 | self.bias = bias 118 | -------------------------------------------------------------------------------- /physbo/blm/prior/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .gauss import gauss 9 | -------------------------------------------------------------------------------- /physbo/blm/prior/gauss.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class cov_const: 12 | """ 13 | isotropic variance-covariance 14 | 15 | All elements have the same variance and are independent with each other 16 | 17 | Attributes 18 | ========== 19 | params: float 20 | half of log of covariance 21 | sigma2: float 22 | covariance 23 | prec: float 24 | precision (= inv. of covariance) 25 | """ 26 | 27 | def __init__(self, params=None): 28 | """ 29 | Parameters 30 | ========== 31 | params: float 32 | half of log of covariance 33 | (default: numpy.log(1)) 34 | """ 35 | if params is None: 36 | self.params = np.log(1) 37 | self.sigma2, self.prec = self._trans_params(params) 38 | 39 | def get_cov(self, nbasis, params=None): 40 | """ 41 | computes the covariance 42 | 43 | Parameters 44 | ========== 45 | nbasis: int 46 | the number of components 47 | params: float 48 | half of log of variance 49 | (default: self.params) 50 | 51 | Returns 52 | ======= 53 | numpy.ndarray 54 | nbasis-by-n-basis covariance matrix 55 | """ 56 | if params is None: 57 | params = self.params 58 | sigma2, prec = self._trans_params(params) 59 | return np.identity(nbasis) * sigma2 60 | 61 | def get_prec(self, nbasis, params=None): 62 | """ 63 | computes the precision 64 | 65 | Parameters 66 | ========== 67 | nbasis: int 68 | the number of components 69 | params: float 70 | half of log of variance 71 | (default: self.params) 72 | 73 | Returns 74 | ======= 75 | numpy.ndarray 76 | nbasis-by-n-basis precision matrix 77 | """ 78 | if params is None: 79 | params = self.params 80 | sigma2, prec = self._trans_params(params) 81 | return np.identity(nbasis) * prec 82 | 83 | def set_params(self, params): 84 | """ 85 | sets params 86 | 87 | Parameters 88 | ========== 89 | params: float 90 | half of log of variance 91 | """ 92 | self.params = params 93 | self.sigma2, self.prec = self._trans_params(params) 94 | 95 | def _trans_params(self, params=None): 96 | """ 97 | calculates variance and precise from params 98 | 99 | Parameters 100 | ========== 101 | params: float 102 | half of log of variance 103 | (default: self.params) 104 | 105 | Returns 106 | ======= 107 | sigma2: float 108 | variance 109 | prec: float 110 | precise (= inv. of variance) 111 | """ 112 | if params is None: 113 | params = self.params 114 | 115 | sigma2 = np.exp(2 * params) 116 | prec = 1 / sigma2 117 | 118 | return sigma2, prec 119 | 120 | 121 | class gauss: 122 | """ 123 | Gaussian prior 124 | 125 | Attributes 126 | ========== 127 | nbasis: int 128 | number of components 129 | cov: cov_const 130 | covariance 131 | """ 132 | 133 | def __init__(self, nbasis, cov=None): 134 | """ 135 | Parameters 136 | ========== 137 | nbasis: int 138 | number of components 139 | cov: cov_const 140 | (default: cov_const()) 141 | """ 142 | self._init_cov(cov) 143 | self.nbasis = nbasis 144 | 145 | def get_mean(self, params=None): 146 | """ 147 | calculates the mean value of priors 148 | 149 | Parameters 150 | ========== 151 | params: float 152 | half of log of variance 153 | (not used) 154 | 155 | Returns 156 | ======= 157 | numpy.ndarray 158 | """ 159 | return np.zeros(self.nbasis) 160 | 161 | def get_cov(self, params=None): 162 | """ 163 | calculates the variance-covariance matrix of priors 164 | 165 | Parameters 166 | ========== 167 | params: float 168 | half of log of variance 169 | (default: self.cov.params) 170 | 171 | Returns 172 | ======= 173 | numpy.ndarray 174 | """ 175 | return self.cov.get_cov(self.nbasis, params) 176 | 177 | def get_prec(self, params=None): 178 | """ 179 | calculates the precise matrix of priors 180 | 181 | Parameters 182 | ========== 183 | params: float 184 | half of log of variance 185 | (default: self.cov.params) 186 | 187 | Returns 188 | ======= 189 | numpy.ndarray 190 | """ 191 | return self.cov.get_prec(self.nbasis, params) 192 | 193 | def set_params(self, params): 194 | """ 195 | sets params 196 | 197 | Parameters 198 | ========== 199 | params: float 200 | half of log of variance 201 | """ 202 | self.cov.set_params(params) 203 | 204 | def _init_cov(self, cov): 205 | """ 206 | initialize covariance 207 | 208 | Parameters 209 | ========== 210 | cov: cov_const 211 | default: ``cov_const()`` 212 | """ 213 | self.cov = cov 214 | if cov is None: 215 | self.cov = cov_const() 216 | -------------------------------------------------------------------------------- /physbo/gp/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from . import cov 9 | from . import mean 10 | from . import lik 11 | 12 | from .core import prior 13 | from .core import model 14 | from .core import sfs 15 | from .core import learning 16 | from .predictor import predictor 17 | -------------------------------------------------------------------------------- /physbo/gp/core/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .prior import prior 9 | from .model import model 10 | from .model import sfs 11 | 12 | # from predictor import predictor 13 | -------------------------------------------------------------------------------- /physbo/gp/core/prior.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | import scipy 10 | 11 | 12 | class prior: 13 | """prior of gaussian process""" 14 | 15 | def __init__(self, mean, cov): 16 | """ 17 | 18 | Parameters 19 | ---------- 20 | mean: numpy.ndarray 21 | mean values of prior 22 | cov: physbo.gp.cov.gauss 23 | covariance matrix of priors 24 | """ 25 | self.mean = mean 26 | self.cov = cov 27 | self.num_params = self.cov.num_params + self.mean.num_params 28 | self.params = self.cat_params(self.mean.params, self.cov.params) 29 | 30 | def cat_params(self, mean_params, cov_params): 31 | """ 32 | 33 | Parameters 34 | ---------- 35 | mean_params: numpy.ndarray 36 | Mean values of parameters 37 | cov_params: numpy.ndarray 38 | Covariance matrix of parameters 39 | Returns 40 | ------- 41 | numpy.ndarray 42 | """ 43 | return np.append(mean_params, cov_params) 44 | 45 | def decomp_params(self, params): 46 | """ 47 | decomposing the parameters to those of mean values and covariance matrix for priors 48 | 49 | Parameters 50 | ---------- 51 | params: numpy.ndarray 52 | parameters 53 | 54 | Returns 55 | ------- 56 | mean_params: numpy.ndarray 57 | cov_params: numpy.ndarray 58 | """ 59 | if params is None: 60 | params = np.copy(self.params) 61 | 62 | mean_params = params[0 : self.mean.num_params] 63 | cov_params = params[self.mean.num_params :] 64 | return mean_params, cov_params 65 | 66 | def get_mean(self, num_data, params=None): 67 | """ 68 | Calculating the mean value of priors 69 | 70 | Parameters 71 | ---------- 72 | num_data: int 73 | Total number of data 74 | params: numpy.ndarray 75 | Parameters 76 | Returns 77 | ------- 78 | float 79 | """ 80 | if params is None: 81 | params = np.copy(self.params) 82 | return self.mean.get_mean(num_data, params[0 : self.mean.num_params]) 83 | 84 | def get_cov(self, X, Z=None, params=None, diag=False): 85 | """ 86 | Calculating the variance-covariance matrix of priors 87 | 88 | Parameters 89 | ---------- 90 | X: numpy.ndarray 91 | N x d dimensional matrix. Each row of X denotes the d-dimensional feature vector of search candidate. 92 | Z: numpy.ndarray 93 | N x d dimensional matrix. Each row of Z denotes the d-dimensional feature vector of tests. 94 | params: numpy.ndarray 95 | Parameters. 96 | diag: bool 97 | If true, only variances (diagonal elements) are returned. 98 | 99 | Returns 100 | ------- 101 | numpy.ndarray 102 | Returned shape is (num_points) if diag=true, (num_points, num_points) if diag=false, 103 | where num_points is the number of points in X. 104 | """ 105 | if params is None: 106 | params = np.copy(self.params) 107 | 108 | return self.cov.get_cov(X, Z, params=params[self.mean.num_params :], diag=diag) 109 | 110 | def get_grad_mean(self, num_data, params=None): 111 | """ 112 | Calculating the gradiant of mean values of priors 113 | 114 | Parameters 115 | ---------- 116 | num_data: int 117 | Total number of data 118 | params: numpy.ndarray 119 | Parameters 120 | 121 | Returns 122 | ------- 123 | numpy.ndarray 124 | 125 | """ 126 | if params is None: 127 | params = np.copy(self.params) 128 | 129 | mean_params, cov_params = self.decomp_params(params) 130 | return self.mean.get_grad(num_data, params=mean_params) 131 | 132 | def get_grad_cov(self, X, params=None): 133 | """ 134 | Calculating the covariance matrix priors 135 | 136 | Parameters 137 | ---------- 138 | X: numpy.ndarray 139 | N x d dimensional matrix. Each row of X denotes the d-dimensional feature vector of search candidate. 140 | params: numpy.ndarray 141 | Parameters. 142 | 143 | Returns 144 | ------- 145 | numpy.ndarray 146 | 147 | """ 148 | if params is None: 149 | params = np.copy(self.params) 150 | mean_params, cov_params = self.decomp_params(params) 151 | return self.cov.get_grad(X, params=cov_params) 152 | 153 | def set_params(self, params): 154 | """ 155 | Setting parameters 156 | 157 | Parameters 158 | ---------- 159 | params: numpy.ndarray 160 | Parameters. 161 | """ 162 | mean_params, cov_params = self.decomp_params(params) 163 | self.set_mean_params(mean_params) 164 | self.set_cov_params(cov_params) 165 | 166 | def set_mean_params(self, params): 167 | """ 168 | Setting parameters for mean values of priors 169 | 170 | Parameters 171 | ---------- 172 | params: numpy.ndarray 173 | Parameters 174 | """ 175 | if self.mean.num_params != 0: 176 | self.params[0 : self.mean.num_params] = params 177 | self.mean.set_params(params) 178 | 179 | def set_cov_params(self, params): 180 | """ 181 | Setting parameters for covariance matrix of priors 182 | 183 | Parameters 184 | ---------- 185 | params: numpy.ndarray 186 | Parameters 187 | """ 188 | self.params[self.mean.num_params :] = params 189 | self.cov.set_params(params) 190 | 191 | def sampling(self, X, N=1): 192 | """ 193 | Sampling from GP prior 194 | 195 | Parameters 196 | ---------- 197 | X: numpy.ndarray 198 | N x d dimensional matrix. Each row of X denotes the d-dimensional feature vector of search candidate. 199 | N: int 200 | 201 | Returns 202 | ------- 203 | float 204 | 205 | """ 206 | num_data = X.shape[0] 207 | G = self.get_cov(X) + 1e-8 * np.identity(num_data) 208 | U = scipy.linalg.cholesky(G, check_finite=False) 209 | Z = np.random.randn(N, num_data) 210 | return np.dot(Z, U) + self.get_mean(num_data) 211 | -------------------------------------------------------------------------------- /physbo/gp/cov/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .gauss import gauss 9 | -------------------------------------------------------------------------------- /physbo/gp/cov/_src/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /physbo/gp/cov/_src/enhance_gauss.pyx: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | cimport numpy as np 10 | import cython 11 | cimport cython 12 | from libc.math cimport exp 13 | 14 | DTYPE64 = np.float64 15 | ctypedef np.float64_t DTYPE64_t 16 | DTYPE32 = np.float32 17 | ctypedef np.float32_t DTYPE32_t 18 | 19 | @cython.boundscheck( False ) 20 | @cython.wraparound( False ) 21 | @cython.nonecheck( False ) 22 | 23 | def grad_width64( np.ndarray[DTYPE64_t, ndim = 2] X, np.ndarray[DTYPE64_t, ndim = 1] width, np.ndarray[DTYPE64_t, ndim = 2] G ): 24 | """ 25 | Gradiant along width direction (64bit). 26 | 27 | Parameters 28 | ---------- 29 | X: numpy.ndarray[numpy.float64_t, ndim = 2] 30 | 31 | width: numpy.ndarray[numpy.float64_t, ndim = 1] 32 | The grid width 33 | G: numpy.ndarray[numpy.float64_t, ndim = 2] 34 | The gram matrix 35 | Returns 36 | ------- 37 | numpy.ndarray 38 | """ 39 | cdef int N = X.shape[0] 40 | cdef int D = X.shape[1] 41 | 42 | cdef np.ndarray[DTYPE64_t, ndim = 3] gradG = np.zeros([D,N,N], dtype = DTYPE64 ) 43 | cdef int i, j, d 44 | 45 | for d in xrange( D ): 46 | for i in xrange( N ): 47 | for j in xrange( i+1, N ): 48 | gradG[d,i,j]= ( X[i,d] - X[j,d] )/width[d] 49 | gradG[d,i,j]= gradG[d,i,j]**2 * G[i,j] 50 | gradG[ d, j, i ] = gradG[ d, i, j ] 51 | return gradG 52 | 53 | @cython.boundscheck( False ) 54 | @cython.wraparound( False ) 55 | @cython.nonecheck( False ) 56 | 57 | def grad_width32( np.ndarray[DTYPE32_t, ndim = 2] X, np.ndarray[DTYPE32_t, ndim = 1] width, np.ndarray[DTYPE32_t, ndim = 2] G ): 58 | """ 59 | 60 | Gradiant along width direction (32bit). 61 | 62 | Parameters 63 | ---------- 64 | X: numpy.ndarray[numpy.float32_t, ndim = 2] 65 | 66 | width: numpy.ndarray[numpy.float32_t, ndim = 1] 67 | The grid width 68 | G: numpy.ndarray[numpy.float32_t, ndim = 2] 69 | The gram matrix 70 | Returns 71 | ------- 72 | numpy.ndarray 73 | """ 74 | cdef int N = X.shape[0] 75 | cdef int D = X.shape[1] 76 | 77 | cdef np.ndarray[DTYPE32_t, ndim = 3] gradG = np.zeros([D,N,N], dtype = DTYPE32 ) 78 | cdef int i, j, d 79 | 80 | for d in xrange( D ): 81 | for i in xrange( N ): 82 | for j in xrange( i+1, N ): 83 | gradG[d,i,j]= ( X[i,d] - X[j,d] )/width[d] 84 | gradG[d,i,j]= gradG[d,i,j]**2 * G[i,j] 85 | gradG[ d, j, i ] = gradG[ d, i, j ] 86 | return gradG 87 | -------------------------------------------------------------------------------- /physbo/gp/inf/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from . import exact 9 | -------------------------------------------------------------------------------- /physbo/gp/lik/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .gauss import gauss 9 | -------------------------------------------------------------------------------- /physbo/gp/lik/gauss.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class gauss: 12 | """Gaussian likelihood function""" 13 | 14 | def __init__(self, std=1, max_params=1e6, min_params=1e-6): 15 | """ 16 | 17 | Parameters 18 | ---------- 19 | std: numpy.ndarray or float 20 | standard deviation. 21 | max_params: float 22 | The maximum value of the parameter. 23 | If the parameter is greater than this value, it will be replaced by this value. 24 | min_params: float 25 | The minimum value of the parameter. 26 | If the parameter is less than this value, it will be replaced by this value. 27 | """ 28 | self.min_params = np.log(min_params) 29 | self.max_params = np.log(max_params) 30 | self.num_params = 1 31 | self.std = std 32 | self.params = np.log(std) 33 | self.set_params(self.params) 34 | 35 | def supp_params(self, params=None): 36 | """ 37 | Set maximum (minimum) values for parameters when the parameter is greater(less) than this value. 38 | 39 | Parameters 40 | ---------- 41 | params: numpy.ndarray 42 | Parameters for optimization. 43 | Array of real elements of size (n,), where ‘n’ is the number of independent variables. 44 | Returns 45 | ------- 46 | 47 | """ 48 | if params is None: 49 | params = np.copy(params) 50 | 51 | if params > self.max_params: 52 | params = self.max_params 53 | 54 | if params < self.min_params: 55 | params = self.min_params 56 | 57 | return params 58 | 59 | def trans_params(self, params=None): 60 | """ 61 | Get exp[params]. 62 | 63 | Parameters 64 | ---------- 65 | params: numpy.ndarray 66 | Parameters for optimization. 67 | Array of real elements of size (n,), where ‘n’ is the number of independent variables. 68 | 69 | Returns 70 | ------- 71 | std: numpy.ndarray 72 | """ 73 | if params is None: 74 | params = np.copy(self.params) 75 | 76 | std = np.exp(params) 77 | return std 78 | 79 | def get_params_bound(self): 80 | """ 81 | Get boundary array. 82 | 83 | Returns 84 | ------- 85 | bound: list 86 | A num_params-dimensional array with the tuple (min_params, max_params). 87 | """ 88 | bound = [(self.min_params, self.max_params) for i in range(0, self.num_params)] 89 | return bound 90 | 91 | def get_cov(self, num_data, params=None): 92 | """ 93 | Get a covariance matrix 94 | 95 | Parameters 96 | ---------- 97 | num_data: int 98 | params: numpy.ndarray 99 | Parameters for optimization. 100 | Array of real elements of size (n,), where ‘n’ is the number of independent variables. 101 | 102 | Returns 103 | ------- 104 | numpy.ndarray 105 | Diagonal element matrix of exp(2.0*params) 106 | """ 107 | std = self.trans_params(params) 108 | var = std**2 109 | return var * np.identity(num_data) 110 | 111 | def get_grad(self, num_data, params=None): 112 | """ 113 | Get a gradient matrix 114 | 115 | Parameters 116 | ---------- 117 | num_data: int 118 | params: numpy.ndarray 119 | Parameters for optimization. 120 | Array of real elements of size (n,), where ‘n’ is the number of independent variables. 121 | 122 | Returns 123 | ------- 124 | numpy.ndarray 125 | Diagonal element matrix of 2.0 * exp(2.0*params) 126 | """ 127 | std = self.trans_params(params) 128 | var = std**2 129 | return var * np.identity(num_data) * 2 130 | 131 | def set_params(self, params): 132 | """ 133 | Set parameters. 134 | 135 | Parameters 136 | ---------- 137 | params: numpy.ndarray 138 | Parameters for optimization. 139 | Array of real elements of size (n,), where ‘n’ is the number of independent variables. 140 | 141 | Returns 142 | ------- 143 | 144 | """ 145 | self.params = self.supp_params(params) 146 | self.std = self.trans_params(params) 147 | 148 | def get_cand_params(self, t): 149 | """ 150 | Getting candidate parameters. 151 | 152 | Parameters 153 | ---------- 154 | t: numpy.ndarray 155 | N dimensional array. The negative energy of each search candidate (value of the objective function to be optimized). 156 | 157 | Returns 158 | ------- 159 | numpy.ndarray 160 | log[ standard deviation of t] - log 10.0 161 | """ 162 | return np.log(np.std(t) / 10) 163 | 164 | # [TODO] Check: This function seems not to be used. 165 | def sampling(self, fmean): 166 | """ 167 | Sampling by adding noise 168 | 169 | Parameters 170 | ---------- 171 | fmean: numpy.ndarray 172 | 173 | Returns 174 | ------- 175 | 176 | """ 177 | num_data = fmean.shape[0] 178 | eps = self.std * np.random.randn(num_data) 179 | return fmean + eps 180 | -------------------------------------------------------------------------------- /physbo/gp/mean/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .zero import zero 9 | from .const import const 10 | -------------------------------------------------------------------------------- /physbo/gp/mean/const.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class const: 12 | """constant""" 13 | 14 | def __init__(self, params=None, max_params=1e12, min_params=-1e12): 15 | """ 16 | 17 | Parameters 18 | ---------- 19 | params: numpy.ndarray 20 | Parameters 21 | max_params: float 22 | Threshold value for specifying the maximum value of the parameter 23 | min_params: float 24 | Threshold value for specifying the minimum value of the parameter 25 | 26 | """ 27 | self.max_params = max_params 28 | self.min_params = min_params 29 | self.init_params(params) 30 | self.num_params = 1 31 | 32 | def supp_params(self, params): 33 | """ 34 | Setting maximum and minimum value of parameters. 35 | 36 | Parameters 37 | ---------- 38 | params: numpy.ndarray 39 | parameters 40 | 41 | Returns 42 | ------- 43 | numpy.ndarray 44 | """ 45 | if params > self.max_params: 46 | params = self.max_params 47 | 48 | if params < self.min_params: 49 | params = self.min_params 50 | 51 | return params 52 | 53 | def get_params_bound(self): 54 | """ 55 | Getting the boundary list for parameters 56 | 57 | Returns 58 | ------- 59 | bound: list 60 | num_params array with the tupple (min_param, max_params) 61 | 62 | """ 63 | bound = [(self.min_params, self.max_params) for i in range(0, self.num_params)] 64 | return bound 65 | 66 | def get_mean(self, num_data, params=None): 67 | """ 68 | 69 | Parameters 70 | ---------- 71 | num_data: int 72 | total number of data 73 | params: numpy.ndarray 74 | parameters 75 | 76 | Returns 77 | ------- 78 | numpy.ndarray 79 | """ 80 | if params is None: 81 | params = np.copy(self.params) 82 | return params * np.ones(num_data) 83 | 84 | def get_grad(self, num_data, params=None): 85 | """ 86 | Returning a new array of (num_data), filled with ones. 87 | 88 | Parameters 89 | ---------- 90 | num_data: int 91 | total number of data 92 | params: object 93 | not used 94 | 95 | Returns 96 | ------- 97 | numpy.ndarray 98 | """ 99 | return np.ones(num_data) 100 | 101 | def set_params(self, params): 102 | """ 103 | Setting parameters defined in const class. 104 | 105 | Parameters 106 | ---------- 107 | params: numpy.ndarray 108 | parameters 109 | 110 | Returns 111 | ------- 112 | numpy.ndarray 113 | """ 114 | self.params = params 115 | 116 | def init_params(self, params): 117 | """ 118 | Initializing parameters 119 | 120 | Parameters 121 | ---------- 122 | params: numpy.ndarray 123 | parameters 124 | 125 | Returns 126 | ------- 127 | params: numpy.ndarray 128 | initialized parameters 129 | """ 130 | if params is None: 131 | self.params = 0 132 | else: 133 | self.params = self.supp_params(params) 134 | 135 | def get_cand_params(self, t): 136 | """ 137 | Getting the median array of candidates. 138 | 139 | Parameters 140 | ---------- 141 | t: array_like 142 | Input array or object that can be converted to an array 143 | 144 | Returns 145 | ------- 146 | median: numpy.ndarray 147 | A new array holding the result. 148 | 149 | """ 150 | return np.median(t) 151 | -------------------------------------------------------------------------------- /physbo/gp/mean/zero.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class zero: 12 | """zero""" 13 | 14 | def __init__(self): 15 | self.num_params = 0 16 | self.params = np.array([]) 17 | 18 | def get_mean(self, num_data, params=None): 19 | """ 20 | Returning numpy.zeros(num_data) 21 | 22 | Parameters 23 | ---------- 24 | num_data: int 25 | dimension of numpy.zeros 26 | params: object 27 | not used 28 | 29 | Returns 30 | ------- 31 | numpy.ndarray 32 | 33 | """ 34 | return np.zeros(num_data) 35 | 36 | def get_grad(self, num_data, params=None): 37 | """ 38 | Returning empty numpy.ndarray 39 | 40 | Parameters 41 | ---------- 42 | num_data: int 43 | not used 44 | params: object 45 | not used 46 | 47 | Returns 48 | ------- 49 | numpy.ndarray 50 | 51 | """ 52 | return np.array([]) 53 | 54 | def set_params(self, params): 55 | """ 56 | Not defined 57 | 58 | Parameters 59 | ---------- 60 | params 61 | 62 | Returns 63 | ------- 64 | 65 | """ 66 | pass 67 | -------------------------------------------------------------------------------- /physbo/gp/predictor.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import physbo.predictor 9 | 10 | 11 | class predictor(physbo.predictor.base_predictor): 12 | """predictor""" 13 | 14 | def __init__(self, config, model=None): 15 | """ 16 | 17 | Parameters 18 | ---------- 19 | config: physbo.misc.set_config 20 | configuration 21 | model: physbo.gp.core.model 22 | """ 23 | super(predictor, self).__init__(config, model) 24 | 25 | def fit(self, training, num_basis=None): 26 | """ 27 | Fitting model to training dataset 28 | 29 | Parameters 30 | ---------- 31 | training: physbo.variable 32 | dataset for training 33 | num_basis: int 34 | the number of basis (default: self.config.predict.num_basis) 35 | """ 36 | if self.model.prior.cov.num_dim is None: 37 | self.model.prior.cov.num_dim = training.X.shape[1] 38 | self.model.fit(training.X, training.t, self.config) 39 | self.delete_stats() 40 | 41 | def get_basis(self, *args, **kwds): 42 | """ 43 | 44 | Parameters 45 | ---------- 46 | args 47 | kwds 48 | 49 | Returns 50 | ------- 51 | 52 | """ 53 | pass 54 | 55 | def get_post_params(self, *args, **kwds): 56 | """ 57 | 58 | Parameters 59 | ---------- 60 | args 61 | kwds 62 | 63 | Returns 64 | ------- 65 | 66 | """ 67 | pass 68 | 69 | def update(self, training, test): 70 | self.prepare(training) 71 | 72 | def prepare(self, training): 73 | """ 74 | Initializing model by using training data set 75 | 76 | Parameters 77 | ---------- 78 | training: physbo.variable 79 | dataset for training 80 | 81 | """ 82 | self.model.prepare(training.X, training.t) 83 | 84 | def delete_stats(self): 85 | self.model.stats = None 86 | 87 | def get_post_fmean(self, training, test): 88 | """ 89 | Calculating posterior mean value of model 90 | 91 | Parameters 92 | ---------- 93 | training: physbo.variable 94 | training dataset. If already trained, the model does not use this. 95 | test: physbo.variable 96 | inputs 97 | 98 | Returns 99 | ------- 100 | numpy.ndarray 101 | 102 | """ 103 | if self.model.stats is None: 104 | self.prepare(training) 105 | return self.model.get_post_fmean(training.X, test.X) 106 | 107 | def get_post_fcov(self, training, test, diag=True): 108 | """ 109 | Calculating posterior variance-covariance matrix of model 110 | 111 | Parameters 112 | ---------- 113 | training: physbo.variable 114 | training dataset. If already trained, the model does not use this. 115 | test: physbo.variable 116 | inputs 117 | diag: bool 118 | If true, only variances (diagonal elements) are returned. 119 | 120 | Returns 121 | ------- 122 | numpy.ndarray 123 | Returned shape is (num_points) if diag=true, (num_points, num_points) if diag=false, 124 | where num_points is the number of points in test. 125 | 126 | """ 127 | if self.model.stats is None: 128 | self.prepare(training) 129 | return self.model.get_post_fcov(training.X, test.X, diag=diag) 130 | 131 | def get_post_samples(self, training, test, alpha=1): 132 | """ 133 | Drawing samples of mean values of model 134 | 135 | Parameters 136 | ---------- 137 | training: physbo.variable 138 | training dataset. If already trained, the model does not use this. 139 | test: physbo.variable 140 | inputs (not used) 141 | alpha: float 142 | tuning parameter of the covariance by multiplying alpha**2 for np.random.multivariate_normal. 143 | Returns 144 | ------- 145 | numpy.ndarray 146 | 147 | """ 148 | if self.model.stats is None: 149 | self.prepare(training) 150 | return self.model.post_sampling(training.X, test.X, alpha=alpha) 151 | 152 | def get_predict_samples(self, training, test, N=1): 153 | """ 154 | Drawing samples of values of model 155 | 156 | Parameters 157 | ---------- 158 | training: physbo.variable 159 | training dataset. If already trained, the model does not use this. 160 | test: physbo.variable 161 | inputs 162 | N: int 163 | number of samples 164 | (default: 1) 165 | 166 | Returns 167 | ------- 168 | numpy.ndarray (N x len(test)) 169 | 170 | """ 171 | if self.model.stats is None: 172 | self.prepare(training) 173 | return self.model.predict_sampling(training.X, test.X, N=N) 174 | -------------------------------------------------------------------------------- /physbo/misc/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .centering import centering 9 | from .gauss_elim import gauss_elim 10 | from .set_config import set_config 11 | from ._src.diagAB import diagAB_64 as diagAB 12 | from ._src.traceAB import traceAB2_64 as traceAB2 13 | from ._src.traceAB import traceAB3_64 as traceAB3 14 | from ._src.cholupdate import cholupdate64 as cholupdate 15 | from ._src.logsumexp import logsumexp64 16 | -------------------------------------------------------------------------------- /physbo/misc/_src/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /physbo/misc/_src/cholupdate.pyx: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from libc.math cimport sqrt 9 | from libc.math cimport abs as cabs 10 | import numpy as np 11 | cimport numpy as np 12 | import cython 13 | cimport cython 14 | 15 | DTYPE = np.float64 16 | ctypedef np.float64_t DTYPE_t 17 | 18 | @cython.boundscheck( False ) 19 | @cython.wraparound( False ) 20 | @cython.nonecheck( False ) 21 | cdef inline double hypot(double x, double y): 22 | cdef double t 23 | x = cabs(x) 24 | y = cabs(y) 25 | t = x if x < y else y 26 | x = x if x > y else y 27 | t = t/x 28 | return x*sqrt(1+t*t) 29 | 30 | @cython.boundscheck( False ) 31 | @cython.wraparound( False ) 32 | @cython.nonecheck( False ) 33 | def cholupdate64( np.ndarray[DTYPE_t, ndim = 2] L, np.ndarray[DTYPE_t, ndim = 1] x ): 34 | cdef int N = x.shape[0] 35 | cdef double c, r, s, eps 36 | cdef int k, i 37 | cdef np.ndarray[DTYPE_t, ndim = 1] x2 = x 38 | 39 | for k in xrange( 0, N ): 40 | r = hypot(L[k,k], x2[k]) 41 | c = r / L[ k, k ] 42 | s = x2[ k ] / L[ k, k ] 43 | L[ k, k ] = r 44 | 45 | for i in xrange( k+1, N ): 46 | L[ k, i ] = ( L[ k, i ] + s * x2[ i ] ) / c 47 | x2[ i ] = c * x2[ i ] - s * L[ k, i ] 48 | -------------------------------------------------------------------------------- /physbo/misc/_src/diagAB.pyx: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | cimport numpy as np 10 | import cython 11 | cimport cython 12 | 13 | DTYPE = np.float64 14 | ctypedef np.float64_t DTYPE_t 15 | 16 | @cython.boundscheck( False ) 17 | @cython.wraparound( False ) 18 | @cython.nonecheck( False ) 19 | def diagAB_64( np.ndarray[DTYPE_t, ndim = 2] A, np.ndarray[DTYPE_t, ndim = 2] B ): 20 | """ Return diagonal part of AB 21 | 22 | Parameters 23 | ========== 24 | A: np.ndarray 25 | NxM matrix 26 | B: np.ndarray 27 | MxN matrix 28 | 29 | Returns 30 | ======= 31 | d: np.ndarray 32 | Diagonal part of the matrix AB 33 | """ 34 | cdef int N = A.shape[0] 35 | cdef int M = A.shape[1] 36 | 37 | cdef np.ndarray[DTYPE_t, ndim = 1] diagAB = np.zeros( N, dtype=DTYPE ) 38 | cdef int i, j 39 | 40 | for i in xrange( N ): 41 | for j in xrange( M ): 42 | diagAB[i] += A[i,j]*B[j,i] 43 | 44 | return diagAB 45 | -------------------------------------------------------------------------------- /physbo/misc/_src/logsumexp.pyx: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from libc.math cimport exp, log 9 | import numpy as np 10 | cimport numpy as np 11 | import cython 12 | cimport cython 13 | 14 | DTYPE = np.float64 15 | ctypedef np.float64_t DTYPE_t 16 | 17 | @cython.boundscheck( False ) 18 | @cython.wraparound( False ) 19 | @cython.nonecheck( False ) 20 | 21 | def logsumexp64( np.ndarray[DTYPE_t, ndim = 1] x ): 22 | """ Calculate log(sum(exp(x))) 23 | 24 | Parameters 25 | ========== 26 | x: np.ndarray 27 | """ 28 | cdef int N = x.shape[0] 29 | cdef int i 30 | cdef double xmax 31 | cdef double tmp = 0 32 | cdef double output 33 | 34 | xmax = np.max(x) 35 | 36 | for i in xrange(0,N): 37 | tmp += exp( x[i] - xmax ) 38 | 39 | return log(tmp) + xmax 40 | -------------------------------------------------------------------------------- /physbo/misc/_src/traceAB.pyx: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | cimport numpy as np 10 | import cython 11 | cimport cython 12 | 13 | DTYPE = np.float64 14 | ctypedef np.float64_t DTYPE_t 15 | 16 | 17 | @cython.boundscheck( False ) 18 | @cython.wraparound( False ) 19 | @cython.nonecheck( False ) 20 | def traceAB3_64( np.ndarray[DTYPE_t, ndim = 2] A, np.ndarray[DTYPE_t, ndim = 3] B ): 21 | """ Calculates vector of trace of AB[i], where i is the first axis of 3-rank tensor B 22 | 23 | Parameters 24 | ========== 25 | A: np.ndarray 26 | NxM matrix 27 | B: np.ndarray 28 | dxMxN tensor 29 | 30 | Returns 31 | ======= 32 | traceAB: np.ndarray 33 | """ 34 | cdef int N = A.shape[0] 35 | cdef int M = A.shape[1] 36 | cdef int D = B.shape[0] 37 | 38 | cdef np.ndarray[DTYPE_t, ndim = 1] traceAB = np.zeros( D, dtype = DTYPE ) 39 | cdef int i, j, d 40 | 41 | for d in xrange( D ): 42 | traceAB[d] = 0 43 | for i in xrange( N ): 44 | for j in xrange( M ): 45 | traceAB[d] += A[i,j]*B[d,j,i] 46 | return traceAB 47 | 48 | @cython.boundscheck( False ) 49 | @cython.wraparound( False ) 50 | @cython.nonecheck( False ) 51 | def traceAB2_64( np.ndarray[DTYPE_t, ndim = 2] A, np.ndarray[DTYPE_t, ndim = 2] B ): 52 | """ Calculates trace of AB 53 | 54 | Parameters 55 | ========== 56 | A: np.ndarray 57 | NxM matrix 58 | B: np.ndarray 59 | MxN matrix 60 | 61 | Returns 62 | ======= 63 | traceAB: float 64 | trace of the matrix AB 65 | """ 66 | cdef int N = A.shape[0] 67 | cdef int M = A.shape[1] 68 | 69 | cdef DTYPE_t traceAB = 0 70 | cdef int i, j, d 71 | 72 | for i in xrange( N ): 73 | for j in xrange( M ): 74 | traceAB += A[i,j]*B[j,i] 75 | return traceAB 76 | -------------------------------------------------------------------------------- /physbo/misc/centering.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | def centering(X): 12 | """ 13 | Normalize the mean and standard deviation along the each column of X to 0 and 1, respectively 14 | 15 | Parameters 16 | ---------- 17 | X: numpy array 18 | N x d dimensional matrix. Each row of X denotes the d-dimensional feature vector of search candidate. 19 | 20 | Returns 21 | ------- 22 | X_normalized: numpy array 23 | normalized N x d dimensional matrix. 24 | """ 25 | stdX = np.std(X, 0) 26 | index = np.where(stdX != 0) 27 | X_normalized = (X[:, index[0]] - np.mean(X[:, index[0]], 0)) / stdX[index[0]] 28 | return X_normalized 29 | -------------------------------------------------------------------------------- /physbo/misc/gauss_elim.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | import scipy 10 | 11 | 12 | def gauss_elim(U, t): 13 | """ 14 | Calculate alpha using scipy.linalg.solve_triangular. 15 | alpha = (U^T U)^-1 t = U^-1 [(U^T)-1 t] 16 | 17 | Parameters 18 | ---------- 19 | U: (M, M) array_like 20 | A triangular matrix 21 | t: (M,) or (M, N) array_like 22 | 23 | Returns 24 | ------- 25 | alpha: numpy.ndarray 26 | Solution to the system L^T alpha = t. Shape of return matches t. 27 | """ 28 | alpha = scipy.linalg.solve_triangular( 29 | U.transpose(), t, lower=True, overwrite_b=False, check_finite=False 30 | ) 31 | 32 | alpha = scipy.linalg.solve_triangular( 33 | U, alpha, lower=False, overwrite_b=False, check_finite=False 34 | ) 35 | return alpha 36 | -------------------------------------------------------------------------------- /physbo/opt/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .adam import adam 9 | -------------------------------------------------------------------------------- /physbo/opt/adam.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class adam: 12 | """ 13 | Optimizer of f(x) with the adam method 14 | 15 | Attributes 16 | ========== 17 | params: numpy.ndarray 18 | current input, x 19 | nparams: int 20 | dimension 21 | grad: function 22 | gradient function, g(x) = f'(x) 23 | m: numpy.ndarray 24 | v: numpy.ndarray 25 | epoch: int 26 | the number of update already done 27 | max_epoch: int 28 | the maximum number of update 29 | alpha: float 30 | beta: float 31 | gamma: float 32 | epsilon: float 33 | """ 34 | 35 | def __init__(self, params, grad, options={}): 36 | """ 37 | 38 | Parameters 39 | ========== 40 | params: 41 | grad: 42 | options: dict 43 | Hyperparameters for the adam method 44 | 45 | - "alpha" (default: 0.001) 46 | - "beta" (default: 0.9) 47 | - "gamma" (default: 0.9999) 48 | - "epsilon" (default: 1e-8) 49 | - "max_epoch" (default: 4000) 50 | """ 51 | self.grad = grad 52 | self.params = params 53 | self.nparams = params.shape[0] 54 | self._set_options(options) 55 | self.m = np.zeros(self.nparams) 56 | self.v = np.zeros(self.nparams) 57 | self.epoch = 0 58 | 59 | def set_params(self, params): 60 | self.params = params 61 | 62 | def update(self, params, *args, **kwargs): 63 | """ 64 | calculates the updates of params 65 | 66 | Parameters 67 | ========== 68 | params: numpy.ndarray 69 | input 70 | args: 71 | will be passed to self.grad 72 | kwargs: 73 | will be passed to self.grad 74 | 75 | Returns 76 | ======= 77 | numpy.ndarray 78 | update of params 79 | """ 80 | g = self.grad(params, *args, **kwargs) 81 | self.m = self.m * self.beta + g * (1 - self.beta) 82 | self.v = self.v * self.gamma + g**2 * (1 - self.gamma) 83 | hat_m = self.m / (1 - self.beta ** (self.epoch + 1)) 84 | hat_v = self.v / (1 - self.gamma ** (self.epoch + 1)) 85 | self.epoch += 1 86 | return -self.alpha * hat_m / (np.sqrt(hat_v) + self.epsilon) 87 | 88 | def run(self, *args, **kwargs): 89 | params = self.params 90 | for epoch in range(self.max_epoch): 91 | update = self.update(params, *args, **kwargs) 92 | params += update 93 | 94 | def _set_options(self, options): 95 | """ 96 | set hyperparameters for the method 97 | 98 | Parameters 99 | ========== 100 | options: dict 101 | 102 | """ 103 | self.alpha = options.get("alpha", 0.001) 104 | self.beta = options.get("beta", 0.9) 105 | self.gamma = options.get("gamma", 0.9999) 106 | self.epsilon = options.get("epsilon", 1e-8) 107 | self.max_epoch = options.get("max_epoch", 4000) 108 | -------------------------------------------------------------------------------- /physbo/predictor.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import pickle as pickle 9 | import numpy as np 10 | from physbo import gp 11 | 12 | 13 | class base_predictor(object): 14 | """ 15 | Base predictor is defined in this class. 16 | 17 | """ 18 | 19 | def __init__(self, config, model=None): 20 | """ 21 | 22 | Parameters 23 | ---------- 24 | config: set_config object (physbo.misc.set_config) 25 | model: model object 26 | A default model is set as gp.core.model 27 | """ 28 | 29 | self.config = config 30 | self.model = model 31 | if self.model is None: 32 | self.model = gp.core.model( 33 | cov=gp.cov.gauss(num_dim=None, ard=False), 34 | mean=gp.mean.const(), 35 | lik=gp.lik.gauss(), 36 | ) 37 | 38 | def fit(self, *args, **kwds): 39 | """ 40 | 41 | Default fit function. 42 | This function must be overwritten in each model. 43 | 44 | Parameters 45 | ---------- 46 | args 47 | kwds 48 | 49 | Returns 50 | ------- 51 | 52 | """ 53 | raise NotImplementedError 54 | 55 | def prepare(self, *args, **kwds): 56 | """ 57 | 58 | Default prepare function. 59 | This function must be overwritten in each model. 60 | 61 | Parameters 62 | ---------- 63 | args 64 | kwds 65 | 66 | Returns 67 | ------- 68 | 69 | """ 70 | raise NotImplementedError 71 | 72 | def delete_stats(self, *args, **kwds): 73 | """ 74 | 75 | Default function to delete status. 76 | This function must be overwritten in each model. 77 | 78 | Parameters 79 | ---------- 80 | args 81 | kwds 82 | 83 | Returns 84 | ------- 85 | 86 | """ 87 | raise NotImplementedError 88 | 89 | def get_basis(self, *args, **kwds): 90 | """ 91 | 92 | Default function to get basis 93 | This function must be overwritten in each model. 94 | 95 | Parameters 96 | ---------- 97 | args 98 | kwds 99 | 100 | Returns 101 | ------- 102 | 103 | """ 104 | raise NotImplementedError 105 | 106 | def get_post_fmean(self, *args, **kwds): 107 | """ 108 | 109 | Default function to get a mean value of the score. 110 | This function must be overwritten in each model. 111 | 112 | Parameters 113 | ---------- 114 | args 115 | kwds 116 | 117 | Returns 118 | ------- 119 | 120 | """ 121 | raise NotImplementedError 122 | 123 | def get_post_fcov(self, *args, **kwds): 124 | """ 125 | 126 | Default function to get a covariance of the score. 127 | This function must be overwritten in each model. 128 | 129 | Parameters 130 | ---------- 131 | args 132 | kwds 133 | 134 | Returns 135 | ------- 136 | 137 | """ 138 | raise NotImplementedError 139 | 140 | def get_post_params(self, *args, **kwds): 141 | """ 142 | 143 | Default function to get parameters. 144 | This function must be overwritten in each model. 145 | 146 | Parameters 147 | ---------- 148 | args 149 | kwds 150 | 151 | Returns 152 | ------- 153 | 154 | """ 155 | raise NotImplementedError 156 | 157 | def get_post_samples(self, *args, **kwds): 158 | """ 159 | 160 | Default function to get samples. 161 | This function must be overwritten in each model. 162 | 163 | Parameters 164 | ---------- 165 | args 166 | kwds 167 | 168 | Returns 169 | ------- 170 | 171 | """ 172 | raise NotImplementedError 173 | 174 | def get_predict_samples(self, *args, **kwds): 175 | """ 176 | 177 | Default function to get prediction variables of samples. 178 | This function must be overwritten in each model. 179 | 180 | Parameters 181 | ---------- 182 | args 183 | kwds 184 | 185 | Returns 186 | ------- 187 | 188 | """ 189 | raise NotImplementedError 190 | 191 | def get_post_params_samples(self, *args, **kwds): 192 | """ 193 | 194 | Default function to get parameters of samples. 195 | This function must be overwritten in each model. 196 | 197 | Parameters 198 | ---------- 199 | args 200 | kwds 201 | 202 | Returns 203 | ------- 204 | 205 | """ 206 | raise NotImplementedError 207 | 208 | def update(self, *args, **kwds): 209 | """ 210 | 211 | Default function to update variables. 212 | This function must be overwritten in each model. 213 | 214 | Parameters 215 | ---------- 216 | args 217 | kwds 218 | 219 | Returns 220 | ------- 221 | 222 | """ 223 | raise NotImplementedError 224 | 225 | def save(self, file_name): 226 | """ 227 | 228 | Default function to save information by using pickle.dump function. 229 | The protocol version is set as 3. 230 | 231 | Parameters 232 | ---------- 233 | file_name: str 234 | A file name to save self.__dict__ object. 235 | 236 | Returns 237 | ------- 238 | 239 | """ 240 | with open(file_name, "wb") as f: 241 | pickle.dump(self.__dict__, f, 4) 242 | 243 | def load(self, file_name): 244 | """ 245 | 246 | Default function to load variables. 247 | The information is updated using self.update function. 248 | 249 | Parameters 250 | ---------- 251 | file_name: str 252 | A file name to load variables from the file. 253 | 254 | Returns 255 | ------- 256 | 257 | """ 258 | with open(file_name, "rb") as f: 259 | tmp_dict = pickle.load(f) 260 | self.config = tmp_dict["config"] 261 | self.model = tmp_dict["model"] 262 | -------------------------------------------------------------------------------- /physbo/search/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from . import score 9 | from . import discrete 10 | from . import score_multi 11 | from . import discrete_multi 12 | -------------------------------------------------------------------------------- /physbo/search/discrete/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .policy import policy 9 | from .results import history 10 | 11 | # __all__ = ["policy", "history"] 12 | -------------------------------------------------------------------------------- /physbo/search/discrete_multi/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from .policy import policy 9 | from .results import history 10 | 11 | # __all__ = ["policy", "history"] 12 | -------------------------------------------------------------------------------- /physbo/search/discrete_multi/results.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | import pickle 10 | import copy 11 | 12 | from .. import pareto 13 | 14 | MAX_SEARCH = int(30000) 15 | 16 | 17 | class history(object): 18 | def __init__(self, num_objectives): 19 | self.num_objectives = num_objectives 20 | self.pareto = pareto.Pareto(num_objectives=self.num_objectives) 21 | 22 | self.num_runs = int(0) 23 | self.total_num_search = int(0) 24 | self.fx = np.zeros((MAX_SEARCH, self.num_objectives), dtype=float) 25 | self.chosen_actions = np.zeros(MAX_SEARCH, dtype=int) 26 | self.terminal_num_run = np.zeros(MAX_SEARCH, dtype=int) 27 | 28 | self._time_total = np.zeros(MAX_SEARCH, dtype=float) 29 | self._time_update_predictor = np.zeros(MAX_SEARCH, dtype=float) 30 | self._time_get_action = np.zeros(MAX_SEARCH, dtype=float) 31 | self._time_run_simulator = np.zeros(MAX_SEARCH, dtype=float) 32 | 33 | @property 34 | def time_total(self): 35 | return copy.copy(self._time_total[0 : self.num_runs]) 36 | 37 | @property 38 | def time_update_predictor(self): 39 | return copy.copy(self._time_update_predictor[0 : self.num_runs]) 40 | 41 | @property 42 | def time_get_action(self): 43 | return copy.copy(self._time_get_action[0 : self.num_runs]) 44 | 45 | @property 46 | def time_run_simulator(self): 47 | return copy.copy(self._time_run_simulator[0 : self.num_runs]) 48 | 49 | def write( 50 | self, 51 | t, 52 | action, 53 | time_total=None, 54 | time_update_predictor=None, 55 | time_get_action=None, 56 | time_run_simulator=None, 57 | ): 58 | t = np.array(t) 59 | action = np.array(action) 60 | 61 | if t.ndim == 1: 62 | N = 1 63 | if len(t) != self.num_objectives: 64 | raise ValueError("t does not match the number of objectives") 65 | else: 66 | N = t.shape[0] 67 | if t.shape[1] != self.num_objectives: 68 | raise ValueError("t does not match the number of objectives") 69 | 70 | st = self.total_num_search 71 | en = st + N 72 | 73 | self.terminal_num_run[self.num_runs] = en 74 | self.fx[st:en] = t 75 | self.chosen_actions[st:en] = action 76 | self.num_runs += 1 77 | self.total_num_search += N 78 | 79 | # update Pareto set 80 | self.pareto.update_front(t) 81 | 82 | if time_total is None: 83 | time_total = np.zeros(N, dtype=float) 84 | self._time_total[st:en] = time_total 85 | 86 | if time_update_predictor is None: 87 | time_update_predictor = np.zeros(N, dtype=float) 88 | self._time_update_predictor[st:en] = time_update_predictor 89 | 90 | if time_get_action is None: 91 | time_get_action = np.zeros(N, dtype=float) 92 | self._time_get_action[st:en] = time_get_action 93 | 94 | if time_run_simulator is None: 95 | time_run_simulator = np.zeros(N, dtype=float) 96 | self._time_run_simulator[st:en] = time_run_simulator 97 | 98 | def export_pareto_front(self): 99 | return self.pareto.export_front() 100 | 101 | def save(self, filename): 102 | N = self.total_num_search 103 | M = self.num_runs 104 | 105 | obj = { 106 | "num_runs": M, 107 | "total_num_search": N, 108 | "fx": self.fx[0:N], 109 | "chosen_actions": self.chosen_actions[0:N], 110 | "terminal_num_run": self.terminal_num_run[0:M], 111 | "pareto": self.pareto, 112 | } 113 | 114 | with open(filename, "wb") as f: 115 | pickle.dump(obj, f) 116 | 117 | def load(self, filename): 118 | with open(filename, "rb") as f: 119 | data = pickle.load(f) 120 | 121 | M = int(data["num_runs"]) 122 | N = int(data["total_num_search"]) 123 | self.num_runs = M 124 | self.total_num_search = N 125 | self.fx[0:N] = data["fx"] 126 | self.chosen_actions[0:N] = data["chosen_actions"] 127 | self.terminal_num_run[0:M] = data["terminal_num_run"] 128 | self.pareto = data["pareto"] 129 | -------------------------------------------------------------------------------- /physbo/search/score.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | import scipy.stats 10 | 11 | 12 | def score(mode, predictor, test, training=None, **kwargs): 13 | """ 14 | Calculate scores (acquisition function) for test data. 15 | 16 | Parameters 17 | ---------- 18 | mode: str 19 | Kind of score. 20 | 21 | "EI", "PI", and "TS" are available. 22 | 23 | predictor: predictor object 24 | Base class is defined in physbo.predictor. 25 | 26 | training: physbo.variable 27 | Training dataset. 28 | If the predictor is not trained, use this for training. 29 | 30 | test: physbo.variable 31 | Inputs 32 | 33 | Other Parameters 34 | ---------------- 35 | fmax: float 36 | Max value of mean of posterior probability distribution. 37 | If not set, the maximum value of posterior mean for training is used. 38 | Used only for mode == "EI" and "PI" 39 | 40 | alpha: float 41 | noise for sampling source (default: 1.0) 42 | Used only for mode == "TS" 43 | 44 | Returns 45 | ------- 46 | score: numpy.ndarray 47 | 48 | Raises 49 | ------ 50 | NotImplementedError 51 | If unknown mode is given 52 | """ 53 | 54 | if test.X.shape[0] == 0: 55 | return np.zeros(0) 56 | 57 | if mode == "EI": 58 | fmax = kwargs.get("fmax", None) 59 | return EI(predictor, training, test, fmax) 60 | elif mode == "PI": 61 | fmax = kwargs.get("fmax", None) 62 | return PI(predictor, training, test, fmax) 63 | elif mode == "TS": 64 | alpha = kwargs.get("alpha", 1.0) 65 | return TS(predictor, training, test, alpha) 66 | else: 67 | raise NotImplementedError("ERROR: mode must be EI, PI or TS.") 68 | 69 | 70 | def EI(predictor, training, test, fmax=None): 71 | """ 72 | Maximum expected improvement. 73 | 74 | Parameters 75 | ---------- 76 | predictor: predictor object 77 | Base class is defined in physbo.predictor. 78 | training: physbo.variable 79 | Training dataset. 80 | If the predictor is not trained, use this for training. 81 | test: physbo.variable 82 | Inputs 83 | fmax: float 84 | Max value of posterior probability distribution. 85 | If not set, the maximum value of posterior mean for training is used. 86 | Returns 87 | ------- 88 | score: numpy.ndarray 89 | """ 90 | fmean = predictor.get_post_fmean(training, test) 91 | fcov = predictor.get_post_fcov(training, test) 92 | fstd = np.sqrt(fcov) 93 | 94 | if fmax is None: 95 | fmax = np.max(predictor.get_post_fmean(training, training)) 96 | 97 | temp1 = fmean - fmax 98 | temp2 = temp1 / fstd 99 | score = temp1 * scipy.stats.norm.cdf(temp2) + fstd * scipy.stats.norm.pdf(temp2) 100 | return score 101 | 102 | 103 | def PI(predictor, training, test, fmax=None): 104 | """ 105 | Maximum probability of improvement. 106 | 107 | Parameters 108 | ---------- 109 | predictor: predictor object 110 | Base class is defined in physbo.predictor. 111 | training: physbo.variable 112 | Training dataset. 113 | If the predictor is not trained, use this for training. 114 | test: physbo.variable 115 | Inputs 116 | fmax: float 117 | Max value of posterior probability distribution. 118 | If not set, the maximum value of posterior mean for training is used. 119 | Returns 120 | ------- 121 | score: numpy.ndarray 122 | """ 123 | fmean = predictor.get_post_fmean(training, test) 124 | fcov = predictor.get_post_fcov(training, test) 125 | fstd = np.sqrt(fcov) 126 | 127 | if fmax is None: 128 | fmax = np.max(predictor.get_post_fmean(training, training)) 129 | 130 | temp = (fmean - fmax) / fstd 131 | score = scipy.stats.norm.cdf(temp) 132 | return score 133 | 134 | 135 | def TS(predictor, training, test, alpha=1): 136 | """ 137 | Thompson sampling (See Sec. 2.1 in Materials Discovery Volume 4, June 2016, Pages 18-21) 138 | 139 | Parameters 140 | ---------- 141 | predictor: predictor object 142 | Base class is defined in physbo.predictor. 143 | training: physbo.variable 144 | Training dataset. 145 | If the predictor is not trained, use this for training. 146 | test: physbo.variable 147 | Inputs 148 | alpha: float 149 | noise for sampling source 150 | (default: 1.0) 151 | Returns 152 | ------- 153 | score: numpy.ndarray 154 | """ 155 | return (predictor.get_post_samples(training, test, alpha=alpha)).flatten() 156 | -------------------------------------------------------------------------------- /physbo/search/utility.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | def show_search_results(history, N): 12 | n = history.total_num_search 13 | index = np.argmax(history.fx[0:n]) 14 | 15 | if N == 1: 16 | print( 17 | "%04d-th step: f(x) = %f (action=%d)" 18 | % (n, history.fx[n - 1], history.chosen_actions[n - 1]) 19 | ) 20 | print( 21 | " current best f(x) = %f (best action=%d) \n" 22 | % (history.fx[index], history.chosen_actions[index]) 23 | ) 24 | else: 25 | print( 26 | "current best f(x) = %f (best action = %d) " 27 | % (history.fx[index], history.chosen_actions[index]) 28 | ) 29 | 30 | print("list of simulation results") 31 | st = history.total_num_search - N 32 | en = history.total_num_search 33 | for n in range(st, en): 34 | print("f(x)=%f (action = %d)" % (history.fx[n], history.chosen_actions[n])) 35 | print("\n") 36 | 37 | 38 | def show_search_results_mo(history, N, disp_pareto_set=False): 39 | n = history.total_num_search 40 | pset, step = history.pareto.export_front() 41 | 42 | def msg_pareto_set_updated(indent=False): 43 | prefix = " " if indent else "" 44 | if history.pareto.front_updated: 45 | print(prefix + "Pareto set updated.") 46 | if disp_pareto_set: 47 | print( 48 | prefix 49 | + "current Pareto set = %s (steps = %s) \n" 50 | % (str(pset), str(step + 1)) 51 | ) 52 | else: 53 | print( 54 | prefix + "the number of Pareto frontiers = %s \n" % str(len(step)) 55 | ) 56 | 57 | if N == 1: 58 | print( 59 | "%04d-th step: f(x) = %s (action = %d)" 60 | % (n, str(history.fx[n - 1]), history.chosen_actions[n - 1]) 61 | ) 62 | 63 | msg_pareto_set_updated(indent=True) 64 | 65 | else: 66 | msg_pareto_set_updated() 67 | 68 | print("list of simulation results") 69 | st = history.total_num_search - N 70 | en = history.total_num_search 71 | for n in range(st, en): 72 | print( 73 | "f(x) = %s (action = %d)" 74 | % (str(history.fx[n]), history.chosen_actions[n]) 75 | ) 76 | print("\n") 77 | 78 | 79 | def show_start_message_multi_search(N, score=None): 80 | if score is None: 81 | score = "random" 82 | print(f"{N+1:04}-th multiple probe search ({score})") 83 | 84 | 85 | def show_interactive_mode(simulator, history): 86 | if simulator is None and history.total_num_search == 0: 87 | print("interactive mode starts ... \n ") 88 | 89 | 90 | def length_vector(t): 91 | N = len(t) if hasattr(t, "__len__") else 1 92 | return N 93 | 94 | 95 | def is_learning(n, interval): 96 | if interval == 0: 97 | return n == 0 98 | elif interval > 0: 99 | return np.mod(n, interval) == 0 100 | else: 101 | return False 102 | -------------------------------------------------------------------------------- /physbo/variable.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import numpy as np 9 | 10 | 11 | class variable(object): 12 | def __init__(self, X=None, t=None, Z=None): 13 | """ 14 | 15 | Parameters 16 | ---------- 17 | X: numpy array 18 | N x d dimensional matrix. Each row of X denotes the d-dimensional feature vector of each search candidate. 19 | t: numpy array 20 | N dimensional array. The negative energy of each search candidate (value of the objective function to be optimized). 21 | Z: 22 | 23 | """ 24 | self.X = X 25 | self.Z = Z 26 | self.t = t 27 | 28 | def get_subset(self, index): 29 | """ 30 | Getting subset of variables. 31 | 32 | Parameters 33 | ---------- 34 | index: int or array of int 35 | Index of selected action. 36 | Returns 37 | ------- 38 | variable: physbo.variable 39 | """ 40 | temp_X = self.X[index, :] if self.X is not None else None 41 | temp_t = self.t[index] if self.t is not None else None 42 | temp_Z = self.Z[index, :] if self.Z is not None else None 43 | 44 | return variable(X=temp_X, t=temp_t, Z=temp_Z) 45 | 46 | def delete(self, num_row): 47 | """ 48 | Deleting variables of X, t, Z whose indexes are specified by num_row. 49 | 50 | Parameters 51 | ---------- 52 | num_row: numpy array 53 | Index array to be deleted. 54 | 55 | Returns 56 | ------- 57 | 58 | """ 59 | self.delete_X(num_row) 60 | self.delete_t(num_row) 61 | self.delete_Z(num_row) 62 | 63 | def add(self, X=None, t=None, Z=None): 64 | """ 65 | Adding variables of X, t, Z. 66 | 67 | Parameters 68 | ---------- 69 | X: numpy array 70 | N x d dimensional matrix. Each row of X denotes the d-dimensional feature vector of each search candidate. 71 | t: numpy array 72 | N dimensional array. The negative energy of each search candidate (value of the objective function to be optimized). 73 | Z 74 | 75 | Returns 76 | ------- 77 | 78 | """ 79 | self.add_X(X) 80 | self.add_t(t) 81 | self.add_Z(Z) 82 | 83 | def delete_X(self, num_row): 84 | """ 85 | Deleting variables of X whose indexes are specified by num_row. 86 | 87 | 88 | Parameters 89 | ---------- 90 | num_row: numpy array 91 | Index array to be deleted. 92 | 93 | Returns 94 | ------- 95 | 96 | """ 97 | if self.X is not None: 98 | self.X = np.delete(self.X, num_row, 0) 99 | 100 | def delete_t(self, num_row): 101 | """ 102 | Deleting variables of t whose indexes are specified by num_row. 103 | 104 | Parameters 105 | ---------- 106 | num_row: numpy array 107 | Index array to be deleted. 108 | 109 | Returns 110 | ------- 111 | 112 | """ 113 | if self.t is not None: 114 | self.t = np.delete(self.t, num_row) 115 | 116 | def delete_Z(self, num_row): 117 | """ 118 | Deleting variables of Z whose indexes are specified by num_row. 119 | 120 | Parameters 121 | ---------- 122 | num_row: numpy array 123 | Index array to be deleted. 124 | 125 | Returns 126 | ------- 127 | 128 | """ 129 | if self.Z is not None: 130 | self.Z = np.delete(self.Z, num_row, 0) 131 | 132 | def add_X(self, X=None): 133 | """ 134 | Adding variable X. If self.X is None, self.X is set as X. 135 | 136 | Parameters 137 | ---------- 138 | X: numpy array 139 | N x d dimensional matrix. Each row of X denotes the d-dimensional feature vector of each search candidate. 140 | 141 | Returns 142 | ------- 143 | 144 | """ 145 | if X is not None: 146 | if self.X is not None: 147 | self.X = np.vstack((self.X, X)) 148 | else: 149 | self.X = X 150 | 151 | def add_t(self, t=None): 152 | """ 153 | Adding variable t. If self.t is None, self.t is set as t. 154 | 155 | Parameters 156 | ---------- 157 | t: numpy array 158 | N dimensional array. The negative energy of each search candidate (value of the objective function to be optimized). 159 | 160 | Returns 161 | ------- 162 | 163 | """ 164 | if not isinstance(t, np.ndarray): 165 | t = np.array([t]) 166 | 167 | if t is not None: 168 | if self.t is not None: 169 | self.t = np.hstack((self.t, t)) 170 | else: 171 | self.t = t 172 | 173 | def add_Z(self, Z=None): 174 | """ 175 | Adding variable Z. If self.Z is None, self.Z is set as Z. 176 | 177 | Parameters 178 | ---------- 179 | Z 180 | 181 | Returns 182 | ------- 183 | 184 | """ 185 | if Z is not None: 186 | if self.Z is None: 187 | self.Z = Z 188 | else: 189 | self.Z = np.vstack((self.Z, Z)) 190 | 191 | def save(self, file_name): 192 | """ 193 | Saving variables X, t, Z to the file. 194 | 195 | Parameters 196 | ---------- 197 | file_name: str 198 | A file name for saving variables X, t, Z using numpy.savez_compressed. 199 | 200 | Returns 201 | ------- 202 | 203 | """ 204 | np.savez_compressed(file_name, X=self.X, t=self.t, Z=self.Z) 205 | 206 | def load(self, file_name): 207 | """ 208 | Loading variables X, t, Z from the file. 209 | 210 | Parameters 211 | ---------- 212 | file_name: str 213 | A file name for loading variables X, t, Z using numpy.load. 214 | 215 | Returns 216 | ------- 217 | 218 | """ 219 | data = np.load(file_name, allow_pickle=True) 220 | self.X = data["X"] 221 | self.t = data["t"] 222 | self.Z = data["Z"] 223 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "wheel", "cython", "numpy<2.0"] 3 | build-backend = "setuptools.build_meta" 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = physbo 3 | version = 2.2.0 4 | description = optimization tool for PHYSics based on Bayesian Optimization 5 | long_description = file: README.md 6 | long_description_content_type = text/markdown 7 | url = https://github.com/issp-center-dev/PHYSBO 8 | license = MPLv2 9 | author = PHYSBO developers 10 | author_email = physbo-dev@issp.u-tokyo.ac.jp 11 | 12 | [options] 13 | packages = find: 14 | zip_safe = False 15 | python_requires= >=3.6 16 | install_requires = 17 | numpy < 2.0 18 | scipy 19 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from Cython.Build import cythonize 9 | from Cython.Distutils import build_ext 10 | from setuptools import setup, Extension 11 | 12 | import numpy 13 | 14 | compile_flags = [ 15 | "-O3", 16 | ] 17 | ext_mods = [ 18 | Extension( 19 | name="physbo.misc._src.traceAB", 20 | sources=["physbo/misc/_src/traceAB.pyx"], 21 | include_dirs=[numpy.get_include()], 22 | extra_compile_args=compile_flags, 23 | ), 24 | Extension( 25 | name="physbo.misc._src.cholupdate", 26 | sources=["physbo/misc/_src/cholupdate.pyx"], 27 | include_dirs=[numpy.get_include()], 28 | extra_compile_args=compile_flags, 29 | ), 30 | Extension( 31 | name="physbo.misc._src.diagAB", 32 | sources=["physbo/misc/_src/diagAB.pyx"], 33 | include_dirs=[numpy.get_include()], 34 | extra_compile_args=compile_flags, 35 | ), 36 | Extension( 37 | name="physbo.gp.cov._src.enhance_gauss", 38 | sources=["physbo/gp/cov/_src/enhance_gauss.pyx"], 39 | include_dirs=[numpy.get_include()], 40 | extra_compile_args=compile_flags, 41 | ), 42 | Extension( 43 | name="physbo.misc._src.logsumexp", 44 | sources=["physbo/misc/_src/logsumexp.pyx"], 45 | include_dirs=[numpy.get_include()], 46 | extra_compile_args=compile_flags, 47 | ), 48 | ] 49 | setup( 50 | package_dir={"physbo": "physbo"}, 51 | cmdclass={"build_ext": build_ext}, 52 | ext_modules=ext_mods, 53 | ) 54 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | To test not the *local* package but the *installed* package, do NOT make `__init__.py` in this directory. 2 | -------------------------------------------------------------------------------- /tests/integrated/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/integrated/test_gp.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from __future__ import print_function 9 | 10 | from itertools import product 11 | 12 | import numpy as np 13 | import pytest 14 | 15 | physbo = pytest.importorskip("physbo") 16 | 17 | 18 | def f(x): 19 | return -np.sum((x - 0.5) ** 2) 20 | 21 | 22 | class simulator: 23 | def __init__(self, noise=1.0e-5): 24 | np.random.seed(12345) 25 | self.nslice = 11 26 | self.dim = 2 27 | self.N = self.nslice**self.dim 28 | self.X = np.zeros((self.N, self.dim)) 29 | self.t = np.zeros(self.N) 30 | for i, x in enumerate( 31 | product(np.linspace(0.0, 1.0, self.nslice), repeat=self.dim) 32 | ): 33 | lx = list(x) 34 | self.X[i, :] = lx 35 | self.t[i] = f(self.X[i, :]) + noise * np.random.randn() 36 | 37 | 38 | def test_gp(): 39 | sim = simulator() 40 | X = sim.X 41 | t = sim.t 42 | X = physbo.misc.centering(X) 43 | 44 | np.random.seed(12345) 45 | N = len(t) 46 | Ntrain = int(N * 0.8) 47 | Ntest = N - Ntrain 48 | id_all = np.random.choice(len(t), len(t), replace=False) 49 | id_train = id_all[0:Ntrain] 50 | id_test = id_all[Ntrain:N] 51 | 52 | X_train = X[id_train] 53 | X_test = X[id_test] 54 | 55 | t_train = t[id_train] 56 | t_test = t[id_test] 57 | 58 | cov = physbo.gp.cov.gauss(X_train.shape[1], ard=False) 59 | mean = physbo.gp.mean.const() 60 | lik = physbo.gp.lik.gauss() 61 | 62 | gp = physbo.gp.model(lik=lik, mean=mean, cov=cov) 63 | config = physbo.misc.set_config() 64 | 65 | gp.fit(X_train, t_train, config) 66 | gp.print_params() 67 | 68 | gp.prepare(X_train, t_train) 69 | fmean = gp.get_post_fmean(X_train, X_test) 70 | _ = gp.get_post_fcov(X_train, X_test) 71 | 72 | res = np.mean((fmean - t_test) ** 2) 73 | ref = 1.0891454518475606e-05 74 | assert res == pytest.approx(ref, rel=1e-3) 75 | 76 | # restart 77 | cov = physbo.gp.cov.gauss(X_train.shape[1], ard=False) 78 | mean = physbo.gp.mean.const() 79 | lik = physbo.gp.lik.gauss() 80 | gp2 = physbo.gp.model(lik=lik, mean=mean, cov=cov) 81 | gp_params = np.append( 82 | np.append(gp.lik.params, gp.prior.mean.params), gp.prior.cov.params 83 | ) 84 | gp2.set_params(gp_params) 85 | gp2.prepare(X_train, t_train) 86 | fmean = gp2.get_post_fmean(X_train, X_test) 87 | _ = gp2.get_post_fcov(X_train, X_test) 88 | 89 | res2 = np.mean((fmean - t_test) ** 2) 90 | assert res == res2 91 | -------------------------------------------------------------------------------- /tests/integrated/test_interactive_example.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from __future__ import print_function 9 | 10 | from itertools import product 11 | 12 | import numpy as np 13 | import pytest 14 | 15 | physbo = pytest.importorskip("physbo") 16 | 17 | 18 | def f(x): 19 | return -np.sum((x - 0.5) ** 2) 20 | 21 | 22 | class simulator: 23 | def __init__(self): 24 | self.nslice = 11 25 | self.dim = 2 26 | self.N = self.nslice**self.dim 27 | self.X = np.zeros((self.N, self.dim)) 28 | for i, x in enumerate( 29 | product(np.linspace(0.0, 1.0, self.nslice), repeat=self.dim) 30 | ): 31 | self.X[i, :] = list(x) 32 | 33 | def __call__(self, actions): 34 | return np.array([f(self.X[action, :]) for action in actions]) 35 | 36 | 37 | def test_interactive(): 38 | sim = simulator() 39 | nrand = 10 40 | nsearch = 5 41 | policy = physbo.search.discrete.policy(test_X=sim.X) 42 | policy.set_seed(12345) 43 | 44 | actions = policy.random_search( 45 | max_num_probes=1, num_search_each_probe=nrand, simulator=None 46 | ) 47 | targets = sim(actions) 48 | print(actions) 49 | print(targets) 50 | policy.write(actions, targets) 51 | physbo.search.utility.show_search_results(policy.history, nrand) 52 | 53 | actions = policy.bayes_search( 54 | max_num_probes=1, num_search_each_probe=nsearch, simulator=None, score="TS" 55 | ) 56 | targets = sim(actions) 57 | print(actions) 58 | print(targets) 59 | policy.write(actions, targets) 60 | physbo.search.utility.show_search_results(policy.history, nsearch) 61 | 62 | res = policy.history 63 | best_fx, best_action = res.export_all_sequence_best_fx() 64 | print(best_fx) 65 | print(best_action) 66 | assert best_fx[-1] == pytest.approx(0.0, abs=0.001) 67 | assert best_action[-1] == 60 68 | -------------------------------------------------------------------------------- /tests/integrated/test_multi_objective.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from __future__ import print_function 9 | 10 | from itertools import product 11 | 12 | import numpy as np 13 | import pytest 14 | 15 | physbo = pytest.importorskip("physbo") 16 | 17 | 18 | def vlmop2_minus(x): 19 | n = x.shape[1] 20 | y1 = 1 - np.exp(-1 * np.sum((x - 1 / np.sqrt(n)) ** 2, axis=1)) 21 | y2 = 1 - np.exp(-1 * np.sum((x + 1 / np.sqrt(n)) ** 2, axis=1)) 22 | 23 | return np.c_[-y1, -y2] 24 | 25 | 26 | class simulator: 27 | def __init__(self): 28 | a = np.linspace(-2, 2, 11) 29 | self.X = np.array(list(product(a, a))) 30 | self.t = vlmop2_minus(self.X) 31 | 32 | def __call__(self, action): 33 | return self.t[action] 34 | 35 | 36 | def test_multi_objective_EHVI(): 37 | sim = simulator() 38 | nrand = 10 39 | nsearch = 5 40 | policy = physbo.search.discrete_multi.policy(test_X=sim.X, num_objectives=2) 41 | policy.set_seed(12345) 42 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 43 | res = policy.bayes_search(max_num_probes=nsearch, simulator=sim, score="EHVI") 44 | vid = res.pareto.volume_in_dominance([-1, -1], [0, 0]) 45 | vid_ref = 0.2392468337984477 46 | assert vid == pytest.approx(vid_ref, rel=1e-3) 47 | policy.get_score("EHVI", xs=sim.X) 48 | 49 | 50 | def test_multi_objective_HVPI(): 51 | sim = simulator() 52 | nrand = 10 53 | nsearch = 5 54 | policy = physbo.search.discrete_multi.policy(test_X=sim.X, num_objectives=2) 55 | policy.set_seed(12345) 56 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 57 | res = policy.bayes_search(max_num_probes=nsearch, simulator=sim, score="HVPI") 58 | vid = res.pareto.volume_in_dominance([-1, -1], [0, 0]) 59 | vid_ref = 0.25322554948754283 60 | assert vid == pytest.approx(vid_ref, rel=1e-3) 61 | policy.get_score("HVPI", xs=sim.X) 62 | 63 | 64 | def test_multi_objective_TS(): 65 | sim = simulator() 66 | nrand = 10 67 | nsearch = 5 68 | policy = physbo.search.discrete_multi.policy(test_X=sim.X, num_objectives=2) 69 | policy.set_seed(12345) 70 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 71 | res = policy.bayes_search(max_num_probes=nsearch, simulator=sim, score="TS") 72 | vid = res.pareto.volume_in_dominance([-1, -1], [0, 0]) 73 | vid_ref = 0.17724278568874974 74 | assert vid == pytest.approx(vid_ref, rel=1e-3) 75 | policy.get_score("TS", xs=sim.X) 76 | 77 | 78 | def test_multi_objective_EHVI_rand(): 79 | sim = simulator() 80 | nrand = 10 81 | nsearch = 5 82 | policy = physbo.search.discrete_multi.policy(test_X=sim.X, num_objectives=2) 83 | policy.set_seed(12345) 84 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 85 | res = policy.bayes_search( 86 | max_num_probes=nsearch, simulator=sim, score="EHVI", num_rand_basis=100 87 | ) 88 | vid = res.pareto.volume_in_dominance([-1, -1], [0, 0]) 89 | vid_ref = 0.08400891973743863 90 | assert vid == pytest.approx(vid_ref, rel=1e-3) 91 | policy.get_score("EHVI", xs=sim.X) 92 | 93 | 94 | def test_multi_objective_HVPI_rand(): 95 | sim = simulator() 96 | nrand = 10 97 | nsearch = 5 98 | policy = physbo.search.discrete_multi.policy(test_X=sim.X, num_objectives=2) 99 | policy.set_seed(12345) 100 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 101 | res = policy.bayes_search( 102 | max_num_probes=nsearch, simulator=sim, score="HVPI", num_rand_basis=100 103 | ) 104 | vid = res.pareto.volume_in_dominance([-1, -1], [0, 0]) 105 | vid_ref = 0.13374086517165518 106 | assert vid == pytest.approx(vid_ref, rel=1e-3) 107 | policy.get_score("HVPI", xs=sim.X) 108 | 109 | 110 | def test_multi_objective_TS_rand(): 111 | sim = simulator() 112 | nrand = 10 113 | nsearch = 5 114 | policy = physbo.search.discrete_multi.policy(test_X=sim.X, num_objectives=2) 115 | policy.set_seed(12345) 116 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 117 | res = policy.bayes_search( 118 | max_num_probes=nsearch, simulator=sim, score="TS", num_rand_basis=100 119 | ) 120 | vid = res.pareto.volume_in_dominance([-1, -1], [0, 0]) 121 | vid_ref = 0.134435814966692 122 | assert vid == pytest.approx(vid_ref, rel=1e-3) 123 | policy.get_score("TS", xs=sim.X) 124 | -------------------------------------------------------------------------------- /tests/integrated/test_simple_example.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from __future__ import print_function 9 | 10 | from itertools import product 11 | 12 | import numpy as np 13 | import pytest 14 | 15 | physbo = pytest.importorskip("physbo") 16 | 17 | 18 | def f(x): 19 | return -np.sum((x - 0.5) ** 2) 20 | 21 | 22 | class simulator: 23 | def __init__(self): 24 | self.nslice = 11 25 | self.dim = 2 26 | self.N = self.nslice**self.dim 27 | self.X = np.zeros((self.N, self.dim)) 28 | for i, x in enumerate( 29 | product(np.linspace(0.0, 1.0, self.nslice), repeat=self.dim) 30 | ): 31 | self.X[i, :] = list(x) 32 | 33 | def __call__(self, action): 34 | return f(self.X[action, :]) 35 | 36 | 37 | def test_random_search(): 38 | sim = simulator() 39 | policy = physbo.search.discrete.policy(test_X=sim.X) 40 | policy.set_seed(12345) 41 | nsearch = 20 42 | res = policy.random_search(max_num_probes=nsearch, simulator=sim) 43 | best_fx, best_action = res.export_all_sequence_best_fx() 44 | print(best_fx[-1]) 45 | print(best_action[-1]) 46 | assert best_fx[-1] == pytest.approx(-0.01, abs=0.001) 47 | assert best_action[-1] == 61 48 | 49 | 50 | def test_bayes_search_EI(): 51 | sim = simulator() 52 | nrand = 10 53 | nsearch = 5 54 | policy = physbo.search.discrete.policy(test_X=sim.X) 55 | policy.set_seed(12345) 56 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 57 | res = policy.bayes_search(max_num_probes=nsearch, simulator=sim, score="EI") 58 | best_fx, best_action = res.export_all_sequence_best_fx() 59 | print(best_fx) 60 | print(best_action) 61 | assert best_fx[-1] == pytest.approx(0.0, abs=0.001) 62 | assert best_action[-1] == 60 63 | policy.get_score("EI", xs=sim.X) 64 | 65 | 66 | def test_bayes_search_EI_rand(): 67 | sim = simulator() 68 | nrand = 10 69 | nsearch = 5 70 | policy = physbo.search.discrete.policy(test_X=sim.X) 71 | policy.set_seed(12345) 72 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 73 | res = policy.bayes_search( 74 | max_num_probes=nsearch, simulator=sim, score="EI", num_rand_basis=100 75 | ) 76 | best_fx, best_action = res.export_all_sequence_best_fx() 77 | print(best_fx) 78 | print(best_action) 79 | assert best_fx[-1] == pytest.approx(0.0, abs=0.001) 80 | assert best_action[-1] == 60 81 | policy.get_score("EI", xs=sim.X) 82 | 83 | 84 | def test_bayes_search_PI(): 85 | sim = simulator() 86 | nrand = 10 87 | nsearch = 5 88 | policy = physbo.search.discrete.policy(test_X=sim.X) 89 | policy.set_seed(12345) 90 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 91 | res = policy.bayes_search(max_num_probes=nsearch, simulator=sim, score="PI") 92 | best_fx, best_action = res.export_all_sequence_best_fx() 93 | print(best_fx) 94 | print(best_action) 95 | assert best_fx[-1] == pytest.approx(0.0, abs=0.001) 96 | assert best_action[-1] == 60 97 | policy.get_score("PI", xs=sim.X) 98 | 99 | 100 | def test_bayes_search_PI_rand(): 101 | sim = simulator() 102 | nrand = 10 103 | nsearch = 5 104 | policy = physbo.search.discrete.policy(test_X=sim.X) 105 | policy.set_seed(12345) 106 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 107 | res = policy.bayes_search( 108 | max_num_probes=nsearch, simulator=sim, score="PI", num_rand_basis=100 109 | ) 110 | best_fx, best_action = res.export_all_sequence_best_fx() 111 | print(best_fx) 112 | print(best_action) 113 | assert best_fx[-1] == pytest.approx(0.0, abs=0.001) 114 | assert best_action[-1] == 60 115 | policy.get_score("PI", xs=sim.X) 116 | 117 | 118 | def test_bayes_search_TS(): 119 | sim = simulator() 120 | nrand = 10 121 | nsearch = 5 122 | policy = physbo.search.discrete.policy(test_X=sim.X) 123 | policy.set_seed(12345) 124 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 125 | res = policy.bayes_search(max_num_probes=nsearch, simulator=sim, score="TS") 126 | best_fx, best_action = res.export_all_sequence_best_fx() 127 | print(best_fx) 128 | print(best_action) 129 | assert best_fx[-1] == pytest.approx(0.0, abs=0.001) 130 | assert best_action[-1] == 60 131 | policy.get_score("TS", xs=sim.X) 132 | 133 | 134 | def test_bayes_search_TS_rand(): 135 | sim = simulator() 136 | nrand = 10 137 | nsearch = 5 138 | policy = physbo.search.discrete.policy(test_X=sim.X) 139 | policy.set_seed(12345) 140 | res = policy.random_search(max_num_probes=nrand, simulator=sim) 141 | res = policy.bayes_search( 142 | max_num_probes=nsearch, simulator=sim, score="TS", num_rand_basis=100 143 | ) 144 | best_fx, best_action = res.export_all_sequence_best_fx() 145 | print(best_fx) 146 | print(best_action) 147 | assert best_fx[-1] == pytest.approx(0.0, abs=0.001) 148 | assert best_action[-1] == 60 149 | policy.get_score("TS", xs=sim.X) 150 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/unit/test_gp.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from __future__ import print_function 9 | 10 | import pytest 11 | import numpy as np 12 | import numpy.random as random 13 | 14 | physbo = pytest.importorskip("physbo") 15 | 16 | 17 | def get_post_fmean(training, test): 18 | print(test) 19 | N = test.shape[0] 20 | return random.randn(N, 1) 21 | 22 | 23 | def get_post_fcov(training, test): 24 | print(test) 25 | N = test.shape[0] 26 | return np.ones((N, 1)) 27 | 28 | 29 | def get_post_samples(training, test, alpha=1.0): 30 | print(test) 31 | N = test.shape[0] 32 | return random.randn(N, 1) 33 | 34 | 35 | @pytest.fixture 36 | def predictor(mocker): 37 | p = mocker.MagicMock() 38 | p.get_post_fmean = mocker.MagicMock(side_effect=get_post_fmean) 39 | p.get_post_fcov = mocker.MagicMock(side_effect=get_post_fcov) 40 | p.get_post_samples = mocker.MagicMock(side_effect=get_post_samples) 41 | return p 42 | 43 | 44 | @pytest.fixture 45 | def X(): 46 | return np.array( 47 | [ 48 | [0.0, 0.0, 0.0], 49 | [1.0, 1.0, 1.0], 50 | [2.0, 2.0, 2.0], 51 | [3.0, 3.0, 3.0], 52 | [4.0, 4.0, 4.0], 53 | [5.0, 5.0, 5.0], 54 | ] 55 | ) 56 | 57 | 58 | @pytest.fixture 59 | def Y(): 60 | return np.array( 61 | [ 62 | [0.0, 0.0, 0.0], 63 | [1.0, 1.0, 1.0], 64 | [2.0, 2.0, 2.0], 65 | [3.0, 3.0, 3.0], 66 | ] 67 | ) 68 | 69 | 70 | @pytest.fixture 71 | def t(): 72 | return np.array([0.0, 1.0, 2.0, 3.0]) 73 | 74 | 75 | def test_gp(predictor, X, t, mocker): 76 | X = physbo.misc.centering(X) 77 | np.random.seed(12345) 78 | N = len(t) 79 | Ntrain = N - 1 80 | Ntest = N - Ntrain 81 | id_all = np.random.choice(len(t), len(t), replace=False) 82 | id_train = id_all[0:Ntrain] 83 | id_test = id_all[Ntrain:N] 84 | 85 | X_train = X[id_train] 86 | X_test = X[id_test] 87 | 88 | t_train = t[id_train] 89 | t_test = t[id_test] 90 | 91 | cov = physbo.gp.cov.gauss(X_train.shape[1], ard=False) 92 | mean = physbo.gp.mean.const() 93 | lik = physbo.gp.lik.gauss() 94 | 95 | adam_run_spy = mocker.spy(physbo.gp.core.learning.adam, "run") 96 | model_set_params_spy = mocker.spy(physbo.gp.core.model, "set_params") 97 | 98 | gp = physbo.gp.model(lik=lik, mean=mean, cov=cov) 99 | config = physbo.misc.set_config() 100 | gp.fit(X_train, t_train, config) 101 | 102 | adam_run_spy.assert_called() 103 | model_set_params_spy.assert_called() 104 | 105 | inf_prepare_spy = mocker.spy(physbo.gp.inf.exact, "prepare") 106 | gp.prepare(X_train, t_train) 107 | fmean = gp.get_post_fmean(X_train, X_test) 108 | inf_prepare_spy.assert_called() 109 | _ = gp.get_post_fcov(X_train, X_test) 110 | -------------------------------------------------------------------------------- /tests/unit/test_misc.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import sys 9 | 10 | import pytest 11 | import numpy as np 12 | 13 | physbo = pytest.importorskip("physbo") 14 | 15 | 16 | @pytest.fixture 17 | def X(): 18 | return np.array( 19 | [[0.0, 0.0, 0.0], [1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [3.0, 3.0, 3.0]] 20 | ) 21 | 22 | 23 | # @pytest.mark.parametrize("index", [2, [0, 1]]) 24 | def test_centering(X): 25 | dim = X.shape[1] 26 | centered = physbo.misc.centering(X) 27 | assert np.array_equal(centered.mean(axis=0), np.zeros(dim)) 28 | assert np.array_equal(centered.std(axis=0), np.ones(dim)) 29 | 30 | 31 | def test_gauss_elim(): 32 | np.random.seed(12345) 33 | N = 5 34 | U = np.random.randn(N, N) 35 | for i in range(N): 36 | for j in range(i): 37 | U[i, j] = 0.0 38 | ref = np.random.randn(N) 39 | t = np.dot(U, ref) 40 | t = np.dot(U.transpose(), t) 41 | res = physbo.misc.gauss_elim(U, t) 42 | np.testing.assert_array_almost_equal(res, ref) 43 | 44 | 45 | @pytest.mark.parametrize("NM", [(3, 5), (5, 3), (5, 5)]) 46 | def test_diagAB(NM): 47 | np.random.seed(12345) 48 | N = NM[0] 49 | M = NM[1] 50 | A = np.random.randn(N, M) 51 | B = np.random.randn(M, N) 52 | ref = np.dot(A, B).diagonal() 53 | res = physbo.misc.diagAB(A, B) 54 | np.testing.assert_array_almost_equal(res, ref) 55 | 56 | 57 | # Now work only for diagnal matrices 58 | @pytest.mark.parametrize("NM", [(3, 5), (5, 3), (5, 5)]) 59 | def test_traceAB2(NM): 60 | np.random.seed(12345) 61 | N = NM[0] 62 | M = NM[1] 63 | A = np.random.randn(N, M) 64 | B = np.random.randn(M, N) 65 | ref = np.dot(A, B).trace() 66 | res = physbo.misc.traceAB2(A, B) 67 | assert res == pytest.approx(ref) 68 | 69 | 70 | # Now work only for diagnal matrices 71 | @pytest.mark.parametrize("NM", [(3, 5), (5, 3), (5, 5)]) 72 | def test_traceAB3(NM): 73 | np.random.seed(12345) 74 | d = 2 75 | N = NM[0] 76 | M = NM[1] 77 | A = np.random.randn(N, M) 78 | B = np.random.randn(d, M, N) 79 | ref = [np.dot(A, B[i, :, :]).trace() for i in range(d)] 80 | res = physbo.misc.traceAB3(A, B) 81 | np.testing.assert_array_almost_equal(res, ref) 82 | 83 | 84 | def test_logsumexp64(): 85 | np.random.seed(12345) 86 | N = 10 87 | xs = np.random.randn(N) 88 | ref = np.log(sum(np.exp(xs))) 89 | res = physbo.misc.logsumexp64(xs) 90 | assert res == pytest.approx(ref) 91 | -------------------------------------------------------------------------------- /tests/unit/test_policy.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from __future__ import print_function 9 | 10 | import os 11 | import pickle 12 | import shutil 13 | import tempfile 14 | 15 | import pytest 16 | import numpy as np 17 | import numpy.testing 18 | 19 | 20 | physbo = pytest.importorskip("physbo") 21 | 22 | 23 | @pytest.fixture 24 | def X(): 25 | return np.array( 26 | [ 27 | [0.0, 0.0, 0.0], 28 | [1.0, 1.0, 1.0], 29 | [2.0, 2.0, 2.0], 30 | [3.0, 3.0, 3.0], 31 | [4.0, 4.0, 4.0], 32 | [5.0, 5.0, 5.0], 33 | ] 34 | ) 35 | 36 | 37 | @pytest.fixture 38 | def policy(): 39 | X = np.array( 40 | [ 41 | [0.0, 0.0, 0.0], 42 | [1.0, 1.0, 1.0], 43 | [2.0, 2.0, 2.0], 44 | [3.0, 3.0, 3.0], 45 | [4.0, 4.0, 4.0], 46 | [5.0, 5.0, 5.0], 47 | ] 48 | ) 49 | return physbo.search.discrete.policy(test_X=X) 50 | 51 | 52 | def test_write(policy, X): 53 | simulator = lambda x: 1.0 54 | ACTIONS = np.array([0, 1], np.int32) 55 | 56 | policy.write(ACTIONS, np.apply_along_axis(simulator, 1, X[ACTIONS])) 57 | numpy.testing.assert_array_equal( 58 | ACTIONS, policy.history.chosen_actions[: len(ACTIONS)] 59 | ) 60 | assert len(X) - len(ACTIONS) == len(policy.actions) 61 | 62 | 63 | def test_randomsearch(policy, mocker): 64 | simulator = mocker.MagicMock(return_value=1.0) 65 | write_spy = mocker.spy(physbo.search.discrete.policy, "write") 66 | 67 | N = 2 68 | 69 | # No simulator is passed: only returns candidates 70 | res = policy.random_search(1, num_search_each_probe=N) 71 | assert len(res) == N 72 | assert policy.history.num_runs == 0 73 | write_spy.assert_not_called() 74 | assert simulator.call_count == 0 75 | 76 | # A simulator is passed: N pairs of action and score are registered 77 | history = policy.random_search(N, simulator=simulator) 78 | assert history.num_runs == N 79 | write_spy.assert_called() 80 | assert simulator.call_count == N 81 | 82 | 83 | def test_bayes_search(policy, mocker): 84 | simulator = mocker.MagicMock(side_effect=lambda x: x) 85 | write_spy = mocker.spy(physbo.search.discrete.policy, "write") 86 | get_actions_spy = mocker.spy(physbo.search.discrete.policy, "_get_actions") 87 | 88 | N = 2 89 | 90 | # initial training 91 | policy.random_search(N, simulator=simulator) 92 | 93 | res = policy.bayes_search(max_num_probes=N, simulator=simulator, score="TS") 94 | assert res.num_runs == N + N 95 | assert write_spy.call_count == N + N 96 | assert simulator.call_count == N + N 97 | assert get_actions_spy.call_count == N 98 | 99 | 100 | def test_saveload(policy, X): 101 | simulator = lambda x: x 102 | 103 | N = 2 104 | policy.random_search(N, simulator=simulator) 105 | policy.bayes_search(max_num_probes=N, simulator=simulator, score="TS") 106 | 107 | with tempfile.TemporaryDirectory() as tempdir: 108 | policy.save( 109 | file_history=os.path.join(tempdir, "history.npz"), 110 | file_training=os.path.join(tempdir, "training.npz"), 111 | file_predictor=os.path.join(tempdir, "predictor.dump"), 112 | ) 113 | 114 | policy2 = physbo.search.discrete.policy(test_X=X) 115 | policy2.load( 116 | file_history=os.path.join(tempdir, "history.npz"), 117 | file_training=os.path.join(tempdir, "training.npz"), 118 | file_predictor=os.path.join(tempdir, "predictor.dump"), 119 | ) 120 | numpy.testing.assert_array_equal(policy.actions, policy2.actions) 121 | assert policy.history.num_runs == policy2.history.num_runs 122 | 123 | 124 | def test_get_score(policy, mocker, X): 125 | simulator = mocker.MagicMock(return_value=1.0) 126 | policy.random_search(2, simulator=simulator) 127 | policy.set_seed(137) 128 | 129 | res = policy.get_score("EI", xs=X) 130 | ref = np.array( 131 | [ 132 | 3.98940120e-07, 133 | 3.98934542e-07, 134 | 3.98924610e-07, 135 | 3.98914969e-07, 136 | 3.98911183e-07, 137 | 3.98914969e-07, 138 | ] 139 | ) 140 | numpy.testing.assert_allclose(res, ref) 141 | 142 | res = policy.get_score("PI", xs=X) 143 | print(res) 144 | ref = np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5]) 145 | numpy.testing.assert_allclose(res, ref) 146 | 147 | res = policy.get_score("TS", xs=X) 148 | ref = np.array( 149 | [1.00000021, 0.99999978, 0.9999993, 0.9999991, 0.99999905, 0.99999888] 150 | ) 151 | numpy.testing.assert_allclose(res, ref) 152 | 153 | with pytest.raises(NotImplementedError): 154 | policy.get_score("XX") 155 | -------------------------------------------------------------------------------- /tests/unit/test_search.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | from __future__ import print_function 9 | 10 | import pytest 11 | import numpy as np 12 | import numpy.random as random 13 | 14 | physbo = pytest.importorskip("physbo") 15 | 16 | 17 | def get_post_fmean(training, test): 18 | print(test) 19 | N = test.shape[0] 20 | return random.randn(N, 1) 21 | 22 | 23 | def get_post_fcov(training, test): 24 | print(test) 25 | N = test.shape[0] 26 | return np.ones((N, 1)) 27 | 28 | 29 | def get_post_samples(training, test, alpha=1.0): 30 | print(test) 31 | N = test.shape[0] 32 | return random.randn(N, 1) 33 | 34 | 35 | @pytest.fixture 36 | def predictor(mocker): 37 | p = mocker.MagicMock() 38 | p.get_post_fmean = mocker.MagicMock(side_effect=get_post_fmean) 39 | p.get_post_fcov = mocker.MagicMock(side_effect=get_post_fcov) 40 | p.get_post_samples = mocker.MagicMock(side_effect=get_post_samples) 41 | return p 42 | 43 | 44 | @pytest.fixture 45 | def X(): 46 | return np.array( 47 | [ 48 | [0.0, 0.0, 0.0], 49 | [1.0, 1.0, 1.0], 50 | [2.0, 2.0, 2.0], 51 | [3.0, 3.0, 3.0], 52 | [4.0, 4.0, 4.0], 53 | [5.0, 5.0, 5.0], 54 | ] 55 | ) 56 | 57 | 58 | @pytest.fixture 59 | def Y(): 60 | return np.array( 61 | [ 62 | [0.0, 0.0, 0.0], 63 | [1.0, 1.0, 1.0], 64 | [2.0, 2.0, 2.0], 65 | [3.0, 3.0, 3.0], 66 | ] 67 | ) 68 | 69 | 70 | def test_EI(predictor, X, Y): 71 | N = Y.shape[0] 72 | score = physbo.search.score.EI(predictor, X, Y) 73 | assert score.shape[0] == N 74 | predictor.get_post_fmean.assert_any_call(X, Y) 75 | predictor.get_post_fcov.assert_called_once_with(X, Y) 76 | predictor.get_post_samples.assert_not_called() 77 | 78 | predictor.get_post_fmean.reset_mock() 79 | predictor.get_post_fcov.reset_mock() 80 | predictor.get_post_samples.reset_mock() 81 | 82 | score = physbo.search.score.EI(predictor, X, Y, fmax=1.0) 83 | assert score.shape[0] == N 84 | predictor.get_post_fmean.assert_called_once_with(X, Y) 85 | predictor.get_post_fcov.assert_called_once_with(X, Y) 86 | predictor.get_post_samples.assert_not_called() 87 | 88 | 89 | def test_PI(predictor, X, Y): 90 | N = Y.shape[0] 91 | score = physbo.search.score.PI(predictor, X, Y) 92 | assert score.shape[0] == N 93 | predictor.get_post_fmean.assert_any_call(X, Y) 94 | predictor.get_post_fcov.assert_called_once_with(X, Y) 95 | predictor.get_post_samples.assert_not_called() 96 | 97 | predictor.get_post_fmean.reset_mock() 98 | predictor.get_post_fcov.reset_mock() 99 | predictor.get_post_samples.reset_mock() 100 | 101 | score = physbo.search.score.EI(predictor, X, Y, fmax=1.0) 102 | assert score.shape[0] == N 103 | predictor.get_post_fmean.assert_called_once_with(X, Y) 104 | predictor.get_post_fcov.assert_called_once_with(X, Y) 105 | predictor.get_post_samples.assert_not_called() 106 | 107 | 108 | def test_TS(predictor, X, Y): 109 | N = Y.shape[0] 110 | alpha = 1.0 111 | score = physbo.search.score.TS(predictor, X, Y, alpha=alpha) 112 | assert score.shape[0] == N 113 | predictor.get_post_fmean.assert_not_called() 114 | predictor.get_post_fcov.assert_not_called() 115 | predictor.get_post_samples.assert_called_once_with(X, Y, alpha=alpha) 116 | -------------------------------------------------------------------------------- /tests/unit/test_variable.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MPL-2.0 2 | # Copyright (C) 2020- The University of Tokyo 3 | # 4 | # This Source Code Form is subject to the terms of the Mozilla Public 5 | # License, v. 2.0. If a copy of the MPL was not distributed with this 6 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | 8 | import sys 9 | 10 | import pytest 11 | import numpy as np 12 | 13 | physbo = pytest.importorskip("physbo") 14 | 15 | 16 | @pytest.fixture 17 | def X(): 18 | return np.array( 19 | [[0.0, 0.0, 0.0], [1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [3.0, 3.0, 3.0]] 20 | ) 21 | 22 | 23 | @pytest.fixture 24 | def t(): 25 | return np.array([0.0, 1.0, 2.0, 3.0]) 26 | 27 | 28 | @pytest.fixture 29 | def Z(): 30 | return np.array([[0.0, 0.0], [1.0, 1.0], [2.0, 2.0], [3.0, 3.0]]) 31 | 32 | 33 | @pytest.fixture 34 | def variable(X, t, Z): 35 | return physbo.variable(X=X, t=t, Z=Z) 36 | 37 | 38 | @pytest.mark.parametrize("index", [2, [0, 1]]) 39 | def test_get_subset(variable, X, t, Z, index): 40 | var2 = variable.get_subset(index) 41 | assert np.array_equal(var2.X, X[index, :]) 42 | assert np.array_equal(var2.t, t[index]) 43 | assert np.array_equal(var2.Z, Z[index, :]) 44 | 45 | 46 | 47 | @pytest.mark.parametrize("index", [2, [0, 1]]) 48 | def test_delete_X(variable, X, index): 49 | variable.delete_X(index) 50 | ref = np.delete(X, index, 0) 51 | assert np.array_equal(variable.X, ref) 52 | 53 | 54 | @pytest.mark.parametrize("index", [2, [0, 1]]) 55 | def test_delete_t(variable, t, index): 56 | variable.delete_t(index) 57 | ref = np.delete(t, index) 58 | assert np.array_equal(variable.t, ref) 59 | 60 | 61 | @pytest.mark.parametrize("index", [2, [0, 1]]) 62 | def test_delete_Z(variable, Z, index): 63 | variable.delete_Z(index) 64 | ref = np.delete(Z, index, 0) 65 | assert np.array_equal(variable.Z, ref) 66 | 67 | 68 | def test_add(variable, X, t, Z, mocker): 69 | variable.add(X, t, Z) 70 | assert np.array_equal(variable.X, np.vstack((X,X))) 71 | assert np.array_equal(variable.t, np.hstack((t,t))) 72 | assert np.array_equal(variable.Z, np.vstack((Z,Z))) 73 | 74 | 75 | def test_add_X(variable, X): 76 | n = X.shape[0] 77 | variable.add_X(X) 78 | assert np.array_equal(variable.X[n : 2 * n, :], X) 79 | 80 | 81 | def test_add_t(variable, t): 82 | n = t.shape[0] 83 | variable.add_t(t) 84 | assert np.array_equal(variable.t[n : 2 * n], t) 85 | 86 | 87 | def test_add_Z(variable, Z): 88 | n = Z.shape[0] 89 | variable.add_Z(Z) 90 | assert np.array_equal(variable.Z[n : 2 * n, :], Z) 91 | 92 | 93 | def test_save_load(variable, tmpdir): 94 | tmpfile = tmpdir.join("tmpfile.npz") 95 | filename = str(tmpfile) 96 | variable.save(filename) 97 | var2 = physbo.variable() 98 | var2.load(filename) 99 | assert np.array_equal(variable.X, var2.X) 100 | assert np.array_equal(variable.t, var2.t) 101 | assert np.array_equal(variable.Z, var2.Z) 102 | 103 | variable.Z = None 104 | variable.save(filename) 105 | var2 = physbo.variable() 106 | var2.load(filename) 107 | assert np.array_equal(variable.X, var2.X) 108 | assert np.array_equal(variable.t, var2.t) 109 | assert np.array_equal(variable.Z, var2.Z) 110 | tmpfile.remove() 111 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | requires = tox>=4 3 | envlist = py37, py38, py39, py310, py311, docs 4 | isolated_build = true 5 | 6 | [gh-actions] 7 | python = 8 | '3.7': py37 9 | '3.8': py38 10 | '3.9': py39 11 | '3.10': py310 12 | '3.11': py311 13 | 14 | [testenv] 15 | deps = 16 | pytest 17 | pytest-mock 18 | 19 | commands = 20 | pytest --capture=sys 21 | 22 | [testenv:docs] 23 | description = invoke sphinx-build to build the HTML docs 24 | basepython = python3.10 25 | deps = 26 | sphinx 27 | sphinx_rtd_theme 28 | recommonmark 29 | ipykernel 30 | nbsphinx 31 | pybtex 32 | ipython_genutils 33 | numpy 34 | scipy 35 | allowlist_externals = rm 36 | passenv = CI, TARGET_NAME 37 | 38 | commands = 39 | rm -rf docs/sphinx/manual/ja/source/api 40 | rm -rf docs/sphinx/manual/en/source/api 41 | sphinx-apidoc -f -e -o docs/sphinx/manual/ja/source/api physbo 42 | sphinx-apidoc -f -e -o docs/sphinx/manual/en/source/api physbo 43 | sphinx-build -d "{toxworkdir}/docs_out/doctree/ja" docs/sphinx/manual/ja/source "{toxworkdir}/docs_out/manual/ja" --color -bhtml {posargs} 44 | sphinx-build -d "{toxworkdir}/docs_out/doctree/en" docs/sphinx/manual/en/source "{toxworkdir}/docs_out/manual/en" --color -bhtml {posargs} 45 | --------------------------------------------------------------------------------