File: curve.py

package info (click to toggle)
python-bumps 1.0.3-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,200 kB
  • sloc: python: 24,517; xml: 493; ansic: 373; makefile: 211; javascript: 99; sh: 94
file content (90 lines) | stat: -rw-r--r-- 3,141 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# Fitting a curve
# ===============
#
# Fitting a curve to a data set and getting uncertainties on the
# parameters was the main reason that bumps was created, so it
# should be very easy to do.  Let's see if it is.
#
# First let's import the standard names:

from bumps.names import *

# Next we need some data.  The x values represent the independent variable,
# and the y values represent the value measured for condition x.  In this
# case x is 1-D, but it could be a sequence of tuples instead.  We also
# need the uncertainty on each measurement if we want to get a meaningful
# uncertainty on the fitted parameters.

x = [1, 2, 3, 4, 5, 6]
y = [2.1, 4.0, 6.3, 8.03, 9.6, 11.9]
dy = [0.05, 0.05, 0.2, 0.05, 0.2, 0.2]

# Instead of using lists we could have loaded the data from a
# three-column text file using:
#
# .. parsed-literal::
#
#    data = np.loadtxt("data.txt").T
#    x, y, dy = data[0, :], data[1, :], data[2, :]
#
# The variations are endless --- cleaning the data so that it is
# in a fit state to model is often the hardest part in the analysis.

# We now define the function we want to fit.  The first argument
# to the function names the independent variable, and the remaining
# arguments are the fittable parameters.  The parameter arguments can
# use a bare name, or they can use name=value to indicate the default
# value for each parameter.  Our function defines a straight like of
# slope $m$ with intercept $b$ defaulting to 0.


def line(x, m, b=0):
    return m * x + b


# We can build a curve fitting object from our function and our data.
# This assumes that the measurement uncertainty is normally
# distributed, with a 1-\ $\sigma$ confidence interval *dy* for each point.
# We specify initial values for $m$ and $b$ when we define the
# model, and then constrain the fit to $m \in [0, 4]$ # and $b \in [-5, 5]$
# with the parameter :meth:`range <bumps.parameter.Parameter.range>` method.

M = Curve(line, x, y, dy, m=2, b=2)
M.m.range(0, 4)
M.b.range(-5, 5)

# Every model file ends with a problem definition including a
# list of all models and datasets which are to be fitted.

problem = FitProblem(M)

# The complete model file :download:`curve.py <curve.py>` looks as follows:
#
# .. literalinclude:: curve.py
#
# We can now load and run the fit:
#
# .. parsed-literal::
#
#    $ bumps.py curve.py --fit=newton --steps=100 --session=fit.h5
#
# The ``--fit=newton`` option says to use the quasi-newton optimizer for
# not more than 100 steps.  The ``--session=fit.h5`` option says to store the
# initial model, the fit results and any monitoring information in the
# HDF5 file ``fit.h5``.
#
# As the fit progresses, we are shown an iteration number and a cost
# value.  The cost value is approximately the normalized $\chi^2_N$.
# The value in parentheses is like the uncertainty in $\chi^2_N$, in
# that a 1-\ $\sigma$ change in parameter values should increase
# $\chi^2_N$ by that amount.
#
# Here is the resulting fit:
#
# .. plot::
#
#    from sitedoc import fit_model
#    fit_model('curve.py')
#
# All is well: Normalized $\chi^2_N$ is close to 1 and the line goes nicely
# through the data.