File: example12.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 (117 lines) | stat: -rwxr-xr-x 3,239 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
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# 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
"""
Example:
    - Solve 5th-order polynomial coefficients with Powell's method.
    - Plot of fitting to 5th-order polynomial.

Demonstrates:
    - model and cost function construction
    - minimal solver interface
"""

# Powell's Directonal solver
from mystic.solvers import fmin_powell

# cost function factory
from mystic.forward_model import CostFactory

# tools
from mystic.tools import getch, random_seed
random_seed(123)
import matplotlib.pyplot as plt
plt.ion()

# build the forward model
def ForwardPolyFactory(coeff):
    """generate a 1-D polynomial instance from a list of coefficients"""
    from numpy import poly1d
    return poly1d(coeff)

# build the cost function
def PolyCostFactory(evalpts,datapts,ndim):
    """generate a cost function instance from evaluation points and data"""
    from numpy import sum
    F = CostFactory()
    F.addModel(ForwardPolyFactory,ndim,"noisy_polynomial")
    return F.getCostFunction(evalpts=evalpts,observations=datapts, \
                             metric=lambda x: sum(x*x),sigma=1000.)

# 'data' generators
def data(params):
    """generate 'data' from polynomial coefficients"""
    from numpy import array
    x = 0.1*(array([list(range(101))])-50.)[0]
    fwd = ForwardPolyFactory(params)
    return x,fwd(x)

def noisy_data(params):
    """generate noisy data from polynomial coefficients"""
    from numpy import random
    x,y = data(params)
    y = [random.normal(0,1) + i for i in y]
    return x,y

# draw the plot
def plot_frame(label=None):
    plt.close()
    plt.title("fitting noisy 5th-order polynomial coefficients")
    plt.xlabel("x")
    plt.ylabel("f(x)")
    plt.draw()
    plt.pause(0.001)
    return
 
# plot the polynomial
def plot_data(evalpts,datapts,style='k.'):
    plt.plot(evalpts,datapts,'%s' % style)
    plt.axis([0,5,0,50])#,'k-')
    plt.draw()
    plt.pause(0.001)
    return
    
def plot_solution(params,style='b-'):
    x,y = data(params)
    plot_data(x,y,style)
    plt.legend(["Data","Fitted"])
    plt.draw()
    plt.pause(0.001)
    return


if __name__ == '__main__':

    print("Powell's Method")
    print("===============")

    # target and initial guess
    target = [-1.,4.,-5.,20.,5.]
    x0     = [-1.,2.,-3.,10.,5.]

    # generate 'observed' data
    x,datapts = noisy_data(target)

    # plot observed data
    plot_frame()
    plot_data(x,datapts)

    # generate cost function
    costfunction = PolyCostFactory(x,datapts,len(target))

    # use Powell's method to solve 5th-order polynomial coefficients
    solution = fmin_powell(costfunction,x0)

    # compare solution with actual target 5th-order polynomial coefficients
    print("\nSolved Coefficients:\n %s\n" % ForwardPolyFactory(solution))
    print("Target Coefficients:\n %s\n" % ForwardPolyFactory(target))
 
    # plot solution versus target coefficients
    plot_solution(solution)
    getch() 

# end of file