File: test_br8.py

package info (click to toggle)
mystic 0.4.3-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,656 kB
  • sloc: python: 40,894; makefile: 33; sh: 9
file content (148 lines) | stat: -rwxr-xr-x 4,852 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python
#
# Author: Patrick Hung (patrickh @caltech)
# Copyright (c) 1997-2016 California Institute of Technology.
# Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
# License: 3-clause BSD.  The full license text is available at:
#  - https://github.com/uqfoundation/mystic/blob/master/LICENSE
"""
Data from Chapter 8 of Bevington and Robinson

Wants to fit
y = a1 + a2 Exp[-t / a4] + a3 Exp[-t/a5] to data
"""

from numpy import *
from scipy.integrate import romberg
from mystic.solvers import DifferentialEvolutionSolver2 as DifferentialEvolutionSolver
from mystic.termination import ChangeOverGeneration, VTR
from mystic.tools import getch, random_seed
from mystic.monitors import VerboseMonitor as MyMonitor

from mystic.models.br8 import decay; F = decay.ForwardFactory
from mystic.models.br8 import cost as myCF
from mystic.models.br8 import data
# evalpts = data[:,0], observations = data[:,1]

def myshow():
    import matplotlib.pyplot as plt
    try:
        import Image
        plt.savefig('test_br8_out',dpi=72)
        im = Image.open('test_br8_out.png')
        im.show()
    except ImportError:
        pass
    plt.show()
    
def plot_sol(solver=None, linestyle='k-'):
    import matplotlib.pyplot as plt
    def _(params):
        import mystic._signal as signal
        print("plotting params: %s" % params)
        # because of the log ordinate axis, will draw errorbars the dumb way
        plt.semilogy(data[:,0],data[:,1],'k.')
        for i, j in data:
            plt.semilogy([i, i], [j-sqrt(j), j+sqrt(j)],'k-')
        plt.grid()
        plt.xlabel('Time (s)')
        plt.ylabel('Number of counts')
        x = arange(15, 900, 5)
        f = F(params)
        plt.plot(x, f(x), linestyle)
        if solver is not None:
            signal.signal(signal.SIGINT, signal.Hander(solver))
    return _

ND = 5
NP = 50
MAX_GENERATIONS = 2000

def de_solve(CF, a4=None, a5=None):
    """solve with DE for given cost funciton; fix a4 and/or a5 if provided"""
    minrange = [0, 100, 100, 1, 1]
    maxrange = [100, 2000, 200, 200, 200]
    interval = 10
    if a5 != None:
        minrange[4] = maxrange[4] = a5
        interval = 20
    if a4 != None:
        minrange[3] = maxrange[3] = a4
        if interval == 20: interval = 1000

    solver = DifferentialEvolutionSolver(ND, NP)
    solver.enable_signal_handler()
    stepmon = MyMonitor(interval)
    solver.SetRandomInitialPoints(min=minrange,max=maxrange)
    solver.SetStrictRanges(min=minrange, max=maxrange)
    solver.SetEvaluationLimits(generations=MAX_GENERATIONS)
    solver.SetGenerationMonitor(stepmon)
    solver.Solve(CF,termination=ChangeOverGeneration(generations=50))
    solution = solver.Solution()
    return solution, stepmon


def error2d(myCF, sol, cx, cy):
    from scipy.optimize import fmin
    # This is the center-point
    x0 = [sol[0], sol[1], sol[2]]
    def curry(x):
        return myCF([x[0], x[1], x[2], cx, cy])
    sol = fmin(curry, x0)
    print(sol)

if __name__ == '__main__':
    sol, steps = de_solve(myCF)
    a1, a2, a3, a4, a5 = sol
    minChiSq = steps.y[-1]
    #
    print(sol)
    plot_sol()(sol)
    # plot the "precomputed" confidence interval too
    s4, ss4 = de_solve(myCF, a4=29.5, a5=163)
    s5, ss5 = de_solve(myCF, a4=38.9, a5=290)
    plot_sol(linestyle='r-')(s4)
    plot_sol(linestyle='r-')(s5)
    myshow()
    #

    # compute the 'uncertainty' of the last parameter, and fit a parabola
    # disable for now
    ## print("redo a5 at several points")
    ## a5x = [a5-30, a5, a5+30]
    ## a5y = [] 
    ## for a in a5x:
    ##    sol2, steps2 = de_solve(myCF, a5=a)
    ##    a5y.append(steps2.y[-1])
    ## import matplotlib.pyplot as plt
    ## plt.clf()
    ## plt.plot(a5x, a5y, 'r+')
    ## # fitting a parabola
    ## x1,x2,x3=a5x
    ## y1,y2,y3=a5y
    ## a1 = -(-x2*y1 + x3*y1 + x1*y2-x3*y2-x1*y3+x2*y3)/(x2-x3)/(x1*x1-x1*x2-x1*x3+x2*x3)
    ## a2 = -(x2*x2*y1-x3*x3*y1-x1*x1*y2+x3*x3*y2+x1*x1*y3-x2*x2*y3)/(x1-x2)/(x1-x3)/(x2-x3)
    ## a3 = -(-x2*x2*x3*y1+x2*x3*x3*y1+x1*x1*x3*y2-x1*x3*x3*y2-x1*x1*x2*y3+x1*x2*x2*y3)/((x2-x3)*(x1*x1-x1*x2-x1*x3+x2*x3))
    ## print("%s %s %s" % (a1, a2, a3))
    ## x = arange(150,270)
    ## from mystic.math import polyeval
    ## plt.plot(x, polyeval([a1,a2,a3],x),'k-')
    ## myshow()

    # 2D (a fine mesh solution can be computed by test_br8_mpi.py)
    try:
        import matplotlib.pyplot as plt
        X = loadtxt('test_br8_mpi.out.X')
        Y = loadtxt('test_br8_mpi.out.Y')
        V = loadtxt('test_br8_mpi.out.V')
        plt.clf()
        plt.plot([[a4]],[[a5]],'k+')
        plt.xlabel('a4')
        plt.ylabel('a5')
        plt.grid()
        plt.contour(X,Y,V, minChiSq + array([1,2,3]),colors='black')
        myshow()
    except IOError:
        print("Run test_br8_mpi to create dataset.")

# end of file