Commit 7f15aba4 authored by Konstantinos Chatzilygeroudis's avatar Konstantinos Chatzilygeroudis
Browse files

Merge remote-tracking branch 'origin' into spt_cmaes

parents a090b3e9 678eee70
......@@ -26,3 +26,7 @@ __pycache__
_build
doxygen_doc
docs/defaults.rst
# Ignored folders/files of the paper
paper.pdf
paper.xml
......@@ -7,6 +7,7 @@ os:
sudo: required
dist: trusty
group: deprecated-2017Q4
compiler:
- gcc
......@@ -64,6 +65,7 @@ addons:
before_install:
- sudo sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers
- sudo rm /etc/apt/sources.list.d/mongodb-3.2.list
install:
- if [ "$EIGEN33" = "ON" ]; then 'ci/install_eigen3_3.sh' ; else 'ci/install_eigen3.sh' ; fi
......@@ -72,7 +74,6 @@ install:
- if [ "$TBB" = "ON" ]; then 'ci/install_tbb.sh' ; fi
- if [ "$SFERES" = "ON" ]; then 'ci/install_sferes.sh' ; fi
# Change this to your needs
script:
- if [ "$SFERES" = "OFF" ]; then $PYTHON ./waf configure $LAPACKE ; else $PYTHON ./waf configure --sferes=$CI_HOME/sferes2 ; fi
......
limbo [![Build Status](https://travis-ci.org/resibots/limbo.svg?branch=master)](https://travis-ci.org/resibots/limbo)
=====
A lightweight framework for Bayesian optimization of black-box functions (C++11) and, more generally, for data-efficient optimization. It is designed to be very fast and very flexible.
Limbo (LIbrary for Model-Based Optimization) is an open-source C++11 library for Gaussian Processes and data-efficient optimization (e.g., Bayesian optimization) that is designed to be both highly flexible and very fast. It can be used as a state-of-the-art optimization library or to experiment with novel algorithms with "plugin" components.
Documentation & Versions
------------------------
The development branch is the [master](https://github.com/resibots/limbo/tree/master) branch. For the latest stable release, check the [release-1.0](https://github.com/resibots/limbo/tree/release-1.0) branch.
The development branch is the [master](https://github.com/resibots/limbo/tree/master) branch. For the latest stable release, check the [release-2.0](https://github.com/resibots/limbo/tree/release-2.0) branch.
Documentation is available at: http://www.resibots.eu/limbo
A short paper that introduces the library is available on arxiv: https://arxiv.org/abs/1611.07343
A short paper that introduces the library is available here: https://members.loria.fr/JBMouret/pdf/limbo_paper.pdf
Citing Limbo
------------
If you use Limbo in a scientific paper, please cite:
Cully, A., Chatzilygeroudis, K., Allocati, F., and Mouret J.-B., (2016). [Limbo: A Fast and Flexible Library for Bayesian Optimization](https://arxiv.org/abs/1611.07343). *arXiv preprint arXiv:1611.07343*.
Cully, A., Chatzilygeroudis, K., Allocati, F., and Mouret J.-B., (2016). [Limbo: A Flexible High-performance Library for Gaussian Processes modeling and Data-Efficient Optimization](https://members.loria.fr/JBMouret/pdf/limbo_paper.pdf). *Preprint*.
In BibTex:
@article{cully_limbo_2016,
title={Limbo: A Fast and Flexible Library for Bayesian Optimization},
title={Limbo: A Flexible High-performance Library for Gaussian Processes modeling and Data-Efficient Optimization},
author={Cully, A. and Chatzilygeroudis, K. and Allocati, F. and Mouret, J.-B.},
year={2016},
journal={arXiv preprint},
pages={arxiv:1611.07343}
journal={Preprint},
url={https://members.loria.fr/JBMouret/pdf/limbo_paper.pdf}
}
......@@ -53,13 +53,16 @@ Main features
- Purposely small to be easily maintained and quickly understood
Scientific articles that use Limbo
--------------------------------
- Cully, A., Clune, J., Tarapore, D., and Mouret, J.B. (2015). [Robots that can adapt like animals](http://www.nature.com/nature/journal/v521/n7553/full/nature14422.html). *Nature*, 521(7553), 503-507.
- Tarapore, D., Clune, J., Cully, A., and Mouret, J.B. (2016). [How Do Different Encodings Influence the Performance of the MAP-Elites Algorithm?](https://hal.inria.fr/hal-01302658/document). *In Proc. of Genetic and Evolutionary Computation Conference*.
- Chatzilygeroudis, K., Vassiliades, V. and Mouret, J.B. (2016). [Reset-free Trial-and-Error Learning for Data-Efficient Robot Damage Recovery](https://arxiv.org/abs/1610.04213). *arXiv preprint arXiv:1610.04213*.
- Chatzilygeroudis, K., Cully, A. and Mouret, J.B. (2016). [Towards semi-episodic learning for robot damage recovery](https://arxiv.org/abs/1610.01407). *Workshop on AI for Long-Term Autonomy at the IEEE International Conference on Robotics and Automation 2016*.
- Papaspyros, V., Chatzilygeroudis, K., Vassiliades, V., and Mouret, J.B. (2016). [Safety-Aware Robot Damage Recovery Using Constrained Bayesian Optimization and Simulated Priors](https://arxiv.org/pdf/1611.09419v3). *Workshop on Bayesian Optimization at the Annual Conference on Neural Information Processing Systems (NIPS) 2016.*
- Chatzilygeroudis K., Rama R., Kaushik, R., Goepp, D., Vassiliades, V. and Mouret, J.B. (2017). [Black-Box Data-efficient Policy Search for Robotics](https://arxiv.org/abs/1703.07261). *Proceedings of the IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)*.
----------------------------------
- Chatzilygeroudis, K., & Mouret, J. B. (2018). [Using Parameterized Black-Box Priors to Scale Up Model-Based Policy Search for Robotics](https://arxiv.org/pdf/1709.06917). *Proceedings of the International Conference on Robotics and Automation (ICRA)*.
- Pautrat, R., Chatzilygeroudis, K., & Mouret, J.-B. (2018). [Bayesian Optimization with Automatic Prior Selection for Data-Efficient Direct Policy Search](https://arxiv.org/pdf/1709.06919). *Proceedings of the International Conference on Robotics and Automation (ICRA)*.
- Chatzilygeroudis, K., Vassiliades, V. and Mouret, J.-B. (2017). [Reset-free Trial-and-Error Learning for Robot Damage Recovery](https://arxiv.org/abs/1610.04213). *Robotics and Autonomous Systems*.
- Karban P., Pánek D., Mach F. and Doležel, I. (2017). [Calibration of numerical models based on advanced optimization and penalization techniques](https://www.degruyter.com/downloadpdf/j/jee.2017.68.issue-5/jee-2017-0073/jee-2017-0073.pdf). *Journal of Electrical Engineering, 68(5), 396-400*.
- Chatzilygeroudis K., Rama R., Kaushik, R., Goepp, D., Vassiliades, V. and Mouret, J.-B. (2017). [Black-Box Data-efficient Policy Search for Robotics](https://arxiv.org/abs/1703.07261). *Proceedings of the IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)*.
- Tarapore, D., Clune, J., Cully, A., and Mouret, J.-B. (2016). [How Do Different Encodings Influence the Performance of the MAP-Elites Algorithm?](https://hal.inria.fr/hal-01302658/document). *In Proc. of Genetic and Evolutionary Computation Conference*.
- Cully, A., Clune, J., Tarapore, D., and Mouret, J.-B. (2015). [Robots that can adapt like animals](http://www.nature.com/nature/journal/v521/n7553/full/nature14422.html). *Nature*, 521(7553), 503-507.
- Chatzilygeroudis, K., Cully, A. and Mouret, J.-B. (2016). [Towards semi-episodic learning for robot damage recovery](https://arxiv.org/abs/1610.01407). *Workshop on AI for Long-Term Autonomy at the IEEE International Conference on Robotics and Automation 2016*.
- Papaspyros, V., Chatzilygeroudis, K., Vassiliades, V., and Mouret, J.-B. (2016). [Safety-Aware Robot Damage Recovery Using Constrained Bayesian Optimization and Simulated Priors](https://arxiv.org/pdf/1611.09419v3). *Workshop on Bayesian Optimization at the Annual Conference on Neural Information Processing Systems (NIPS) 2016.*
Research projects that use Limbo
--------------------------------
......
......@@ -5,10 +5,12 @@ sudo mkdir build && cd build
sudo cmake ..
sudo make
sudo cp *.a /usr/lib
cd && git clone https://github.com/beniz/libcmaes.git
cd && git clone https://github.com/resibots/libcmaes.git
cd libcmaes
./autogen.sh
./configure
git checkout fix_flags_native
mkdir build
cd build
cmake -DUSE_TBB=ON -DUSE_OPENMP=OFF ..
make
sudo make install
sudo ldconfig
......
......@@ -341,7 +341,7 @@ Template
.. code-block:: cpp
template <typename Params>
struct MeanFunction {
struct MeanFunction : public BaseMean<Params> {
MeanFunction(size_t dim_out = 1) : _dim_out(dim_out) {}
template <typename GP>
Eigen::VectorXd operator()(const Eigen::VectorXd& v, const GP&) const
......
......@@ -178,6 +178,8 @@ html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# remove timestamp to avoid too many commits
html_last_updated_fmt = None
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
......@@ -322,4 +324,4 @@ intersphinx_mapping = {
}
# for versioning
scv_whitelist_branches = ('master', 'release-1.0')
scv_whitelist_branches = ('master', 'release-1.0', 'new_benchmarks')
......@@ -39,8 +39,10 @@ Contents:
tutorials/index
guides/index
api
bo
defaults
benchmarks
reg_benchmarks
bo_benchmarks
faq
......
#!/bin/sh
set -x
echo "generating doxygen for Limbo, current path $PWD"
doxygen Doxyfile
......@@ -8,3 +9,16 @@ cd ..
./waf default_params
echo "getting the latest benchmark result (needs to be in $HOME/limbo_benchmarks)"
# get the last benchmark
DIR=$HOME/limbo_benchmarks
BENCHMARKS=$DIR/`ls -t $DIR | head -n 1`
cp $BENCHMARKS/bo_benchmarks.rst docs/bo_benchmarks.rst
cp -r $BENCHMARKS/fig_benchmarks docs
echo "getting the latest regression benchmark result (needs to be in $HOME/limbo_reg_benchmarks)"
DIR=$HOME/limbo_reg_benchmarks
BENCHMARKS=$DIR/`ls -t $DIR | head -n 1`
cp $BENCHMARKS/regression_benchmarks.rst docs/reg_benchmarks.rst
cp -r $BENCHMARKS/regression_benchmark_figs docs/fig_benchmarks
......@@ -19,7 +19,9 @@ Required
Optional but highly recommended
+++++++++++++++++++++++++++++++++
* `NLOpt <http://ab-initio.mit.edu/wiki/index.php/NLopt>`_ with C++ binding: ::
* `Intel TBB <https://www.threadingbuildingblocks.org>`_ is not mandatory, but highly recommended; TBB is used in Limbo to take advantage of multicore architectures.
* `NLOpt <http://ab-initio.mit.edu/wiki/index.php/NLopt>`_ [mirror: http://members.loria.fr/JBMouret/mirrors/nlopt-2.4.2.tar.gz] with C++ binding: ::
./configure --with-cxx --enable-shared --without-python --without-matlab --without-octave
sudo make install
......@@ -28,7 +30,7 @@ Optional but highly recommended
The Debian/Unbuntu NLOpt package does NOT come with C++ bindings. Therefore you need to compile NLOpt yourself. The brew package (OSX) comes with C++ bindings (`brew install homebrew/science/nlopt`).
* `libcmaes <https://github.com/beniz/libcmaes>`_. Make sure that you install with **sudo** or configure the **LD_LIBRARY_PATH** accordingly. Be careful that gtest (which is a dependency of libcmaes) needs to be manually compiled **even if you install it with your package manager** (e.g. apt-get). Follow the instructions `here <https://github.com/beniz/libcmaes#build>`_, reproduced for your convenience::
* `libcmaes <https://github.com/beniz/libcmaes>`_. We advise you to use our own `fork of libcmaes <https://github.com/resibots/libcmaes>`_ (branch **fix_flags_native**). Make sure that you install with **sudo** or configure the **LD_LIBRARY_PATH** accordingly. Be careful that gtest (which is a dependency of libcmaes) needs to be manually compiled **even if you install it with your package manager** (e.g. apt-get): ::
sudo apt-get install libgtest-dev
sudo cd /usr/src/gtest
......@@ -37,15 +39,40 @@ Optional but highly recommended
sudo make
sudo cp *.a /usr/lib
In addition, you should be careful to configure **libcmaes** to use the same Eigen3 version as what you intend to use with Limbo (configuring with Makefiles)::
Follow the instructions below (you can also have a look `here <https://github.com/resibots/libcmaes#build>`_): ::
git clone https://github.com/resibots/libcmaes.git
cd libcmaes
git checkout fix_flags_native
Configuring with Makefiles: ::
./autogen.sh
./configure
make -j4
or CMake: ::
mkdir build
cd build
cmake ..
make -j4
In addition, you should be careful to configure **libcmaes** to use the same Eigen3 version as what you intend to use with Limbo (configuring with Makefiles): ::
./configure --with-eigen3-include=YOUR_DESIRED_DIR/include/eigen3
or (configure with CMake)::
or (configuring with CMake): ::
cmake -DEIGEN3_INCLUDE_DIR=YOUR_DESIRED_DIR/include/eigen3 ..
* `Intel TBB <https://www.threadingbuildingblocks.org>`_ is not mandatory, but highly recommended; TBB is used in Limbo to take advantage of multicore architectures.
Additionally, you can enable the usage of TBB for parallelization (configuring with Makefiles): ::
./configure --enable-tbb
or (configuring with CMake): ::
cmake -DUSE_TBB=ON -DUSE_OPENMP=OFF ..
Optional
+++++++++++++
......
......@@ -13,7 +13,7 @@ We assume that our samples are in a vector called ``samples`` and that our obser
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 77-86
:lines: 79-88
Basic usage
------------
......@@ -23,14 +23,14 @@ We first create a basic GP with an Exponential kernel (``kernel::Exp<Params>``)
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 59-72
:lines: 61-74
The type of the GP is defined by the following lines:
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 87-91
:lines: 89-93
To use the GP, we need :
......@@ -40,7 +40,7 @@ To use the GP, we need :
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 92-97
:lines: 94-99
Here we assume that the noise is the same for all samples and that it is equal to 0.01.
......@@ -57,7 +57,7 @@ To visualize the predictions of the GP, we can query it for many points and reco
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 101-110
:lines: 101-112
Hyper-parameter optimization
......@@ -71,21 +71,21 @@ A new GP type is defined as follows:
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 112-116
:lines: 114-118
It uses the default values for the parameters of ``SquaredExpARD``:
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 64-67
:lines: 66-69
After calling the ``compute()`` method, the hyper-parameters can be optimized by calling the ``optimize_hyperparams()`` function. The GP does not need to be recomputed and we pass ``false`` for the last parameter in ``compute()`` as we do not need to compute the kernel matrix again (it will be recomputed in the hyper-parameters optimization).
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 119-121
:lines: 121-123
We can have a look at the difference between the two GPs:
......@@ -105,4 +105,25 @@ Here is the complete ``main.cpp`` file of this tutorial:
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:lines: 48-
:lines: 46-
Saving and Loading
-------------------
We can also save our optimized GP model:
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 140-141
This will create a directory called ``myGP`` with several files (the GP data, kernel hyperparameters etc.). If we want a binary format (i.e., more compact), we can replace the ``TextArchive`` by ``BinaryArchive``.
To the load a saved model, we can do the following:
.. literalinclude:: ../../src/tutorials/gp.cpp
:language: c++
:linenos:
:lines: 143-144
Note that we need to have the same kernel and mean function (i.e., the same GP type) as the one used for saving.
\ No newline at end of file
all: paper.pdf
paper.pdf: paper.md paper.bib paper.xml
pandoc -o paper.pdf -V geometry:margin=1in --filter pandoc-citeproc --bibliography paper.bib paper.md --template latex.template
paper.xml: paper.md paper.bib
pandoc -s -f markdown paper.md -o paper.xml --template xml.template
clean:
rm paper.xml
rm paper.pdf
.PHONY: clean
{
"@context": "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld",
"@type": "Code",
"author": [
{
"@id": "0000-0002-3190-7073 ",
"@type": "Person",
"email": "a.cully@imperial.ac.uk",
"name": "Antoine Cully",
"affiliation": "Personal Robotics Lab, Imperial College London, London, United Kingdom"
},
{
"@id": "0000-0003-3585-1027",
"@type": "Person",
"email": "konstantinos.chatzilygeroudis@inria.fr",
"name": "Konstantinos Chatzilygeroudis",
"affiliation": "Inria Nancy Grand - Est, Villers-lès-Nancy, France"
},
{
"@id": "",
"@type": "Person",
"email": "",
"name": "Federico Allocati",
"affiliation": "Inria Nancy Grand - Est, Villers-lès-Nancy, France"
},
{
"@id": "0000-0002-2513-027X",
"@type": "Person",
"email": "jean-baptiste.mouret@inria.fr",
"name": "Jean-Baptiste Mouret",
"affiliation": "Inria Nancy Grand - Est, Villers-lès-Nancy, France"
}
],
"identifier": "",
"codeRepository": "https://github.com/resibots/limbo",
"datePublished": "2017-05-20",
"dateModified": "2017-05-20",
"dateCreated": "2017-05-20",
"description": "LIbrary for Model-based Bayesian Optimization",
"keywords": "Bayesian Optimization, Gaussian Processes, C++11",
"license": "CeCiLL",
"title": "Limbo",
"version": "v1.0"
}
\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{article}
$if(fontfamily)$
\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$}
$else$
\usepackage{lmodern}
$endif$
\usepackage{authblk}
$if(linestretch)$
\usepackage{setspace}
\setstretch{$linestretch$}
$endif$
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
\usepackage[utf8]{inputenc}
$if(euro)$
\usepackage{eurosym}
$endif$
\else % if luatex or xelatex
\ifxetex
\usepackage{mathspec}
\else
\usepackage{fontspec}
\fi
\defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}
$if(euro)$
\newcommand{\euro}{}
$endif$
$if(mainfont)$
\setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$}
$endif$
$if(sansfont)$
\setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$}
$endif$
$if(monofont)$
\setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$endif$]{$monofont$}
$endif$
$if(mathfont)$
\setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
$endif$
$if(CJKmainfont)$
\usepackage{xeCJK}
\setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$}
$endif$
\fi
% use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
% use microtype if available
\IfFileExists{microtype.sty}{%
\usepackage{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
$if(geometry)$
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
\usepackage{hyperref}
$if(colorlinks)$
\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref
$endif$
\hypersetup{unicode=true,
$if(title-meta)$
pdftitle={$title-meta$},
$endif$
$if(author-meta)$
pdfauthor={$author-meta$},
$endif$
$if(keywords)$
pdfkeywords={$for(keywords)$$keywords$$sep$; $endfor$},
$endif$
$if(colorlinks)$
colorlinks=true,
linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$,
citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$,
urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$,
$else$
pdfborder={0 0 0},
$endif$
breaklinks=true}
\urlstyle{same} % don't use monospace font for urls
$if(lang)$
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel}
$if(babel-newcommands)$
$babel-newcommands$
$endif$
\else
\usepackage{polyglossia}
\setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$}
$for(polyglossia-otherlangs)$
\setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$}
$endfor$
\fi
$endif$
$if(natbib)$
\usepackage{natbib}
\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
$endif$
$if(biblatex)$
\usepackage$if(biblio-style)$[style=$biblio-style$]$endif${biblatex}
$if(biblatexoptions)$\ExecuteBibliographyOptions{$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$}$endif$
$for(bibliography)$
\addbibresource{$bibliography$}
$endfor$
$endif$
$if(listings)$
\usepackage{listings}
$endif$
$if(lhs)$
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$
$if(highlighting-macros)$
$highlighting-macros$
$endif$
$if(verbatim-in-note)$
\usepackage{fancyvrb}
\VerbatimFootnotes % allows verbatim text in footnotes
$endif$
$if(tables)$
\usepackage{longtable,booktabs}
$endif$
$if(graphics)$
\usepackage{graphicx,grffile}
\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
\makeatother
% Scale images if necessary, so that they will not overflow the page
% margins by default, and it is still possible to overwrite the defaults
% using explicit options in \includegraphics[width, height, ...]{}
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
$endif$
$if(links-as-notes)$
% Make links footnotes instead of hotlinks:
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}
$endif$
$if(strikeout)$
\usepackage[normalem]{ulem}
% avoid problems with \sout in headers with hyperref:
\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
$endif$
$if(indent)$
$else$
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
}
$endif$
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
$if(numbersections)$
\setcounter{secnumdepth}{5}
$else$
\setcounter{secnumdepth}{0}
$endif$
$if(subparagraph)$
$else$
% Redefines (sub)paragraphs to behave more like sections
\ifx\paragraph\undefined\else
\let\oldparagraph\paragraph
\renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
\fi
\ifx\subparagraph\undefined\else
\let\oldsubparagraph\subparagraph
\renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
\fi
$endif$
$if(dir)$
\ifxetex
% load bidi as late as possible as it modifies e.g. graphicx
$if(latex-dir-rtl)$
\usepackage[RTLdocument]{bidi}
$else$
\usepackage{bidi}
$endif$
\fi
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\TeXXeTstate=1
\newcommand{\RL}[1]{\beginR #1\endR}
\newcommand{\LR}[1]{\beginL #1\endL}
\newenvironment{RTL}{\beginR}{\endR}
\newenvironment{LTR}{\beginL}{\endL}
\fi
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$if(title)$
\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
$endif$
$if(subtitle)$
\providecommand{\subtitle}[1]{}
\subtitle{$subtitle$}
$endif$
$if(authors)$
$for(authors)$
$if(authors.affiliation)$
\author[$authors.affiliation$]{$authors.name$}
$else$
\author{$authors.name$}
$endif$
$endfor$
$endif$
$if(affiliations)$
$for(affiliations)$
\affil[$affiliations.index$]{$affiliations.name$}
$endfor$
$endif$
\date{$date$}
\begin{document}
$if(title)$
\maketitle
$endif$
$if(abstract)$
\begin{abstract}
$abstract$
\end{abstract}
$endif$
\textbf{Paper DOI:} \url{http://dx.doi.org/$formatted_doi$}\\
\textbf{Software Repository:} \url{$repository$}\\
\textbf{Software Archive:} \url{$archive_doi$}\\
$for(include-before)$
$include-before$
$endfor$
$if(toc)$
{
$if(colorlinks)$
\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$}
$endif$
\setcounter{tocdepth}{$toc-depth