fumi-python-lib
Loading...
Searching...
No Matches
error_propagation_class.py
1import sympy
2import numpy
3from IPython.display import Math
4from IPython.display import display
5import copy
6from .basic_algebraic_calculation_class import BasicAlgebraicCalculationClass
7
9 def __init__(self):
10 super().__init__()
11 self.dfdx_symbol = None
12 self.dfdx_value = None
13 self.error_series = None
14 self.value_series = None
15 self.dfdx_value_args = None
16 self.dfdx_value = None
17 self.error_series_variable = None
19 self.propagated_error = None
20 self.propagated_value = None
21 self.original_function = None
22 self.latex_paste_mode = False
23
24 def copy_class(self):
25 '''
26 Copy object
27 '''
28 return copy.copy(self)
29
30 def set_value_series(self, values):
31 '''
32 '''
33 self.value_series = []
34 for i in range( len( values ) ):
35 self.value_series.append( values[i] )
36
37 def set_error_series(self, evalues):
38 '''
39 '''
40 self.error_series = []
41 for i in range( len( evalues ) ):
42 self.error_series.append( evalues[i] )
43
44 def print_each_term(self, lhs, rhs, i):
45 '''
46 '''
47 if not self.latex_paste_mode:
48 display( Math( f'\\frac{{\\partial {self.left_hand_side} }}{{ \\partial {self.variable_symbols[i]} }} = {sympy.latex( self.dfdx_symbol[i] )}' ) )
49 elif self.latex_paste_mode:
50 print(( '\\frac{{\\partial} f}{{\\partial} x_%d}=\\frac{{\\partial}%s}{{\\partial}%s}=%s \\\\' % (i, sympy.latex(self.left_hand_side), sympy.latex( lhs ), sympy.latex( rhs ) )))
51
52 def partial_derivative(self, dump_flag=False):
53 '''
54 '''
55 self.dfdx_symbol = []
56 if self.original_function is None:
58 elif self.original_function != self.right_hand_side:
60
61 if dump_flag:
62 if not self.latex_paste_mode:
63 display( Math( r'{\delta}f=\sqrt{\sum_{i=0}^{n} \left( \frac{{\partial} f}{{\partial} x_i} {\delta}x_i \right)^2}') )
64 for i in range( len(self.variable_symbols) ):
65 display( Math( f'x_{i} = {self.variable_symbols[i]}' ) )
66 elif self.latex_paste_mode:
67 print( f'x_{i} = {self.variable_symbols[i]}' )
68 for i in range( len( self.variable_symbols ) ):
69 self.dfdx_symbol.append( sympy.diff( self.right_hand_side, self.variable_symbols[i] ) )
70 if dump_flag:
71 self.print_each_term( self.variable_symbols[i], self.dfdx_symbol[i], i )
72
73 def calculate_erorr(self, dump_flag=False, round_digits=None):
74 '''
75 '''
76 calc_variable_symbols = self.variable_symbols
77 calc_dfdx_symbol = self.dfdx_symbol
78 calc_value_series = self.value_series
79 calc_error_series = self.error_series
80 calc_original_function = self.original_function
81
82 self.assign_values( calc_variable_symbols, calc_value_series )
85 self.set_right_hand_side( calc_original_function )
86
87 self.dfdx_value_args = []
88 self.dfdx_value = []
89 self.error_series_variable = []
91 for i in range( len( calc_variable_symbols ) ):
92 self.dfdx_value_args.append( sympy.lambdify( calc_variable_symbols, calc_dfdx_symbol[i], "numpy" ) )
93 self.dfdx_value.append( self.dfdx_value_args[i]( *calc_value_series ) )
94 self.error_series_variable.append( self.dfdx_value[i] * calc_error_series[i] )
96
97 self.propagated_error = numpy.sqrt( sum( self.error_series_variable_pow2 ) )
98
99 val_print = self.propagated_value
100 err_print = self.propagated_error
101 if round_digits is not None :
102 val_print = round( self.propagated_value, round_digits )
103 err_print = round( self.propagated_error, round_digits )
104
105 if dump_flag:
106 if not self.latex_paste_mode:
107 display( Math( f'{self.left_hand_side} \\pm \\delta {self.left_hand_side} = {val_print} \\pm {err_print}' ) )
108 elif self.latex_paste_mode:
109 print( f'{val_print} \\pm {err_print} \\\\' )
110
111 return self.propagated_error, self.propagated_value