Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,813 changes: 1,469 additions & 3,344 deletions docs/source/algorithms.md

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the algorithm examples, the value passed to params parameter is a list, and the lambda function passed to fun does a matrix multiplication. If someone tries to directly copy and paste the example, it fails. How about changing the lambda function to lambda x: sum(v**2 for v in x) or the list into a NumPy array, and also removing the ellipsis from the algorithm options?


For example:

import optimagic as om

om.minimize(
    fun=lambda x: sum(v**2 for v in x),
    params=[1.0, 2.0, 3.0],
    algorithm=om.algos.scipy_neldermead(stopping_maxiter=1_000),
)

Or

import numpy as np
import optimagic as om

om.minimize(
    fun=lambda x: x @ x,
    params=np.array([1.0, 2.0, 3.0]),
    algorithm=om.algos.scipy_neldermead(stopping_maxiter=1_000),
)

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions docs/source/how_to/how_to_add_optimizers.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -421,10 +421,14 @@
" needs_jac=False,\n",
" # does the optimizer need the hessian? -> no, gaco is derivative free\n",
" needs_hess=False,\n",
" # does the optimizer need bounds? -> yes, gaco needs finite bounds\n",
" needs_bounds=True,\n",
" # does the optimizer support parallelism? -> yes\n",
" supports_parallelism=True,\n",
" # does the optimizer support bounds? -> yes\n",
" supports_bounds=True,\n",
" # does the optimizer support infinite bounds? -> no, bounds must be finite\n",
" supports_infinite_bounds=False,\n",
" # does the optimizer support linear constraints? -> no\n",
" supports_linear_constraints=False,\n",
" # does the optimizer support nonlinear constraints? -> no\n",
Expand Down Expand Up @@ -603,11 +607,11 @@
"of commonly used convergence and stopping criteria. We also align the default values for \n",
"stopping and convergence criteria as much as possible. \n",
"\n",
"You can find the harmonized names and value [here](algo_options_docs). \n",
"You can find the harmonized names and value {ref}`here <algo_options>`. \n",
"\n",
"To align the names of other tuning parameters as much as possible with what is already \n",
"there, simple have a look at the optimizers we already wrapped. For example, if you are \n",
"wrapping a bfgs or lbfgs algorithm from some libray, try to look at all existing wrappers \n",
"there, simply have a look at the optimizers we already wrapped. For example, if you are \n",
"wrapping a bfgs or lbfgs algorithm from some library, try to look at all existing wrappers \n",
"of bfgs algorithms and use the same names for the same options. \n",
"\n",
"You can see what this means for the gaco algorithm [here](\n",
Expand Down
12 changes: 12 additions & 0 deletions docs/source/how_to/how_to_document_optimizers.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ more memory but may converge faster for some problems.
Without this, type hints such as ``PositiveInt`` may appear decomposed in the
documentation (e.g., as ``Annotated[int, Gt(gt=0)]``).

.. warning::
Option values are validated against the field annotations with pydantic, which
resolves the annotations at runtime. Every name used in a field annotation must
therefore be importable at runtime -- a name that is only imported inside an
``if TYPE_CHECKING:`` block will raise an error when the algorithm is
instantiated. If an optional dependency provides a type you want to use in an
annotation, add a runtime fallback next to the ``TYPE_CHECKING`` import, as is
done for ``HessianApproximation`` in ``optimagic/optimizers/fides.py``.

Since annotations are enforced, they must also be honest: document and annotate
the values the optimizer actually accepts, rather than a narrower set.

