-
Notifications
You must be signed in to change notification settings - Fork 0
/
best_fit_advanced.py
216 lines (180 loc) · 6.54 KB
/
best_fit_advanced.py
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# best fit di una serie di dati con varie funzioni
# Dati di input nel file best_fit.txt
from IPython import get_ipython
get_ipython().magic('cls')
get_ipython().magic('reset -sf')
# import delle librerie di python
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.optimize import curve_fit
class driver_class():
def __init__(self):
self.deg=None
self.x=None
self.y=None
self.x_orig=None
self.y_orig=None
self.flag=False
def set_degree(self,deg):
"""
Fissa il grado del polinomio e della funzione myfunc_2
Parameters
----------
deg : grado del polinomio e della funzione a*x^deg
"""
self.deg=deg
def set_xlimit(self,xmin,xmax):
"""
Definisce l'intervallo della variabile indipendente x
Parameters
----------
xmin : valore minimo dell'intervallo
xmax : valore massimo dell'intervallo
"""
self.xmin=xmin
self.xmax=xmax
select=(self.x_orig >= xmin) & (self.x_orig <= xmax)
self.x=self.x_orig[select]
self.y=self.y_orig[select]
print("X data range set to [%5.2f, %5.2f]" % (xmin, xmax))
def xlimit_reset(self):
"""
Riporta l'intervallo di definizione della variabile indipendente
x al valore originale.
"""
self.x=np.copy(self.x_orig)
self.y=np.copy(self.y_orig)
drv=driver_class()
print("Programma 'best_fit'\n\nUtilizzo:")
print("I dati (x, y) vengono letti dal file 'best_fit.txt'")
print("\nLa funzione 'fit' esegue il fit e accetta il parametro (opzionale) deg che")
print("specifica il grado del polinomio e del modello myfunc_2 (default: 2)")
print("\nIl metodo drv.set_xlimit consente di definire l'intervallo della variabile")
print("indipendente x su cui eseguire il fit")
print("\nIl metodo drv.xlimit_reset riporta l'intervallo di definizione della variabile")
print("al valore originale\n")
print("La funzione load_data carica i dati di input")
# definizione della funzione y(x)=a*x^b
# myfunc accetta come input la serie di valori della
# variabile dipendente x, e i parametro "a" e "b" da ottimizzare
def myfunc(x,a,b):
return a*x**b
# definizione della funzione y(x)=a*x^deg
# myfunc accetta come input la serie di valori della
# variabile dipendente x, e il parametro "a" da ottimizzare
def myfunc_2(x,a):
return a*x**drv.deg
def load_data(file='best_fit.txt'):
"""
Carica i dati di input
Parameters
----------
file : nome del file di dati (default 'best_fit.txt')
"""
data=np.loadtxt(file)
x=data[:,0]
y=data[:,1]
drv.x=x
drv.y=y
drv.x_orig=np.copy(drv.x)
drv.y_orig=np.copy(drv.y)
drv.flag=True
print("Input file: %s\n" % file)
dati=(drv.x,drv.y)
df=pd.DataFrame(dati, index=['X','Y'])
df=df.T
df2=df.round(3)
print(df2.to_string(index=False))
def fit(deg=2,file='best_fit.txt',reload=False, ret=False):
"""
Esegue il fit.
Parameters
----------
deg : grado del polinomio e della funzione myfunc_2 (default 2)
file : nome del file i dati (default best_fit.txt)
reload : se True, forza il ricaricamento del file di dati (default False)
ret : se True restituisce in uscita i valori dei parametri ottimizzati
(default False)
"""
drv.set_degree(2)
if deg != 2:
drv.set_degree(deg)
if (not drv.flag) or reload:
try:
load_data(file)
except:
print("File di input non presente")
return
opt, pcov = curve_fit(myfunc, drv.x, drv.y, p0=[1,1])
err=np.sqrt(np.diag(pcov))
a=opt[0]
b=opt[1]
print("\nFit del modello 'myfunc'")
print("Parametro 'a' ottimizzato: %5.3f (%3.2f)" % (a, err[0]))
print("Parametro 'b' ottimizzato: %5.3f (%3.2f)\n" % (b, err[1]))
opt_2,err= curve_fit(myfunc_2, drv.x, drv.y)
err=np.sqrt(err)
a_2=opt_2[0]
err_2=np.sqrt(err[0,0])
print("Fit del modello 'myfunc_2'")
print("Parametro 'a' ottimizzato: %5.3f (%3.2f)\n" % (a_2, err_2))
opt_p, pcov_p=np.polyfit(drv.x,drv.y,drv.deg,cov=True)
err_p=np.sqrt(np.diag(pcov_p))
print("Fit polinomiale: parametri ottimizzati:")
idx=0
for ip in opt_p:
id1=idx+1
print("Parametro %3i: %7.3f (%6.2f)" % (id1, ip, err_p[idx]))
idx=idx+1
x_list=np.linspace(min(drv.x_orig),max(drv.x_orig),30)
y_list=myfunc(x_list,a,b)
y_2_list=myfunc_2(x_list,a_2)
y_p_list=np.polyval(opt_p,x_list)
yc=myfunc(drv.x,a,b)
delta=drv.y-yc
yc_2=myfunc_2(drv.x,a_2)
delta_2=drv.y-yc_2
yc_p=np.polyval(opt_p,drv.x)
delta_p=drv.y-yc_p
print("-------------------------------------")
print("\nModello 'myfunc'")
serie=(drv.x,drv.y,yc,delta)
df=pd.DataFrame(serie, index=['x','y','y calc','delta'])
df=df.T
df2=df.round(3)
print(df2.to_string(index=False))
sdt=np.sqrt(np.sum((drv.y-yc)**2)/(drv.x.size-1))
print("\nDeviazione standard: %5.1f" % sdt)
print("------")
print("\nModello 'myfunc_2'")
serie=(drv.x,drv.y,yc_2,delta_2)
df=pd.DataFrame(serie, index=['x','y','y calc','delta'])
df=df.T
df2=df.round(3)
print(df2.to_string(index=False))
sdt=np.sqrt(np.sum((drv.y-yc_2)**2)/(drv.x.size-1))
print("\nDeviazione standard: %5.1f" % sdt)
print("------")
ds=str(drv.deg)
print("\nModello polinomiale di grado %s" % ds)
serie_p=(drv.x,drv.y,yc_p,delta_p)
df_p=pd.DataFrame(serie_p, index=['x','y','y calc','delta'])
df_p=df_p.T
df2_p=df_p.round(3)
print(df2_p.to_string(index=False))
sdt_p=np.sqrt(np.sum((drv.y-yc_p)**2)/(drv.x.size-1))
print("\nDeviazione standard: %5.1f" % sdt_p)
# --- Sezione di plot ---
lab_p="Poly: grado "+ds
plt.figure()
plt.plot(drv.x_orig,drv.y_orig,"k*") # dati "reali"
plt.plot(x_list,y_list,"b-",label="myfunc") # dati calcolati da myfunc
plt.plot(x_list,y_2_list,"r--",label="myfunc_2") # dati calcolati myfunc_2
plt.plot(x_list,y_p_list,"b--", label=lab_p) # dati modello polinomiale
plt.xlabel("x")
plt.ylabel("y")
plt.legend(frameon=False)
plt.show()
if ret:
return a, b, opt_2[0], opt_p