├── .gitignore ├── Lagrange_interpolating.cpp ├── README.md ├── Romberg.py ├── cubic1.png ├── cubic2.png ├── cubic3.png ├── cubic_spline_interpolation.py ├── horner.cpp ├── iteration_method.py ├── lagrange_function_plot.py ├── linear_equation_group.py ├── newton_plot.cpp ├── nonlinear_equation.py ├── numerical_integration.py ├── quick_sqrt ├── quick_sqrt.cpp └── recurrence.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.out 3 | .vscode/ 4 | tmp_* -------------------------------------------------------------------------------- /Lagrange_interpolating.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | double lagrange_interpolating(double); 6 | 7 | vector > value_table; 8 | 9 | int main() { 10 | value_table.push_back(make_pair(0.0, 0.5)); 11 | value_table.push_back(make_pair(0.1, 0.5398)); 12 | value_table.push_back(make_pair(0.2, 0.5793)); 13 | value_table.push_back(make_pair(0.3, 0.6179)); 14 | value_table.push_back(make_pair(0.4, 0.7554)); 15 | 16 | cout << "f(0.13) = " << lagrange_interpolating(0.13) << endl; 17 | cout << "f(0.22) = " << lagrange_interpolating(0.22) << endl; 18 | cout << "f(0.36) = " << lagrange_interpolating(0.36) << endl; 19 | return 0; 20 | } 21 | 22 | double lagrange_interpolating(double x_value) { 23 | double sum = 0; 24 | for (int i = 0; i != value_table.size(); ++i) { 25 | double tmp1 = 1; 26 | double tmp2 = 1; 27 | for (vector >::iterator iter = value_table.begin(); 28 | iter != value_table.end(); ++iter) { 29 | if (iter->first != value_table[i].first) { 30 | tmp1 = tmp1 * (x_value - iter->first); 31 | tmp2 = tmp2 * (value_table[i].first - iter->first); 32 | } 33 | } 34 | sum = sum + value_table[i].second * (tmp1 / tmp2); 35 | } 36 | return sum; 37 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # numerical_calculation 2 | 数值计算Python实现 (三次样条、拉格朗日插值、龙贝格积分法、线性方程组迭代法等) 3 | -------------------------------------------------------------------------------- /Romberg.py: -------------------------------------------------------------------------------- 1 | #%% 2 | from math import sin 3 | import math 4 | 5 | def f(x): 6 | if x==0: 7 | return 1 8 | return sin(x)/x 9 | 10 | def Romberg(function,lower_limit,upper_limit,deviation): 11 | T_n=1/2*(function(lower_limit)+function(upper_limit)) 12 | length=(upper_limit-lower_limit) 13 | divide=1 14 | step=length/divide 15 | k=0 16 | T_list=[] 17 | T_list.append(T_n) 18 | print("k={0} T_0={1}".format(k,T_n)) 19 | while True: 20 | tmp=0 21 | for i in range(divide): 22 | tmp=tmp+function(((lower_limit+i*step)+(lower_limit+(i+1)*step))/2) 23 | T_2n=1/2*T_n+step/2*tmp 24 | print("\nk={0} T_0={1}".format(k+1,T_2n)) 25 | T_list.append(T_2n) 26 | m=1 27 | for j in range(len(T_list)-1,0,-1): 28 | temp=4**m/(4**m-1)*T_list[j]-1/(4**m-1)*T_list[j-1] 29 | print("m={0} T={1}".format(m,temp)) 30 | if j==1 : 31 | if abs(temp-T_list[j-1]) 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | vector coefficient; // polynomial coefficient 7 | double tmp; 8 | // while (cin >> tmp) 9 | // { 10 | // coefficient.push_back(tmp); 11 | // } 12 | coefficient.push_back(2); 13 | coefficient.push_back(0); 14 | coefficient.push_back(-3); 15 | coefficient.push_back(3); 16 | coefficient.push_back(-4); 17 | 18 | double x_value = -2; 19 | // cin >> x_value; 20 | double poly_value = coefficient.front(), 21 | first_derivative = coefficient.front(); 22 | vector::size_type subscript_i = 0; 23 | while (subscript_i != coefficient.size() - 1) { 24 | poly_value = poly_value * x_value + coefficient[++subscript_i]; 25 | if (subscript_i != coefficient.size() - 1) { 26 | first_derivative = first_derivative * x_value + poly_value; 27 | } 28 | } 29 | cout << "poly_value: " << poly_value << endl; 30 | cout << "first_derivative: " << first_derivative << endl; 31 | return 0; 32 | } -------------------------------------------------------------------------------- /iteration_method.py: -------------------------------------------------------------------------------- 1 | #%% 2 | import numpy as np 3 | 4 | 5 | def spectral_radius(iter_matrix): 6 | eigvalue, eigvector = np.linalg.eig(iter_matrix) 7 | return max(abs(eigvalue)) 8 | 9 | 10 | def jacobi_iteration(coe_matrix, const_col): 11 | size = const_col.size 12 | x_vector = np.zeros(const_col.size) 13 | xTmpVector = np.zeros(const_col.size) 14 | 15 | LMatrix = -1 * np.tril(coe_matrix, -1) 16 | UMatrix = -1 * np.triu(coe_matrix, 1) 17 | DMatrix = coe_matrix + LMatrix + UMatrix 18 | iter_matrix = (np.linalg.inv(DMatrix)).dot(LMatrix + UMatrix) 19 | spectral_value = spectral_radius(iter_matrix) 20 | if spectral_value >= 1: 21 | print("该矩阵不收敛!其谱半径为:{0}".format(spectral_value)) 22 | return 1 23 | 24 | num=0 25 | while True: 26 | for i in range(size): 27 | tmpSum = 0 28 | for j in range(size): 29 | if i == j: 30 | continue 31 | tmpSum = tmpSum + (coe_matrix[i][j] * x_vector[j]) 32 | xTmpVector[i] = (const_col[i] - tmpSum) / coe_matrix[i][i] 33 | if sum(abs(xTmpVector - x_vector)) < 0.0001: 34 | break 35 | x_vector = np.copy(xTmpVector) 36 | # print("临时迭代解:{0}".format(xTmpVector)) 37 | num=num+1; 38 | 39 | print("方程的解为:{0} ,迭代总次数为:{1},误差为0.0001".format(x_vector,num)) 40 | 41 | 42 | def G_S_Iteration(coe_matrix, const_col): 43 | size = const_col.size 44 | x_vector = np.zeros(const_col.size) 45 | xTmpVector = np.zeros(const_col.size) 46 | 47 | LMatrix = -1 * np.tril(coe_matrix, -1) 48 | UMatrix = -1 * np.triu(coe_matrix, 1) 49 | DMatrix = coe_matrix + LMatrix + UMatrix 50 | iter_matrix = (np.linalg.inv(DMatrix - LMatrix)).dot(UMatrix) 51 | spectral_value = spectral_radius(iter_matrix) 52 | if spectral_value >= 1: 53 | print("该矩阵不收敛!其谱半径为:{0}".format(spectral_value)) 54 | return 1 55 | 56 | num=0 57 | while True: 58 | for i in range(size): 59 | tmpSum1 = 0 60 | tmpSum2 = 0 61 | for j in range(i - 1): 62 | tmpSum1 = tmpSum1 + (coe_matrix[i][j] * xTmpVector[j]) 63 | for j in range(i + 1, size, 1): 64 | tmpSum2 = tmpSum2 + (coe_matrix[i][j] * xTmpVector[j]) 65 | xTmpVector[i] = (const_col[i] - tmpSum1 - tmpSum2) / coe_matrix[i][i] 66 | if sum(abs(xTmpVector - x_vector)) < 0.0001: 67 | break 68 | x_vector = np.copy(xTmpVector) 69 | # print("临时迭代解:{0}".format(xTmpVector)) 70 | num=num+1; 71 | 72 | print("方程的解为:{0} ,迭代总次数为:{1},误差为0.0001".format(x_vector,num)) 73 | 74 | def SOR_Iteration(coe_matrix,const_col,w_factor): 75 | size = const_col.size 76 | x_vector = np.zeros(const_col.size) 77 | xTmpVector = np.zeros(const_col.size) 78 | 79 | LMatrix = -1 * np.tril(coe_matrix, -1) 80 | UMatrix = -1 * np.triu(coe_matrix, 1) 81 | DMatrix = coe_matrix + LMatrix + UMatrix 82 | iter_matrix = (np.linalg.inv(DMatrix -w_factor * LMatrix)).dot((1-w_factor)*DMatrix+w_factor*UMatrix) 83 | spectral_value = spectral_radius(iter_matrix) 84 | if spectral_value >= 1: 85 | print("该矩阵不收敛!其谱半径为:{0}".format(spectral_value)) 86 | return 1 87 | 88 | num=0 89 | while True: 90 | for i in range(size): 91 | tmpSum1 = 0 92 | tmpSum2 = 0 93 | for j in range(i - 1): 94 | tmpSum1 = tmpSum1 + (coe_matrix[i][j] * xTmpVector[j]) 95 | for j in range(i , size, 1): 96 | tmpSum2 = tmpSum2 + (coe_matrix[i][j] * x_vector[j]) 97 | xTmpVector[i] = x_vector[i] + w_factor*(const_col[i] - tmpSum1 - tmpSum2) / coe_matrix[i][i] 98 | if sum(abs(xTmpVector - x_vector)) < 0.000001: 99 | break 100 | x_vector = np.copy(xTmpVector) 101 | # print("临时迭代解:{0}".format(xTmpVector)) 102 | num=num+1; 103 | 104 | 105 | print("方程的解为:{0},迭代总次数为:{1}".format(x_vector,num)) 106 | 107 | 108 | def main(): 109 | coe_matrix = np.array([[1, 0.8, 0.8], [0.8, 1, 0.8], [ 110 | 0.8, 0.8, 1]], dtype=np.float) 111 | const_col = np.array([1, 2, 3], dtype=np.float) 112 | print("雅克比迭代过程:") 113 | jacobi_iteration(coe_matrix, const_col) 114 | print("\n高斯-赛德尔迭代过程:") 115 | G_S_Iteration(coe_matrix,const_col) 116 | 117 | coe_matrix1 = np.array([[4,3,0],[3,4,-1],[0,-1,4]],dtype=np.float) 118 | const_col1 = np.array([1,-5,3],dtype=np.float) 119 | 120 | for w_factor in [0.2,0.5,1.0,1.24,1.5,2.2]: 121 | print("\nw因子为:{0} 时,误差为:0.000001时的SOR迭代:".format(w_factor)) 122 | SOR_Iteration(coe_matrix1,const_col1,w_factor) 123 | 124 | 125 | if __name__ == '__main__': 126 | main() 127 | 128 | # result: 129 | # 雅克比迭代过程: 130 | # 该矩阵不收敛!其谱半径为:1.6 131 | # 132 | # 高斯-赛德尔迭代过程: 133 | # 方程的解为:[-1.23847588 -1.19264976 3.99078071] ,迭代总次数为:34,误差为0.0001 134 | # 135 | # w因子为:0.2 时,误差为:0.000001时的SOR迭代: 136 | # 方程的解为:[ 1.04687854 -1.0625022 0.74999908],迭代总次数为:61 137 | # 138 | # w因子为:0.5 时,误差为:0.000001时的SOR迭代: 139 | # 方程的解为:[ 1.04687611 -1.0625002 0.74999996],迭代总次数为:24 140 | # 141 | # w因子为:1.0 时,误差为:0.000001时的SOR迭代: 142 | # 方程的解为:[ 1.046875 -1.0625 0.75 ],迭代总次数为:3 143 | # 144 | # w因子为:1.24 时,误差为:0.000001时的SOR迭代: 145 | # 方程的解为:[ 1.04687477 -1.06250001 0.75 ],迭代总次数为:15 146 | # 147 | # w因子为:1.5 时,误差为:0.000001时的SOR迭代: 148 | # 方程的解为:[ 1.04687558 -1.06249998 0.75 ],迭代总次数为:30 149 | # 150 | # w因子为:2.2 时,误差为:0.000001时的SOR迭代: 151 | # 该矩阵不收敛!其谱半径为:1.200000000000001 152 | -------------------------------------------------------------------------------- /lagrange_function_plot.py: -------------------------------------------------------------------------------- 1 | #%% 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | from scipy.interpolate import lagrange 5 | 6 | x = np.linspace(-5, 5, 1000) 7 | ax = plt.subplot() 8 | 9 | ax.plot(x, 1 / (1 + x**2), label="f(x)") 10 | for n in [2, 4, 8, 10]: 11 | x_n = [-5 + (10 / n) * i for i in range(n + 1)] 12 | y_n = [1 / (1 + x**2) for x in x_n] 13 | lag = lagrange(x_n, y_n) 14 | ax.plot(x, lag(x), label="n={0}".format(n)) 15 | ax.grid() 16 | ax.legend() 17 | plt.show() 18 | -------------------------------------------------------------------------------- /linear_equation_group.py: -------------------------------------------------------------------------------- 1 | #%% 2 | import numpy as np 3 | 4 | def matrix_decomposition(augMatrix): 5 | row,col=augMatrix.shape 6 | for r in range (row): 7 | tmpSum=0 8 | for k in range(0,r,1): 9 | tmpSum=tmpSum+augMatrix[r,k]*augMatrix[k,r] 10 | augMatrix[r,r]=augMatrix[r,r]-tmpSum 11 | s=augMatrix[r,r] 12 | sMax=abs(s) 13 | rowNum=r 14 | for i in range(r+1,row,1): 15 | tmpSum=0 16 | for k in range(0,r,1): 17 | tmpSum=tmpSum+augMatrix[i,k]*augMatrix[k,r] 18 | augMatrix[i,r]=augMatrix[i,r]-tmpSum 19 | s=abs(augMatrix[i,r]) 20 | if s>sMax: 21 | sMax=s 22 | rowNum=i 23 | if rowNum!=r: 24 | augMatrix[[r, rowNum], :] = augMatrix[[rowNum, r], :] 25 | for i in range(r+1,row,1): 26 | if r!=row-1: 27 | augMatrix[i,r]=augMatrix[i,r]/augMatrix[r,r] 28 | tmpSum=0 29 | for k in range(0,r,1): 30 | tmpSum=tmpSum+augMatrix[r,k]*augMatrix[k,i] 31 | augMatrix[r,i]=augMatrix[r,i]-tmpSum 32 | 33 | for i in range(1,row,1): 34 | tmpSum=0 35 | for k in range(0,i,1): 36 | tmpSum=tmpSum+augMatrix[i,k]*augMatrix[k,col-1] 37 | augMatrix[i,col-1]=augMatrix[i,col-1]-tmpSum 38 | 39 | augMatrix[row-1,col-1]=augMatrix[row-1,col-1]/augMatrix[row-1,row-1] 40 | for i in range(row-2,-1,-1): 41 | tmpSum=0 42 | for k in range(i+1,row,1): 43 | tmpSum=tmpSum+augMatrix[i,k]*augMatrix[k,col-1] 44 | augMatrix[i,col-1]=(augMatrix[i,col-1]-tmpSum)/augMatrix[i,i] 45 | print(augMatrix) 46 | return 0 47 | 48 | 49 | 50 | def gauss_column_elimination(augMatrix): 51 | det = 1 52 | row, col = augMatrix.shape 53 | for i in range(row - 1): 54 | colMaxNum = i 55 | for rowNum in range(i, row): 56 | if abs(augMatrix[rowNum, i]) > abs(augMatrix[i, i]): 57 | colMaxNum = rowNum 58 | if augMatrix[colMaxNum, i] == 0: 59 | det = 0 60 | print("矩阵的det=0!") 61 | return 1 62 | if colMaxNum != i: 63 | augMatrix[[i, colMaxNum], :] = augMatrix[[colMaxNum, i], :] 64 | det = det * (-1) 65 | for rowNum in range(i + 1, row): 66 | augMatrix[rowNum, i] = augMatrix[rowNum, i] / augMatrix[i, i] 67 | for colNum in range(i + 1, col): 68 | augMatrix[rowNum, colNum] = augMatrix[rowNum, colNum] - \ 69 | augMatrix[rowNum, i] * augMatrix[i, colNum] 70 | det = det * augMatrix[i, i] 71 | if augMatrix[row - 1, row - 1] == 0: 72 | det = 0 73 | print("矩阵的det=0!") 74 | return 1 75 | det = det * augMatrix[row - 1, row - 1] 76 | print("矩阵的det={0:.2f}".format(det)) 77 | for i in range(row - 1, -1, -1): 78 | tmpSum = 0 79 | for j in range(i + 1, row, 1): 80 | tmpSum = tmpSum + augMatrix[j, col - 1] * augMatrix[i, j] 81 | augMatrix[i, col - 1] = (augMatrix[i, col - 1] - tmpSum) / augMatrix[i, i] 82 | for i in range(row): 83 | print("x[{0}]={1:.2f}".format(i + 1, augMatrix[i, col - 1])) 84 | return 0 85 | 86 | def main(): 87 | coeMatrix = np.array([[10, -7, 0,1], [-3, 2.099999, 6,2], [5, -1, 5,-1],[2,1,0,2]],dtype=np.float) 88 | constCol = np.array([[8], [5.900001], [5],[1]],dtype=np.float) 89 | e=np.concatenate((coeMatrix, constCol), axis=1) 90 | d=np.copy(e) 91 | np.set_printoptions(precision=6, suppress=True) 92 | print("增广矩阵为:\n{0}".format(e)) 93 | print("高斯列选主元消去法:") 94 | gauss_column_elimination(e) 95 | print("矩阵三角选主元分解法:") 96 | matrix_decomposition(d) 97 | return 0 98 | 99 | if __name__ == '__main__': 100 | main() 101 | 102 | # result: 103 | # 增广矩阵为: 104 | # [[ 10. -7. 0. 1. 8. ] 105 | # [ -3. 2.099999 6. 2. 5.900001] 106 | # [ 5. -1. 5. -1. 5. ] 107 | # [ 2. 1. 0. 2. 1. ]] 108 | # 高斯列选主元消去法: 109 | # 矩阵的det=-762.00 110 | # x[1]=0.00 111 | # x[2]=-1.00 112 | # x[3]=1.00 113 | # x[4]=1.00 114 | # 矩阵三角选主元分解法: 115 | # [[ 10. -7. 0. 1. -0. ] 116 | # [ 0.5 2.5 5. -1.5 -1. ] 117 | # [ -0.3 -0. 6.000002 2.299999 1. ] 118 | # [ 0.2 0.96 -0.8 5.079999 1. ]] -------------------------------------------------------------------------------- /newton_plot.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | void difference_quotient(); 6 | double newton_interpolating(double); 7 | 8 | vector > value_table; 9 | 10 | int main() { 11 | value_table.push_back(make_pair(0.0, 0.5)); 12 | value_table.push_back(make_pair(0.1, 0.5398)); 13 | value_table.push_back(make_pair(0.2, 0.5793)); 14 | value_table.push_back(make_pair(0.3, 0.6179)); 15 | value_table.push_back(make_pair(0.4, 0.7554)); 16 | 17 | difference_quotient(); 18 | for (int i = 0; i < 40; ++i) { 19 | cout << "f(" << 0.01 * (i + 1) 20 | << ") = " << newton_interpolating(0.01 * (i + 1)) << " \t"; 21 | } 22 | return 0; 23 | } 24 | 25 | void difference_quotient() { 26 | for (int i = 0; i != value_table.size() - 1; ++i) { 27 | for (vector >::iterator iter = value_table.end() - 1; 28 | iter != value_table.begin() + i; --iter) { 29 | iter->second = (iter->second - (iter - 1)->second) / 30 | (iter->first - (iter - i - 1)->first); 31 | } 32 | } 33 | } 34 | 35 | double newton_interpolating(double x_value) { 36 | double sum = value_table.begin()->second; 37 | double tmp = 1; 38 | for (vector >::iterator iter = value_table.begin(); 39 | iter != value_table.end() - 1; ++iter) { 40 | tmp = tmp * (x_value - iter->first); 41 | sum = sum + ((iter + 1)->second) * tmp; 42 | } 43 | return sum; 44 | } -------------------------------------------------------------------------------- /nonlinear_equation.py: -------------------------------------------------------------------------------- 1 | import os 2 | -------------------------------------------------------------------------------- /numerical_integration.py: -------------------------------------------------------------------------------- 1 | #%% 2 | from math import sin 3 | 4 | def f(x): 5 | if x==0: 6 | return 1 7 | return sin(x)/x 8 | 9 | def composite_trapezoidal_formula(function,lower_limit,upper_limit,divide): 10 | tmp=0 11 | step=(upper_limit-lower_limit)/divide 12 | for i in range(divide): 13 | tmp=tmp+function(lower_limit+i*step)+function(lower_limit+(i+1)*step) 14 | return step/2*tmp 15 | 16 | def compound_Simpson_formula(function,lower_limit,upper_limit,divide): 17 | tmp=0 18 | step=(upper_limit-lower_limit)/divide 19 | for i in range(divide): 20 | tmp=tmp+function(lower_limit+i*step)+function(lower_limit+(i+1)*step)+4*function(((lower_limit+i*step)+(lower_limit+(i+1)*step))/2) 21 | return step/6*tmp 22 | 23 | def half_trapezoidal(function,lower_limit,upper_limit,deviation): 24 | T_n=1/2*(function(lower_limit)+function(upper_limit)) 25 | length=(upper_limit-lower_limit) 26 | divide=1 27 | step=length/divide 28 | k=0 29 | while True: 30 | tmp=0 31 | for i in range(divide): 32 | tmp=tmp+function(((lower_limit+i*step)+(lower_limit+(i+1)*step))/2) 33 | T_2n=1/2*T_n+step/2*tmp 34 | print("等分次数:{0} Tn:{1}".format(k+1,T_2n)) 35 | if abs(T_2n-T_n) 2 | using namespace std; 3 | 4 | float Q_rsqrt( float number ) 5 | { 6 | long i; 7 | float x2, y; 8 | const float threehalfs = 1.5F; 9 | x2 = number * 0.5F; 10 | y = number; 11 | i = * ( long * ) &y; 12 | i = 0x5f3759df - ( i >> 1 ); 13 | y = * ( float * ) &i; 14 | y = y * ( threehalfs - ( x2 * y * y ) ); 15 | return y; 16 | } 17 | 18 | int main(){ 19 | float num=19588; 20 | cout << num*Q_rsqrt(num) << endl; 21 | return 0; 22 | } -------------------------------------------------------------------------------- /recurrence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void recurrence(int, int, double, int = 4); 6 | 7 | int main() { 8 | recurrence(0, 9, 0.6321); 9 | recurrence(9, 0, 0.0684); 10 | return 0; 11 | } 12 | 13 | void recurrence(int input_subscript, int destination_subscript, 14 | double input_value, int precision) { 15 | double value = input_value; 16 | int subscript = input_subscript; 17 | cout << "I[" << subscript << "] = " << setprecision(precision) << value 18 | << endl; 19 | if (subscript < destination_subscript) { 20 | while (subscript != destination_subscript) { 21 | value = 1 - (++subscript) * value; 22 | cout << "I[" << subscript << "] = " << setprecision(precision) << value 23 | << endl; 24 | } 25 | } else { 26 | while (subscript != destination_subscript) { 27 | value = (1 - value) / (subscript--); 28 | cout << "I[" << subscript << "] = " << setprecision(precision) << value 29 | << endl; 30 | } 31 | } 32 | } --------------------------------------------------------------------------------