```

### Step 4: Integrate into `algorithms.md`
Expand Down
178 changes: 178 additions & 0 deletions docs/source/refs.bib
Original file line number Diff line number Diff line change
Expand Up @@ -1114,4 +1114,182 @@ @article{Ni2013
year = {2013}
}

@Article{Froehlich2022,
author = {Fabian Fr{\"o}hlich and Peter K. Sorger},
journal = {PLOS Computational Biology},
title = {Fides: Reliable trust-region optimization for parameter estimation of ordinary differential equation models},
year = {2022},
month = {jul},
number = {7},
pages = {e1010322},
volume = {18},
doi = {10.1371/journal.pcbi.1010322},
publisher = {Public Library of Science ({PLoS})},
}

@Misc{Johnson2007,
author = {Johnson, Steven G.},
title = {The NLopt nonlinear-optimization package},
year = {2007},
url = {https://github.com/stevengj/nlopt},
}

@Article{Svanberg1987,
author = {Svanberg, Krister},
journal = {International Journal for Numerical Methods in Engineering},
title = {The method of moving asymptotes---a new method for structural optimization},
year = {1987},
number = {2},
pages = {359--373},
volume = {24},
doi = {10.1002/nme.1620240207},
}

@Article{LeeWiswall2007,
author = {Lee, Donghoon and Wiswall, Matthew},
journal = {Computational Economics},
title = {A Parallel Implementation of the Simplex Function Minimization Routine},
year = {2007},
number = {2},
pages = {171--187},
volume = {30},
doi = {10.1007/s10614-007-9094-2},
}

@Article{Wessing2019,
author = {Wessing, Simon},
journal = {Optimization Letters},
title = {Proper initialization is crucial for the Nelder--Mead simplex search},
year = {2019},
pages = {847--856},
volume = {13},
doi = {10.1007/s11590-018-1284-4},
}

@Book{Nash1990,
author = {Nash, John C.},
publisher = {Adam Hilger},
title = {Compact Numerical Methods for Computers: Linear Algebra and Function Minimisation},
year = {1990},
address = {Bristol},
edition = {2nd},
}

@Misc{Varadhan2016,
author = {Varadhan, Ravi and Borchers, Hans W.},
title = {dfoptim: Derivative-Free Optimization},
year = {2016},
note = {R package version 2016.7-1},
url = {https://CRAN.R-project.org/package=dfoptim},
}

@Article{Powell1964,
author = {Powell, M. J. D.},
journal = {The Computer Journal},
title = {An efficient method for finding the minimum of a function of several variables without calculating derivatives},
year = {1964},
number = {2},
pages = {155--162},
volume = {7},
doi = {10.1093/comjnl/7.2.155},
}

@Article{Branch1999,
author = {Branch, Mary Ann and Coleman, Thomas F. and Li, Yuying},
journal = {SIAM Journal on Scientific Computing},
title = {A Subspace, Interior, and Conjugate Gradient Method for Large-Scale Bound-Constrained Minimization Problems},
year = {1999},
number = {1},
pages = {1--23},
volume = {21},
doi = {10.1137/S1064827595289108},
}

@InProceedings{Voglis2004,
author = {Voglis, C. and Lagaris, I. E.},
booktitle = {WSEAS International Conference on Applied Mathematics},
title = {A Rectangular Trust Region Dogleg Approach for Unconstrained and Bound Constrained Nonlinear Optimization},
year = {2004},
address = {Corfu, Greece},
url = {https://www.cs.uoi.gr/~lagaris/papers/PREPRINTS/dogbox.pdf},
}

@InCollection{More1978,
author = {Mor{\'e}, Jorge J.},
booktitle = {Numerical Analysis},
editor = {Watson, G. A.},
pages = {105--116},
publisher = {Springer},
series = {Lecture Notes in Mathematics},
title = {The Levenberg-Marquardt algorithm: Implementation and theory},
volume = {630},
year = {1978},
doi = {10.1007/BFb0067700},
}

@Article{Nash1984,
author = {Nash, Stephen G.},
journal = {SIAM Journal on Numerical Analysis},
title = {Newton-Type Minimization via the Lanczos Method},
year = {1984},
number = {4},
pages = {770--788},
volume = {21},
doi = {10.1137/0721052},
}

@Article{Endres2018,
author = {Endres, Stefan C. and Sandrock, Carl and Focke, Walter W.},
journal = {Journal of Global Optimization},
title = {A simplicial homology algorithm for {Lipschitz} optimisation},
year = {2018},
number = {2},
pages = {181--217},
volume = {72},
doi = {10.1007/s10898-018-0645-y},
}

@Article{Tsallis1988,
author = {Tsallis, Constantino},
journal = {Journal of Statistical Physics},
title = {Possible generalization of {Boltzmann-Gibbs} statistics},
year = {1988},
number = {1-2},
pages = {479--487},
volume = {52},
doi = {10.1007/BF01016429},
}

@Article{TsallisStariolo1996,
author = {Tsallis, Constantino and Stariolo, Daniel A.},
journal = {Physica A: Statistical Mechanics and its Applications},
title = {Generalized simulated annealing},
year = {1996},
number = {1-2},
pages = {395--406},
volume = {233},
doi = {10.1016/S0378-4371(96)00271-3},
}

@Article{Xiang1997,
author = {Xiang, Y. and Sun, D. Y. and Fan, W. and Gong, X. G.},
journal = {Physics Letters A},
title = {Generalized simulated annealing algorithm and its application to the {Thomson} model},
year = {1997},
number = {3},
pages = {216--220},
volume = {233},
doi = {10.1016/S0375-9601(97)00474-X},
}

@techreport{Gabler2024,
author = {Gabler, Jano{\'s} and Gsell, Sebastian and Mensinger, Tim and Petrosyan, Mariam},
title = {Tranquilo: An Optimizer for the Method of Simulated Moments},
institution = {CRC TR 224, University of Bonn and University of Mannheim},
type = {Discussion Paper},
number = {522},
year = {2024},
url = {https://www.crctr224.de/research/discussion-papers/archive/dp522}
}

@Comment{jabref-meta: databaseType:bibtex;}
37 changes: 37 additions & 0 deletions src/optimagic/optimizers/bhhh.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Implement Berndt-Hall-Hall-Hausman (BHHH) algorithm."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Callable, cast

Expand Down Expand Up @@ -31,9 +33,44 @@
)
@dataclass(frozen=True)
class BHHH(Algorithm):
"""Minimize a likelihood function using the BHHH algorithm.

BHHH (:cite:`Berndt1974`) can - and should ONLY - be used for minimizing (or
maximizing) a likelihood function. It is similar to the Newton-Raphson algorithm,
but replaces the Hessian matrix with the outer product of the gradients of the
likelihood contributions. This approximation is based on the information matrix
equality (:cite:`Halbert1982`) and is thus only valid when minimizing (or
maximizing) a likelihood function. In exchange, the approximated Hessian is
always positive semidefinite and no second derivatives are needed.

To use bhhh, the objective function must be a likelihood function, i.e. a
function that is decorated with ``om.mark.likelihood`` and returns the
likelihood contributions of each observation rather than their sum.

The algorithm is a local optimizer that uses first derivatives of the
likelihood contributions. It does not support bounds or constraints.

.. note::
This is a pure-Python implementation within optimagic. It is currently
considered experimental.

"""

converence_gtol_abs: NonNegativeFloat = 1e-8
"""Stopping criterion for the gradient tolerance.

The algorithm converges when the inner product of the aggregated gradient and
the candidate search direction falls below this value.

"""

# TODO: Why is this 200?
stopping_maxiter: PositiveInt = 200
"""Maximum number of iterations.

If reached, terminate.

"""

def _solve_internal_problem(
self, problem: InternalOptimizationProblem, x0: NDArray[np.float64]
Expand Down
Loading
Loading