-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfit_functions.py
107 lines (87 loc) · 2.96 KB
/
fit_functions.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
import numpy as np
fit_function_list = dict()
def register_fit_function(func, bounds=(-np.inf, np.inf)):
"""This decorator registers a new fit function and writes an entry to fit_function_list."""
global fit_function_list
fit_function_list[func.__name__] = (func, bounds)
return func
@register_fit_function
def gauss(x, a, x0, sigma, export=False):
"""Gaussian function, used for fitting data.
:param x: parameter
:param a: amplitude
:param x0: maximum
:param sigma: width
:param export: enable text output of function
"""
if export == 'Mathematica':
return f'{a} * Exp[-({x}-{x0})^2 / (2*{sigma}^2)]'
else:
return a*np.exp(-(x-x0)**2/(2*sigma**2))
@register_fit_function
def sine_lin(x, a, omega, phase, c, b, export=False):
"""Sine function with linear term added for fitting data.
:param x: parameter
:param a: amplitude
:param omega: frequency
:param phase: phase
:param c: offset
:param b: slope
:param export: enable text output of function
"""
if export == 'Mathematica':
return f'{a} * Sin[{x}*{omega} + {phase}] + {b}*{x} + {c}'
else:
return a*np.sin(x*omega + phase) + b*x + c
@register_fit_function
def poly5(x, a5, a4, a3, a2, a1, a0, export=False):
"""Polynom 5th degree for fitting.
:param x: parameter
:param a5: coeff
:param a4: coeff
:param a3: coeff
:param a2: coeff
:param a1: coeff
:param a0: coeff
:param export: enable text output of function
:returns: function -- polynomial 5th degree
"""
if export == 'Mathematica':
return f'((((({a5}*{x} + {a4})*{x} + {a3})*{x} + {a2})*{x} + {a1})*{x} + {a0})'
else:
return (((((a5*x + a4)*x + a3)*x + a2)*x + a1)*x + a0)
@register_fit_function
def poly(x, *args, export=False):
"""Polynom nth degree for fitting.
:param x: parameter
:type x: int, float
:param *args: list of coefficients [a_N,a_N-1, ..., a_1, a_0]
:type *args: list
:param export: enable text output of function, defaults to False
:type export: bool or string, optional
:return: returns the polynomial
:rtype: str, int, float
>>> poly(3.4543, 5,4,3,2,1, export='Mathematica')
'5*3.4543^5 + 4*3.4543^4 + 3*3.4543^3 + 2*3.4543^2 + 1*3.4543^1'
>>> poly(3.4543, 5,4,3,2,1)
920.4602110784704
"""
a = list(args)
if export == 'Mathematica':
return ' + '.join([f'{a[i]}*{x}^{len(a)-i}' for i in range(len(a))])
else:
return poly(x, *a[0:-1])*x + a[-1] if len(a) > 1 else a[0]
@register_fit_function
def sine(x, a, omega, phase, c, export=False):
"""Sine function for fitting data.
:param x: parameter
:param a: amplitude
:param omega: frequency
:param phase: phase
:param c: offset
:param export: enable text output of function
"""
if export == 'Mathematica':
return f'{a}*Sin[{x}*{omega} + {phase}] + {c}'
else:
return a*np.sin(x*omega + phase) + c