Nelder-Mead downhill simplex

class PyAstronomy.funcFit.NelderMead(abg=(1.0, 0.5, 2.0), isw=0.05, critlim=1e-08)

Downhill-Simplex algorithm for minimization.

This implementation is based on the publication: Nelder and Mead, The Computer Journal 7, 308-313, 1965 (NM 1965)

Halting criterion

The default stop criterion is the one used by NM 1965. In particular, the value

\[\sqrt{\sum (\bar{y}-y_i) / n}\]

is calculated. If it falls below the limit defined by the attribute nmCritLim, the iteration stops.

Parameters
abgtuple of three floats, optional

Values for alpha, beta, and gamma.

iswfloat, optional

Initial step width for simplex.

critlimfloat, optional

Critical limit for stopping criterion.

Attributes
alpha, beta, gammafloat

The reflection-, expansion-, and contraction-coefficients. The default values (after NM 1965) are 1.0, 0.5, and 2.0. These coefficients control the modification of the simplex.

initialStepWidthFacfloat

This factor determines how the initial simplex is calculated. The first simplex point is the starting value, the others are constructed by adding a fraction defined by this factor to the starting value. The default is 0.05.

nmCritLimfloat

Critical value for the NM 1965 stopping criterion. The default is 1e-8.

Methods

fit(m, ds[, objf, initDelta, maxIter, ...])

Carry out the model fit.

_initSimplex(m, initDelta)

Define the initial simplex.

Parameters
mInstance of OneDFit

The model.

initDeltadictionary

Maps parameter name to the initial step width for the simplex.

_step(m)

Proceed one step of the simplex algorithm.

_stopNM1965()

Apply the NM 1965 stopping criterion.

Returns
Reachedboolean

True, if the stopping criterion has been reached.

fit(m, ds, objf='chisqr', initDelta=None, maxIter=10000.0, callback=None, nmCritLim=None)

Carry out the model fit.

After the iteration, the iterCount attribute contains the number of iterations. The maxIterReached attribute flag is False, if the maximum number of iterations has not been reached and True otherwise.

Parameters
mInstance of OneDFit

The model to be fitted.

dsInstance of FufDS

The data.

objfstring

The objective function to be used. Possible choices are “chisqr” (default), “sqrdiff”, and “cash79”.

initDeltadictionary, optional

A dictionary mapping parameter names to the initial step width. This can be very useful, if the starting values are zero or very small. The here defined step will be added to the starting value to construct the simplex.

maxIterint, optional

The maximum number of iterations. The default is 10000.

nmCritLimfloat, optional

Critical value for stopping criterion. The default is 1e-8.

callbackcallable, optional

If not None, “callback” will be called with the three parameters: number of iteration (int), current best parameter set (array), and current simplex (array).

Returns
Best-fit valuesdictionary

Maps parameter name to the best-fit value.

Example: Application of the NelderMead class

from PyAstronomy import funcFit as fuf
import numpy as np

# Construct the fitter
nm = fuf.NelderMead()

# Get a GaussFit object ...
gf = fuf.GaussFit1d()
gf.thaw(["A", "mu"])
# ... and define some initial values.
gf["A"] = 5.0
gf["mu"] = 2.0
gf["sig"] = 1.0

# Construct some "data" ...
x = np.arange(100)/20.
y = gf.evaluate(x) + np.random.normal(0.0, 0.08, len(x))
yerr = np.ones(len(x)) * 0.08
# ... and define a "data set" object
ds = fuf.FufDS(x, y, yerr=yerr)

# On purpose, we vail our knowledge about the correct
# parameters
gf["A"] = 1.0
gf["mu"] = 1.0

# We carry out the fit. In particular, the squared
# distance between the model and the data is minimized
# (sqrdiff).
bfpars = nm.fit(gf, ds, objf="sqrdiff", maxIter=100)
# Have a look at the result
print "Best-fit parameters: ", bfpars
print
# Have a look at the entire fit object
gf.parameterSummary()


print
# Again, we change the starting parameters. Note that ...
gf["A"] = 1.0
# ... mu has been set to zero.
gf["mu"] = 0.0

# To allow the construction of an appropriate start simplex,
# we need to provide an "initDelta" for mu, which should
# reflect the typical scale of the problem.
bfpars = nm.fit(gf, ds, objf="chisqr", initDelta={"mu": 0.1})
print "Second fit, best-fit parameters: ", bfpars