Skip to content

Commit 751df3c

Browse files
committed
python module
1 parent 3cbe0b3 commit 751df3c

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
from __future__ import print_function
2+
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
from matplotlib.pyplot import plot, title
6+
from scipy.optimize import fmin, leastsq
7+
8+
from diffpy.srfit.fitbase import (
9+
FitContribution,
10+
FitRecipe,
11+
FitResults,
12+
Profile,
13+
)
14+
15+
16+
def main():
17+
# ----------------------------------------------------------------------
18+
# Generate synthetic noisy data: y = 0.5 * x + 3 + noise
19+
# ----------------------------------------------------------------------
20+
xobs = np.arange(-10, 10.1)
21+
dyobs = 0.3 * np.ones_like(xobs)
22+
yobs = 0.5 * xobs + 3 + dyobs * np.random.randn(xobs.size)
23+
24+
plot(xobs, yobs, "x")
25+
title("y = 0.5*x + 3 with Gaussian noise (σ=0.3)")
26+
plt.show()
27+
# ----------------------------------------------------------------------
28+
# Create a Profile object to hold the data
29+
# ----------------------------------------------------------------------
30+
linedata = Profile()
31+
linedata.setObservedProfile(xobs, yobs, dyobs)
32+
33+
# ----------------------------------------------------------------------
34+
# Define a FitContribution: linear model A*x + B
35+
# ----------------------------------------------------------------------
36+
linefit = FitContribution("linefit")
37+
linefit.setProfile(linedata)
38+
linefit.setEquation("A * x + B")
39+
40+
linefit.show()
41+
42+
# Assign initial guesses for parameters
43+
linefit.A = 3
44+
linefit.B = 5
45+
print("Initial A:", linefit.A, "value:", linefit.A.value)
46+
print("Initial B:", linefit.B, "value:", linefit.B.value)
47+
48+
# Evaluate model with initial parameters
49+
print("linefit.evaluate() =", linefit.evaluate())
50+
print("linefit.residual() =", linefit.residual())
51+
52+
plot(xobs, yobs, "x", linedata.x, linefit.evaluate(), "-")
53+
title("Line simulated at A=3, B=5")
54+
plt.show()
55+
56+
# ----------------------------------------------------------------------
57+
# Create a FitRecipe to manage fitting
58+
# ----------------------------------------------------------------------
59+
rec = FitRecipe()
60+
rec.clearFitHooks()
61+
rec.addContribution(linefit)
62+
rec.show()
63+
64+
# Add variables to be refined
65+
rec.addVar(rec.linefit.A)
66+
rec.addVar(rec.linefit.B)
67+
68+
print("rec.A =", rec.A)
69+
print("rec.A.value =", rec.A.value)
70+
print("rec.values =", rec.values)
71+
print("rec.names =", rec.names)
72+
print("rec.residual() =", rec.residual())
73+
print("rec.residual([2, 4]) =", rec.residual([2, 4]))
74+
75+
# ----------------------------------------------------------------------
76+
# Fit using least squares optimizer
77+
# ----------------------------------------------------------------------
78+
leastsq(rec.residual, rec.values)
79+
print("After leastsq:", rec.names, "-->", rec.values)
80+
linefit.show()
81+
82+
plot(linedata.x, linedata.y, "x", linedata.x, linedata.ycalc, "-")
83+
title("Line fit using leastsq optimizer")
84+
plt.show()
85+
86+
# ----------------------------------------------------------------------
87+
# Fit using scalar optimizer (fmin)
88+
# ----------------------------------------------------------------------
89+
fmin(rec.scalarResidual, [1, 1])
90+
print("After fmin:", rec.names, "-->", rec.values)
91+
92+
plot(linedata.x, linedata.y, "x", linedata.x, linedata.ycalc, "-")
93+
title("Line fit using fmin optimizer")
94+
plt.show()
95+
96+
# Display fit results
97+
res = FitResults(rec)
98+
print(res)
99+
100+
# ----------------------------------------------------------------------
101+
# Example: Fixing a parameter
102+
# ----------------------------------------------------------------------
103+
rec.fix(B=0)
104+
print("Free:", rec.names, "-->", rec.values)
105+
print("Fixed:", rec.fixednames, "-->", rec.fixedvalues)
106+
107+
leastsq(rec.residual, rec.values)
108+
print("Fit with B fixed to 0:", FitResults(rec))
109+
110+
plot(linedata.x, linedata.y, "x", linedata.x, linedata.ycalc, "-")
111+
title("Line fit with B fixed at 0")
112+
plt.show()
113+
114+
rec.free("all")
115+
116+
# ----------------------------------------------------------------------
117+
# Example: Adding a constraint (A = 2*B)
118+
# ----------------------------------------------------------------------
119+
rec.constrain(rec.A, "2 * B")
120+
leastsq(rec.residual, rec.values)
121+
print("Fit with A constrained to 2*B:", FitResults(rec))
122+
123+
plot(linedata.x, linedata.y, "x", linedata.x, linedata.ycalc, "-")
124+
title("Line fit with constraint A=2*B")
125+
plt.show()
126+
127+
rec.unconstrain(rec.A)
128+
129+
# ----------------------------------------------------------------------
130+
# Example: Adding a restraint (A close to <= 0.2 with penalty)
131+
# ----------------------------------------------------------------------
132+
rec.restrain(rec.A, ub=0.2, sig=0.001)
133+
leastsq(rec.residual, rec.values)
134+
print("Fit with A restrained to ub=0.2:", FitResults(rec))
135+
136+
plot(linedata.x, linedata.y, "x", linedata.x, linedata.ycalc, "-")
137+
title("Line fit with restraint on A (ub=0.2)")
138+
plt.show()
139+
140+
141+
if __name__ == "__main__":
142+
main()

0 commit comments

Comments
 (0)