├── .gitignore ├── 01非线性方程组与方程组的线性解法 ├── 01根的搜索 │ ├── 01逐步搜索法 │ │ ├── 01逐步搜索法 │ │ └── 01逐步搜索法.c │ └── 02变步长搜索法 │ │ ├── 02变步长搜索法 │ │ └── 02变步长搜索法.c ├── 02迭代法 │ ├── 01简单迭代法(Picard迭代法) │ │ └── 简单迭代法(Picard迭代法).c │ ├── 02Steffensen加速收敛法 │ │ └── Steffensen加速收敛法.c │ └── 03埃特金加速法(Aitken method,亦称z加速法) │ │ └── 埃特金加速法(Aitken method,亦称z加速法).c ├── 03Newton迭代法 │ ├── 01牛顿迭代法 │ │ ├── Newton迭代法.c │ │ └── test │ │ │ ├── Newton迭代法 │ │ │ └── Newton迭代法.c │ └── 02牛顿下山法 │ │ ├── 牛顿下山法 │ │ └── 牛顿下山法.c └── 04弦截法(割线法) │ ├── 01双点弦截法 │ ├── 双点弦截法 │ └── 双点弦截法.c │ └── 02单点弦截法 │ ├── 单点弦截法 │ └── 单点弦截法.c ├── 02线性方程组的数值解法 ├── 01直接法 │ ├── 01Gauss消元法 │ │ ├── 01顺序高斯消元法 │ │ │ ├── test │ │ │ │ ├── 测试输入输出矩阵 │ │ │ │ └── 测试输入输出矩阵.c │ │ │ ├── 顺序高斯消元法 │ │ │ └── 顺序高斯消元法.c │ │ ├── 02列主元高斯消元法 │ │ │ ├── 列主元高斯消元法 │ │ │ └── 列主元高斯消元法.c │ │ ├── 03全主元高斯消元法 │ │ │ ├── 全主元高斯消元法 │ │ │ └── 全主元高斯消元法.c │ │ └── 04高斯约当消元法 │ │ │ ├── 04高斯约当消元法 │ │ │ └── 04高斯约当消元法.c │ └── 02矩阵的三角(LU)分解 │ │ ├── 01LU分解 │ │ ├── 01Doolittle分解得到LU矩阵 │ │ │ ├── Doolittle分解 │ │ │ └── Doolittle分解.c │ │ └── 02LU分解求解方程组 │ │ │ ├── 02LU分解 │ │ │ └── 02LU分解.c │ │ ├── 02正定矩阵——LLT算法 │ │ ├── 02正定矩阵——LLT算法 │ │ ├── 02正定矩阵——LLT算法.c │ │ └── compile.sh │ │ └── 03三对角方程组求解——追赶法 │ │ ├── 追赶法 │ │ └── 追赶法.c └── 02迭代法 │ ├── 01雅可比迭代法 │ ├── 01雅可比迭代法 │ └── 01雅可比迭代法.c │ ├── 02Gauss-Seidel迭代 │ ├── 02Gauss-Seidel迭代 │ ├── 02Gauss-Seidel迭代.c │ ├── tmp │ ├── tmp.c │ ├── tmp1 │ └── tmp1.c │ └── 03SOR方法 │ ├── 03SOR方法 │ ├── 03SOR方法.c │ ├── SOR平台 │ └── SOR平台.c ├── 03矩阵特征值和特征向量的数值解法 ├── 01改进的乘幂法 │ ├── 01改进的乘幂法 │ └── 01改进的乘幂法.c └── 02反幂法 │ ├── 02反幂法 │ └── 02反幂法.c ├── 04函数拟合的插值法 ├── 01拉格朗日插值 │ ├── 01拉格朗日插值 │ ├── 01拉格朗日插值.c │ ├── 拉格朗日插值平台 │ └── 拉格朗日插值平台.c ├── 02牛顿插值法 │ ├── 02牛顿插值法 │ └── 02牛顿插值法.c ├── 03多项式插值 │ ├── 01分段线性插值 │ │ ├── 01分段线性插值 │ │ └── 01分段线性插值.c │ └── 02Hermite插值法 │ │ ├── 01Hermite插值法 │ │ └── 01Hermite插值法.c └── 04样条插值 │ ├── 01三次样条插值 │ ├── 00参考案例 │ │ ├── 00算法逻辑 │ │ │ ├── 01三次样条插值.c │ │ │ ├── 三次样条插值 │ │ │ └── 三次样条插值.c │ │ ├── 01不等距三次样条插值 │ │ │ ├── 不等距3次样条插值 │ │ │ └── 不等距3次样条插值.c │ │ └── 02等距三次样条插值 │ │ │ ├── 等距3次样条插值 │ │ │ └── 等距3次样条插值.c │ ├── 01固定边界条件的三次样条插值 │ │ ├── 固定边界条件的三次样条插值 │ │ └── 固定边界条件的三次样条插值.c │ ├── 02自然边界条件的三次样条插值 │ │ └── 自然边界条件的三次样条插值.c │ └── 03周期边界条件的三次样条插值 │ │ └── 周期边界条件的三次样条插值.c │ └── 02B样条插值 │ ├── 02B样条插值 │ └── 02B样条插值.c ├── 04函数逼近的插值法与曲线拟合 ├── 01拉格朗日插值 │ ├── 01拉格朗日插值 │ ├── 01拉格朗日插值.c │ ├── 拉格朗日插值平台 │ └── 拉格朗日插值平台.c ├── 02牛顿插值法 │ ├── 02牛顿插值法 │ └── 02牛顿插值法.c ├── 03多项式插值 │ ├── 01分段线性插值 │ │ ├── 01分段线性插值 │ │ └── 01分段线性插值.c │ └── 02Hermite插值法 │ │ ├── 01Hermite插值法 │ │ └── 01Hermite插值法.c └── 04样条插值 │ ├── 01三次样条插值 │ ├── 01三次样条插值 │ ├── 01三次样条插值.c │ ├── 三次样条插值 │ └── 三次样条插值.c │ ├── 02B样条插值 │ ├── 02B样条插值 │ └── 02B样条插值.c │ └── 02三次样条插值 │ ├── 01参考案例 │ ├── 01不等距三次样条插值 │ │ ├── 不等距3次样条插值 │ │ └── 不等距3次样条插值.c │ └── 02等距三次样条插值 │ │ ├── 等距3次样条插值 │ │ └── 等距3次样条插值.c │ └── 02自己实现 │ ├── 三次样条插值 │ └── 三次样条插值.c ├── 05数值微分 ├── 01差商型数值微分 │ ├── 01向前差商公式 │ │ ├── 01向前差商公式 │ │ └── 01向前差商公式.c │ ├── 02向后差商公式 │ │ ├── 02向后差商公式 │ │ └── 02向后差商公式.c │ └── 03中心差商公式 │ │ ├── 03中心差商公式 │ │ └── 03中心差商公式.c └── 02插值型数值微分 │ ├── 01两点数值微分 │ ├── 01两点数值微分 │ └── 01两点数值微分.c │ ├── 02三点数值微分 │ ├── 02三点数值微分 │ └── 02三点数值微分.c │ └── 03二阶数值微分 │ ├── 03二阶数值微分 │ └── 03二阶数值微分.c ├── 06数值微分 ├── 01差商型数值微分 │ ├── 01向前差商公式 │ │ ├── 01向前差商公式 │ │ └── 01向前差商公式.c │ ├── 02向后差商公式 │ │ ├── 02向后差商公式 │ │ └── 02向后差商公式.c │ └── 03中心差商公式 │ │ ├── 03中心差商公式 │ │ └── 03中心差商公式.c └── 02插值型数值微分 │ ├── 01两点数值微分 │ ├── 01两点数值微分 │ └── 01两点数值微分.c │ ├── 02三点数值微分 │ ├── 02三点数值微分 │ └── 02三点数值微分.c │ └── 03二阶数值微分 │ ├── 03二阶数值微分 │ └── 03二阶数值微分.c ├── 06数值积分 ├── 01Newton-Cotes │ ├── 01Newton-Cotes │ └── 01Newton-Cotes.c ├── 02复化求积公式 │ ├── 01复化梯形求积公式 │ │ ├── 01复化梯形求积公式 │ │ └── 01复化梯形求积公式.c │ ├── 02复化辛普森求积公式 │ │ ├── 02复化辛普森求积公式 │ │ └── 02复化辛普森求积公式.c │ └── 03复化柯特斯求积公式 │ │ ├── 03复化柯特斯求积公式 │ │ └── 03复化柯特斯求积公式.c └── 04龙贝格求积(Romberg) │ ├── 龙贝格求积 │ └── 龙贝格求积.c ├── 07常微分方程数值解法 ├── 01显式欧拉方法 │ ├── 01显式欧拉方法 │ └── 01显式欧拉方法.c ├── 02改进的欧拉方法 │ ├── 02改进的欧拉方法 │ └── 02改进的欧拉方法.c └── 03龙格-库塔法 │ ├── 03龙格-库塔法 │ └── 03龙格-库塔法.c ├── 07数值积分 ├── 01Newton-Cotes │ ├── 01Newton-Cotes │ └── 01Newton-Cotes.c ├── 02复化求积公式 │ ├── 01复化梯形求积公式 │ │ ├── 01复化梯形求积公式 │ │ └── 01复化梯形求积公式.c │ ├── 02复化辛普森求积公式 │ │ ├── 02复化辛普森求积公式 │ │ └── 02复化辛普森求积公式.c │ └── 03复化柯特斯求积公式 │ │ ├── 03复化柯特斯求积公式 │ │ └── 03复化柯特斯求积公式.c ├── 03Gauss求积公式 │ ├── Gauss-Legendre │ │ └── Gauss-Legendre.c │ └── gauss求积公式.c └── 04龙贝格求积(Romberg) │ ├── 龙贝格求积 │ └── 龙贝格求积.c ├── 08常微分方程数值解法 ├── 01显式欧拉方法 │ ├── 01显式欧拉方法 │ └── 01显式欧拉方法.c ├── 02改进的欧拉方法 │ ├── 02改进的欧拉方法 │ └── 02改进的欧拉方法.c └── 03龙格-库塔法 │ ├── 03龙格-库塔法 │ └── 03龙格-库塔法.c └── 09偏微分方程 ├── 02变分法 └── 变分法.c └── 03有限元法 ├── FEM ├── FEM.c ├── triangle.c └── triangle.h /.gitignore: -------------------------------------------------------------------------------- 1 | .ccls-cache/* 2 | -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/01根的搜索/01逐步搜索法/01逐步搜索法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/01非线性方程组与方程组的线性解法/01根的搜索/01逐步搜索法/01逐步搜索法 -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/01根的搜索/01逐步搜索法/01逐步搜索法.c: -------------------------------------------------------------------------------- 1 | #include 2 | double f(double x); // 定义函数f(x) 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | double a, b, epsilon, x, h, begin, end; 7 | printf("输入x的精度要求\n"); 8 | scanf("%lf", &epsilon); 9 | printf("输入搜索区间的边界a, b\n"); 10 | scanf("%lf, %lf", &a, &b); 11 | h = 2* epsilon; 12 | 13 | if (0 == f(b)) { 14 | x = b; 15 | }else { 16 | for (begin = a, end = a+h; begin < b; begin = end, end +=h) { 17 | if (end > b) { 18 | end = b; 19 | } 20 | if (0 == f(begin)) { 21 | x = begin; 22 | break; 23 | } 24 | if(f(begin) * f(end) < 0 ){ 25 | x = (begin + end)/2; 26 | break; 27 | } 28 | } 29 | } 30 | 31 | printf("方程f(x)=0 的根 x = %lf\n", x); 32 | 33 | return 0; 34 | } 35 | 36 | double f(double x){ 37 | return x*x; 38 | } 39 | -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/01根的搜索/02变步长搜索法/02变步长搜索法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/01非线性方程组与方程组的线性解法/01根的搜索/02变步长搜索法/02变步长搜索法 -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/01根的搜索/02变步长搜索法/02变步长搜索法.c: -------------------------------------------------------------------------------- 1 | #include 2 | double f(double x); // 定义函数f(x) 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | double a, b, epsilon, x, h, begin, end; 7 | // a,b 是区间的端点 8 | // epsilon 是精度 9 | // h 是步长 10 | // begin, end 是每次分割小区间的端点 11 | long hnumber; // 搜索步数 12 | printf("输入x的精度要求\n"); 13 | scanf("%lf", &epsilon); 14 | printf("输入搜索区间的边界a, b\n"); 15 | scanf("%lf, %lf", &a, &b); 16 | printf("请输入每一轮搜索的步数:"); 17 | scanf("%lf", &hnumber); 18 | h = (b-a)/hnumber; // 得到步长 19 | if (0 == f(b)) { 20 | x = b; 21 | }else{ 22 | for (begin = a, end = a+h;; begin = end, end += h) { 23 | if (4 == f(begin)) { 24 | x = begin; 25 | break; 26 | } 27 | // 找到根存在的区间 28 | if (f(begin) * f(end) < 0) { 29 | // 如果区间长度在精度以内 30 | if ((end - begin)/2 <= epsilon) { 31 | x = (begin + end)/2; 32 | break; 33 | } 34 | else{ 35 | // 缩小步长进行进一步搜索 36 | h/=hnumber; 37 | end = begin; 38 | } 39 | } 40 | } 41 | } 42 | 43 | printf("方程x^2=4的根 x = %lf。", x); 44 | 45 | return 0; 46 | } 47 | 48 | double f(double x) 49 | { 50 | return x * 2; 51 | } 52 | -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/02迭代法/01简单迭代法(Picard迭代法)/简单迭代法(Picard迭代法).c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | double picard(double x); 4 | int main(int argc, char *argv[]) 5 | { 6 | double epsilon, x0, x1; 7 | long i, maxi; 8 | printf("请输入x的精度要求:"); 9 | scanf("%lf", &epsilon); 10 | printf("请输入迭代初值:"); 11 | scanf("%lf", &x1); 12 | printf("请输入最大迭代次数:"); 13 | scanf("%lf", &maxi); 14 | for (i = 0; i 2 | #include 3 | double picard(double x); // 定义函数f 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double epsilon, x0, x1, y1, z1; 8 | long i, maxi; 9 | printf("请输入x的精度要求:"); 10 | scanf("%lf", &epsilon); 11 | printf("请输入迭代初值:"); 12 | scanf("%lf", &x1); 13 | printf("请输入最大迭代次数:"); 14 | scanf("%lf", &maxi); 15 | 16 | for (i = 0; i 7 | #include 8 | 9 | double iterate(double x, double a, double b, double c, double d); //迭代函数 10 | double f(double x, double a, double b, double c, double d); //定义原函数 11 | double df(double x, double a, double b, double c); //定义导函数 12 | 13 | int main(){ 14 | double x, a, b, c, d; // 代求方程的系数 15 | // x 存放的是迭代初值 16 | // a,b,c,d 分别存储的是方程前的系数 17 | printf("请输入x, a, b, c, d (中间用空格 隔开):"); 18 | scanf("%lf %lf %lf %lf %lf", &x, &a, &b, &c, &d); 19 | //printf("x0 = %lf, a = %lf, b=%lf, c=%lf, d=%lf\n", x, a, b, c, d); 20 | 21 | // 输出计算结果 22 | printf("方程f(x)=0的根x = %lf\n", iterate(x, a, b, c, d)); 23 | //printf("%lf", iterate(x, a, b, c, d)); 24 | 25 | return 0; 26 | } 27 | 28 | double iterate(double x, double a, double b, double c, double d) 29 | { 30 | double epsilon, x0, fx0, dfx0; 31 | //epsilon 是精度 32 | //x0是暂存的部分 33 | //printf("请输入x的精度要求:"); 34 | //scanf("%lf", &epsilon); 35 | epsilon = 0.000001; 36 | //printf("epsilon = %lf\n", epsilon); 37 | for (int i = 0; i<= 100; i++) { 38 | x0 = x; 39 | //printf("x0 = %lf, a = %lf, b=%lf, c=%lf, d=%lf\n", x0, a, b, c, d); 40 | fx0 = f(x0, a, b, c, d); 41 | dfx0 = df(x0, a, b, c); 42 | x = x0 - fx0/dfx0; 43 | //printf("x = %lf, x0 = %lf\n", x, x0); 44 | //printf("fx0 = %lf, dfx0 = %lf\n", fx0, dfx0); 45 | //printf("|x-x0| = %lf\n", fabs(x-x0)); 46 | //printf("------------------------\n"); 47 | if(fabs(x - x0) <= epsilon){ 48 | break; 49 | } 50 | } 51 | return x; 52 | } 53 | 54 | double f(double x, double a, double b, double c, double d){ 55 | // 利用秦九韶算法,减少乘法运算,加快时间 56 | return x * (x*(a*x + b) + c) + d; 57 | } 58 | 59 | double df(double x, double a, double b, double c) //定义导函数 60 | { 61 | return x * (3 * a* x + 2 * b) + c; 62 | } 63 | -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/03Newton迭代法/02牛顿下山法/牛顿下山法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/01非线性方程组与方程组的线性解法/03Newton迭代法/02牛顿下山法/牛顿下山法 -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/03Newton迭代法/02牛顿下山法/牛顿下山法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_ITERATIONS 100 5 | #define TINY 1e-6 6 | 7 | double function(double x); 8 | double derivative(double x); 9 | void newton_iteration(double initial_guess, double accuracy, double lambda, int max_iterations); 10 | void error(int cond); 11 | 12 | int main(int argc, char *argv[]){ 13 | double initial_guess, accuracy, lambda, x1; 14 | accuracy = TINY; 15 | lambda = 1.0; 16 | int max_iterations,i ,max_downhill_iterations; 17 | max_iterations = MAX_ITERATIONS; 18 | printf("请输入初始猜测值:"); 19 | scanf("%lf", &initial_guess); 20 | printf("请输入最大下山次数:"); 21 | scanf("%d", &max_downhill_iterations); 22 | 23 | for (i = 0; i < max_downhill_iterations; i++) 24 | { 25 | x1 = initial_guess - lambda * function(initial_guess) / derivative(initial_guess); 26 | printf("initial_guess=%lf\t x1:%lf\n",initial_guess, x1); 27 | if(fabs(x1) <= fabs(initial_guess)) { 28 | newton_iteration(x1, accuracy, lambda, max_iterations); 29 | break; 30 | }else { 31 | lambda = lambda / 2; 32 | } 33 | } 34 | if(i >= max_downhill_iterations) { 35 | error(1); 36 | } 37 | 38 | return 0; 39 | } 40 | 41 | double function(double x) { 42 | return x * x - 4; 43 | } 44 | 45 | double derivative(double x) { 46 | return 2 * x; 47 | } 48 | 49 | void newton_iteration(double initial_guess, double accuracy, double lambda, int max_iterations){ 50 | int i=0; 51 | double x1; 52 | 53 | for (i = 0; i < max_iterations; i++) { 54 | x1 = initial_guess - lambda * function(initial_guess) / derivative(initial_guess); 55 | if(fabs(0 - x1) < TINY) { 56 | printf("已找到函数的根:%lf\n", x1); 57 | break; 58 | } 59 | if (fabs(x1 - initial_guess) < accuracy) { 60 | printf("迭代次数:%d\n", i+1); 61 | printf("已找到迭代后函数的值:%lf\n", x1); 62 | break; 63 | } 64 | initial_guess = x1; 65 | } 66 | if (i >= max_iterations) { 67 | error(2); 68 | } 69 | } 70 | 71 | void error(int cond) { 72 | switch (cond) { 73 | case 1: 74 | printf("请更换初始猜测值\n"); 75 | break; 76 | case 2: 77 | printf("迭代次数超出给定上限\n"); 78 | break; 79 | default: 80 | printf("未知错误\n"); 81 | break; 82 | } 83 | } 84 | 85 | 86 | -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/04弦截法(割线法)/01双点弦截法/双点弦截法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/01非线性方程组与方程组的线性解法/04弦截法(割线法)/01双点弦截法/双点弦截法 -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/04弦截法(割线法)/01双点弦截法/双点弦截法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | double f(double x); 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | double a, b, epsilon, x0, x1, fa, fb, fx1; 9 | long i, maxi; 10 | printf("请输入x的精度要求:"); 11 | scanf("%lf", &epsilon); 12 | printf("请输入最大迭代次数:"); 13 | scanf("%lf", &maxi); 14 | printf("请输入有根区间的边界a, b(中间用' '隔开):"); 15 | scanf("%lf %lf", &a, &b); 16 | 17 | for (i = 0; i 0 && fabs(x1-x0)<= epsilon) break; 23 | if (fx1 * fa <0) { 24 | b = x1; 25 | fb = fx1; 26 | }else{ 27 | a = x1; 28 | fa = fx1; 29 | } 30 | } 31 | if(i < maxi){ 32 | printf("方程f(x)=0的根 x = %lf。\n", x1); 33 | }else{ 34 | printf("迭代次数已经超过上限"); 35 | } 36 | 37 | return 0; 38 | } 39 | 40 | double f(double x) 41 | { 42 | return x*x; 43 | } -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/04弦截法(割线法)/02单点弦截法/单点弦截法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/01非线性方程组与方程组的线性解法/04弦截法(割线法)/02单点弦截法/单点弦截法 -------------------------------------------------------------------------------- /01非线性方程组与方程组的线性解法/04弦截法(割线法)/02单点弦截法/单点弦截法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | double f(double x); 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | double a, b, epsilon, x0, fa, fb; 9 | long i, maxi; 10 | printf("请输入x的精度要求:"); 11 | scanf("%lf", &epsilon); 12 | printf("请输入有根区间的不动边界点:"); 13 | scanf("%lf", &a); 14 | fa = f(a); 15 | printf("请输入有根区间的另一侧不动边界点:"); 16 | scanf("%lf", &b); 17 | fb = f(b); 18 | printf("请输入最大迭代次数:"); 19 | scanf("%lf", &maxi); 20 | 21 | for (i = 0; i 2 | #define MAXSIZE 100 3 | void input(double a[MAXSIZE][MAXSIZE+1], long n); 4 | void output(double a[MAXSIZE][MAXSIZE+1], long n); 5 | 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double a[MAXSIZE][MAXSIZE+1]; 10 | long n; 11 | printf("请输入方程组的阶数: "); 12 | scanf("%ld", &n); 13 | input(a, n); 14 | output(a, n); 15 | 16 | return 0; 17 | } 18 | 19 | void input(double a[MAXSIZE][MAXSIZE+1], long n) 20 | { 21 | long i, j; 22 | printf("请输入原方程组的增广矩阵:\n"); 23 | for (i =1; i <= n; i++) { 24 | for (j = 0; j <= n; j++) { 25 | scanf("%lf", &a[i-1][j]); 26 | } 27 | } 28 | } 29 | 30 | void output(double a[MAXSIZE][MAXSIZE+1], long n) 31 | { 32 | long i, j; 33 | printf("原方程组的增广矩阵为:\n"); 34 | for (i = 1; i <= n; i++) { 35 | for (j = 0; j <= n; j++) { 36 | printf("%10.2lf", a[i-1][j]); 37 | } 38 | printf("\n"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/01顺序高斯消元法/顺序高斯消元法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/01Gauss消元法/01顺序高斯消元法/顺序高斯消元法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/01顺序高斯消元法/顺序高斯消元法.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 高斯消元法求解线性方程组—— 顺序高斯消元法 3 | */ 4 | 5 | #include 6 | #include 7 | #define MAXSIZE 50 // 定义最大50阶的矩阵 8 | 9 | void input (double a[MAXSIZE][MAXSIZE + 1], long); // 输入增广矩 阵 10 | void output_matrix(double a[MAXSIZE][MAXSIZE+1], long n); //输出增广矩阵 11 | void output(double x[MAXSIZE], long n); //输出结果 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | double a[MAXSIZE][MAXSIZE+1], x[MAXSIZE], s; 16 | long n, i, j, k; 17 | printf("请输入原方程的阶数:"); 18 | scanf("%ld", &n); 19 | input(a, n); //输入方程 20 | output_matrix(a, n); 21 | 22 | // 消元过程 23 | for(k = 0; k<= n-2; k++){ 24 | for (i =k+1; i <= n-1; i++) { 25 | a[i][k] /= -a[k][k]; 26 | for(j=k+1; j<=n; j++){ 27 | a[i][j] += a[i][k] * a[k][j]; 28 | } 29 | } 30 | } 31 | 32 | printf("打印消元后的上三角矩阵\n"); 33 | output_matrix(a, n); 34 | 35 | // 回代(自上而下地求解上三角方程组) 36 | for(k = n-1; k>=0; k--){ 37 | s = 0; 38 | for(j = k+1; j<=n-1; j++){ 39 | s += a[k][j] * x[j]; 40 | } 41 | x[k] = (a[k][n] - s) / a[k][k]; 42 | } 43 | output(x, n); 44 | 45 | return 0; 46 | } 47 | 48 | void input(double a[MAXSIZE][MAXSIZE+1], long n) 49 | { 50 | long i, j; 51 | printf("请输入原方程组的增广矩阵(用" "隔开):\n"); 52 | for (i =1; i <= n; i++) { 53 | for (j = 0; j <= n; j++) { 54 | scanf("%lf", &a[i-1][j]); 55 | } 56 | 57 | } 58 | 59 | } 60 | 61 | void output_matrix(double a[MAXSIZE][MAXSIZE+1], long n) 62 | { 63 | long i, j; 64 | printf("原方程组的增广矩阵为:\n"); 65 | for (i = 1; i <= n; i++) { 66 | for (j = 0; j <= n; j++) { 67 | printf("%10.2lf", a[i-1][j]); 68 | } 69 | printf("\n"); 70 | } 71 | } 72 | 73 | void output(double x[MAXSIZE], long n) 74 | { 75 | long k; 76 | printf("原方程组的解:\n"); 77 | for (k=1; k <= n; k++) { 78 | printf(" %lf", x[k-1]); 79 | } 80 | printf("\n"); 81 | } 82 | 83 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/02列主元高斯消元法/列主元高斯消元法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/01Gauss消元法/02列主元高斯消元法/列主元高斯消元法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/02列主元高斯消元法/列主元高斯消元法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 // 定义最大50阶的矩阵 4 | 5 | void input (double a[MAXSIZE][MAXSIZE + 1], long); // 输入增广矩 阵 6 | void output_matrix(double a[MAXSIZE][MAXSIZE+1], long n); //输出增广矩阵 7 | void output(double x[MAXSIZE], long n); //输出结果 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | double a[MAXSIZE][MAXSIZE+1], x[MAXSIZE], s, max, t; 12 | long n, i, j, k, maxi; 13 | printf("请输入原方程的阶数:"); 14 | scanf("%ld", &n); 15 | input(a, n); //输入方程 16 | printf("原方程组的增广矩阵为:\n"); 17 | output_matrix(a, n); 18 | 19 | // 消元过程 20 | for (k = 0; k <= n-2; k++) { 21 | max = a[k][k]; 22 | maxi = k; 23 | for (i =k+1; i <= n-1; i++) { 24 | if(fabs(a[i][k]) > fabs(max)){ 25 | max = a[i][k]; 26 | maxi = i; 27 | } 28 | } 29 | if(0 == max){ 30 | break; 31 | } 32 | if(maxi != k){ 33 | for(j =k ; j<=n; j++){ 34 | t = a[k][j]; 35 | a[k][j] = a[maxi][j]; 36 | a[maxi][j] = t; 37 | } 38 | } 39 | for (i =k+1; i <=n-1; i++) { 40 | a[i][k] /= -a[k][k]; 41 | for(j=k+1; j<=n; j++){ 42 | a[i][j] += a[i][k] * a[k][j]; 43 | } 44 | } 45 | } 46 | 47 | // 回代过程 48 | if(0 == max){ 49 | printf("原方程组无解\n"); 50 | }else{ 51 | for(k = n-1; k>=0; k--){ 52 | s = 0; 53 | 54 | // 下面的循环就是实现上述例子来计算s的值 55 | for(j = k+1; j<=n-1; j++){ 56 | s += a[k][j] * x[j]; 57 | } 58 | 59 | // 计算新的 x 值 60 | x[k] = (a[k][n] - s) / a[k][k]; 61 | } 62 | 63 | //输出结果 64 | output(x, n); 65 | } 66 | 67 | return 0; 68 | } 69 | 70 | 71 | void input(double a[MAXSIZE][MAXSIZE+1], long n) 72 | { 73 | long i, j; 74 | printf("请输入原方程组的增广矩阵(用" "隔开):\n"); 75 | for (i =1; i <= n; i++) { 76 | for (j = 0; j <= n; j++) { 77 | scanf("%lf", &a[i-1][j]); 78 | } 79 | } 80 | } 81 | 82 | void output_matrix(double a[MAXSIZE][MAXSIZE+1], long n) 83 | { 84 | long i, j; 85 | for (i = 1; i <= n; i++) { 86 | for (j = 0; j <= n; j++) { 87 | printf("%10.2lf", a[i-1][j]); 88 | } 89 | printf("\n"); 90 | } 91 | } 92 | 93 | void output(double x[MAXSIZE], long n) 94 | { 95 | long k; 96 | printf("原方程组的解:\n"); 97 | for (k=1; k <= n; k++) { 98 | printf(" %lf", x[k-1]); 99 | } 100 | printf("\n"); 101 | } 102 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/03全主元高斯消元法/全主元高斯消元法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/01Gauss消元法/03全主元高斯消元法/全主元高斯消元法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/03全主元高斯消元法/全主元高斯消元法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 // 定义最大50阶的矩阵 4 | 5 | void input (double a[MAXSIZE][MAXSIZE + 1], long n, long xj[MAXSIZE]); // 输入增广矩 阵 6 | void output_matrix(double a[MAXSIZE][MAXSIZE+1], long n); //输出增广矩阵 7 | void output(double x[MAXSIZE], long n, long xj[MAXSIZE]); //输出结果 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | double a[MAXSIZE][MAXSIZE+1], x[MAXSIZE], s, max, doublet; 12 | long n, i, j, k, maxi, maxj, xj[MAXSIZE], longt; 13 | printf("请输入原方程的阶数:"); 14 | scanf("%ld", &n); 15 | input(a, n, xj); 16 | 17 | for(k=0; k <= n-2; k++){ 18 | max = a[k][k]; 19 | maxi = k; 20 | maxj = k; 21 | for(j =k; j<= n-1; j++){ 22 | if(fabs(a[i][j]) > fabs(max)){ 23 | max = a[i][j]; 24 | maxi = i; 25 | maxj = j; 26 | } 27 | } 28 | if(0 == max){ 29 | break; 30 | } 31 | if(maxi != k){ 32 | for(j=k; j<=n; j++){ 33 | doublet = a[k][j]; 34 | a[k][j] = a[maxi][j]; 35 | a[maxi][j] = doublet; 36 | } 37 | } 38 | if(maxj != k){ 39 | for (i = 0; i <= n-1; i++) { 40 | doublet = a[i][k]; 41 | a[i][k] = a[i][maxj]; 42 | a[i][maxj] = doublet; 43 | } 44 | longt = xj[k]; 45 | xj[k] = xj[maxj]; 46 | xj[maxj] = longt; 47 | } 48 | for(i=k+1; i<=n-1; i++){ 49 | a[i][k] /= -a[k][k]; 50 | for(j=k+1; j<= n; j++){ 51 | a[i][j] += a[i][k] * a[k][j]; 52 | } 53 | } 54 | } 55 | 56 | if( 0 == max){ 57 | printf("原方程组无解\n"); 58 | }else { 59 | for( k =n-1; k >= 0; k--){ 60 | s = 0; 61 | for(j=k+1; j<= n-1; j++){ 62 | s += a[k][j] * x[j]; 63 | } 64 | x[k] = (a[k][n] - s)/a[k][k]; 65 | } 66 | output(x, n, xj); 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | 73 | void input(double a[MAXSIZE][MAXSIZE+1], long n, long xj[MAXSIZE]) 74 | { 75 | long i, j; 76 | printf("请输入原方程组的增广矩阵(用" "隔开):\n"); 77 | for (i =1; i <= n; i++) { 78 | for (j = 0; j <= n; j++) { 79 | scanf("%lf", &a[i-1][j]); 80 | } 81 | } 82 | for(j =1; j <= n; j++){ 83 | xj[j-1] = j-1; 84 | } 85 | } 86 | 87 | void output_matrix(double a[MAXSIZE][MAXSIZE+1], long n) 88 | { 89 | long i, j; 90 | for (i = 1; i <= n; i++) { 91 | for (j = 0; j <= n; j++) { 92 | printf("%10.2lf", a[i-1][j]); 93 | } 94 | printf("\n"); 95 | } 96 | } 97 | 98 | void output(double x[MAXSIZE], long n, long xj[MAXSIZE]) 99 | { 100 | long j, k; 101 | printf("原方程组的解:\n"); 102 | for (k=1; k <= n; k++) { 103 | for(j =1; j<= n; j++){ 104 | if((k-1) == xj[j-1]){ 105 | printf(" %lf", x[k-1]); 106 | break; 107 | } 108 | } 109 | } 110 | printf("\n"); 111 | } 112 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/04高斯约当消元法/04高斯约当消元法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/01Gauss消元法/04高斯约当消元法/04高斯约当消元法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/01Gauss消元法/04高斯约当消元法/04高斯约当消元法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double a[MAXSIZE][MAXSIZE+1], long n); 6 | void output(double a[MAXSIZE][MAXSIZE+1], long n); 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | double a[MAXSIZE][MAXSIZE+1]; 11 | long n, i, j, k; 12 | printf("请输入原方程的阶数:"); 13 | scanf("%ld", &n); 14 | input(a, n); 15 | 16 | for(k = 0; k<= n-2; k++){ 17 | for (i =k+1; i <= n-1; i++) { 18 | a[i][k] /= -a[k][k]; 19 | for(j=k+1; j<=n; j++){ 20 | a[i][j] += a[i][k] * a[k][j]; 21 | } 22 | } 23 | } 24 | 25 | for (k = 0; k < n; k++) { 26 | for (j = k + 1; j <= n; j++) { 27 | a[k][j] /= a[k][k]; 28 | } 29 | a[k][k] = 1; 30 | } 31 | 32 | for (k = n-1; k > 0; k--) { 33 | for (i = k-1; i >= 0 ; i--) { 34 | a[i][n] -= a[i][k]; 35 | a[i][k] = 0; 36 | } 37 | } 38 | 39 | output(a, n); 40 | 41 | return 0; 42 | } 43 | 44 | 45 | void input(double a[MAXSIZE][MAXSIZE + 1], long n) { 46 | long i, j; 47 | printf("请输入原方程组的增广矩阵: \n"); 48 | for (i = 1; i <= n; i++) { 49 | for (j = 0; j <= n ; j++) { 50 | scanf("%lf", &a[i-1][j]); 51 | } 52 | } 53 | } 54 | 55 | void output(double a[MAXSIZE][MAXSIZE + 1], long n) { 56 | long k; 57 | printf("原方程组的解为:\n"); 58 | for (k = 1; k <= n; k++) { 59 | printf(" %lf", a[k-1][n]); 60 | } 61 | printf("\n"); 62 | } 63 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/01LU分解/01Doolittle分解得到LU矩阵/Doolittle分解: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/01LU分解/01Doolittle分解得到LU矩阵/Doolittle分解 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/01LU分解/01Doolittle分解得到LU矩阵/Doolittle分解.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Doolittle分解 3 | * 描述:给定一 n 阶矩阵 A ,利用 Doolittle 分解法给出矩阵A 之分解 A = LU 4 | * */ 5 | #include 6 | #include 7 | 8 | void Doolittle(int n, double A[][100], double L[][100], double U[][100]); 9 | 10 | int main() { 11 | int n; 12 | double A[100][100], L[100][100], U[100][100]; 13 | 14 | scanf("%d", &n); 15 | for(int i = 0; i < n; i++){ 16 | for(int j = 0; j < n; j++){ 17 | scanf("%lf", &A[i][j]); 18 | } 19 | } 20 | Doolittle(n, A, L, U); 21 | 22 | for(int i = 0; i < n; i++){ 23 | for(int j = 0;j < n; j++){ 24 | printf("%lf ", L[i][j]); 25 | } 26 | printf("\n"); 27 | } 28 | for(int i = 0; i < n; i++){ 29 | for(int j = 0;j < n; j++){ 30 | printf("%lf ", U[i][j]); 31 | } 32 | printf("\n"); 33 | } 34 | } 35 | 36 | void Doolittle(int n, double A[][100], double L[][100], double U[][100]){ 37 | //Doolittle分解 38 | // U赋初值 39 | for (int i = 0; i < n; i++) { 40 | U[0][i] = A[0][i]; 41 | } 42 | for(int j = 0; j <= n-1; j++){ 43 | double s = 0; 44 | //计算矩阵L之第i列第k行元素 45 | // l_{ij} = \frac{a_{ij} - \sum\limits_{k=1}^{j-1} l_{ik}u_{kj}}{u_{jj}} \quad i = j+1, j+2, \dots, n 46 | // 给 L 的对角线赋值为1 47 | L[j][j] =1; 48 | for(int i = j+1; i <= n-1; i++){ 49 | for(int k = 0; k<= j; k++){ 50 | s += L[i][k] * U[k][j]; 51 | } 52 | L[i][j] = (A[i][j] - s)/U[j][j]; 53 | } 54 | 55 | //计算矩阵U之第i行第k列元素 56 | // u_{ij} = a_{ij} - \sum\limits_{k=1}^{i-1} l_{ik}u_{kj} \quad j = i, i+1, \dots, n 57 | for(int k = j+1; k <= n-1; k++){ 58 | s = 0; 59 | for(int i = 0; i <= j; i++){ 60 | s += L[j+1][i] * U[i][k]; 61 | } 62 | U[j+1][k] = A[j+1][k] - s; 63 | } 64 | } 65 | 66 | return; 67 | } 68 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/01LU分解/02LU分解求解方程组/02LU分解: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/01LU分解/02LU分解求解方程组/02LU分解 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/01LU分解/02LU分解求解方程组/02LU分解.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double a[MAXSIZE][MAXSIZE], double x[MAXSIZE], long n); 6 | void output_matrix(double a[MAXSIZE][MAXSIZE], double x[MAXSIZE], long n); 7 | void output(double x[MAXSIZE], long n); 8 | void print_L(double a[MAXSIZE][MAXSIZE], long n); 9 | void print_U(double a[MAXSIZE][MAXSIZE], long n); 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | double a[MAXSIZE][MAXSIZE], x[MAXSIZE], s; 14 | long n, i, j, k; 15 | printf("请输入原方程的阶数: "); 16 | scanf("%ld", &n); 17 | input(a, x, n); 18 | printf("原方程组的增广矩阵为:\n"); 19 | output_matrix(a, x, n); 20 | for(k = 0; k <= n-2; k++){ 21 | for (i = k+1; i <= n-1; i++) { 22 | s = 0; 23 | for(j=0; j<= k-1; j++){ 24 | s += a[i][j] * a[j][k]; 25 | } 26 | a[i][k] = (a[i][k] -s)/a[k][k]; 27 | } 28 | for(j = k+1; j<= n-1; j++){ 29 | s = 0; 30 | for (i = 0; i <= k; i++) { 31 | s += a[k+1][i] * a[i][j]; 32 | } 33 | a[k+1][j] -= s; 34 | } 35 | } 36 | printf("打印一下LU分解后的矩阵:\n"); 37 | print_L(a, n); 38 | print_U(a, n); 39 | 40 | printf("打印一下右端常数列的值:\n"); 41 | output(x, n); 42 | for (i = 1; i <= n-1; i++) { 43 | s=0; 44 | for(j = 0; j < i; j++){ 45 | s += a[i][j] * x[j]; 46 | } 47 | x[i] -= s; 48 | } 49 | printf("打印中间变量y_1到y_n的值:\n"); 50 | output( x, n); 51 | 52 | for (i = n-1; i >= 0; i--) { 53 | s = 0; 54 | for(j = i+1; j<= n-1; j++){ 55 | s += a[i][j] * x[j]; 56 | } 57 | x[i] = (x[i] - s)/a[i][i]; 58 | } 59 | printf("原方程组的解为:\n"); 60 | output(x, n); 61 | 62 | return 0; 63 | } 64 | 65 | void input(double a[MAXSIZE][MAXSIZE], double x[MAXSIZE], long n) 66 | { 67 | long i, j; 68 | printf("请输入原方程组的增广矩阵:(用\" \"隔开):\n"); 69 | for (i = 1; i <= n; i++) { 70 | for (j = 0; j <= n-1; j++) { 71 | scanf("%lf", &a[i-1][j]); 72 | } 73 | scanf("%lf", &x[i-1]); 74 | } 75 | } 76 | 77 | void output_matrix(double a[MAXSIZE][MAXSIZE], double x[MAXSIZE], long n) 78 | { 79 | long i, j; 80 | for (i = 1; i <= n; i++) { 81 | for (j = 0; j <= n-1; j++) { 82 | printf("%10.2lf", a[i-1][j]); 83 | } 84 | printf("%10.2lf", x[i-1]); 85 | printf("\n"); 86 | } 87 | } 88 | 89 | void output(double x[MAXSIZE], long n) 90 | { 91 | long i; 92 | for (i = 0; i <= n-1; i++) { 93 | printf(" %lf", x[i]); 94 | } 95 | printf("\n"); 96 | } 97 | 98 | void print_L(double a[MAXSIZE][MAXSIZE], long n) 99 | { 100 | printf("打印单位下三角矩阵L\n"); 101 | long i; 102 | printf("1\n"); 103 | for(i = 1; i <= n-1; i++){ 104 | for(long j = 0; j < i; j++){ 105 | printf("%lf ", a[i][j]); 106 | } 107 | printf("1\n"); 108 | } 109 | printf("\n"); 110 | } 111 | 112 | void print_U(double a[MAXSIZE][MAXSIZE], long n) 113 | { 114 | printf("打印上三角矩阵U\n"); 115 | for(long i = 0; i <= n-1; i++){ 116 | for(long k = i; k > 0; k--){ 117 | printf("\t "); 118 | } 119 | for(long j =i; j <= n-1; j++){ 120 | printf("%lf ", a[i][j]); 121 | } 122 | printf("\n"); 123 | } 124 | printf("\n"); 125 | } 126 | 127 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/02正定矩阵——LLT算法/02正定矩阵——LLT算法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/02正定矩阵——LLT算法/02正定矩阵——LLT算法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/02正定矩阵——LLT算法/02正定矩阵——LLT算法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double a[MAXSIZE][MAXSIZE], double x[MAXSIZE], long n); 6 | void output(double x[MAXSIZE], long n); 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | double a[MAXSIZE][MAXSIZE], x[MAXSIZE], s; 11 | long n, i, j, k; 12 | printf("请输入原方程的阶数:\n"); 13 | scanf("%ld", &n); 14 | input(a, x, n); 15 | for (k = 0; k <= n-1; k++) { 16 | s = 0; 17 | for (j = 0; j <= k-1; j++) { 18 | s += a[k][j] * a[k][j]; 19 | } 20 | a[k][k] = sqrt(a[k][k] - s); 21 | for(i=k+1; i<= n-1; i++){ 22 | s = 0; 23 | for (j = 0; j <= k-1; j++) { 24 | s += a[i][j] * a[k][j]; 25 | } 26 | a[i][k] = (a[i][k] - s)/ a[k][k]; 27 | } 28 | } 29 | 30 | for(i = 0; i <= n-1; i++){ 31 | s = 0; 32 | for(j = 0; j <= i-1; j++){ 33 | s += a[i][j] * x[j]; 34 | } 35 | x[i] = (x[i] - s)/a[i][i]; 36 | } 37 | for (i = n-1; i >= 0; i--) { 38 | s = 0; 39 | for(j = i+1; j <= n-1; j++){ 40 | s += a[j][i] * x[j]; 41 | } 42 | x[i] = (x[i] - s)/a[i][i]; 43 | } 44 | output(x, n); 45 | 46 | return 0; 47 | } 48 | 49 | void input(double a[MAXSIZE][MAXSIZE], double x[MAXSIZE], long n) 50 | { 51 | long i, j; 52 | printf("请输入原方程组的增广矩阵:(用\" \"隔开):\n"); 53 | for (i = 0; i <= n-1; i++) { 54 | for(j =0; j <= n-1; j++){ 55 | scanf("%lf", &a[i][j]); 56 | } 57 | scanf("%lf", &x[i]); 58 | } 59 | } 60 | 61 | void output(double x[MAXSIZE], long n) 62 | { 63 | long i; 64 | printf("原方程组的解为:\n"); 65 | for (i = 0; i <= n-1; i++) { 66 | printf(" %lf\n", x[i]); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/02正定矩阵——LLT算法/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | gcc 02正定矩阵——LLT算法.c -lm -o 02正定矩阵——LLT算法 3 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/03三对角方程组求解——追赶法/追赶法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/03三对角方程组求解——追赶法/追赶法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/01直接法/02矩阵的三角(LU)分解/03三对角方程组求解——追赶法/追赶法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double a[], double b[], double c[], double d[], long n); 6 | void output(double x[], long n); 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | double a[MAXSIZE], b[MAXSIZE], c[MAXSIZE], d[MAXSIZE], x[MAXSIZE]; 11 | long n, i; 12 | printf("请输入原方程的阶数:"); 13 | scanf("%ld", &n); 14 | input(a, b, c, d, n); 15 | for (i = 1; i < n; i++) { 16 | a[i] /= -b[i-1]; 17 | b[i] += c[i-1] * a[i]; 18 | d[i] += d[i-1] * a[i]; 19 | } 20 | 21 | x[n-1] = d[n-1] / b[n-1]; 22 | for(i = n-2; i>= 0; i--){ 23 | x[i] = (d[i] - c[i] * x[i+1])/b[i]; 24 | } 25 | output(x, n); 26 | printf("\n"); 27 | 28 | return 0; 29 | } 30 | 31 | void input(double a[], double b[], double c[], double d[], long n) 32 | { 33 | long i; 34 | printf("请输入原方程组的增广矩阵:\n"); 35 | printf("b1, c1, d1: "); 36 | scanf("%lf, %lf, %lf", &b[0], &c[0], &d[0]); 37 | for (i = 2; i <= n-1; i++) { 38 | printf("a%ld, b%ld, c%ld, d%ld: ", i, i, i, i); 39 | scanf("%lf, %lf, %lf, %lf", &a[i-1], &b[i-1], &c[i-1], &d[i-1]); 40 | } 41 | printf("a%ld, b%ld, d%ld: ", n, n, n); 42 | scanf("%lf, %lf, %lf", &a[n-1], &b[n-1], &d[n-1]); 43 | } 44 | 45 | void output(double x[], long n) 46 | { 47 | long i; 48 | printf("方程组的解为:\n"); 49 | for (i = 1; i <= n; i++) { 50 | printf(" %lf", x[i-1]); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/01雅可比迭代法/01雅可比迭代法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/02迭代法/01雅可比迭代法/01雅可比迭代法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/01雅可比迭代法/01雅可比迭代法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n); 5 | void output(double x[MAXSIZE], long n); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double a[MAXSIZE][MAXSIZE], b[MAXSIZE], x[MAXSIZE], oldx[MAXSIZE]; 10 | double epsilon, e, s; 11 | long n, i, j, k, maxk; 12 | printf("请输入原方程组的阶数: "); 13 | scanf("%ld" , &n); 14 | input(a, b, n); 15 | printf("请输入迭代初始向量(中间用‘ ’隔开): "); 16 | for(i =0; i <= n-1; i++){ 17 | scanf("%lf", &oldx[i]); 18 | } 19 | printf("请输入最大迭代次数\n"); 20 | scanf("%ld", &maxk); 21 | printf("请输入误差上限: "); 22 | scanf("%lf", &epsilon); 23 | 24 | for(k=1; k <= maxk; k++){ 25 | for(i=0; i<= n-1; i++){ 26 | s = 0; 27 | for(j = 0; j<=n-1; j++){ 28 | if(j != i){ 29 | s += a[i][j] * oldx[j]; 30 | } 31 | } 32 | x[i] = (b[i]-s)/a[i][i]; 33 | } 34 | e = 0; 35 | for(i = 0; i<= n-1; i++){ 36 | if(e < fabs(x[i] - oldx[i])){ 37 | e = fabs(x[i] - oldx[i]); 38 | } 39 | } 40 | if( e< epsilon){ 41 | break; 42 | } 43 | for(i=0; i<= n-1; i++){ 44 | oldx[i] = x[i]; 45 | } 46 | } 47 | if( k <= maxk){ 48 | output(x, n); 49 | }else{ 50 | printf("迭代次数已经超过上限\n"); 51 | } 52 | 53 | return 0; 54 | } 55 | 56 | 57 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n) 58 | { 59 | long i, j; 60 | printf("请输入原方程的增广矩阵\n"); 61 | for(i=0; i <= n-1; i++){ 62 | for(j=0; j<= n-1; j++){ 63 | scanf("%lf", &a[i][j]); 64 | } 65 | scanf("%lf", &b[i]); 66 | } 67 | } 68 | void output(double x[MAXSIZE], long n) 69 | { 70 | long i; 71 | printf("原方程组的解为: \n"); 72 | for(i = 0; i <= n-1; i++){ 73 | printf("%lf\n", x[i]); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/02Gauss-Seidel迭代: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/02Gauss-Seidel迭代 -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/02Gauss-Seidel迭代.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n); 5 | void output(double x[MAXSIZE], long n); 6 | 7 | int main(int argc, char *argv[]){ 8 | double a[MAXSIZE][MAXSIZE], b[MAXSIZE], x[MAXSIZE];//, oldx[MAXSIZE]; 9 | double epsilon, e, s, oldx; 10 | long n, i, j, k, maxk; 11 | printf("请输入原方程组的阶数: "); 12 | scanf("%ld" , &n); 13 | input(a, b, n); 14 | printf("请输入迭代初始向量(中间用‘ ’隔开): "); 15 | for(i =0; i <= n-1; i++){ 16 | scanf("%lf", &x[i]); 17 | } 18 | printf("请输入最大迭代次数\n"); 19 | scanf("%ld", &maxk); 20 | printf("请输入误差上限: "); 21 | scanf("%lf", &epsilon); 22 | 23 | for(k=1; k <= maxk; k++){ 24 | e = 0; 25 | for(i=0; i<= n-1; i++){ 26 | oldx = x[i]; 27 | s = 0; 28 | for(j=0; j <= n-1; j++){ 29 | if(j!=i){ 30 | s += a[i][j] * x[j]; 31 | } 32 | } 33 | x[i] = (b[i] - s)/a[i][i]; 34 | if(e < fabs(oldx - x[i])){ 35 | e = fabs(oldx - x[i]); 36 | } 37 | } 38 | 39 | if( e< epsilon){ 40 | break; 41 | } 42 | } 43 | if( k <= maxk){ 44 | output(x, n); 45 | }else{ 46 | printf("迭代次数已经超过上限\n"); 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | 53 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n){ 54 | long i, j; 55 | printf("请输入原方程的增广矩阵(每一行用' '隔开)\n"); 56 | for(i=0; i <= n-1; i++){ 57 | for(j=0; j<= n-1; j++){ 58 | scanf("%lf", &a[i][j]); 59 | } 60 | scanf("%lf", &b[i]); 61 | } 62 | } 63 | 64 | void output(double x[MAXSIZE], long n){ 65 | long i; 66 | printf("原方程组的解为: \n"); 67 | for(i = 0; i <= n-1; i++){ 68 | printf("%lf\n", x[i]); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/tmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/tmp -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/tmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n); 5 | void output(double x[MAXSIZE], long n); 6 | 7 | int main(int argc, char *argv[]){ 8 | double a[MAXSIZE][MAXSIZE], b[MAXSIZE], x[MAXSIZE];//, oldx[MAXSIZE]; 9 | double epsilon, e, s, oldx; 10 | long n, i, j, k, maxk; 11 | scanf("%ld" , &n); 12 | input(a, b, n); 13 | for(i =0; i <= n-1; i++){ 14 | scanf("%lf", &x[i]); 15 | } 16 | maxk = 1000; 17 | epsilon = 0.000001; 18 | 19 | for(k=1; k <= maxk; k++){ 20 | e = 0; 21 | for(i=0; i<= n-1; i++){ 22 | oldx = x[i]; 23 | s = 0; 24 | for(j=0; j <= n-1; j++){ 25 | if(j!=i){ 26 | s += a[i][j] * x[j]; 27 | } 28 | } 29 | x[i] = (b[i] - s)/a[i][i]; 30 | if(e < fabs(oldx - x[i])){ 31 | e = fabs(oldx - x[i]); 32 | } 33 | } 34 | 35 | if( e< epsilon){ 36 | break; 37 | } 38 | } 39 | if( k <= maxk){ 40 | output(x, n); 41 | }else{ 42 | printf("迭代次数已经超过上限\n"); 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | 49 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n){ 50 | long i, j; 51 | for(i=0; i <= n-1; i++){ 52 | for(j=0; j<= n-1; j++){ 53 | scanf("%lf", &a[i][j]); 54 | } 55 | } 56 | 57 | for(i=0; i <= n-1; i++){ 58 | scanf("%lf", &b[i]); 59 | } 60 | } 61 | 62 | void output(double x[MAXSIZE], long n){ 63 | long i; 64 | for(i = 0; i <= n-1; i++){ 65 | printf("%lf ", x[i]); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/tmp1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/tmp1 -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/02Gauss-Seidel迭代/tmp1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //#define MaxStep 1000 4 | //#define eps 0.000001 5 | 6 | double _abs(double a){ 7 | return a > 0 ? a : -a; 8 | } 9 | 10 | double _max(double a, double b){ 11 | return a > b ? a : b; 12 | } 13 | 14 | void Gauss_Seidel(int n , double a[][100] , double b[], double x[]){ 15 | int MaxStep=1000; 16 | double eps = 0.000001; 17 | //判断迭代是否可进行 18 | for(int i = 1; i <= n; i++){ 19 | if(_abs(a[i][i]) < 1e-15){ 20 | printf("Fail."); 21 | return; 22 | } 23 | } 24 | 25 | int cnt = 0; 26 | double err = eps + 1.0; 27 | double tmp; //临时变量 存放正在计算的数值 28 | //计算完毕后滚动存放到数组x中 29 | 30 | while((err >= eps) && (cnt <= MaxStep)){ 31 | err = 0; 32 | for(int i = 1; i <= n; i++){ 33 | //迭代 34 | tmp = b[i]; 35 | for(int j = 1; j <= n; j++){ 36 | if(j != i){ 37 | tmp -= a[i][j] * x[j]; 38 | } 39 | } 40 | tmp /= a[i][i]; 41 | 42 | //计算误差 43 | err = _max(err,_abs(tmp-x[i])/(1.0+_abs(tmp))); 44 | 45 | x[i] = tmp; 46 | 47 | 48 | } 49 | 50 | //更新计算次数 51 | cnt++; 52 | 53 | } 54 | 55 | if(cnt >= MaxStep){ 56 | printf("Fail."); 57 | return; 58 | } 59 | else{ 60 | for(int i = 1; i <= n; i++){ 61 | printf("%lf ", x[i]); 62 | } 63 | return; 64 | } 65 | 66 | } 67 | 68 | int main(){ 69 | 70 | int n; 71 | double a[100][100]; 72 | double b[100],x[100]; 73 | 74 | scanf("%d", &n); 75 | for(int i = 1; i <= n; i++){ 76 | for(int j = 1; j <= n; j++){ 77 | scanf("%lf", &a[i][j]); 78 | } 79 | } 80 | for(int i = 1; i <= n; i++){ 81 | scanf("%lf", &b[i]); 82 | } 83 | for(int i = 1; i <= n; i++){ 84 | scanf("%lf", &x[i]); 85 | } 86 | 87 | Gauss_Seidel(n, a, b, x); 88 | 89 | return 0; 90 | 91 | } 92 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/03SOR方法/03SOR方法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/02迭代法/03SOR方法/03SOR方法 -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/03SOR方法/03SOR方法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 100 4 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n); 5 | void output(double x[MAXSIZE], long n); 6 | long SOR(long n, double A[MAXSIZE][MAXSIZE], double b[MAXSIZE], double x[MAXSIZE], double w, long maxk, double epsilon); 7 | int main(int argc, char *argv[]){ 8 | long n, maxk; 9 | double epsilon; 10 | double A[MAXSIZE][MAXSIZE],b[MAXSIZE],x[MAXSIZE], w; 11 | 12 | printf("请输入原方程组的阶数: "); 13 | scanf("%ld", &n); 14 | input(A, b, n); 15 | printf("请输入提速因子ω: "); 16 | scanf("%lf", &w); 17 | printf("请输入迭代初始向量(中间用‘ ’隔开): "); 18 | for(long i =0; i <= n-1; i++){ 19 | scanf("%lf", &x[i]); 20 | } 21 | printf("请输入最大迭代次数: "); 22 | scanf("%ld", &maxk); 23 | printf("请输入误差上限: "); 24 | scanf("%lf", &epsilon); 25 | 26 | long k = SOR(n, A, b, x, w, maxk, epsilon); 27 | if( k <= maxk){ 28 | output(x, n); 29 | printf("迭代次数%ld\n", k); 30 | }else{ 31 | printf("迭代次数已经超过上限\n"); 32 | } 33 | 34 | return 0; 35 | } 36 | 37 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n) 38 | { 39 | printf("请输入原方程的增广矩阵(每一行中的元素用' '隔开)\n"); 40 | for(long i=0; i <= n-1; i++){ 41 | for(long j=0; j<= n-1; j++){ 42 | scanf("%lf", &a[i][j]); 43 | } 44 | scanf("%lf", &b[i]); 45 | } 46 | } 47 | 48 | void output(double x[MAXSIZE], long n) 49 | { 50 | printf("原方程组的解为: \n"); 51 | for(long i=0; i <= n-1; i++) 52 | { 53 | printf("%lf\n", x[i]); 54 | } 55 | } 56 | 57 | long SOR(long n, double A[MAXSIZE][MAXSIZE], double b[MAXSIZE], double x[MAXSIZE], double w, long maxk, double epsilon) 58 | { 59 | double e, oldx, s; 60 | long k =1, i, j; 61 | while( k<= maxk){ 62 | e = 0; 63 | for(i=0; i<= n-1; i++){ 64 | oldx = x[i]; 65 | s = 0; 66 | for(j=0; j <= n-1; j++){ 67 | s += A[i][j] * x[j]; 68 | } 69 | x[i] = oldx + w * (b[i] - s)/A[i][i]; 70 | if(e < fabs(oldx - x[i])){ 71 | e = fabs(oldx - x[i]); 72 | } 73 | } 74 | 75 | if( e< epsilon){ 76 | break; 77 | } 78 | k += 1; 79 | } 80 | 81 | return k; 82 | } 83 | -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/03SOR方法/SOR平台: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/02线性方程组的数值解法/02迭代法/03SOR方法/SOR平台 -------------------------------------------------------------------------------- /02线性方程组的数值解法/02迭代法/03SOR方法/SOR平台.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 100 4 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n); 5 | void output(double x[MAXSIZE], long n); 6 | long SOR(long n, double A[MAXSIZE][MAXSIZE], double b[MAXSIZE], double x[MAXSIZE], double w, long maxk, double epsilon); 7 | int main(int argc, char *argv[]){ 8 | long n, maxk; 9 | double epsilon; 10 | double A[MAXSIZE][MAXSIZE],b[MAXSIZE],x[MAXSIZE], w; 11 | 12 | //printf("请输入原方程组的阶数: "); 13 | scanf("%ld", &n); 14 | input(A, b, n); 15 | //printf("请输入迭代初始向量(中间用‘ ’隔开): "); 16 | for(long i =0; i <= n-1; i++){ 17 | scanf("%lf", &x[i]); 18 | } 19 | //printf("请输入提速因子ω: "); 20 | scanf("%lf", &w); 21 | //printf("请输入最大迭代次数: "); 22 | //scanf("%ld", &maxk); 23 | maxk = 1000; 24 | //printf("请输入误差上限: "); 25 | //scanf("%lf", &epsilon); 26 | epsilon = 0.000001; 27 | 28 | long k = SOR(n, A, b, x, w, maxk, epsilon); 29 | if( k <= maxk){ 30 | output(x, n); 31 | printf("%ld\n", k); 32 | }else{ 33 | printf("迭代次数已经超过上限\n"); 34 | } 35 | 36 | return 0; 37 | } 38 | 39 | void input(double a[MAXSIZE][MAXSIZE], double b[MAXSIZE], long n) 40 | { 41 | //printf("请输入原方程的系数矩阵(每一行中的元素用' '隔开)\n"); 42 | for(long i=0; i <= n-1; i++){ 43 | for(long j=0; j<= n-1; j++){ 44 | scanf("%lf", &a[i][j]); 45 | } 46 | } 47 | //printf("请输入原方程的常数项(中间用' '隔开)\n"); 48 | for(long i=0; i <= n-1; i++){ 49 | scanf("%lf", &b[i]); 50 | } 51 | } 52 | 53 | void output(double x[MAXSIZE], long n) 54 | { 55 | //printf("原方程组的解为: \n"); 56 | for(long i=0; i <= n-1; i++) 57 | { 58 | printf("%lf ", x[i]); 59 | } 60 | printf("\n"); 61 | } 62 | 63 | long SOR(long n, double A[MAXSIZE][MAXSIZE], double b[MAXSIZE], double x[MAXSIZE], double w, long maxk, double epsilon) 64 | { 65 | double e, oldx, s; 66 | long k =1, i, j; 67 | while( k<= maxk){ 68 | e = 0; 69 | for(i=0; i<= n-1; i++){ 70 | oldx = x[i]; 71 | s = 0; 72 | for(j=0; j <= n-1; j++){ 73 | s += A[i][j] * x[j]; 74 | } 75 | x[i] = oldx + w * (b[i] - s)/A[i][i]; 76 | if(e < fabs(oldx - x[i])){ 77 | e = fabs(oldx - x[i]); 78 | } 79 | } 80 | 81 | if( e< epsilon){ 82 | break; 83 | } 84 | k += 1; 85 | } 86 | 87 | return k; 88 | } 89 | -------------------------------------------------------------------------------- /03矩阵特征值和特征向量的数值解法/01改进的乘幂法/01改进的乘幂法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/03矩阵特征值和特征向量的数值解法/01改进的乘幂法/01改进的乘幂法 -------------------------------------------------------------------------------- /03矩阵特征值和特征向量的数值解法/01改进的乘幂法/01改进的乘幂法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double a[][MAXSIZE], double v[], long n); 6 | void matrix_product(double a[][MAXSIZE], double u[], double v[], long n); 7 | void normalization(double u[], double v[], long n, double *pm1); 8 | void output(double v[], long n, double m1); 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | double a[MAXSIZE][MAXSIZE], u[MAXSIZE], v[MAXSIZE]; 13 | double epsilon, m0, m1; 14 | long n, maxk, i; 15 | printf("请输入方阵A的阶数: "); 16 | scanf("%ld", &n); 17 | input(a, v, n); 18 | printf("请输入最大迭代次数: "); 19 | scanf("%ld", &maxk); 20 | printf("请输入主特征值的精度要求: "); 21 | scanf("%lf", &epsilon); 22 | matrix_product(a, u, v, n); 23 | normalization(u, v, n, &m1); 24 | for (i = 1; i <= maxk; i++) { 25 | m0 = m1; 26 | matrix_product(a, u, v, n); 27 | normalization(u, v, n, &m1); 28 | if (fabs(m1 - m0) <= epsilon) { 29 | break; 30 | } 31 | } 32 | if (i <= maxk) { 33 | output(v, n, m1); 34 | }else{ 35 | printf("迭代次数已超过上限\n"); 36 | } 37 | 38 | return 0; 39 | } 40 | 41 | void input(double a[][MAXSIZE], double v[], long n) 42 | { 43 | long i, j; 44 | printf("请输入%ld阶方阵A: \n", n); 45 | for (i = 0; i <= n-1; i++) { 46 | for (j = 0; j <= n-1; j++) { 47 | scanf("%lf", &a[i][j]); 48 | } 49 | } 50 | printf("请输入初始迭代向量: \n"); 51 | for (i = 0; i <= n-1; i++) { 52 | scanf("%lf", &v[i]); 53 | } 54 | } 55 | 56 | void matrix_product(double a[][MAXSIZE], double u[], double v[], long n) 57 | { 58 | long i, j; 59 | for (i = 0; i <= n-1; i++) { 60 | u[i] = 0; 61 | for (j = 0; j <= n-1; j++) { 62 | u[i] += a[i][j] * v[j]; 63 | } 64 | } 65 | } 66 | 67 | void normalization(double u[], double v[], long n, double *pm1) 68 | { 69 | long i; 70 | * pm1 = u[0]; 71 | for (i = 1; i <= n-1; i++) { 72 | if (fabs(* pm1) < fabs(u[i])) { 73 | * pm1 = u[i]; 74 | } 75 | } 76 | for (i = 0; i <= n-1; i++) { 77 | v[i] = u[i] / (* pm1); 78 | } 79 | } 80 | 81 | void output(double v[], long n, double m1) 82 | { 83 | long i; 84 | printf("方阵A的主特征值约为: %lf\n", m1); 85 | printf("其对应特征向量约为: \n"); 86 | for (i = 0; i <= n-1; i++) { 87 | printf("%lf\n", v[i]); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /03矩阵特征值和特征向量的数值解法/02反幂法/02反幂法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/03矩阵特征值和特征向量的数值解法/02反幂法/02反幂法 -------------------------------------------------------------------------------- /03矩阵特征值和特征向量的数值解法/02反幂法/02反幂法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | void input(double a[][MAXSIZE], double v[], long n); 5 | void doolittle(double a[][MAXSIZE], long n); 6 | void back_substitution(double a[][MAXSIZE], double v[], long n); 7 | void normalization(double v[], long n, double * pm1); 8 | void output(double v[], long n, double m1); 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | double a[MAXSIZE][MAXSIZE], v[MAXSIZE]; 13 | double epsilon, m0, m1; 14 | long n, maxk, k; 15 | printf("请输入方阵A的阶数: "); 16 | scanf("%ld", &n); 17 | input(a, v, n); 18 | printf("请输入最大迭代次数: "); 19 | scanf("%ld", &maxk); 20 | printf("请输入主特征值的精度要求: "); 21 | scanf("%lf", &epsilon); 22 | doolittle(a, n); 23 | back_substitution(a, v, n); 24 | normalization(v, n, &m1); 25 | for(k=1; k<= maxk; k++){ 26 | m0 = m1; 27 | back_substitution(a, v, n); 28 | normalization(v, n, &m1); 29 | if(fabs(m1-m0) <= epsilon){ 30 | break; 31 | } 32 | } 33 | if(k <= maxk){ 34 | output(v, n, 1/m1); 35 | }else{ 36 | printf("迭代次数已经超过上限\n"); 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | 43 | void input(double a[][MAXSIZE], double v[], long n) 44 | { 45 | long i, j; 46 | printf("请输入%ld阶方阵A: \n", n); 47 | for (i = 0; i <= n-1; i++) { 48 | for(j = 0; j <= n-1; j++){ 49 | scanf("%lf", &a[i][j]); 50 | } 51 | } 52 | printf("请输入初始迭代向量(请用’ ‘隔开): "); 53 | for(i = 0; i <= n-1; i++){ 54 | scanf("%lf", &v[i]); 55 | } 56 | } 57 | 58 | void doolittle(double a[][MAXSIZE], long n) 59 | { 60 | long i,j, k; 61 | double s; 62 | for(k = 0; k <= n-2; k++){ 63 | for(i = k+1; i <= n-1; i++){ 64 | s = 0; 65 | for(j=0; j <= k-1; j++){ 66 | s += a[i][j] * a[j][k]; 67 | } 68 | a[i][k] = (a[i][k] -s)/a[k][k]; 69 | } 70 | for(j=k+1; j <= n-1; j++){ 71 | s = 0; 72 | for(i=0; i<=k; i++){ 73 | s += a[k+1][i] * a[i][j]; 74 | } 75 | a[k+1][j] -= s; 76 | } 77 | } 78 | } 79 | 80 | void back_substitution(double a[][MAXSIZE], double v[], long n) 81 | { 82 | double s; 83 | long i, j; 84 | for(i = 1; i<=n-1; i++){ 85 | s = 0; 86 | for(j=0; j<=i-1; j++){ 87 | s += a[i][j]*v[j]; 88 | } 89 | v[i] -= s; 90 | } 91 | for( i=n-1; i >= 0; i--){ 92 | s = 0; 93 | for(j=i+1; j<=n-1; j++){ 94 | s += a[i][j] * v[j]; 95 | } 96 | v[i] = (v[i] - s)/a[i][i]; 97 | } 98 | } 99 | 100 | void normalization(double v[], long n, double * pm1) 101 | { 102 | long i; 103 | * pm1 = v[0]; 104 | for(i = 0; i <= n-1; i++){ 105 | if(fabs(* pm1) < fabs(v[i])){ 106 | * pm1 = v[i]; 107 | } 108 | } 109 | for(i =0; i <= n-1; i++){ 110 | v[i] = v[i]/(* pm1); 111 | } 112 | } 113 | 114 | void output(double v[], long n, double m1) 115 | { 116 | long i; 117 | printf("方阵A的主特征值约为: %lf\n", m1); 118 | printf("其对应的特征向量约为: \n"); 119 | for(i=0; i<=n-1; i++){ 120 | printf("%lf ", v[i]); 121 | } 122 | } 123 | 124 | -------------------------------------------------------------------------------- /04函数拟合的插值法/01拉格朗日插值/01拉格朗日插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数拟合的插值法/01拉格朗日插值/01拉格朗日插值 -------------------------------------------------------------------------------- /04函数拟合的插值法/01拉格朗日插值/01拉格朗日插值.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double x[MAXSIZE], double y[MAXSIZE], long n); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double x[MAXSIZE], y[MAXSIZE], l[MAXSIZE], Interpolation_x, Interpolation_y, tmp; 10 | long n, i, j; 11 | printf("请输入插值节点的个数:"); 12 | scanf("%ld", &n); 13 | input(x, y, n); 14 | printf("请输入待计算的插值点x的值:"); 15 | scanf("%lf", &Interpolation_x); 16 | Interpolation_y = 0; 17 | for (i = 0; i <= n-1; i++) { 18 | tmp = 1; 19 | for(j = 0; j <= n-1; j++){ 20 | if(j != i){ 21 | tmp *= (Interpolation_x - x[j]) / (x[i] - x[j]); 22 | } 23 | } 24 | l[i] = tmp; 25 | Interpolation_y += tmp * y[i]; 26 | } 27 | printf("-----------------------------\n"); 28 | printf("Lagrange插值节点的基函数:\n"); 29 | for (int i = 0; i < n; i++) { 30 | printf("l[%d] = %ld\n", i, l[i]); 31 | } 32 | printf("-----------------------------\n"); 33 | printf("插值点(x, y) = (%lf, %lf)\n", Interpolation_x, Interpolation_y); 34 | 35 | 36 | return 0; 37 | } 38 | 39 | 40 | void input(double x[MAXSIZE], double y[MAXSIZE], long n) 41 | { 42 | long i; 43 | for (i = 0; i <= n-1; i++) { 44 | printf("请输入插值节点 x[%ld], y[%ld]:(中间用英文\",\"隔开): ", i, i); 45 | scanf("%lf, %lf", &x[i], &y[i]); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /04函数拟合的插值法/01拉格朗日插值/拉格朗日插值平台: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数拟合的插值法/01拉格朗日插值/拉格朗日插值平台 -------------------------------------------------------------------------------- /04函数拟合的插值法/01拉格朗日插值/拉格朗日插值平台.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double x[MAXSIZE], double y[MAXSIZE], long n); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double x[MAXSIZE], y[MAXSIZE], l[MAXSIZE], Interpolation_x[MAXSIZE], Interpolation_y[MAXSIZE], tmp; 10 | long n,m, i, j; 11 | printf("请输入插值节点的个数:"); 12 | scanf("%ld", &n); 13 | input(x, y, n); 14 | printf("请输入待求节点的个数:"); 15 | scanf("%ld", &m); 16 | for (i = 0; i < m; i++) 17 | { 18 | printf("请输入待计算的插值点x的值:"); 19 | scanf("%lf", Interpolation_x[i]); 20 | Interpolation_y[i] = 0; 21 | for (i = 0; i <= n-1; i++) { 22 | tmp = 1; 23 | for(j = 0; j <= n-1; j++){ 24 | if(j != i){ 25 | tmp *= (Interpolation_x[i] - x[j]) / (x[i] - x[j]); 26 | } 27 | } 28 | l[i] = tmp; 29 | Interpolation_y[i] += tmp * y[i]; 30 | } 31 | } 32 | 33 | //printf("-----------------------------\n"); 34 | //printf("Lagrange插值节点的基函数:\n"); 35 | //for (int i = 0; i < n; i++) { 36 | // printf("l[%d] = %ld\n", i, l[i]); 37 | //} 38 | printf("-----------------------------\n"); 39 | for (i = 0; i < m; i++) 40 | { 41 | printf("插值点(x, y) = (%lf, %lf)\n", Interpolation_x[i], Interpolation_y[i]); 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | 48 | void input(double x[MAXSIZE], double y[MAXSIZE], long n) 49 | { 50 | long i; 51 | for (i = 0; i <= n-1; i++) { 52 | printf("请输入插值节点 x[%ld], y[%ld]:(中间用英文' '隔开): ", i, i); 53 | scanf("%lf %lf", &x[i], &y[i]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /04函数拟合的插值法/02牛顿插值法/02牛顿插值法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数拟合的插值法/02牛顿插值法/02牛顿插值法 -------------------------------------------------------------------------------- /04函数拟合的插值法/02牛顿插值法/02牛顿插值法.c: -------------------------------------------------------------------------------- 1 | /* 2 | * n 次牛顿插值的算法 3 | * 实现方法 4 | * 1.先实现差商表,用二维数组 f[i][j]存储 5 | * 2.利用差商表计算插值节点 6 | * 3.参考改进:利用秦九韶算法,遇到重复的乘法就提出公因子 7 | */ 8 | #include 9 | #include 10 | #define MAXSIZE 50 11 | 12 | void input(double x[MAXSIZE], double f[MAXSIZE][MAXSIZE], long n); 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | double x[MAXSIZE], f[MAXSIZE][MAXSIZE], Interpolation_x, Interpolation_y; 17 | long n, i, j; 18 | printf("请输入插值节点个数:"); 19 | scanf("%ld", &n); 20 | input(x, f, n); 21 | printf("请输入代求的插值点:"); 22 | scanf("%lf", &Interpolation_x); 23 | for(j=1; j<= n-1; j++){ 24 | for (i = j; i <= n-1; i++) { 25 | f[i][j] = (f[i][j-1] - f[i-1][j-1])/(x[i] - x[i-j]); 26 | } 27 | } 28 | Interpolation_y = f[n-1][n-1]; 29 | for(i = n-2; i>=0; i--){ 30 | Interpolation_y = f[i][i] + (Interpolation_x - x[i]) * Interpolation_y; 31 | } 32 | printf("插值点(x, y)=(%lf, %lf)\n", Interpolation_x, Interpolation_y); 33 | 34 | return 0; 35 | } 36 | 37 | 38 | void input(double x[MAXSIZE], double f[MAXSIZE][MAXSIZE], long n) 39 | { 40 | long i; 41 | for(i = 0; i <= n-1; i++){ 42 | printf("请输入插值节点x[%ld], y[%ld](中间用英文 \",\"隔开):", i, i); 43 | scanf("%lf, %lf", &x[i], &f[i][0]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /04函数拟合的插值法/03多项式插值/01分段线性插值/01分段线性插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数拟合的插值法/03多项式插值/01分段线性插值/01分段线性插值 -------------------------------------------------------------------------------- /04函数拟合的插值法/03多项式插值/01分段线性插值/01分段线性插值.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // 定义存储插值点的结构体 5 | struct Point{ 6 | double x; 7 | double y; 8 | }; 9 | 10 | // 求出两个点之间的斜率 11 | double getK(struct Point p1, struct Point p2){ 12 | return (p2.y - p1.y) / (p2.x - p1.x); 13 | } 14 | 15 | // 分段线性插值 16 | double interpolate(double x, struct Point points[], int numPoints) 17 | { 18 | double result = 0; 19 | 20 | // 遍历所有的点 21 | for (int i = 0; i < numPoints - 1; i++) 22 | { 23 | // 判断x是否在两个点之间 24 | if (x >= points[i].x && x <= points[i + 1].x) 25 | { 26 | // 求出两个点之间的斜率 27 | double k = getK(points[i], points[i + 1]); 28 | // 求出y值 29 | result = k * (x - points[i].x) + points[i].y; 30 | break; 31 | } 32 | } 33 | return result; 34 | } 35 | 36 | int main(int argc, char *argv[]) 37 | { 38 | long numPoints; 39 | printf("请输入需要插值的点的个数:"); 40 | scanf("%ld", &numPoints); 41 | struct Point points[numPoints]; 42 | for (int i = 0; i < numPoints; i++) 43 | { 44 | printf("请输入第%d个点的x值:", i + 1); 45 | scanf("%lf", &points[i].x); 46 | printf("请输入第%d个点的y值:", i + 1); 47 | scanf("%lf", &points[i].y); 48 | } 49 | printf("请输入需要插值的x值:"); 50 | double x; 51 | scanf("%lf", &x); 52 | double result = interpolate(x, points, numPoints); 53 | printf("插值结果为:%lf\n", result); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /04函数拟合的插值法/03多项式插值/02Hermite插值法/01Hermite插值法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数拟合的插值法/03多项式插值/02Hermite插值法/01Hermite插值法 -------------------------------------------------------------------------------- /04函数拟合的插值法/03多项式插值/02Hermite插值法/01Hermite插值法.c: -------------------------------------------------------------------------------- 1 | /* 2 | * n个插值节点带1阶导数的埃尔米特插值 3 | */ 4 | #include 5 | #define MAXSIZE 50 6 | void input(double x[MAXSIZE], double f[MAXSIZE], double df[MAXSIZE], long n); 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | double x[MAXSIZE], f[MAXSIZE], df[MAXSIZE], Interpolation_x, Interpolation_y, l, dl; 11 | long n, i, j; 12 | printf("请输入插值节点的个数: "); 13 | scanf("%ld", &n); 14 | input(x, f, df, n); 15 | printf("请输入插值点: "); 16 | scanf("%lf", &Interpolation_x); 17 | Interpolation_y = 0; 18 | for (i = 0; i <= n-1; i++) { 19 | l = 1; 20 | for(j = 0; j <= n-1; j++){ 21 | if(j != i){ 22 | l *= (Interpolation_x - x[j]) / (x[i] - x[j]); 23 | } 24 | } 25 | 26 | dl = 0; 27 | for(j = 0; j<= n-1; j++){ 28 | if(j != i){ 29 | dl += 1/(x[i] - x[j]); 30 | } 31 | } 32 | Interpolation_y += (1-2 * dl * (Interpolation_x - x[i])) * l * l * f[i] + (Interpolation_x - x[i])* l * l * df[i]; 33 | } 34 | printf("插值点(x, y)= (%lf, %lf)\n", Interpolation_x, Interpolation_y); 35 | 36 | return 0; 37 | } 38 | 39 | 40 | void input(double x[MAXSIZE], double f[MAXSIZE], double df[MAXSIZE], long n) 41 | { 42 | long i; 43 | for(i = 0; i <= n-1; i++) 44 | { 45 | printf("请输入插值节点x[%ld], 函数值f[%ld], 导数值df[%ld](请用,隔开):", i, i, i); 46 | scanf("%lf, %lf, %lf", &x[i], &f[i], &df[i]); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /04函数拟合的插值法/04样条插值/01三次样条插值/00参考案例/00算法逻辑/01三次样条插值.c: -------------------------------------------------------------------------------- 1 | /******三次样条插值,边界条件为给定两个端点的一阶导数值*************/ 2 | #include 3 | #include 4 | #define N 4 5 | double zhuigan(double m[N+1],double b2[N-1],double a[N+1]) //返回数组m 6 | { 7 | int i,j; 8 | double A[N-1][N-1],L[N-1][N-1],U[N-1][N-1],a1[N-1],b1[N-2],y[N-1]; 9 | for(i=0;i=1&&j==i-1) 22 | { 23 | A[i][j]=1-a[i+1]; 24 | } 25 | else 26 | A[i][j]=0; 27 | } 28 | } 29 | for(i=0;i=1;i--) 102 | { 103 | m[i]=y[i-1]-U[i-1][i]*m[i+1]; 104 | } 105 | return 0; 106 | } 107 | double S(double x_,double x[],double y[],double m[]) 108 | { 109 | int i; 110 | double s; 111 | for(i=0;i=x[i]&&x_<=x[i+1]) 114 | break; 115 | else 116 | ; 117 | } 118 | s=(1+2*(x_-x[i])/(x[i+1]-x[i]))*pow(((x_-x[i+1])/(x[i]-x[i+1])),2)*y[i]+(1+2*(x_-x[i+1])/(x[i]-x[i+1]))*pow(((x_-x[i])/(x[i+1]-x[i])),2)*y[i+1]+(x_-x[i])*pow(((x_-x[i+1])/(x[i]-x[i+1])),2)*m[i]+(x_-x[i+1])*pow(((x_-x[i])/(x[i+1]-x[i])),2)*m[i+1]; 119 | return s; 120 | 121 | } 122 | void main() 123 | { 124 | int i; 125 | double x[N+1],y[N+1],a[N+1],b[N+1],m[N+1],h[N],b2[N-1],s,x_; 126 | m[0]=2.125;m[N]=-2.375; 127 | printf("请输入插值点及其对应的函数值"); //可进行交互输入 128 | for(i=0;i 6 | 7 | int main() { 8 | /** Step 0 9 | * 输入程序运行所需的初始值 10 | * */ 11 | long n, i, j; 12 | printf("请输入区间个数: "); 13 | scanf("%ld", &n); 14 | n++; 15 | double x[n], a[n], h[n-1], A[n-1], l[n], u[n], z[n], c[n], b[n-1], d[n-1]; 16 | // x[] 存放插值节点坐标 17 | // a[] 存放插值节点对应的函数值 18 | // h[] 存放分割成小区间后的区间长度 19 | // A[] 20 | // l[] 21 | // u[] 22 | // z[] 23 | // c[] 24 | // b[] 25 | // d[] 26 | for (i = 0; i < n; i++) { 27 | printf("输入插值节点是值x_%ld: ", i); 28 | scanf("%lf", &x[i]); 29 | } 30 | // 输入x_i 对应的 函数值 f(x_i) 31 | for (i = 0; i < n; i++) { 32 | printf("请输入节点x_%ld的函数值f(x_%ld)", i, i); 33 | scanf("%lf", &a[i]); 34 | } 35 | 36 | /** Step 1 37 | * 初始化 h[i] 38 | * */ 39 | for (i = 0; i < n ; i++) { 40 | h[i] = x[i + 1] - x[i]; 41 | } 42 | 43 | /** Step 2 44 | * 计算 α_i = \frac{3}{h_i}(a_{i+1} - a_{i}) - \frac{3}{h_{i-1}}(a_{i} - a_{i-1}) 45 | */ 46 | for (i = 1; i = 0; j--) { 70 | c[j] = z[j] - u[j] * c[j+1]; 71 | b[j] = (a[j+1] - a[j]) / h[j] - h[j] * (c[j+1] + 2*c[j]) / 3; 72 | d[j] = (c[j+1] - c[j]) / (3*h[j]); 73 | } 74 | 75 | /** Step 7 76 | * 输出结果 77 | */ 78 | printf("%2s %8s %8s %8s %8s\n", "i", "ai", "bi", "ci", "di"); 79 | for (i = 0; i < n; i++) 80 | printf("%2d %8.2f %8.2f %8.2f %8.2f\n", i, a[i], b[i], c[i], d[i]); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /04函数拟合的插值法/04样条插值/01三次样条插值/00参考案例/01不等距三次样条插值/不等距3次样条插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数拟合的插值法/04样条插值/01三次样条插值/00参考案例/01不等距三次样条插值/不等距3次样条插值 -------------------------------------------------------------------------------- /04函数拟合的插值法/04样条插值/01三次样条插值/00参考案例/01不等距三次样条插值/不等距3次样条插值.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | *************CUBIC SPLINE PROGRAM***************** 3 | ************************************************* 4 | The program asks the user to enter the data-points and then returns the cubic splines equations 5 | for each interval 6 | Equation for ith interval being: 7 | ai(x-xi)^3+bi(x-xi)^2+ci(x-xi)+di*/ 8 | #include 9 | #include 10 | /******* 11 | Function that performs Gauss-Elimination and returns the Upper triangular matrix and solution of equations: 12 | There are two options to do this in C. 13 | 1. Pass the augmented matrix (a) as the parameter, and calculate and store the upperTriangular(Gauss-Eliminated Matrix) in it. 14 | 2. Use malloc and make the function of pointer type and return the pointer. 15 | This program uses the first option. 16 | ********/ 17 | void gaussEliminationLS(int m, int n, double a[m][n], double x[n-1]){ 18 | int i,j,k; 19 | for(i=0;i=0;i--){ 44 | x[i]=a[i][n-1]; 45 | for(j=i+1;j 5 | #include 6 | /******* 7 | Function that performs Gauss-Elimination and returns the Upper triangular matrix and solution of equations: 8 | There are two options to do this in C. 9 | 1. Pass the augmented matrix (a) as the parameter, and calculate and store the upperTriangular(Gauss-Eliminated Matrix) in it. 10 | 2. Use malloc and make the function of pointer type and return the pointer. 11 | This program uses the first option. 12 | ********/ 13 | void gaussEliminationLS(int m, int n, double a[m][n], double x[n-1]){ 14 | int i,j,k; 15 | for(i=0;i=0;i--){ 40 | x[i]=a[i][n-1]; 41 | for(j=i+1;j 10 | #include 11 | #include 12 | 13 | typedef struct Point{ 14 | double x; 15 | double y; 16 | }Point; 17 | 18 | double cubicSpline(long n, struct Point *points, double xs, double *h, long location); 19 | double compute(long n, struct Point *points, double *M, double xs, double *h, long loaction); 20 | void ColEliminate(long n, double **A, double *b, double *x); 21 | void swapRow(long n, long r, long k, double **A, double *b); 22 | void partition(long n, struct Point *points, double *h); 23 | void sort(long n, struct Point *points); 24 | long findlocation(long n, struct Point *points, double xs); 25 | void print_array(long n, double *array, char *name); 26 | void print_points(long n, struct Point *points); 27 | void print_matrix(double **Matrix, long m, long n); 28 | 29 | int main(int argc, char *argv[]){ 30 | printf("请输入插值节点的个数:"); 31 | long n; 32 | scanf("%ld", &n); 33 | 34 | Point *points = (Point *) malloc (sizeof(Point) * (n + 1)); 35 | 36 | double xs; // 待求节点的横坐标。 37 | double ys; // 待求节点的纵坐标。 38 | 39 | double h[n-1]; 40 | partition(n, points, h); 41 | 42 | printf("请输入待求节点的横坐标:"); 43 | scanf("%lf", &xs); 44 | long location = findlocation(n, points, xs); 45 | 46 | ys = cubicSpline(n, points, xs, h, location); 47 | printf("在%lf处利用固定边界条件的三次样条计算的结果:%lf\n", xs, ys); 48 | 49 | free(points); 50 | 51 | } 52 | 53 | double cubicSpline(long n, struct Point *points, double xs, double *h, long location){ 54 | double * alpha = (double *) malloc (sizeof(double) * (n + 1)); 55 | double *b = (double *) malloc (sizeof(double) * (n + 1)); 56 | double * beta = (double *) malloc (sizeof(double) * (n + 1)); 57 | double *c = (double *) malloc (sizeof(double) * (n + 1)); 58 | double *M = (double *) malloc (sizeof(double) * (n + 1)); 59 | 60 | // 这里自定义边界条件 一阶导与二阶导的值 61 | printf("请输入区间端点导数值 \n"); 62 | printf("左端点的导数值 f'(%lf):", points[0].x); 63 | double dy_left; 64 | scanf("%lf", &dy_left); 65 | printf("右端点的导数值 f'(%lf):", points[n-1].x); 66 | double dy_right; 67 | scanf("%lf", &dy_right); 68 | 69 | // 对第一行单独赋值 70 | //alpha[0] = 0.0; 71 | b[0] = 2.0; 72 | beta[0] = 1.0; 73 | c[0] = 6.0 / h[0] * ((points[1].y - points[0].y) / h[0] - dy_left); 74 | 75 | for(long i = 1; i < n-1; i++){ 76 | alpha[i] = h[i - 1] / (h[i - 1] + h[i]); 77 | b[i] = 2.0; 78 | beta[i] = h[i] / (h[i - 1] + h[i]); 79 | c[i] = (6.0 / (h[i-1] + h[i])) * ((points[i + 1].y - points[i].y) / h[i] - (points[i].y - points[i-1].y) / h[i-1]); 80 | } 81 | // 对最后一行单独赋值 82 | alpha[n-1] = 1.0; 83 | b[n-1]=2.0; 84 | //beta[n-1]=0.0; 85 | c[n-1]=6.0 / h[n-2] * (dy_right - (points[n-1].y - points[n-2].y) / h[n-2]); 86 | 87 | double **A = (double **) malloc (sizeof(double *) * n); 88 | for(long i = 0; i < n; i++){ 89 | A[i] = (double *) malloc (sizeof(double) * n); 90 | } 91 | // 3对角矩阵赋值 92 | for(long i = 1; i < n; i++) A[i][i - 1] = alpha[i]; 93 | for(long i = 0; i < n; i++) A[i][i] = b[i]; 94 | for(long i = 0; i < n-1; i++) A[i][i + 1] = beta[i]; 95 | 96 | printf("系数矩阵A = \n"); 97 | print_matrix(A, n, n); 98 | printf("常数项c = \n"); 99 | print_array(n, c, "c"); 100 | 101 | // 列主元消去法求解三对角矩阵 102 | ColEliminate(n, A, c, M); 103 | // 消元后的结果 104 | printf("消元后的结果:\n"); 105 | print_matrix(A, n, n); 106 | printf("解向量M = \n"); 107 | print_array(n, M, "M"); 108 | // 带入样条插值公式 109 | return compute(n, points, M, xs, h, location); 110 | free(alpha); 111 | free(b); 112 | free(beta); 113 | free(c); 114 | free(M); 115 | } 116 | 117 | // 二分法查找待求点所在的区间 118 | long findlocation(long n, struct Point *points, double xs) 119 | { 120 | if (xs < points[0].x || xs > points[n - 1].x) 121 | { 122 | printf("要求的点不在已给的区间[%lf, %lf]内\n", points[0].x, points[n - 1].x); 123 | return -1; 124 | } 125 | 126 | long left = 0, right = n - 1, mid; 127 | while(left <= right){ 128 | mid = (left + right) / 2; 129 | if(points[mid].x == xs) return mid; 130 | else if(points[mid].x < xs) left = mid + 1; 131 | else right = mid - 1; 132 | } 133 | return left; 134 | 135 | } 136 | 137 | /* 138 | * 计算 样条插值公式结果。 139 | * 140 | * 将解出的$M_j$代入下面的方程中,其中$x_j/x_{j+1}$表示区间端点,需要依次累加 141 | * \begin{equation} 142 | * \begin{aligned} 143 | * p_{j}(x) &= \frac{M_{j+1}}{6h_{j}}(x-x_j)^3 144 | * &- \frac{M_{j}}{6h_{j}}(x-x_{j+1})^3 \\ 145 | * &+ \frac{1}{h_{j}}(y_{j+1} - \frac{M_{j+1}h_{j}^{2}}{6})(x-x_j) 146 | * &- \frac{1}{h_{j}}(y_j-\frac{M_{j}h_{j}^2}{6})(x-x_{j+1}) \\ 147 | * j=0, 1, \cdots, n-1 148 | * \end{aligned} 149 | * \end{equation} 150 | */ 151 | double compute(long n, struct Point *points, double *M, double xs, double *h, long location) 152 | { 153 | // j 表示第j个 154 | //long j = ceil((xs - left) / h[0]); 155 | //long j = findlocation(n, points, xs); 156 | //if (-1 == j) 157 | //{ 158 | // return -1; 159 | //}else{ 160 | // printf("要找的元素在第 %ld个区间\n", j); 161 | //} 162 | long j = location-1; 163 | double xj = points[j].x; 164 | double xj1 = points[j + 1].x; 165 | double yj = points[j].y; 166 | double yj1 = points[j + 1].y; 167 | printf("要找的元素在第 %ld 个区间[%lf, %lf]\n", location, xj, xj1); 168 | return M[j] * pow(xj1 - xs, 3) / (6 * h[j]) 169 | + M[j + 1] * pow(xs - xj, 3) / (6 * h[j]) 170 | + (yj - M[j] * h[j] * h[j] / 6) * (xj1 - xs) / h[j] 171 | + (yj1 - M[j + 1] * h[j] * h[j] / 6) * (xs - xj) / h[j]; 172 | } 173 | 174 | /* 175 | * 列主元高斯消去法 176 | * 计算 AM=c 中的M 177 | */ 178 | void ColEliminate(long n, double **A, double *b, double *x){ 179 | for(long k = 0; k < n - 1; k++){ 180 | long r = k; 181 | for(long i = k + 1; i < n; i++){ 182 | // 找到第k列上 绝对值最大的行 183 | if(fabs(A[i][k]) > fabs(A[r][k])){ 184 | r = i; 185 | } 186 | } 187 | 188 | if(r != k){ 189 | swapRow(n, r, k, A, b); 190 | } 191 | 192 | // 消元 193 | for(long i = k + 1; i < n; i++){ 194 | A[i][k] /= A[k][k]; 195 | b[i] -= A[i][k] * b[k]; 196 | for(long j = k + 1; j < n; j++){ 197 | A[i][j] -= A[i][k] * A[k][j]; 198 | } 199 | A[i][k] = 0; 200 | } 201 | } 202 | 203 | if( 0 == A[n - 1][n - 1]){ 204 | printf("矩阵奇异,无法求解。\n"); 205 | exit(0); 206 | }else{ 207 | for(long i = n - 1; i >= 0; i--){ 208 | x[i] = 0; 209 | for(long j = i + 1; j < n; j++){ 210 | x[i] += A[i][j] * x[j]; 211 | } 212 | x[i] = (b[i] - x[i]) / A[i][i]; 213 | } 214 | } 215 | } 216 | 217 | /* 218 | * 交换矩阵 A 的第 r 行和第 k 行, 219 | * 向量 b 的第 r 个元素和第 k 个元素。 220 | */ 221 | void swapRow(long n, long r, long k, double **A, double *b){ 222 | double tmp; 223 | 224 | for(long i = 0; i < n; i++){ 225 | tmp = A[r][i]; 226 | A[r][i] = A[k][i]; 227 | A[k][i] = tmp; 228 | } 229 | 230 | tmp = b[r]; 231 | b[r] = b[k]; 232 | b[k] = tmp; 233 | 234 | return; 235 | } 236 | 237 | /* 238 | * 将 n + 1 个节点的横坐标存入数组 points 中。 239 | * 并计算相邻两个元素之差 h 的值。 240 | */ 241 | void partition(long n, struct Point *points, double *h){ 242 | printf("请输入插值节点的横坐标和纵坐标(中间用' '隔开)\n"); 243 | for(long i = 0; i < n; i++){ 244 | printf("请输入第%d个节点的横坐标和纵坐标(x[%ld] y[%ld]):", i + 1, i , i ); 245 | scanf("%lf %lf", &points[i].x, &points[i].y); 246 | } 247 | printf("排序前的结果:\n"); 248 | print_points(n, points); 249 | // 对输入完的结果进行排序 250 | sort(n, points); 251 | printf("排序后的结果:\n"); 252 | print_points(n, points); 253 | 254 | // 计算h的值 255 | for(long i = 0; i < n; i++){ 256 | h[i] = points[i + 1].x - points[i].x; 257 | } 258 | print_array(n-1, h, "h"); 259 | return; 260 | } 261 | 262 | void print_points(long n, struct Point *points){ 263 | for(long i = 0; i < n; i++){ 264 | printf("(%lf, %lf) ", points[i].x, points[i].y); 265 | } 266 | printf("\n"); 267 | } 268 | 269 | void print_array(long n, double *array, char* name){ 270 | for(long i = 0; i < n; i++){ 271 | printf("%s[%ld] = %lf ",name, i, array[i]); 272 | } 273 | printf("\n"); 274 | } 275 | 276 | void print_matrix(double **Matrix, long m, long n) 277 | { 278 | long i, j; 279 | for(i = 0; i < m; i++) 280 | { 281 | for(j = 0; j < n; j++) 282 | printf(" %lf ", Matrix[i][j]); 283 | printf("\n"); 284 | } 285 | } 286 | 287 | // 以x为参考,从小到大排序 288 | // 这里使用冒泡排序 289 | void sort(long n, struct Point *points){ 290 | for(long i = 0; i < n; i++){ 291 | for(long j = i + 1; j < n; j++){ 292 | if(points[i].x > points[j].x){ 293 | struct Point tmp = points[i]; 294 | points[i] = points[j]; 295 | points[j] = tmp; 296 | } 297 | } 298 | } 299 | } -------------------------------------------------------------------------------- /04函数拟合的插值法/04样条插值/01三次样条插值/02自然边界条件的三次样条插值/自然边界条件的三次样条插值.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 自然边界条件的三次样条插值 3 | * 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | typedef struct Point{ 10 | double x; 11 | double y; 12 | }Point; 13 | 14 | double cubicSpline(long n, struct Point *points, double xs, double *h, long location); 15 | double compute(long n, struct Point *points, double *M, double xs, double *h, long loaction); 16 | void ColEliminate(long n, double **A, double *b, double *x); 17 | void swapRow(long n, long r, long k, double **A, double *b); 18 | void partition(long n, struct Point *points, double *h); 19 | void sort(long n, struct Point *points); 20 | long findlocation(long n, struct Point *points, double xs); 21 | void print_array(long n, double *array, char *name); 22 | void print_points(long n, struct Point *points); 23 | void print_matrix(double **Matrix, long m, long n); 24 | 25 | int main(int argc, char *argv[]){ 26 | printf("请输入插值节点的个数:"); 27 | long n; 28 | scanf("%ld", &n); 29 | 30 | Point *points = (Point *) malloc (sizeof(Point) * (n + 1)); 31 | 32 | double xs; // 待求节点的横坐标。 33 | double ys; // 待求节点的纵坐标。 34 | 35 | double h[n-1]; 36 | partition(n, points, h); 37 | 38 | printf("请输入待求节点的横坐标:"); 39 | scanf("%lf", &xs); 40 | long location = findlocation(n, points, xs); 41 | 42 | ys = cubicSpline(n, points, xs, h, location); 43 | printf("在%lf处利用固定边界条件的三次样条计算的结果:%lf\n", xs, ys); 44 | 45 | free(points); 46 | 47 | } 48 | 49 | double cubicSpline(long n, struct Point *points, double xs, double *h, long location){ 50 | double * alpha = (double *) malloc (sizeof(double) * (n + 1)); 51 | double *b = (double *) malloc (sizeof(double) * (n + 1)); 52 | double * beta = (double *) malloc (sizeof(double) * (n + 1)); 53 | double *c = (double *) malloc (sizeof(double) * (n + 1)); 54 | double *M = (double *) malloc (sizeof(double) * (n + 1)); 55 | 56 | // 这里自定义边界条件 一阶导与二阶导的值 57 | printf("请输入区间端点导数值 \n"); 58 | printf("左端点的二阶导数值 f'(%lf):", points[0].x); 59 | double ddy_left; 60 | scanf("%lf", &ddy_left); 61 | printf("右端点的二阶导数值 f'(%lf):", points[n-1].x); 62 | double ddy_right; 63 | scanf("%lf", &ddy_right); 64 | 65 | // 对第一行单独赋值 66 | //alpha[0] = 0.0; 67 | b[0] = 2.0; 68 | beta[0] = 0; 69 | //c[0] = 6.0 / h[0] * ((points[1].y - points[0].y) / h[0] - dy_left); 70 | c[0] = 2 * ddy_left; 71 | M[0] = ddy_left; 72 | 73 | for(long i = 2; i < n-2; i++){ 74 | alpha[i] = h[i - 1] / (h[i - 1] + h[i]); 75 | b[i] = 2.0; 76 | beta[i] = h[i] / (h[i - 1] + h[i]); 77 | c[i] = (6.0 / (h[i-1] + h[i])) * ((points[i + 1].y - points[i].y) / h[i] - (points[i].y - points[i-1].y) / h[i-1]); 78 | } 79 | 80 | // 对最后一行单独赋值 81 | alpha[n-1] = 0; 82 | b[n-1]=2.0; 83 | //beta[n-2]=h[n-2] / (h[n-3] + h[n-2]); 84 | //c[n-1]=6.0 / h[n-2] * (dy_right - (points[n-1].y - points[n-2].y) / h[n-2]); 85 | c[n-1] = 2 * ddy_right; 86 | M[n-1] = ddy_right; 87 | 88 | double **A = (double **) malloc (sizeof(double *) * n); 89 | for(long i = 0; i < n; i++){ 90 | A[i] = (double *) malloc (sizeof(double) * n); 91 | } 92 | // 3对角矩阵赋值 93 | for(long i = 1; i < n; i++) A[i][i - 1] = alpha[i]; 94 | for(long i = 0; i < n; i++) A[i][i] = b[i]; 95 | for(long i = 0; i < n-1; i++) A[i][i + 1] = beta[i]; 96 | 97 | printf("系数矩阵A = \n"); 98 | print_matrix(A, n, n); 99 | printf("常数项c = \n"); 100 | print_array(n, c, "c"); 101 | 102 | // 列主元消去法求解三对角矩阵 103 | ColEliminate(n, A, c, M); 104 | // 消元后的结果 105 | printf("消元后的结果:\n"); 106 | print_matrix(A, n, n); 107 | printf("解向量M = \n"); 108 | print_array(n, M, "M"); 109 | // 带入样条插值公式 110 | return compute(n, points, M, xs, h, location); 111 | free(alpha); 112 | free(b); 113 | free(beta); 114 | free(c); 115 | free(M); 116 | } 117 | 118 | // 二分法查找待求点所在的区间 119 | long findlocation(long n, struct Point *points, double xs) 120 | { 121 | if (xs < points[0].x || xs > points[n - 1].x) 122 | { 123 | printf("要求的点不在已给的区间[%lf, %lf]内\n", points[0].x, points[n - 1].x); 124 | return -1; 125 | } 126 | 127 | long left = 0, right = n - 1, mid; 128 | while(left <= right){ 129 | mid = (left + right) / 2; 130 | if(points[mid].x == xs) return mid; 131 | else if(points[mid].x < xs) left = mid + 1; 132 | else right = mid - 1; 133 | } 134 | return left; 135 | 136 | } 137 | 138 | /* 139 | * 计算 样条插值公式结果。 140 | * 141 | * 将解出的$M_j$代入下面的方程中,其中$x_j/x_{j+1}$表示区间端点,需要依次累加 142 | * \begin{equation} 143 | * \begin{aligned} 144 | * p_{j}(x) &= \frac{M_{j+1}}{6h_{j}}(x-x_j)^3 145 | * &- \frac{M_{j}}{6h_{j}}(x-x_{j+1})^3 \\ 146 | * &+ \frac{1}{h_{j}}(y_{j+1} - \frac{M_{j+1}h_{j}^{2}}{6})(x-x_j) 147 | * &- \frac{1}{h_{j}}(y_j-\frac{M_{j}h_{j}^2}{6})(x-x_{j+1}) \\ 148 | * j=0, 1, \cdots, n-1 149 | * \end{aligned} 150 | * \end{equation} 151 | */ 152 | double compute(long n, struct Point *points, double *M, double xs, double *h, long location) 153 | { 154 | // j 表示第j个 155 | //long j = ceil((xs - left) / h[0]); 156 | //long j = findlocation(n, points, xs); 157 | //if (-1 == j) 158 | //{ 159 | // return -1; 160 | //}else{ 161 | // printf("要找的元素在第 %ld个区间\n", j); 162 | //} 163 | long j = location-1; 164 | double xj = points[j].x; 165 | double xj1 = points[j + 1].x; 166 | double yj = points[j].y; 167 | double yj1 = points[j + 1].y; 168 | printf("要找的元素在第 %ld 个区间[%lf, %lf]\n", location, xj, xj1); 169 | return M[j] * pow(xj1 - xs, 3) / (6 * h[j]) 170 | + M[j + 1] * pow(xs - xj, 3) / (6 * h[j]) 171 | + (yj - M[j] * h[j] * h[j] / 6) * (xj1 - xs) / h[j] 172 | + (yj1 - M[j + 1] * h[j] * h[j] / 6) * (xs - xj) / h[j]; 173 | } 174 | 175 | /* 176 | * 列主元高斯消去法 177 | * 计算 AM=c 中的M 178 | */ 179 | void ColEliminate(long n, double **A, double *b, double *x){ 180 | for(long k = 0; k < n - 1; k++){ 181 | long r = k; 182 | for(long i = k + 1; i < n; i++){ 183 | // 找到第k列上 绝对值最大的行 184 | if(fabs(A[i][k]) > fabs(A[r][k])){ 185 | r = i; 186 | } 187 | } 188 | 189 | if(r != k){ 190 | swapRow(n, r, k, A, b); 191 | } 192 | 193 | // 消元 194 | for(long i = k + 1; i < n; i++){ 195 | A[i][k] /= A[k][k]; 196 | b[i] -= A[i][k] * b[k]; 197 | for(long j = k + 1; j < n; j++){ 198 | A[i][j] -= A[i][k] * A[k][j]; 199 | } 200 | A[i][k] = 0; 201 | } 202 | } 203 | 204 | if( 0 == A[n - 1][n - 1]){ 205 | printf("矩阵奇异,无法求解。\n"); 206 | exit(0); 207 | }else{ 208 | for(long i = n - 1; i >= 0; i--){ 209 | x[i] = 0; 210 | for(long j = i + 1; j < n; j++){ 211 | x[i] += A[i][j] * x[j]; 212 | } 213 | x[i] = (b[i] - x[i]) / A[i][i]; 214 | } 215 | } 216 | } 217 | 218 | /* 219 | * 交换矩阵 A 的第 r 行和第 k 行, 220 | * 向量 b 的第 r 个元素和第 k 个元素。 221 | */ 222 | void swapRow(long n, long r, long k, double **A, double *b){ 223 | double tmp; 224 | 225 | for(long i = 0; i < n; i++){ 226 | tmp = A[r][i]; 227 | A[r][i] = A[k][i]; 228 | A[k][i] = tmp; 229 | } 230 | 231 | tmp = b[r]; 232 | b[r] = b[k]; 233 | b[k] = tmp; 234 | 235 | return; 236 | } 237 | 238 | /* 239 | * 将 n + 1 个节点的横坐标存入数组 points 中。 240 | * 并计算相邻两个元素之差 h 的值。 241 | */ 242 | void partition(long n, struct Point *points, double *h){ 243 | printf("请输入插值节点的横坐标和纵坐标(中间用' '隔开)\n"); 244 | for(long i = 0; i < n; i++){ 245 | printf("请输入第%d个节点的横坐标和纵坐标(x[%ld] y[%ld]):", i + 1, i , i ); 246 | scanf("%lf %lf", &points[i].x, &points[i].y); 247 | } 248 | printf("排序前的结果:\n"); 249 | print_points(n, points); 250 | // 对输入完的结果进行排序 251 | sort(n, points); 252 | printf("排序后的结果:\n"); 253 | print_points(n, points); 254 | 255 | // 计算h的值 256 | for(long i = 0; i < n; i++){ 257 | h[i] = points[i + 1].x - points[i].x; 258 | } 259 | print_array(n-1, h, "h"); 260 | return; 261 | } 262 | 263 | void print_points(long n, struct Point *points){ 264 | for(long i = 0; i < n; i++){ 265 | printf("(%lf, %lf) ", points[i].x, points[i].y); 266 | } 267 | printf("\n"); 268 | } 269 | 270 | void print_array(long n, double *array, char* name){ 271 | for(long i = 0; i < n; i++){ 272 | printf("%s[%ld] = %lf ",name, i, array[i]); 273 | } 274 | printf("\n"); 275 | } 276 | 277 | void print_matrix(double **Matrix, long m, long n) 278 | { 279 | long i, j; 280 | for(i = 0; i < m; i++) 281 | { 282 | for(j = 0; j < n; j++) 283 | printf(" %lf ", Matrix[i][j]); 284 | printf("\n"); 285 | } 286 | } 287 | 288 | // 以x为参考,从小到大排序 289 | // 这里使用冒泡排序 290 | void sort(long n, struct Point *points){ 291 | for(long i = 0; i < n; i++){ 292 | for(long j = i + 1; j < n; j++){ 293 | if(points[i].x > points[j].x){ 294 | struct Point tmp = points[i]; 295 | points[i] = points[j]; 296 | points[j] = tmp; 297 | } 298 | } 299 | } 300 | } -------------------------------------------------------------------------------- /04函数拟合的插值法/04样条插值/01三次样条插值/03周期边界条件的三次样条插值/周期边界条件的三次样条插值.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 周期边界条件的三次样条插值 3 | * 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | typedef struct Point{ 10 | double x; 11 | double y; 12 | }Point; 13 | 14 | double cubicSpline(long n, struct Point *points, double xs, double *h, long location); 15 | double compute(long n, struct Point *points, double *M, double xs, double *h, long loaction); 16 | void ColEliminate(long n, double **A, double *b, double *x); 17 | void swapRow(long n, long r, long k, double **A, double *b); 18 | void partition(long n, struct Point *points, double *h); 19 | void sort(long n, struct Point *points); 20 | long findlocation(long n, struct Point *points, double xs); 21 | void print_array(long n, double *array, char *name); 22 | void print_points(long n, struct Point *points); 23 | void print_matrix(double **Matrix, long m, long n); 24 | 25 | int main(int argc, char *argv[]){ 26 | printf("请输入插值节点的个数:"); 27 | long n; 28 | scanf("%ld", &n); 29 | 30 | Point *points = (Point *) malloc (sizeof(Point) * (n + 1)); 31 | 32 | double xs; // 待求节点的横坐标。 33 | double ys; // 待求节点的纵坐标。 34 | 35 | double h[n-1]; 36 | partition(n, points, h); 37 | 38 | printf("请输入待求节点的横坐标:"); 39 | scanf("%lf", &xs); 40 | long location = findlocation(n, points, xs); 41 | 42 | ys = cubicSpline(n, points, xs, h, location); 43 | printf("在%lf处利用固定边界条件的三次样条计算的结果:%lf\n", xs, ys); 44 | 45 | free(points); 46 | 47 | } 48 | 49 | double cubicSpline(long n, struct Point *points, double xs, double *h, long location){ 50 | double * alpha = (double *) malloc (sizeof(double) * (n + 1)); 51 | double *b = (double *) malloc (sizeof(double) * (n + 1)); 52 | double * beta = (double *) malloc (sizeof(double) * (n + 1)); 53 | double *c = (double *) malloc (sizeof(double) * (n + 1)); 54 | double *M = (double *) malloc (sizeof(double) * (n + 1)); 55 | 56 | // 这里自定义边界条件 一阶导与二阶导的值 57 | printf("请输入区间端点导数值 \n"); 58 | printf("左端点的二阶导数值 f'(%lf):", points[0].x); 59 | double ddy_left; 60 | scanf("%lf", &ddy_left); 61 | printf("右端点的二阶导数值 f'(%lf):", points[n-1].x); 62 | double ddy_right; 63 | scanf("%lf", &ddy_right); 64 | 65 | // 第一行求解 M0 其实好像并没有什么好的初值,但是因为 M0 = M_{n-1} 66 | // 所以最后只要把 M_{n-1}的结果放到 M_0 里面就行 67 | // 因此只要保证 第1行此时的系数 不导致矩阵奇异就行 68 | alpha[0] = 10000; 69 | b[0] = 2.0; 70 | beta[0] = 10000; 71 | c[0] = 100000; 72 | 73 | for(long i = 2; i < n-2; i++){ 74 | alpha[i] = h[i - 1] / (h[i - 1] + h[i]); 75 | b[i] = 2.0; 76 | beta[i] = h[i] / (h[i - 1] + h[i]); 77 | c[i] = (6.0 / (h[i-1] + h[i])) * ((points[i + 1].y - points[i].y) / h[i] - (points[i].y - points[i-1].y) / h[i-1]); 78 | } 79 | 80 | // 对最后一行单独赋值 81 | alpha[n-1] = h[n-2] / (h[0] + h[n-2]); 82 | b[n-1]=2.0; 83 | c[n-1] = (6/(h[0] + h[n-2])) * ((points[1].y - points[0].y) / h[0] - (points[n-1].y - points[n-2].y) / h[n-2]); 84 | M[n-1] = ddy_right; 85 | 86 | double **A = (double **) malloc (sizeof(double *) * n); 87 | for(long i = 0; i < n; i++){ 88 | A[i] = (double *) malloc (sizeof(double) * n); 89 | } 90 | // 3对角矩阵赋值 91 | for(long i = 1; i < n; i++) A[i][i - 1] = alpha[i]; 92 | for(long i = 0; i < n; i++) A[i][i] = b[i]; 93 | for(long i = 0; i < n-1; i++) A[i][i + 1] = beta[i]; 94 | A[0][n-1] = alpha[0]; 95 | A[n-1][0] = beta[n-1]; 96 | 97 | printf("系数矩阵A = \n"); 98 | print_matrix(A, n, n); 99 | printf("常数项c = \n"); 100 | print_array(n, c, "c"); 101 | 102 | // 列主元消去法求解三对角矩阵 103 | ColEliminate(n, A, c, M); 104 | // 消元后的结果 105 | printf("消元后的结果:\n"); 106 | print_matrix(A, n, n); 107 | M[0] = M[n-1]; 108 | printf("解向量M = \n"); 109 | print_array(n, M, "M"); 110 | // 带入样条插值公式 111 | return compute(n, points, M, xs, h, location); 112 | free(alpha); 113 | free(b); 114 | free(beta); 115 | free(c); 116 | free(M); 117 | } 118 | 119 | // 二分法查找待求点所在的区间 120 | long findlocation(long n, struct Point *points, double xs) 121 | { 122 | if (xs < points[0].x || xs > points[n - 1].x) 123 | { 124 | printf("要求的点不在已给的区间[%lf, %lf]内\n", points[0].x, points[n - 1].x); 125 | return -1; 126 | } 127 | 128 | long left = 0, right = n - 1, mid; 129 | while(left <= right){ 130 | mid = (left + right) / 2; 131 | if(points[mid].x == xs) return mid; 132 | else if(points[mid].x < xs) left = mid + 1; 133 | else right = mid - 1; 134 | } 135 | return left; 136 | 137 | } 138 | 139 | /* 140 | * 计算 样条插值公式结果。 141 | * 142 | * 将解出的$M_j$代入下面的方程中,其中$x_j/x_{j+1}$表示区间端点,需要依次累加 143 | * \begin{equation} 144 | * \begin{aligned} 145 | * p_{j}(x) &= \frac{M_{j+1}}{6h_{j}}(x-x_j)^3 146 | * &- \frac{M_{j}}{6h_{j}}(x-x_{j+1})^3 \\ 147 | * &+ \frac{1}{h_{j}}(y_{j+1} - \frac{M_{j+1}h_{j}^{2}}{6})(x-x_j) 148 | * &- \frac{1}{h_{j}}(y_j-\frac{M_{j}h_{j}^2}{6})(x-x_{j+1}) \\ 149 | * j=0, 1, \cdots, n-1 150 | * \end{aligned} 151 | * \end{equation} 152 | */ 153 | double compute(long n, struct Point *points, double *M, double xs, double *h, long location) 154 | { 155 | // j 表示第j个 156 | //long j = ceil((xs - left) / h[0]); 157 | //long j = findlocation(n, points, xs); 158 | //if (-1 == j) 159 | //{ 160 | // return -1; 161 | //}else{ 162 | // printf("要找的元素在第 %ld个区间\n", j); 163 | //} 164 | long j = location-1; 165 | double xj = points[j].x; 166 | double xj1 = points[j + 1].x; 167 | double yj = points[j].y; 168 | double yj1 = points[j + 1].y; 169 | printf("要找的元素在第 %ld 个区间[%lf, %lf]\n", location, xj, xj1); 170 | return M[j] * pow(xj1 - xs, 3) / (6 * h[j]) 171 | + M[j + 1] * pow(xs - xj, 3) / (6 * h[j]) 172 | + (yj - M[j] * h[j] * h[j] / 6) * (xj1 - xs) / h[j] 173 | + (yj1 - M[j + 1] * h[j] * h[j] / 6) * (xs - xj) / h[j]; 174 | } 175 | 176 | /* 177 | * 列主元高斯消去法 178 | * 计算 AM=c 中的M 179 | */ 180 | void ColEliminate(long n, double **A, double *b, double *x){ 181 | for(long k = 0; k < n - 1; k++){ 182 | long r = k; 183 | for(long i = k + 1; i < n; i++){ 184 | // 找到第k列上 绝对值最大的行 185 | if(fabs(A[i][k]) > fabs(A[r][k])){ 186 | r = i; 187 | } 188 | } 189 | 190 | if(r != k){ 191 | swapRow(n, r, k, A, b); 192 | } 193 | 194 | // 消元 195 | for(long i = k + 1; i < n; i++){ 196 | A[i][k] /= A[k][k]; 197 | b[i] -= A[i][k] * b[k]; 198 | for(long j = k + 1; j < n; j++){ 199 | A[i][j] -= A[i][k] * A[k][j]; 200 | } 201 | A[i][k] = 0; 202 | } 203 | } 204 | 205 | if( 0 == A[n - 1][n - 1]){ 206 | printf("矩阵奇异,无法求解。\n"); 207 | exit(0); 208 | }else{ 209 | for(long i = n - 1; i >= 0; i--){ 210 | x[i] = 0; 211 | for(long j = i + 1; j < n; j++){ 212 | x[i] += A[i][j] * x[j]; 213 | } 214 | x[i] = (b[i] - x[i]) / A[i][i]; 215 | } 216 | } 217 | } 218 | 219 | /* 220 | * 交换矩阵 A 的第 r 行和第 k 行, 221 | * 向量 b 的第 r 个元素和第 k 个元素。 222 | */ 223 | void swapRow(long n, long r, long k, double **A, double *b){ 224 | double tmp; 225 | 226 | for(long i = 0; i < n; i++){ 227 | tmp = A[r][i]; 228 | A[r][i] = A[k][i]; 229 | A[k][i] = tmp; 230 | } 231 | 232 | tmp = b[r]; 233 | b[r] = b[k]; 234 | b[k] = tmp; 235 | 236 | return; 237 | } 238 | 239 | /* 240 | * 将 n + 1 个节点的横坐标存入数组 points 中。 241 | * 并计算相邻两个元素之差 h 的值。 242 | */ 243 | void partition(long n, struct Point *points, double *h){ 244 | printf("请输入插值节点的横坐标和纵坐标(中间用' '隔开)\n"); 245 | for(long i = 0; i < n; i++){ 246 | printf("请输入第%d个节点的横坐标和纵坐标(x[%ld] y[%ld]):", i + 1, i , i ); 247 | scanf("%lf %lf", &points[i].x, &points[i].y); 248 | } 249 | printf("排序前的结果:\n"); 250 | print_points(n, points); 251 | // 对输入完的结果进行排序 252 | sort(n, points); 253 | printf("排序后的结果:\n"); 254 | print_points(n, points); 255 | 256 | // 计算h的值 257 | for(long i = 0; i < n; i++){ 258 | h[i] = points[i + 1].x - points[i].x; 259 | } 260 | print_array(n-1, h, "h"); 261 | return; 262 | } 263 | 264 | void print_points(long n, struct Point *points){ 265 | for(long i = 0; i < n; i++){ 266 | printf("(%lf, %lf) ", points[i].x, points[i].y); 267 | } 268 | printf("\n"); 269 | } 270 | 271 | void print_array(long n, double *array, char* name){ 272 | for(long i = 0; i < n; i++){ 273 | printf("%s[%ld] = %lf ",name, i, array[i]); 274 | } 275 | printf("\n"); 276 | } 277 | 278 | void print_matrix(double **Matrix, long m, long n) 279 | { 280 | long i, j; 281 | for(i = 0; i < m; i++) 282 | { 283 | for(j = 0; j < n; j++) 284 | printf(" %lf ", Matrix[i][j]); 285 | printf("\n"); 286 | } 287 | } 288 | 289 | // 以x为参考,从小到大排序 290 | // 这里使用冒泡排序 291 | void sort(long n, struct Point *points){ 292 | for(long i = 0; i < n; i++){ 293 | for(long j = i + 1; j < n; j++){ 294 | if(points[i].x > points[j].x){ 295 | struct Point tmp = points[i]; 296 | points[i] = points[j]; 297 | points[j] = tmp; 298 | } 299 | } 300 | } 301 | } -------------------------------------------------------------------------------- /04函数拟合的插值法/04样条插值/02B样条插值/02B样条插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数拟合的插值法/04样条插值/02B样条插值/02B样条插值 -------------------------------------------------------------------------------- /04函数拟合的插值法/04样条插值/02B样条插值/02B样条插值.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 编写程序,对函数f(x)=cos(πx) 在区间 [−1,1] 做三次样条插值,边界条件取周期边界条件,对于给定的待求节点 xs 求出其插值函数值 ys 。 3 | * 设定等分区间为 32 个。 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define N 32 // 等分区间数 11 | #define PI 3.14159265358979323846 12 | 13 | double f(double x) { 14 | return cos(PI * x); 15 | } 16 | 17 | double spline(double x, double *a, double *b, double *c, double *d) { 18 | int k = (int) ((x + 1.0) * N / 2.0); // 计算所在区间 19 | double dx = 2.0 / N; 20 | double t = (x - (-1.0 + k * dx)) / dx; // 归一化 21 | double y = a[k] + b[k] * t + c[k] * t * t + d[k] * t * t * t; // 计算插值函数值 22 | return y; 23 | } 24 | 25 | int main() { 26 | double a[N+1], b[N+1], c[N+1], d[N+1]; 27 | double h = 2.0 / N; 28 | double x[N+1]; 29 | for (int i = 0; i <= N; i++) { 30 | x[i] = -1.0 + i * h; 31 | a[i] = f(x[i]); 32 | } 33 | c[0] = c[N] = 0.0; // 周期边界条件 34 | for (int i = 1; i < N; i++) { 35 | double hi = x[i] - x[i-1]; 36 | double hi1 = x[i+1] - x[i]; 37 | double A = hi; 38 | double B = hi1; 39 | double C = 2.0 * (hi + hi1); 40 | double F = 6.0 * ((a[i+1] - a[i]) / hi1 - (a[i] - a[i-1]) / hi); 41 | double z = (A * c[i-1] + C + B * c[i+1]) / B; 42 | c[i] = -A / z; 43 | d[i] = (F - A * d[i-1]) / z; 44 | } 45 | for (int i = N-1; i >= 0; i--) { 46 | c[i] = c[i] * c[i+1] + d[i]; 47 | } 48 | double xs = 0.333333; // 待求节点 49 | double ys = spline(xs, a, b, c, d); 50 | printf("f(%f) = %f\n", xs, ys); 51 | return 0; 52 | } -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/01拉格朗日插值/01拉格朗日插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/01拉格朗日插值/01拉格朗日插值 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/01拉格朗日插值/01拉格朗日插值.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double x[MAXSIZE], double y[MAXSIZE], long n); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double x[MAXSIZE], y[MAXSIZE], l[MAXSIZE], Interpolation_x, Interpolation_y, tmp; 10 | long n, i, j; 11 | printf("请输入插值节点的个数:"); 12 | scanf("%ld", &n); 13 | input(x, y, n); 14 | printf("请输入待计算的插值点x的值:"); 15 | scanf("%lf", &Interpolation_x); 16 | Interpolation_y = 0; 17 | for (i = 0; i <= n-1; i++) { 18 | tmp = 1; 19 | for(j = 0; j <= n-1; j++){ 20 | if(j != i){ 21 | tmp *= (Interpolation_x - x[j]) / (x[i] - x[j]); 22 | } 23 | } 24 | l[i] = tmp; 25 | Interpolation_y += tmp * y[i]; 26 | } 27 | printf("-----------------------------\n"); 28 | printf("Lagrange插值节点的基函数:\n"); 29 | for (int i = 0; i < n; i++) { 30 | printf("l[%d] = %ld\n", i, l[i]); 31 | } 32 | printf("-----------------------------\n"); 33 | printf("插值点(x, y) = (%lf, %lf)\n", Interpolation_x, Interpolation_y); 34 | 35 | 36 | return 0; 37 | } 38 | 39 | 40 | void input(double x[MAXSIZE], double y[MAXSIZE], long n) 41 | { 42 | long i; 43 | for (i = 0; i <= n-1; i++) { 44 | printf("请输入插值节点 x[%ld], y[%ld]:(中间用英文\",\"隔开): ", i, i); 45 | scanf("%lf, %lf", &x[i], &y[i]); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/01拉格朗日插值/拉格朗日插值平台: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/01拉格朗日插值/拉格朗日插值平台 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/01拉格朗日插值/拉格朗日插值平台.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | void input(double x[MAXSIZE], double y[MAXSIZE], long n); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double x[MAXSIZE], y[MAXSIZE], l[MAXSIZE], Interpolation_x[MAXSIZE], Interpolation_y[MAXSIZE], tmp; 10 | long n,m, i, j; 11 | printf("请输入插值节点的个数:"); 12 | scanf("%ld", &n); 13 | input(x, y, n); 14 | printf("请输入待求节点的个数:"); 15 | scanf("%ld", &m); 16 | for (i = 0; i < m; i++) 17 | { 18 | printf("请输入待计算的插值点x的值:"); 19 | scanf("%lf", Interpolation_x[i]); 20 | Interpolation_y[i] = 0; 21 | for (i = 0; i <= n-1; i++) { 22 | tmp = 1; 23 | for(j = 0; j <= n-1; j++){ 24 | if(j != i){ 25 | tmp *= (Interpolation_x[i] - x[j]) / (x[i] - x[j]); 26 | } 27 | } 28 | l[i] = tmp; 29 | Interpolation_y[i] += tmp * y[i]; 30 | } 31 | } 32 | 33 | //printf("-----------------------------\n"); 34 | //printf("Lagrange插值节点的基函数:\n"); 35 | //for (int i = 0; i < n; i++) { 36 | // printf("l[%d] = %ld\n", i, l[i]); 37 | //} 38 | printf("-----------------------------\n"); 39 | for (i = 0; i < m; i++) 40 | { 41 | printf("插值点(x, y) = (%lf, %lf)\n", Interpolation_x[i], Interpolation_y[i]); 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | 48 | void input(double x[MAXSIZE], double y[MAXSIZE], long n) 49 | { 50 | long i; 51 | for (i = 0; i <= n-1; i++) { 52 | printf("请输入插值节点 x[%ld], y[%ld]:(中间用英文' '隔开): ", i, i); 53 | scanf("%lf %lf", &x[i], &y[i]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/02牛顿插值法/02牛顿插值法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/02牛顿插值法/02牛顿插值法 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/02牛顿插值法/02牛顿插值法.c: -------------------------------------------------------------------------------- 1 | /* 2 | * n 次牛顿插值的算法 3 | * 实现方法 4 | * 1.先实现差商表,用二维数组 f[i][j]存储 5 | * 2.利用差商表计算插值节点 6 | * 3.参考改进:利用秦九韶算法,遇到重复的乘法就提出公因子 7 | */ 8 | #include 9 | #include 10 | #define MAXSIZE 50 11 | 12 | void input(double x[MAXSIZE], double f[MAXSIZE][MAXSIZE], long n); 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | double x[MAXSIZE], f[MAXSIZE][MAXSIZE], Interpolation_x, Interpolation_y; 17 | long n, i, j; 18 | printf("请输入插值节点个数:"); 19 | scanf("%ld", &n); 20 | input(x, f, n); 21 | printf("请输入代求的插值点:"); 22 | scanf("%lf", &Interpolation_x); 23 | for(j=1; j<= n-1; j++){ 24 | for (i = j; i <= n-1; i++) { 25 | f[i][j] = (f[i][j-1] - f[i-1][j-1])/(x[i] - x[i-j]); 26 | } 27 | } 28 | Interpolation_y = f[n-1][n-1]; 29 | for(i = n-2; i>=0; i--){ 30 | Interpolation_y = f[i][i] + (Interpolation_x - x[i]) * Interpolation_y; 31 | } 32 | printf("插值点(x, y)=(%lf, %lf)\n", Interpolation_x, Interpolation_y); 33 | 34 | return 0; 35 | } 36 | 37 | 38 | void input(double x[MAXSIZE], double f[MAXSIZE][MAXSIZE], long n) 39 | { 40 | long i; 41 | for(i = 0; i <= n-1; i++){ 42 | printf("请输入插值节点x[%ld], y[%ld](中间用英文 \",\"隔开):", i, i); 43 | scanf("%lf, %lf", &x[i], &f[i][0]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/03多项式插值/01分段线性插值/01分段线性插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/03多项式插值/01分段线性插值/01分段线性插值 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/03多项式插值/01分段线性插值/01分段线性插值.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // 定义存储插值点的结构体 5 | struct Point{ 6 | double x; 7 | double y; 8 | }; 9 | 10 | // 求出两个点之间的斜率 11 | double getK(struct Point p1, struct Point p2){ 12 | return (p2.y - p1.y) / (p2.x - p1.x); 13 | } 14 | 15 | // 分段线性插值 16 | double interpolate(double x, struct Point points[], int numPoints) 17 | { 18 | double result = 0; 19 | 20 | // 遍历所有的点 21 | for (int i = 0; i < numPoints - 1; i++) 22 | { 23 | // 判断x是否在两个点之间 24 | if (x >= points[i].x && x <= points[i + 1].x) 25 | { 26 | // 求出两个点之间的斜率 27 | double k = getK(points[i], points[i + 1]); 28 | // 求出y值 29 | result = k * (x - points[i].x) + points[i].y; 30 | break; 31 | } 32 | } 33 | return result; 34 | } 35 | 36 | int main(int argc, char *argv[]) 37 | { 38 | long numPoints; 39 | printf("请输入需要插值的点的个数:"); 40 | scanf("%ld", &numPoints); 41 | struct Point points[numPoints]; 42 | for (int i = 0; i < numPoints; i++) 43 | { 44 | printf("请输入第%d个点的x值:", i + 1); 45 | scanf("%lf", &points[i].x); 46 | printf("请输入第%d个点的y值:", i + 1); 47 | scanf("%lf", &points[i].y); 48 | } 49 | printf("请输入需要插值的x值:"); 50 | double x; 51 | scanf("%lf", &x); 52 | double result = interpolate(x, points, numPoints); 53 | printf("插值结果为:%lf\n", result); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/03多项式插值/02Hermite插值法/01Hermite插值法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/03多项式插值/02Hermite插值法/01Hermite插值法 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/03多项式插值/02Hermite插值法/01Hermite插值法.c: -------------------------------------------------------------------------------- 1 | /* 2 | * n个插值节点带1阶导数的埃尔米特插值 3 | */ 4 | #include 5 | #define MAXSIZE 50 6 | void input(double x[MAXSIZE], double f[MAXSIZE], double df[MAXSIZE], long n); 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | double x[MAXSIZE], f[MAXSIZE], df[MAXSIZE], Interpolation_x, Interpolation_y, l, dl; 11 | long n, i, j; 12 | printf("请输入插值节点的个数: "); 13 | scanf("%ld", &n); 14 | input(x, f, df, n); 15 | printf("请输入插值点: "); 16 | scanf("%lf", &Interpolation_x); 17 | Interpolation_y = 0; 18 | for (i = 0; i <= n-1; i++) { 19 | l = 1; 20 | for(j = 0; j <= n-1; j++){ 21 | if(j != i){ 22 | l *= (Interpolation_x - x[j]) / (x[i] - x[j]); 23 | } 24 | } 25 | 26 | dl = 0; 27 | for(j = 0; j<= n-1; j++){ 28 | if(j != i){ 29 | dl += 1/(x[i] - x[j]); 30 | } 31 | } 32 | Interpolation_y += (1-2 * dl * (Interpolation_x - x[i])) * l * l * f[i] + (Interpolation_x - x[i])* l * l * df[i]; 33 | } 34 | printf("插值点(x, y)= (%lf, %lf)\n", Interpolation_x, Interpolation_y); 35 | 36 | return 0; 37 | } 38 | 39 | 40 | void input(double x[MAXSIZE], double f[MAXSIZE], double df[MAXSIZE], long n) 41 | { 42 | long i; 43 | for(i = 0; i <= n-1; i++) 44 | { 45 | printf("请输入插值节点x[%ld], 函数值f[%ld], 导数值df[%ld](请用,隔开):", i, i, i); 46 | scanf("%lf, %lf, %lf", &x[i], &f[i], &df[i]); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/04样条插值/01三次样条插值/01三次样条插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/04样条插值/01三次样条插值/01三次样条插值 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/04样条插值/01三次样条插值/01三次样条插值.c: -------------------------------------------------------------------------------- 1 | /******三次样条插值,边界条件为给定两个端点的一阶导数值*************/ 2 | #include 3 | #include 4 | #define N 4 5 | double zhuigan(double m[N+1],double b2[N-1],double a[N+1]) //返回数组m 6 | { 7 | int i,j; 8 | double A[N-1][N-1],L[N-1][N-1],U[N-1][N-1],a1[N-1],b1[N-2],y[N-1]; 9 | for(i=0;i=1&&j==i-1) 22 | { 23 | A[i][j]=1-a[i+1]; 24 | } 25 | else 26 | A[i][j]=0; 27 | } 28 | } 29 | for(i=0;i=1;i--) 102 | { 103 | m[i]=y[i-1]-U[i-1][i]*m[i+1]; 104 | } 105 | return 0; 106 | } 107 | double S(double x_,double x[],double y[],double m[]) 108 | { 109 | int i; 110 | double s; 111 | for(i=0;i=x[i]&&x_<=x[i+1]) 114 | break; 115 | else 116 | ; 117 | } 118 | s=(1+2*(x_-x[i])/(x[i+1]-x[i]))*pow(((x_-x[i+1])/(x[i]-x[i+1])),2)*y[i]+(1+2*(x_-x[i+1])/(x[i]-x[i+1]))*pow(((x_-x[i])/(x[i+1]-x[i])),2)*y[i+1]+(x_-x[i])*pow(((x_-x[i+1])/(x[i]-x[i+1])),2)*m[i]+(x_-x[i+1])*pow(((x_-x[i])/(x[i+1]-x[i])),2)*m[i+1]; 119 | return s; 120 | 121 | } 122 | void main() 123 | { 124 | int i; 125 | double x[N+1],y[N+1],a[N+1],b[N+1],m[N+1],h[N],b2[N-1],s,x_; 126 | m[0]=2.125;m[N]=-2.375; 127 | printf("请输入插值点及其对应的函数值"); //可进行交互输入 128 | for(i=0;i 8 | #include 9 | #include 10 | 11 | double *spline(double *x, double *y, int n, double *xs, int m) { 12 | double *a = (double *) malloc(sizeof(double) * (n+1)); 13 | double *b = (double *) malloc(sizeof(double) * (n+1)); 14 | double *c = (double *) malloc(sizeof(double) * (n+1)); 15 | double *d = (double *) malloc(sizeof(double) * (n+1)); 16 | double *h = (double *) malloc(sizeof(double) * (n+1)); 17 | double *alpha = (double *) malloc(sizeof(double) * (n+1)); 18 | double *l = (double *) malloc(sizeof(double) * (n+1)); 19 | double *mu = (double *) malloc(sizeof(double) * (n+1)); 20 | double *z = (double *) malloc(sizeof(double) * (n+1)); 21 | double *ys = (double *) malloc(sizeof(double) * m); 22 | for (int i = 1; i <= n; i++) { 23 | h[i] = x[i] - x[i-1]; 24 | alpha[i] = 3.0 / h[i] * (y[i] - y[i-1]) - 3.0 / h[i-1] * (y[i-1] - y[i-2]); 25 | } 26 | l[1] = 1.0; 27 | mu[1] = 0.0; 28 | z[1] = 0.0; 29 | for (int i = 2; i <= n-1; i++) { 30 | l[i] = 2.0 * (x[i+1] - x[i-1]) - h[i-1] * mu[i-1]; 31 | mu[i] = h[i] / l[i]; 32 | z[i] = (alpha[i] - h[i-1] * z[i-1]) / l[i]; 33 | } 34 | l[n] = 1.0; 35 | z[n] = 0.0; 36 | c[n] = 0.0; 37 | for (int j = n-1; j >= 1; j--) { 38 | c[j] = z[j] - mu[j] * c[j+1]; 39 | b[j] = (y[j+1] - y[j]) / h[j] - h[j] * (c[j+1] + 2.0 * c[j]) / 3.0; 40 | d[j] = (c[j+1] - c[j]) / (3.0 * h[j]); 41 | a[j] = y[j]; 42 | } 43 | for (int i = 0; i < m; i++) { 44 | int k = 1; 45 | while (xs[i] > x[k]) { 46 | k++; 47 | } 48 | double t = (xs[i] - x[k-1]) / h[k]; 49 | ys[i] = a[k] + b[k] * t + c[k] * t * t + d[k] * t * t * t; 50 | } 51 | free(a); 52 | free(b); 53 | free(c); 54 | free(d); 55 | free(h); 56 | free(alpha); 57 | free(l); 58 | free(mu); 59 | free(z); 60 | return ys; 61 | } 62 | 63 | int main() { 64 | int n, m; 65 | printf("请输入插值节点个数:"); 66 | scanf("%d", &n); 67 | double *x = (double *) malloc(sizeof(double) * (n+1)); 68 | double *y = (double *) malloc(sizeof(double) * (n+1)); 69 | printf("请输入插值节点:\n"); 70 | for (int i = 1; i <= n; i++) { 71 | scanf("%lf %lf", &x[i], &y[i]); 72 | } 73 | 74 | printf("请输入待求节点个数:"); 75 | scanf("%d", &m); 76 | double *xs = (double *) malloc(sizeof(double) * m); 77 | printf("请输入待求节点:\n"); 78 | for (int i = 0; i < m; i++) { 79 | scanf("%lf", &xs[i]); 80 | } 81 | double *ys = spline(x, y, n, xs, m); 82 | printf("插值函数值为:\n"); 83 | for (int i = 0; i < m; i++) { 84 | printf("f(%f) = %f\n", xs[i], ys[i]); 85 | } 86 | free(x); 87 | free(y); 88 | free(xs); 89 | free(ys); 90 | return 0; 91 | } -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/04样条插值/02B样条插值/02B样条插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/04样条插值/02B样条插值/02B样条插值 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/04样条插值/02B样条插值/02B样条插值.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 编写程序,对函数f(x)=cos(πx) 在区间 [−1,1] 做三次样条插值,边界条件取周期边界条件,对于给定的待求节点 xs 求出其插值函数值 ys 。 3 | * 设定等分区间为 32 个。 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define N 32 // 等分区间数 11 | #define PI 3.14159265358979323846 12 | 13 | double f(double x) { 14 | return cos(PI * x); 15 | } 16 | 17 | double spline(double x, double *a, double *b, double *c, double *d) { 18 | int k = (int) ((x + 1.0) * N / 2.0); // 计算所在区间 19 | double dx = 2.0 / N; 20 | double t = (x - (-1.0 + k * dx)) / dx; // 归一化 21 | double y = a[k] + b[k] * t + c[k] * t * t + d[k] * t * t * t; // 计算插值函数值 22 | return y; 23 | } 24 | 25 | int main() { 26 | double a[N+1], b[N+1], c[N+1], d[N+1]; 27 | double h = 2.0 / N; 28 | double x[N+1]; 29 | for (int i = 0; i <= N; i++) { 30 | x[i] = -1.0 + i * h; 31 | a[i] = f(x[i]); 32 | } 33 | c[0] = c[N] = 0.0; // 周期边界条件 34 | for (int i = 1; i < N; i++) { 35 | double hi = x[i] - x[i-1]; 36 | double hi1 = x[i+1] - x[i]; 37 | double A = hi; 38 | double B = hi1; 39 | double C = 2.0 * (hi + hi1); 40 | double F = 6.0 * ((a[i+1] - a[i]) / hi1 - (a[i] - a[i-1]) / hi); 41 | double z = (A * c[i-1] + C + B * c[i+1]) / B; 42 | c[i] = -A / z; 43 | d[i] = (F - A * d[i-1]) / z; 44 | } 45 | for (int i = N-1; i >= 0; i--) { 46 | c[i] = c[i] * c[i+1] + d[i]; 47 | } 48 | double xs = 0.333333; // 待求节点 49 | double ys = spline(xs, a, b, c, d); 50 | printf("f(%f) = %f\n", xs, ys); 51 | return 0; 52 | } -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/04样条插值/02三次样条插值/01参考案例/01不等距三次样条插值/不等距3次样条插值: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/04函数逼近的插值法与曲线拟合/04样条插值/02三次样条插值/01参考案例/01不等距三次样条插值/不等距3次样条插值 -------------------------------------------------------------------------------- /04函数逼近的插值法与曲线拟合/04样条插值/02三次样条插值/01参考案例/01不等距三次样条插值/不等距3次样条插值.c: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | *************CUBIC SPLINE PROGRAM***************** 3 | ************************************************* 4 | The program asks the user to enter the data-points and then returns the cubic splines equations 5 | for each interval 6 | Equation for ith interval being: 7 | ai(x-xi)^3+bi(x-xi)^2+ci(x-xi)+di*/ 8 | #include 9 | #include 10 | /******* 11 | Function that performs Gauss-Elimination and returns the Upper triangular matrix and solution of equations: 12 | There are two options to do this in C. 13 | 1. Pass the augmented matrix (a) as the parameter, and calculate and store the upperTriangular(Gauss-Eliminated Matrix) in it. 14 | 2. Use malloc and make the function of pointer type and return the pointer. 15 | This program uses the first option. 16 | ********/ 17 | void gaussEliminationLS(int m, int n, double a[m][n], double x[n-1]){ 18 | int i,j,k; 19 | for(i=0;i=0;i--){ 44 | x[i]=a[i][n-1]; 45 | for(j=i+1;j 5 | #include 6 | /******* 7 | Function that performs Gauss-Elimination and returns the Upper triangular matrix and solution of equations: 8 | There are two options to do this in C. 9 | 1. Pass the augmented matrix (a) as the parameter, and calculate and store the upperTriangular(Gauss-Eliminated Matrix) in it. 10 | 2. Use malloc and make the function of pointer type and return the pointer. 11 | This program uses the first option. 12 | ********/ 13 | void gaussEliminationLS(int m, int n, double a[m][n], double x[n-1]){ 14 | int i,j,k; 15 | for(i=0;i=0;i--){ 40 | x[i]=a[i][n-1]; 41 | for(j=i+1;j 6 | 7 | int main() { 8 | /** Step 0 9 | * 输入程序运行所需的初始值 10 | * */ 11 | long n, i, j; 12 | printf("请输入区间个数: "); 13 | scanf("%ld", &n); 14 | n++; 15 | double x[n], a[n], h[n-1], A[n-1], l[n], u[n], z[n], c[n], b[n-1], d[n-1]; 16 | // x[] 存放插值节点坐标 17 | // a[] 存放插值节点对应的函数值 18 | // h[] 存放分割成小区间后的区间长度 19 | // A[] 20 | // l[] 21 | // u[] 22 | // z[] 23 | // c[] 24 | // b[] 25 | // d[] 26 | for (i = 0; i < n; i++) { 27 | printf("输入插值节点是值x_%ld: ", i); 28 | scanf("%lf", &x[i]); 29 | } 30 | // 输入x_i 对应的 函数值 f(x_i) 31 | for (i = 0; i < n; i++) { 32 | printf("请输入节点x_%ld的函数值f(x_%ld)", i, i); 33 | scanf("%lf", &a[i]); 34 | } 35 | 36 | /** Step 1 37 | * 初始化 h[i] 38 | * */ 39 | for (i = 0; i < n ; i++) { 40 | h[i] = x[i + 1] - x[i]; 41 | } 42 | 43 | /** Step 2 44 | * 计算 α_i = \frac{3}{h_i}(a_{i+1} - a_{i}) - \frac{3}{h_{i-1}}(a_{i} - a_{i-1}) 45 | */ 46 | for (i = 1; i = 0; j--) { 70 | c[j] = z[j] - u[j] * c[j+1]; 71 | b[j] = (a[j+1] - a[j]) / h[j] - h[j] * (c[j+1] + 2*c[j]) / 3; 72 | d[j] = (c[j+1] - c[j]) / (3*h[j]); 73 | } 74 | 75 | /** Step 7 76 | * 输出结果 77 | */ 78 | printf("%2s %8s %8s %8s %8s\n", "i", "ai", "bi", "ci", "di"); 79 | for (i = 0; i < n; i++) 80 | printf("%2d %8.2f %8.2f %8.2f %8.2f\n", i, a[i], b[i], c[i], d[i]); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /05数值微分/01差商型数值微分/01向前差商公式/01向前差商公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/05数值微分/01差商型数值微分/01向前差商公式/01向前差商公式 -------------------------------------------------------------------------------- /05数值微分/01差商型数值微分/01向前差商公式/01向前差商公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point{ 5 | double x; 6 | double y; 7 | }; 8 | 9 | double ForwardDifference(struct Point *p, int n, double x){ 10 | double result = 0; 11 | long forward_point, next_point, current_point; 12 | forward_point = next_point = current_point = 0; 13 | 14 | for(int i = 0; i = p[i].x){ 21 | forward_point = i; 22 | } 23 | } 24 | } 25 | 26 | for (int i = 0; i < n; i++) { 27 | if (p[i].x == x) { 28 | current_point = i; 29 | } 30 | } 31 | 32 | for(int i = 0; i x){ 34 | if(p[i].x > x && p[next_point].x >= p[i].x){ 35 | next_point = i; 36 | } 37 | }else{ 38 | if(p[i].x > x && p[next_point].x <= p[i].x){ 39 | next_point = i; 40 | } 41 | } 42 | } 43 | 44 | printf("forward_point = %ld, current_point = %ld, next_point = %ld\n", forward_point, current_point, next_point); 45 | double h = p[next_point].x - p[current_point].x; 46 | result = (p[next_point].y - p[current_point].y) / h; 47 | return result; 48 | } 49 | 50 | void input(struct Point *p, int n){ 51 | for(int i = 0; i < n; i++){ 52 | printf("请输入第%d个插值点的x和y坐标(使用' '隔开):", i + 1); 53 | scanf("%lf %lf", &p[i].x, &p[i].y); 54 | } 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | printf("请输入插值点的个数:"); 60 | long n; 61 | scanf("%ld", &n); 62 | struct Point p[n]; 63 | input(p, n); 64 | printf("请输入待求的差商的x坐标:"); 65 | double x; 66 | scanf("%lf", &x); 67 | printf("插值点处的差商为:%lf\n", ForwardDifference(p, n, x)); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /05数值微分/01差商型数值微分/02向后差商公式/02向后差商公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/05数值微分/01差商型数值微分/02向后差商公式/02向后差商公式 -------------------------------------------------------------------------------- /05数值微分/01差商型数值微分/02向后差商公式/02向后差商公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point{ 5 | double x; 6 | double y; 7 | }; 8 | 9 | double BackwardDifference(struct Point *p, int n, double x){ 10 | double result = 0; 11 | long forward_point, next_point, current_point; 12 | forward_point = next_point = current_point = 0; 13 | 14 | for(int i = 0; i = p[i].x){ 21 | forward_point = i; 22 | } 23 | } 24 | } 25 | 26 | for (int i = 0; i < n; i++) { 27 | if (p[i].x == x) { 28 | current_point = i; 29 | } 30 | } 31 | 32 | for(int i = 0; i x){ 34 | if(p[i].x > x && p[next_point].x >= p[i].x){ 35 | next_point = i; 36 | } 37 | }else{ 38 | if(p[i].x > x && p[next_point].x <= p[i].x){ 39 | next_point = i; 40 | } 41 | } 42 | } 43 | 44 | printf("forward_point = %ld, current_point = %ld, next_point = %ld\n", forward_point, current_point, next_point); 45 | double h = p[current_point].x - p[forward_point].x; 46 | result = (p[current_point].y - p[forward_point].y) / h; 47 | return result; 48 | } 49 | 50 | void input(struct Point *p, int n){ 51 | for(int i = 0; i < n; i++){ 52 | printf("请输入第%d个插值点的x和y坐标(使用' '隔开):", i + 1); 53 | scanf("%lf %lf", &p[i].x, &p[i].y); 54 | } 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | printf("请输入插值点的个数:"); 60 | long n; 61 | scanf("%ld", &n); 62 | struct Point p[n]; 63 | input(p, n); 64 | printf("请输入待求的差商的x坐标:"); 65 | double x; 66 | scanf("%lf", &x); 67 | printf("插值点处的差商为:%lf\n", BAckwardDifference(p, n, x)); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /05数值微分/01差商型数值微分/03中心差商公式/03中心差商公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/05数值微分/01差商型数值微分/03中心差商公式/03中心差商公式 -------------------------------------------------------------------------------- /05数值微分/01差商型数值微分/03中心差商公式/03中心差商公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point{ 5 | double x; 6 | double y; 7 | }; 8 | 9 | double CentralDifference(struct Point *p, int n, double x){ 10 | double result = 0; 11 | long forward_point, next_point, current_point; 12 | forward_point = next_point = current_point = 0; 13 | 14 | for(int i = 0; i = p[i].x){ 21 | forward_point = i; 22 | } 23 | } 24 | } 25 | 26 | for (int i = 0; i < n; i++) { 27 | if (p[i].x == x) { 28 | current_point = i; 29 | } 30 | } 31 | 32 | for(int i = 0; i x){ 34 | if(p[i].x > x && p[next_point].x >= p[i].x){ 35 | next_point = i; 36 | } 37 | }else{ 38 | if(p[i].x > x && p[next_point].x <= p[i].x){ 39 | next_point = i; 40 | } 41 | } 42 | } 43 | 44 | printf("forward_point = %ld, current_point = %ld, next_point = %ld\n", forward_point, current_point, next_point); 45 | double h = p[next_point].x - p[forward_point].x; 46 | result = (p[next_point].y - p[forward_point].y) / h; 47 | return result; 48 | } 49 | 50 | void input(struct Point *p, int n){ 51 | for(int i = 0; i < n; i++){ 52 | printf("请输入第%d个插值点的x和y坐标(使用' '隔开):", i + 1); 53 | scanf("%lf %lf", &p[i].x, &p[i].y); 54 | } 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | printf("请输入插值点的个数:"); 60 | long n; 61 | scanf("%ld", &n); 62 | struct Point p[n]; 63 | input(p, n); 64 | printf("请输入待求的差商的x坐标:"); 65 | double x; 66 | scanf("%lf", &x); 67 | printf("插值点处的差商为:%lf\n", CentralDifference(p, n, x)); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /05数值微分/02插值型数值微分/01两点数值微分/01两点数值微分: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/05数值微分/02插值型数值微分/01两点数值微分/01两点数值微分 -------------------------------------------------------------------------------- /05数值微分/02插值型数值微分/01两点数值微分/01两点数值微分.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double f(double x) 4 | { 5 | return x * x; 6 | } 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | double x1, x2; 11 | printf("此算法是用两点数值微分法求函数f(x)在某点处的导数值\n"); 12 | printf("请输入x1的值:"); 13 | scanf("%lf", &x1); 14 | printf("请输入x2的值:"); 15 | scanf("%lf", &x2); 16 | double h = x2 - x1; 17 | printf("函数f(x)在x1处的导数值为:%lf\n", (f(x2) - f(x1)) / h); 18 | printf("函数f(x)在x2处的导数值为:%lf\n", (f(x2) - f(x1)) / h); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /05数值微分/02插值型数值微分/02三点数值微分/02三点数值微分: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/05数值微分/02插值型数值微分/02三点数值微分/02三点数值微分 -------------------------------------------------------------------------------- /05数值微分/02插值型数值微分/02三点数值微分/02三点数值微分.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | double f(double x) 4 | { 5 | return x * x; 6 | } 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | printf("此程序利用3等距节点计算函数f(x)在某点处的导数\n"); 11 | double x[3], h; 12 | printf("请输入3个点的x坐标(中间用' '隔开):"); 13 | scanf("%lf %lf %lf", &x[0], &x[1], &x[2]); 14 | //3个数排序 15 | double tmp; 16 | for(int i = 0; i < 3; i++) 17 | { 18 | for(int j = i; j < 3; j++) 19 | { 20 | if(x[i] > x[j]) 21 | { 22 | tmp = x[i]; 23 | x[i] = x[j]; 24 | x[j] = tmp; 25 | } 26 | } 27 | } 28 | if(fabs(x[1]-x[0]) == fabs(x[2]-x[1])) 29 | { 30 | h = fabs(x[1]-x[0]); 31 | }else{ 32 | printf("输入的3个点不是等距节点,请重新输入\n"); 33 | return 0; 34 | } 35 | printf("第1个点处 %lf 的导数值为: %lf \n", x[0], ((-3)*f(x[0]) + 4*f(x[1]) + (-1)*f(x[2]))/(2 * h) ); 36 | printf("第2个点处 %lf 的导数值为: %lf \n", x[1], ((-1)*f(x[0]) + 1*f(x[2]))/(2 * h) ); 37 | printf("第3个点处 %lf 的导数值为: %lf \n", x[2], (f(x[0]) + (-4)*f(x[1]) + (3)*f(x[2]))/(2 * h) ); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /05数值微分/02插值型数值微分/03二阶数值微分/03二阶数值微分: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/05数值微分/02插值型数值微分/03二阶数值微分/03二阶数值微分 -------------------------------------------------------------------------------- /05数值微分/02插值型数值微分/03二阶数值微分/03二阶数值微分.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | double f(double x) 4 | { 5 | return x*x; 6 | } 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | printf("此算法利用3等距节点计算函数f(x)在某点处的二阶导数\n"); 11 | double x[3], h; 12 | printf("请输入3个点的x坐标(中间用' '隔开):"); 13 | scanf("%lf %lf %lf", &x[0], &x[1], &x[2]); 14 | //3个数排序 15 | double tmp; 16 | for(int i = 0; i < 3; i++) 17 | { 18 | for(int j = i; j < 3; j++) 19 | { 20 | if(x[i] > x[j]) 21 | { 22 | tmp = x[i]; 23 | x[i] = x[j]; 24 | x[j] = tmp; 25 | } 26 | } 27 | } 28 | if(fabs(x[1]-x[0]) == fabs(x[2]-x[1])) 29 | { 30 | h = fabs(x[1]-x[0]); 31 | }else{ 32 | printf("输入的3个点不是等距节点,请重新输入\n"); 33 | return 0; 34 | } 35 | 36 | printf("二阶导数值f''(xi)=%lf (i=0,1,2)\n", (f(x[0]) - 2 * f(x[1]) + f(x[2])) / (h * h)); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /06数值微分/01差商型数值微分/01向前差商公式/01向前差商公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值微分/01差商型数值微分/01向前差商公式/01向前差商公式 -------------------------------------------------------------------------------- /06数值微分/01差商型数值微分/01向前差商公式/01向前差商公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point{ 5 | double x; 6 | double y; 7 | }; 8 | 9 | double ForwardDifference(struct Point *p, int n, double x){ 10 | double result = 0; 11 | long forward_point, next_point, current_point; 12 | forward_point = next_point = current_point = 0; 13 | 14 | for(int i = 0; i = p[i].x){ 21 | forward_point = i; 22 | } 23 | } 24 | } 25 | 26 | for (int i = 0; i < n; i++) { 27 | if (p[i].x == x) { 28 | current_point = i; 29 | } 30 | } 31 | 32 | for(int i = 0; i x){ 34 | if(p[i].x > x && p[next_point].x >= p[i].x){ 35 | next_point = i; 36 | } 37 | }else{ 38 | if(p[i].x > x && p[next_point].x <= p[i].x){ 39 | next_point = i; 40 | } 41 | } 42 | } 43 | 44 | printf("forward_point = %ld, current_point = %ld, next_point = %ld\n", forward_point, current_point, next_point); 45 | double h = p[next_point].x - p[current_point].x; 46 | result = (p[next_point].y - p[current_point].y) / h; 47 | return result; 48 | } 49 | 50 | void input(struct Point *p, int n){ 51 | for(int i = 0; i < n; i++){ 52 | printf("请输入第%d个插值点的x和y坐标(使用' '隔开):", i + 1); 53 | scanf("%lf %lf", &p[i].x, &p[i].y); 54 | } 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | printf("请输入插值点的个数:"); 60 | long n; 61 | scanf("%ld", &n); 62 | struct Point p[n]; 63 | input(p, n); 64 | printf("请输入待求的差商的x坐标:"); 65 | double x; 66 | scanf("%lf", &x); 67 | printf("插值点处的差商为:%lf\n", ForwardDifference(p, n, x)); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /06数值微分/01差商型数值微分/02向后差商公式/02向后差商公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值微分/01差商型数值微分/02向后差商公式/02向后差商公式 -------------------------------------------------------------------------------- /06数值微分/01差商型数值微分/02向后差商公式/02向后差商公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point{ 5 | double x; 6 | double y; 7 | }; 8 | 9 | double BackwardDifference(struct Point *p, int n, double x){ 10 | double result = 0; 11 | long forward_point, next_point, current_point; 12 | forward_point = next_point = current_point = 0; 13 | 14 | for(int i = 0; i = p[i].x){ 21 | forward_point = i; 22 | } 23 | } 24 | } 25 | 26 | for (int i = 0; i < n; i++) { 27 | if (p[i].x == x) { 28 | current_point = i; 29 | } 30 | } 31 | 32 | for(int i = 0; i x){ 34 | if(p[i].x > x && p[next_point].x >= p[i].x){ 35 | next_point = i; 36 | } 37 | }else{ 38 | if(p[i].x > x && p[next_point].x <= p[i].x){ 39 | next_point = i; 40 | } 41 | } 42 | } 43 | 44 | printf("forward_point = %ld, current_point = %ld, next_point = %ld\n", forward_point, current_point, next_point); 45 | double h = p[current_point].x - p[forward_point].x; 46 | result = (p[current_point].y - p[forward_point].y) / h; 47 | return result; 48 | } 49 | 50 | void input(struct Point *p, int n){ 51 | for(int i = 0; i < n; i++){ 52 | printf("请输入第%d个插值点的x和y坐标(使用' '隔开):", i + 1); 53 | scanf("%lf %lf", &p[i].x, &p[i].y); 54 | } 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | printf("请输入插值点的个数:"); 60 | long n; 61 | scanf("%ld", &n); 62 | struct Point p[n]; 63 | input(p, n); 64 | printf("请输入待求的差商的x坐标:"); 65 | double x; 66 | scanf("%lf", &x); 67 | printf("插值点处的差商为:%lf\n", BAckwardDifference(p, n, x)); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /06数值微分/01差商型数值微分/03中心差商公式/03中心差商公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值微分/01差商型数值微分/03中心差商公式/03中心差商公式 -------------------------------------------------------------------------------- /06数值微分/01差商型数值微分/03中心差商公式/03中心差商公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point{ 5 | double x; 6 | double y; 7 | }; 8 | 9 | double CentralDifference(struct Point *p, int n, double x){ 10 | double result = 0; 11 | long forward_point, next_point, current_point; 12 | forward_point = next_point = current_point = 0; 13 | 14 | for(int i = 0; i = p[i].x){ 21 | forward_point = i; 22 | } 23 | } 24 | } 25 | 26 | for (int i = 0; i < n; i++) { 27 | if (p[i].x == x) { 28 | current_point = i; 29 | } 30 | } 31 | 32 | for(int i = 0; i x){ 34 | if(p[i].x > x && p[next_point].x >= p[i].x){ 35 | next_point = i; 36 | } 37 | }else{ 38 | if(p[i].x > x && p[next_point].x <= p[i].x){ 39 | next_point = i; 40 | } 41 | } 42 | } 43 | 44 | printf("forward_point = %ld, current_point = %ld, next_point = %ld\n", forward_point, current_point, next_point); 45 | double h = p[next_point].x - p[forward_point].x; 46 | result = (p[next_point].y - p[forward_point].y) / h; 47 | return result; 48 | } 49 | 50 | void input(struct Point *p, int n){ 51 | for(int i = 0; i < n; i++){ 52 | printf("请输入第%d个插值点的x和y坐标(使用' '隔开):", i + 1); 53 | scanf("%lf %lf", &p[i].x, &p[i].y); 54 | } 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | printf("请输入插值点的个数:"); 60 | long n; 61 | scanf("%ld", &n); 62 | struct Point p[n]; 63 | input(p, n); 64 | printf("请输入待求的差商的x坐标:"); 65 | double x; 66 | scanf("%lf", &x); 67 | printf("插值点处的差商为:%lf\n", CentralDifference(p, n, x)); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /06数值微分/02插值型数值微分/01两点数值微分/01两点数值微分: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值微分/02插值型数值微分/01两点数值微分/01两点数值微分 -------------------------------------------------------------------------------- /06数值微分/02插值型数值微分/01两点数值微分/01两点数值微分.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double f(double x) 4 | { 5 | return x * x; 6 | } 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | double x1, x2; 11 | printf("此算法是用两点数值微分法求函数f(x)在某点处的导数值\n"); 12 | printf("请输入x1的值:"); 13 | scanf("%lf", &x1); 14 | printf("请输入x2的值:"); 15 | scanf("%lf", &x2); 16 | double h = x2 - x1; 17 | printf("函数f(x)在x1处的导数值为:%lf\n", (f(x2) - f(x1)) / h); 18 | printf("函数f(x)在x2处的导数值为:%lf\n", (f(x2) - f(x1)) / h); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /06数值微分/02插值型数值微分/02三点数值微分/02三点数值微分: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值微分/02插值型数值微分/02三点数值微分/02三点数值微分 -------------------------------------------------------------------------------- /06数值微分/02插值型数值微分/02三点数值微分/02三点数值微分.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | double f(double x) 4 | { 5 | return x * x; 6 | } 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | printf("此程序利用3等距节点计算函数f(x)在某点处的导数\n"); 11 | double x[3], h; 12 | printf("请输入3个点的x坐标(中间用' '隔开):"); 13 | scanf("%lf %lf %lf", &x[0], &x[1], &x[2]); 14 | //3个数排序 15 | double tmp; 16 | for(int i = 0; i < 3; i++) 17 | { 18 | for(int j = i; j < 3; j++) 19 | { 20 | if(x[i] > x[j]) 21 | { 22 | tmp = x[i]; 23 | x[i] = x[j]; 24 | x[j] = tmp; 25 | } 26 | } 27 | } 28 | if(fabs(x[1]-x[0]) == fabs(x[2]-x[1])) 29 | { 30 | h = fabs(x[1]-x[0]); 31 | }else{ 32 | printf("输入的3个点不是等距节点,请重新输入\n"); 33 | return 0; 34 | } 35 | printf("第1个点处 %lf 的导数值为: %lf \n", x[0], ((-3)*f(x[0]) + 4*f(x[1]) + (-1)*f(x[2]))/(2 * h) ); 36 | printf("第2个点处 %lf 的导数值为: %lf \n", x[1], ((-1)*f(x[0]) + 1*f(x[2]))/(2 * h) ); 37 | printf("第3个点处 %lf 的导数值为: %lf \n", x[2], (f(x[0]) + (-4)*f(x[1]) + (3)*f(x[2]))/(2 * h) ); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /06数值微分/02插值型数值微分/03二阶数值微分/03二阶数值微分: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值微分/02插值型数值微分/03二阶数值微分/03二阶数值微分 -------------------------------------------------------------------------------- /06数值微分/02插值型数值微分/03二阶数值微分/03二阶数值微分.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | double f(double x) 4 | { 5 | return x*x; 6 | } 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | printf("此算法利用3等距节点计算函数f(x)在某点处的二阶导数\n"); 11 | double x[3], h; 12 | printf("请输入3个点的x坐标(中间用' '隔开):"); 13 | scanf("%lf %lf %lf", &x[0], &x[1], &x[2]); 14 | //3个数排序 15 | double tmp; 16 | for(int i = 0; i < 3; i++) 17 | { 18 | for(int j = i; j < 3; j++) 19 | { 20 | if(x[i] > x[j]) 21 | { 22 | tmp = x[i]; 23 | x[i] = x[j]; 24 | x[j] = tmp; 25 | } 26 | } 27 | } 28 | if(fabs(x[1]-x[0]) == fabs(x[2]-x[1])) 29 | { 30 | h = fabs(x[1]-x[0]); 31 | }else{ 32 | printf("输入的3个点不是等距节点,请重新输入\n"); 33 | return 0; 34 | } 35 | 36 | printf("二阶导数值f''(xi)=%lf (i=0,1,2)\n", (f(x[0]) - 2 * f(x[1]) + f(x[2])) / (h * h)); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /06数值积分/01Newton-Cotes/01Newton-Cotes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值积分/01Newton-Cotes/01Newton-Cotes -------------------------------------------------------------------------------- /06数值积分/01Newton-Cotes/01Newton-Cotes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 7 3 | void input(double f[MAXSIZE+1], double a, double b, long n); 4 | int main(int argc, char *argv[]) 5 | { 6 | long c[MAXSIZE][MAXSIZE/2 +2] = {{2, 1}, 7 | {6, 1, 4}, 8 | {8, 1, 3}, 9 | {90, 7, 32, 12}, 10 | {288, 19, 75, 50}, 11 | {840, 41, 216, 27, 272}, 12 | {17280, 751, 3577, 1323, 2989}}; 13 | double a, b, f[MAXSIZE+1], integral; 14 | long n, i; 15 | printf("请输入积分区间边界a, b(用, 隔开): "); 16 | scanf("%lf, %lf", &a, &b); 17 | printf("请输入求积节点的个数(2~8): "); 18 | scanf("%ld", &n); 19 | if(n >8 || n <2){ 20 | printf("输入节点个数不在(2~8)的范围!!!\n"); 21 | return -1; 22 | } 23 | input(f, a, b, n); 24 | integral = 0; 25 | for(i = 0; i < n/2; i++){ 26 | integral += (f[i] + f[n-i-1]) * c[n-2][i+1]/c[n-2][0]; 27 | } 28 | if(n%2){ 29 | integral += f[n/2] * c[n-2][n/2+1]/c[n-2][0]; 30 | } 31 | integral *= b-a; 32 | printf("积分值 = %lf\n", integral); 33 | 34 | return 0; 35 | } 36 | 37 | 38 | void input(double f[MAXSIZE+1], double a, double b, long n) 39 | { 40 | long i; 41 | double h; 42 | h = (b-a)/(n-1); 43 | printf("请输入求积节点纵坐标:\n"); 44 | for (i = 0; i <= n-1; i++) { 45 | printf("x[%ld] = %lf, f[%ld]=", i, a+i*h, i); 46 | scanf("%lf", &f[i]); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /06数值积分/02复化求积公式/01复化梯形求积公式/01复化梯形求积公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值积分/02复化求积公式/01复化梯形求积公式/01复化梯形求积公式 -------------------------------------------------------------------------------- /06数值积分/02复化求积公式/01复化梯形求积公式/01复化梯形求积公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | 4 | void input(double f[MAXSIZE], double a, double h, long n); 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | double a, b, h, f[MAXSIZE], integral; 9 | long n, i; 10 | printf("请输入积分区间边界a, b: "); 11 | scanf("%lf, %lf", &a, &b); 12 | printf("请输入求积节点的个数: "); 13 | scanf("%ld", &n); 14 | h = (b-a)/(n-1); 15 | input(f, a, h, n); 16 | integral = (f[0] + f[n-1])/2; 17 | for (i =1; i < n-1; i++) { 18 | integral += f[i]; 19 | } 20 | integral *= h; 21 | printf("积分值=%lf\n", integral); 22 | 23 | return 0; 24 | } 25 | 26 | 27 | void input(double f[MAXSIZE], double a, double h, long n) 28 | { 29 | long i; 30 | printf("请输入求积节点的纵坐标:\n"); 31 | for (i = 0; i <= n-1; i++) { 32 | printf("x[%ld]=%lf, f[%ld]=", i, a+i*h, i); 33 | scanf("%lf", &f[i]); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /06数值积分/02复化求积公式/02复化辛普森求积公式/02复化辛普森求积公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值积分/02复化求积公式/02复化辛普森求积公式/02复化辛普森求积公式 -------------------------------------------------------------------------------- /06数值积分/02复化求积公式/02复化辛普森求积公式/02复化辛普森求积公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | void input(double f[MAXSIZE], double a, double h, long n); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, f[MAXSIZE], integral, s; 8 | long n, i; 9 | printf("请输入积分区间边界a, b(请用, 隔开): "); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入求积节点的个数: "); 12 | scanf("%ld", &n); 13 | h = (b-a)/(n-1); 14 | input(f, a, h, n); 15 | integral = f[0] + f[n-1]; 16 | s = 0; 17 | for (i = 2; i < n-1; i += 2) { 18 | s += f[i]; 19 | } 20 | integral += s*2; 21 | s = 0; 22 | for (i = 1; i < n-1; i += 2) { 23 | s += f[i]; 24 | } 25 | integral += s * 4; 26 | integral *= h/3; 27 | printf("积分值=%lf\n", integral); 28 | 29 | return 0; 30 | } 31 | 32 | 33 | void input(double f[MAXSIZE], double a, double h, long n) 34 | { 35 | long i; 36 | printf("请输入求积节点的纵坐标:\n"); 37 | for (i = 0; i <= n; i++) { 38 | printf("x[%ld] = %lf, f[%ld]=",i, a+i*h, i); 39 | scanf("%lf", &f[i]); 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /06数值积分/02复化求积公式/03复化柯特斯求积公式/03复化柯特斯求积公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值积分/02复化求积公式/03复化柯特斯求积公式/03复化柯特斯求积公式 -------------------------------------------------------------------------------- /06数值积分/02复化求积公式/03复化柯特斯求积公式/03复化柯特斯求积公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | void input(double f[MAXSIZE], double a, double h, long n); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, f[MAXSIZE], integral, s, s1, s2; 8 | long n, i; 9 | printf("请输入积分区间边界a, b(请用, 分割): "); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入求积节点的个数: "); 12 | scanf("%ld", &n); 13 | h = (b-a)/(n-1); 14 | input(f, a, h, n); 15 | s = s1 = s2 = 0; 16 | for(i =4; i < n-1; i += 4){ 17 | s += f[i]; 18 | } 19 | for (i = 0; i < n-1; i += 4) { 20 | s1 += f[i+1] + f[i+3]; 21 | s2 += f[i+2]; 22 | } 23 | integral = 7 * (f[0] + f[n-1]) + 14 * s + 32 * s1 + 12 * s2; 24 | integral *= 1 * h/45; 25 | printf("积分值 = %lf\n", integral); 26 | 27 | return 0; 28 | } 29 | 30 | 31 | void input(double f[MAXSIZE], double a, double h, long n) 32 | { 33 | long i; 34 | printf("请输入求积节点的纵坐标: "); 35 | for (i = 0; i <= n-1; i++) { 36 | printf("x[%ld]=%lf, f[%ld]=", i, a+i*h, i); 37 | scanf("%lf", &f[i]); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /06数值积分/04龙贝格求积(Romberg)/龙贝格求积: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/06数值积分/04龙贝格求积(Romberg)/龙贝格求积 -------------------------------------------------------------------------------- /06数值积分/04龙贝格求积(Romberg)/龙贝格求积.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | double f(double x); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double x, a, b, h, s, epsilon, r[MAXSIZE][MAXSIZE]; 10 | long n, i, j, m; 11 | printf("请输入积分区间边界a, b(请用, 隔开): "); 12 | scanf("%lf, %lf", &a, &b); 13 | printf("请输入精度要求: "); 14 | scanf("%lf", &epsilon); 15 | h = (b-a)/2; 16 | n=1; 17 | r[0][0] = h * (f(a) + f(b)); 18 | for (i = 1; i <= MAXSIZE - 1; i++) { 19 | s = 0; 20 | for (j = 0; j <= n-1; j++) { 21 | x = a + h * (2 * j + 1); 22 | s += f(x); 23 | } 24 | r[i][0] = r[i-1][0]/2 + h*s; 25 | n *= 2; 26 | h /= 2; 27 | 28 | m = 1; 29 | for(j=1; j<=i; j++){ 30 | m *= 4; 31 | r[i-j][j] = r[i-j+1][j-1] + (r[i-j+1][j-1] - r[i-j][j-1])/(m-1); 32 | } 33 | if(fabs(r[0][i] - r[0][i-1]) <= epsilon){ 34 | break; 35 | } 36 | } 37 | 38 | if (i <= MAXSIZE -1) { 39 | printf("积分值=%lf\n", r[0][i]); 40 | }else{ 41 | printf("迭代次数已经超过上限!!!\n"); 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | 48 | double f(double x) 49 | { 50 | return x*x; 51 | } -------------------------------------------------------------------------------- /07常微分方程数值解法/01显式欧拉方法/01显式欧拉方法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07常微分方程数值解法/01显式欧拉方法/01显式欧拉方法 -------------------------------------------------------------------------------- /07常微分方程数值解法/01显式欧拉方法/01显式欧拉方法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | double f(double x, double y); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, x[MAXSIZE], y[MAXSIZE]; 8 | long i, n; 9 | printf("请输入求解区间a, b(中间用英文, 隔开): "); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入步长 h: "); 12 | scanf("%lf", &h); 13 | n = (long)((b-a)/h); 14 | x[0] = a; 15 | printf("请输入起点 x[0] = %lf 处的纵坐标 y[0]: ", x[0]); 16 | scanf("%lf", &y[0]); 17 | for (i = 0; i < n; i++) { 18 | x[i+1] = x[i] + h; 19 | y[i+1] = y[i] + h * f(x[i], y[i]); 20 | } 21 | printf("计算结果为: \n"); 22 | for (i = 0; i <= n; i++) { 23 | printf("x[%ld]=%lf, y[%ld]=%lf\n",i, x[i], i, y[i]); 24 | } 25 | 26 | return 0; 27 | } 28 | 29 | 30 | double f(double x, double y) 31 | { 32 | return -y + x +1; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /07常微分方程数值解法/02改进的欧拉方法/02改进的欧拉方法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07常微分方程数值解法/02改进的欧拉方法/02改进的欧拉方法 -------------------------------------------------------------------------------- /07常微分方程数值解法/02改进的欧拉方法/02改进的欧拉方法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | double f(double x, double y); 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | double a, b, h, x[MAXSIZE], y[MAXSIZE]; 9 | long i, n; 10 | printf("请输入求解区间a, b(中间用英文, 隔开): "); 11 | scanf("%lf, %lf", &a, &b); 12 | printf("请输入步长h: "); 13 | scanf("%lf", &h); 14 | n = (long)((b-a)/h); 15 | x[0] = a; 16 | printf("请输入起点x[0]=%lf处的纵坐标y[0]: ", x[0]); 17 | scanf("%lf", &y[0]); 18 | for (i = 0; i < n; i++) { 19 | x[i+1] = x[i] + h; 20 | // 预测 21 | y[i+1] = y[i] + h*f(x[i], y[i]); 22 | // 校正 23 | y[i+1] = y[i] + h*(f(x[i], y[i]) + f(x[i+1], y[i+1]))/2; 24 | } 25 | printf("计算结果为: \n"); 26 | for (i = 0; i <= n; i++) { 27 | printf("x[%ld]=%lf, y[%ld]=%lf\n", i,x[i], i, y[i]); 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | 34 | double f(double x, double y) 35 | { 36 | return y - (2 * x)/(y); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /07常微分方程数值解法/03龙格-库塔法/03龙格-库塔法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07常微分方程数值解法/03龙格-库塔法/03龙格-库塔法 -------------------------------------------------------------------------------- /07常微分方程数值解法/03龙格-库塔法/03龙格-库塔法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | double f(double x, double y); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, k1, k2, k3, k4, x[MAXSIZE], y[MAXSIZE]; 8 | long i, n; 9 | printf("请输入求解区间a, b(请用英文, 隔开) :"); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入步长h: "); 12 | scanf("%lf", &h); 13 | n = (long)((b-a)/h); 14 | x[0] = a; 15 | printf("请输入起点 x[0]=%lf处的纵坐标y[0]: ", x[0]); 16 | scanf("%lf", &y[0]); 17 | for (i = 0; i < n; i++) { 18 | x[i+1] = x[i] + h; 19 | k1 = f(x[i], y[i]); 20 | k2 = f(x[i]+h/2, y[i] + k1 * h/2); 21 | k3 = f(x[i]+h/2, y[i] + k2 * h/2); 22 | k4 = f(x[i]+h, y[i] + k3*h); 23 | y[i+1] = y[i] + h * (k1 + 2*k2 + 2*k3 + k4)/6; 24 | } 25 | printf("计算结果为: \n"); 26 | for (i = 0; i <= n; i++) { 27 | printf("x[%ld]=%lf, y[%ld]=%lf\n", i, x[i], i, y[i]); 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | 34 | double f(double x, double y) 35 | { 36 | return y - 2*x /y; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /07数值积分/01Newton-Cotes/01Newton-Cotes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07数值积分/01Newton-Cotes/01Newton-Cotes -------------------------------------------------------------------------------- /07数值积分/01Newton-Cotes/01Newton-Cotes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 7 3 | void input(double f[MAXSIZE+1], double a, double b, long n); 4 | int main(int argc, char *argv[]) 5 | { 6 | long c[MAXSIZE][MAXSIZE/2 +2] = {{2, 1}, 7 | {6, 1, 4}, 8 | {8, 1, 3}, 9 | {90, 7, 32, 12}, 10 | {288, 19, 75, 50}, 11 | {840, 41, 216, 27, 272}, 12 | {17280, 751, 3577, 1323, 2989}}; 13 | double a, b, f[MAXSIZE+1], integral; 14 | long n, i; 15 | printf("请输入积分区间边界a, b(用, 隔开): "); 16 | scanf("%lf, %lf", &a, &b); 17 | printf("请输入求积节点的个数(2~8): "); 18 | scanf("%ld", &n); 19 | if(n >8 || n <2){ 20 | printf("输入节点个数不在(2~8)的范围!!!\n"); 21 | return -1; 22 | } 23 | input(f, a, b, n); 24 | integral = 0; 25 | for(i = 0; i < n/2; i++){ 26 | integral += (f[i] + f[n-i-1]) * c[n-2][i+1]/c[n-2][0]; 27 | } 28 | if(n%2){ 29 | integral += f[n/2] * c[n-2][n/2+1]/c[n-2][0]; 30 | } 31 | integral *= b-a; 32 | printf("积分值 = %lf\n", integral); 33 | 34 | return 0; 35 | } 36 | 37 | 38 | void input(double f[MAXSIZE+1], double a, double b, long n) 39 | { 40 | long i; 41 | double h; 42 | h = (b-a)/(n-1); 43 | printf("请输入求积节点纵坐标:\n"); 44 | for (i = 0; i <= n-1; i++) { 45 | printf("x[%ld] = %lf, f[%ld]=", i, a+i*h, i); 46 | scanf("%lf", &f[i]); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /07数值积分/02复化求积公式/01复化梯形求积公式/01复化梯形求积公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07数值积分/02复化求积公式/01复化梯形求积公式/01复化梯形求积公式 -------------------------------------------------------------------------------- /07数值积分/02复化求积公式/01复化梯形求积公式/01复化梯形求积公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | 4 | void input(double f[MAXSIZE], double a, double h, long n); 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | double a, b, h, f[MAXSIZE], integral; 9 | long n, i; 10 | printf("请输入积分区间边界a, b: "); 11 | scanf("%lf, %lf", &a, &b); 12 | printf("请输入求积节点的个数: "); 13 | scanf("%ld", &n); 14 | h = (b-a)/(n-1); 15 | input(f, a, h, n); 16 | integral = (f[0] + f[n-1])/2; 17 | for (i =1; i < n-1; i++) { 18 | integral += f[i]; 19 | } 20 | integral *= h; 21 | printf("积分值=%lf\n", integral); 22 | 23 | return 0; 24 | } 25 | 26 | 27 | void input(double f[MAXSIZE], double a, double h, long n) 28 | { 29 | long i; 30 | printf("请输入求积节点的纵坐标:\n"); 31 | for (i = 0; i <= n-1; i++) { 32 | printf("x[%ld]=%lf, f[%ld]=", i, a+i*h, i); 33 | scanf("%lf", &f[i]); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /07数值积分/02复化求积公式/02复化辛普森求积公式/02复化辛普森求积公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07数值积分/02复化求积公式/02复化辛普森求积公式/02复化辛普森求积公式 -------------------------------------------------------------------------------- /07数值积分/02复化求积公式/02复化辛普森求积公式/02复化辛普森求积公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | void input(double f[MAXSIZE], double a, double h, long n); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, f[MAXSIZE], integral, s; 8 | long n, i; 9 | printf("请输入积分区间边界a, b(请用, 隔开): "); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入求积节点的个数: "); 12 | scanf("%ld", &n); 13 | h = (b-a)/(n-1); 14 | input(f, a, h, n); 15 | integral = f[0] + f[n-1]; 16 | s = 0; 17 | for (i = 2; i < n-1; i += 2) { 18 | s += f[i]; 19 | } 20 | integral += s*2; 21 | s = 0; 22 | for (i = 1; i < n-1; i += 2) { 23 | s += f[i]; 24 | } 25 | integral += s * 4; 26 | integral *= h/3; 27 | printf("积分值=%lf\n", integral); 28 | 29 | return 0; 30 | } 31 | 32 | 33 | void input(double f[MAXSIZE], double a, double h, long n) 34 | { 35 | long i; 36 | printf("请输入求积节点的纵坐标:\n"); 37 | for (i = 0; i <= n; i++) { 38 | printf("x[%ld] = %lf, f[%ld]=",i, a+i*h, i); 39 | scanf("%lf", &f[i]); 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /07数值积分/02复化求积公式/03复化柯特斯求积公式/03复化柯特斯求积公式: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07数值积分/02复化求积公式/03复化柯特斯求积公式/03复化柯特斯求积公式 -------------------------------------------------------------------------------- /07数值积分/02复化求积公式/03复化柯特斯求积公式/03复化柯特斯求积公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | void input(double f[MAXSIZE], double a, double h, long n); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, f[MAXSIZE], integral, s, s1, s2; 8 | long n, i; 9 | printf("请输入积分区间边界a, b(请用, 分割): "); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入求积节点的个数: "); 12 | scanf("%ld", &n); 13 | h = (b-a)/(n-1); 14 | input(f, a, h, n); 15 | s = s1 = s2 = 0; 16 | for(i =4; i < n-1; i += 4){ 17 | s += f[i]; 18 | } 19 | for (i = 0; i < n-1; i += 4) { 20 | s1 += f[i+1] + f[i+3]; 21 | s2 += f[i+2]; 22 | } 23 | integral = 7 * (f[0] + f[n-1]) + 14 * s + 32 * s1 + 12 * s2; 24 | integral *= 1 * h/45; 25 | printf("积分值 = %lf\n", integral); 26 | 27 | return 0; 28 | } 29 | 30 | 31 | void input(double f[MAXSIZE], double a, double h, long n) 32 | { 33 | long i; 34 | printf("请输入求积节点的纵坐标: "); 35 | for (i = 0; i <= n-1; i++) { 36 | printf("x[%ld]=%lf, f[%ld]=", i, a+i*h, i); 37 | scanf("%lf", &f[i]); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /07数值积分/03Gauss求积公式/Gauss-Legendre/Gauss-Legendre.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 这段代码实现了Gauss-Legendre求积公式。首先,它定义了一个名为gauss_legendre的函数,该函数接受两个参数(表示积分的下限和上限),并返回积分的值。然后,它使用一个循环来计算积分的值,其中每一项是权重乘以函数在相应点的值。最后,它将计算得到的积分值输出。注意,这里使用的是n=5的Gauss-Legendre权重和节点,你可以根据需要修改这些值。 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | // Gauss-Legendre weights and abscissas for n=5 9 | double w[5] = {0.2369268850, 0.4786286705, 0.5688888889, 0.4786286705, 0.2369268850}; 10 | double x[5] = {-0.9061798459, -0.5384693101, 0.0, 0.5384693101, 0.9061798459}; 11 | 12 | // Function to integrate 13 | double f(double x) { 14 | return x*x; // Change this to your function 15 | } 16 | 17 | // Gauss-Legendre Quadrature 18 | double gauss_legendre(double a, double b) { 19 | double sum = 0.0; 20 | for (int i = 0; i < 5; i++) { 21 | sum += w[i] * f((b-a)/2.0 * x[i] + (b+a)/2.0); 22 | } 23 | return sum * (b-a)/2.0; 24 | } 25 | 26 | int main() { 27 | double a, b; 28 | printf("Enter the lower limit of integration: "); 29 | scanf("%lf", &a); 30 | printf("Enter the upper limit of integration: "); 31 | scanf("%lf", &b); 32 | double result = gauss_legendre(a, b); 33 | printf("The integral is: %f\n", result); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /07数值积分/03Gauss求积公式/gauss求积公式.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void gaussQuadrature(int n, double x[], double w[]) { 4 | // 定义角频率 5 | double omega = 1.0 / (2.0 * n); 6 | // 初始化权重 7 | double w0 = 1.0, w1 = 1.0; 8 | // 计算主要循环 9 | for(int i = 1; i < n; i++) { 10 | // 计算当前节点的x值 11 | x[i] = cos((2.0 * i - 1.0) * omega); 12 | // 计算当前节点的权重 13 | w[i] = (2.0 / ((4.0 * i - 1.0) * (4.0 * i - 3.0))) * (w0 - w1); 14 | // 更新初始权重 15 | w0 = w1; 16 | w1 = w[i]; 17 | } 18 | // 对x值进行归一化处理 19 | double sum = 0.0; 20 | for(int i = 0; i < n; i++) { 21 | sum += x[i] * x[i]; 22 | } 23 | double normalize = sqrt(1.0 / (4.0 * n * sum)); 24 | // 对x值和权重进行归一化处理 25 | for(int i = 0; i < n; i++) { 26 | x[i] *= normalize; 27 | w[i] *= normalize; 28 | } 29 | } 30 | 31 | int main() { 32 | // 指定求积公式节点数 33 | int n = 4; 34 | // 用于存储节点的x值和权重 35 | double x[n], w[n]; 36 | // 调用求积函数 37 | gaussQuadrature(n, x, w); 38 | // 打印结果 39 | printf("Gauss型求积公式的节点x值:"); 40 | for(int i = 0; i < n; i++) { 41 | printf("%f ", x[i]); 42 | } 43 | printf("\n节点x值对应的权重:"); 44 | for(int i = 0; i < n; i++) { 45 | printf("%f ", w[i]); 46 | } 47 | return 0; 48 | } -------------------------------------------------------------------------------- /07数值积分/04龙贝格求积(Romberg)/龙贝格求积: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/07数值积分/04龙贝格求积(Romberg)/龙贝格求积 -------------------------------------------------------------------------------- /07数值积分/04龙贝格求积(Romberg)/龙贝格求积.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | 5 | double f(double x); 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | double x, a, b, h, s, epsilon, r[MAXSIZE][MAXSIZE]; 10 | long n, i, j, m; 11 | printf("请输入积分区间边界a, b(请用, 隔开): "); 12 | scanf("%lf, %lf", &a, &b); 13 | printf("请输入精度要求: "); 14 | scanf("%lf", &epsilon); 15 | h = (b-a)/2; 16 | n=1; 17 | r[0][0] = h * (f(a) + f(b)); 18 | for (i = 1; i <= MAXSIZE - 1; i++) { 19 | s = 0; 20 | for (j = 0; j <= n-1; j++) { 21 | x = a + h * (2 * j + 1); 22 | s += f(x); 23 | } 24 | r[i][0] = r[i-1][0]/2 + h*s; 25 | n *= 2; 26 | h /= 2; 27 | 28 | m = 1; 29 | for(j=1; j<=i; j++){ 30 | m *= 4; 31 | r[i-j][j] = r[i-j+1][j-1] + (r[i-j+1][j-1] - r[i-j][j-1])/(m-1); 32 | } 33 | if(fabs(r[0][i] - r[0][i-1]) <= epsilon){ 34 | break; 35 | } 36 | } 37 | 38 | if (i <= MAXSIZE -1) { 39 | printf("积分值=%lf\n", r[0][i]); 40 | }else{ 41 | printf("迭代次数已经超过上限!!!\n"); 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | 48 | double f(double x) 49 | { 50 | return x*x; 51 | } -------------------------------------------------------------------------------- /08常微分方程数值解法/01显式欧拉方法/01显式欧拉方法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/08常微分方程数值解法/01显式欧拉方法/01显式欧拉方法 -------------------------------------------------------------------------------- /08常微分方程数值解法/01显式欧拉方法/01显式欧拉方法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | double f(double x, double y); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, x[MAXSIZE], y[MAXSIZE]; 8 | long i, n; 9 | printf("请输入求解区间a, b(中间用英文, 隔开): "); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入步长 h: "); 12 | scanf("%lf", &h); 13 | n = (long)((b-a)/h); 14 | x[0] = a; 15 | printf("请输入起点 x[0] = %lf 处的纵坐标 y[0]: ", x[0]); 16 | scanf("%lf", &y[0]); 17 | for (i = 0; i < n; i++) { 18 | x[i+1] = x[i] + h; 19 | y[i+1] = y[i] + h * f(x[i], y[i]); 20 | } 21 | printf("计算结果为: \n"); 22 | for (i = 0; i <= n; i++) { 23 | printf("x[%ld]=%lf, y[%ld]=%lf\n",i, x[i], i, y[i]); 24 | } 25 | 26 | return 0; 27 | } 28 | 29 | 30 | double f(double x, double y) 31 | { 32 | return -y + x +1; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /08常微分方程数值解法/02改进的欧拉方法/02改进的欧拉方法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/08常微分方程数值解法/02改进的欧拉方法/02改进的欧拉方法 -------------------------------------------------------------------------------- /08常微分方程数值解法/02改进的欧拉方法/02改进的欧拉方法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXSIZE 50 4 | double f(double x, double y); 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | double a, b, h, x[MAXSIZE], y[MAXSIZE]; 9 | long i, n; 10 | printf("请输入求解区间a, b(中间用英文, 隔开): "); 11 | scanf("%lf, %lf", &a, &b); 12 | printf("请输入步长h: "); 13 | scanf("%lf", &h); 14 | n = (long)((b-a)/h); 15 | x[0] = a; 16 | printf("请输入起点x[0]=%lf处的纵坐标y[0]: ", x[0]); 17 | scanf("%lf", &y[0]); 18 | for (i = 0; i < n; i++) { 19 | x[i+1] = x[i] + h; 20 | // 预测 21 | y[i+1] = y[i] + h*f(x[i], y[i]); 22 | // 校正 23 | y[i+1] = y[i] + h*(f(x[i], y[i]) + f(x[i+1], y[i+1]))/2; 24 | } 25 | printf("计算结果为: \n"); 26 | for (i = 0; i <= n; i++) { 27 | printf("x[%ld]=%lf, y[%ld]=%lf\n", i,x[i], i, y[i]); 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | 34 | double f(double x, double y) 35 | { 36 | return y - (2 * x)/(y); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /08常微分方程数值解法/03龙格-库塔法/03龙格-库塔法: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/08常微分方程数值解法/03龙格-库塔法/03龙格-库塔法 -------------------------------------------------------------------------------- /08常微分方程数值解法/03龙格-库塔法/03龙格-库塔法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAXSIZE 50 3 | double f(double x, double y); 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | double a, b, h, k1, k2, k3, k4, x[MAXSIZE], y[MAXSIZE]; 8 | long i, n; 9 | printf("请输入求解区间a, b(请用英文, 隔开) :"); 10 | scanf("%lf, %lf", &a, &b); 11 | printf("请输入步长h: "); 12 | scanf("%lf", &h); 13 | n = (long)((b-a)/h); 14 | x[0] = a; 15 | printf("请输入起点 x[0]=%lf处的纵坐标y[0]: ", x[0]); 16 | scanf("%lf", &y[0]); 17 | for (i = 0; i < n; i++) { 18 | x[i+1] = x[i] + h; 19 | k1 = f(x[i], y[i]); 20 | k2 = f(x[i]+h/2, y[i] + k1 * h/2); 21 | k3 = f(x[i]+h/2, y[i] + k2 * h/2); 22 | k4 = f(x[i]+h, y[i] + k3*h); 23 | y[i+1] = y[i] + h * (k1 + 2*k2 + 2*k3 + k4)/6; 24 | } 25 | printf("计算结果为: \n"); 26 | for (i = 0; i <= n; i++) { 27 | printf("x[%ld]=%lf, y[%ld]=%lf\n", i, x[i], i, y[i]); 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | 34 | double f(double x, double y) 35 | { 36 | return y - 2*x /y; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /09偏微分方程/02变分法/变分法.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // 定义函数类型 5 | typedef double (*func_ptr)(double x); 6 | 7 | // 定义求导函数 8 | double differentiate(func_ptr func, double x, double h) { 9 | // 使用前进差商法求函数在x点的导数值 10 | return (func(x + h) - func(x)) / h; 11 | } 12 | 13 | // 定义求函数在闭区间[a, b]上的定积分值 14 | double integrate(func_ptr func, double a, double b) { 15 | double h = 0.001; // 隔距 16 | int n = (int)(b - a) / h; // 区间分点数 17 | double sum = 0.0; 18 | double x; 19 | for (int i = 0; i < n; i++) { 20 | x = a + i * h; 21 | sum += func(x) * h; 22 | } 23 | return sum; 24 | } 25 | 26 | // 定义求解二阶常微分方程的边值问题的函数 27 | void solve_bvp(func_ptr f, double a, double b, double y_a, double y_b) { 28 | double h = 0.1; // 步长 29 | double x = a; // 当前点 30 | double y = y_a; // 初始条件 31 | double k1 = 0.0, k2 = 0.0; 32 | printf("%f %f\n", x, y); 33 | while (x < b) { 34 | k1 = f(x, y); // 计算k1 35 | k2 = f(x + h / 2, y + h * k1 / 2); // 计算k2 36 | y += h * (k1 + k2) / 2; // 更新y 37 | x += h; // 更新x 38 | printf("%f %f\n", x, y); 39 | } 40 | } 41 | 42 | int main() { 43 | // 定义函数f(x, y) = x^2 + y 44 | func_ptr f = ^(double x, double y) { 45 | return 2 * x + 1; 46 | }; 47 | 48 | // 求解边值问题 49 | solve_bvp(f, 0, 1, 0, 0); 50 | 51 | return 0; 52 | } -------------------------------------------------------------------------------- /09偏微分方程/03有限元法/FEM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IammyselfYBX/calculation-method-implementation-code/c968d30c4dbcefeeb2db7f9218e4a60df119cc70/09偏微分方程/03有限元法/FEM -------------------------------------------------------------------------------- /09偏微分方程/03有限元法/triangle.h: -------------------------------------------------------------------------------- 1 | /* ------- NOTE ----------------------------------------------- 2 | * This is a modified version of Shewchuk's code. 3 | * The modifications change only the compilation options. 4 | * The triangulation code itself is not touched. 5 | * 6 | * -- Rouben Rostamian 7 | * -- 2009-05-07 8 | */ 9 | 10 | /*****************************************************************************/ 11 | /* */ 12 | /* (triangle.h) */ 13 | /* */ 14 | /* Include file for programs that call Triangle. */ 15 | /* */ 16 | /* Accompanies Triangle Version 1.6 */ 17 | /* July 28, 2005 */ 18 | /* */ 19 | /* Copyright 1996, 2005 */ 20 | /* Jonathan Richard Shewchuk */ 21 | /* 2360 Woolsey #H */ 22 | /* Berkeley, California 94705-1927 */ 23 | /* jrs@cs.berkeley.edu */ 24 | /* */ 25 | /*****************************************************************************/ 26 | 27 | /*****************************************************************************/ 28 | /* */ 29 | /* How to call Triangle from another program */ 30 | /* */ 31 | /* */ 32 | /* If you haven't read Triangle's instructions (run "triangle -h" to read */ 33 | /* them), you won't understand what follows. */ 34 | /* */ 35 | /* Triangle must be compiled into an object file (triangle.o) with the */ 36 | /* TRILIBRARY symbol defined (generally by using the -DTRILIBRARY compiler */ 37 | /* switch). The makefile included with Triangle will do this for you if */ 38 | /* you run "make trilibrary". The resulting object file can be called via */ 39 | /* the procedure triangulate(). */ 40 | /* */ 41 | /* If the size of the object file is important to you, you may wish to */ 42 | /* generate a reduced version of triangle.o. The REDUCED symbol gets rid */ 43 | /* of all features that are primarily of research interest. Specifically, */ 44 | /* the -DREDUCED switch eliminates Triangle's -i, -F, -s, and -C switches. */ 45 | /* The CDT_ONLY symbol gets rid of all meshing algorithms above and beyond */ 46 | /* constrained Delaunay triangulation. Specifically, the -DCDT_ONLY switch */ 47 | /* eliminates Triangle's -r, -q, -a, -u, -D, -Y, -S, and -s switches. */ 48 | /* */ 49 | /* IMPORTANT: These definitions (TRILIBRARY, REDUCED, CDT_ONLY) must be */ 50 | /* made in the makefile or in triangle.c itself. Putting these definitions */ 51 | /* in this file (triangle.h) will not create the desired effect. */ 52 | /* */ 53 | /* */ 54 | /* The calling convention for triangulate() follows. */ 55 | /* */ 56 | /* void triangulate(triswitches, in, out, vorout) */ 57 | /* char *triswitches; */ 58 | /* struct triangulateio *in; */ 59 | /* struct triangulateio *out; */ 60 | /* struct triangulateio *vorout; */ 61 | /* */ 62 | /* `triswitches' is a string containing the command line switches you wish */ 63 | /* to invoke. No initial dash is required. Some suggestions: */ 64 | /* */ 65 | /* - You'll probably find it convenient to use the `z' switch so that */ 66 | /* points (and other items) are numbered from zero. This simplifies */ 67 | /* indexing, because the first item of any type always starts at index */ 68 | /* [0] of the corresponding array, whether that item's number is zero or */ 69 | /* one. */ 70 | /* - You'll probably want to use the `Q' (quiet) switch in your final code, */ 71 | /* but you can take advantage of Triangle's printed output (including the */ 72 | /* `V' switch) while debugging. */ 73 | /* - If you are not using the `q', `a', `u', `D', `j', or `s' switches, */ 74 | /* then the output points will be identical to the input points, except */ 75 | /* possibly for the boundary markers. If you don't need the boundary */ 76 | /* markers, you should use the `N' (no nodes output) switch to save */ 77 | /* memory. (If you do need boundary markers, but need to save memory, a */ 78 | /* good nasty trick is to set out->pointlist equal to in->pointlist */ 79 | /* before calling triangulate(), so that Triangle overwrites the input */ 80 | /* points with identical copies.) */ 81 | /* - The `I' (no iteration numbers) and `g' (.off file output) switches */ 82 | /* have no effect when Triangle is compiled with TRILIBRARY defined. */ 83 | /* */ 84 | /* `in', `out', and `vorout' are descriptions of the input, the output, */ 85 | /* and the Voronoi output. If the `v' (Voronoi output) switch is not used, */ 86 | /* `vorout' may be NULL. `in' and `out' may never be NULL. */ 87 | /* */ 88 | /* Certain fields of the input and output structures must be initialized, */ 89 | /* as described below. */ 90 | /* */ 91 | /*****************************************************************************/ 92 | 93 | /*****************************************************************************/ 94 | /* */ 95 | /* The `triangulateio' structure. */ 96 | /* */ 97 | /* Used to pass data into and out of the triangulate() procedure. */ 98 | /* */ 99 | /* */ 100 | /* Arrays are used to store points, triangles, markers, and so forth. In */ 101 | /* all cases, the first item in any array is stored starting at index [0]. */ 102 | /* However, that item is item number `1' unless the `z' switch is used, in */ 103 | /* which case it is item number `0'. Hence, you may find it easier to */ 104 | /* index points (and triangles in the neighbor list) if you use the `z' */ 105 | /* switch. Unless, of course, you're calling Triangle from a Fortran */ 106 | /* program. */ 107 | /* */ 108 | /* Description of fields (except the `numberof' fields, which are obvious): */ 109 | /* */ 110 | /* `pointlist': An array of point coordinates. The first point's x */ 111 | /* coordinate is at index [0] and its y coordinate at index [1], followed */ 112 | /* by the coordinates of the remaining points. Each point occupies two */ 113 | /* REALs. */ 114 | /* `pointattributelist': An array of point attributes. Each point's */ 115 | /* attributes occupy `numberofpointattributes' REALs. */ 116 | /* `pointmarkerlist': An array of point markers; one int per point. */ 117 | /* */ 118 | /* `trianglelist': An array of triangle corners. The first triangle's */ 119 | /* first corner is at index [0], followed by its other two corners in */ 120 | /* counterclockwise order, followed by any other nodes if the triangle */ 121 | /* represents a nonlinear element. Each triangle occupies */ 122 | /* `numberofcorners' ints. */ 123 | /* `triangleattributelist': An array of triangle attributes. Each */ 124 | /* triangle's attributes occupy `numberoftriangleattributes' REALs. */ 125 | /* `trianglearealist': An array of triangle area constraints; one REAL per */ 126 | /* triangle. Input only. */ 127 | /* `neighborlist': An array of triangle neighbors; three ints per */ 128 | /* triangle. Output only. */ 129 | /* */ 130 | /* `segmentlist': An array of segment endpoints. The first segment's */ 131 | /* endpoints are at indices [0] and [1], followed by the remaining */ 132 | /* segments. Two ints per segment. */ 133 | /* `segmentmarkerlist': An array of segment markers; one int per segment. */ 134 | /* */ 135 | /* `holelist': An array of holes. The first hole's x and y coordinates */ 136 | /* are at indices [0] and [1], followed by the remaining holes. Two */ 137 | /* REALs per hole. Input only, although the pointer is copied to the */ 138 | /* output structure for your convenience. */ 139 | /* */ 140 | /* `regionlist': An array of regional attributes and area constraints. */ 141 | /* The first constraint's x and y coordinates are at indices [0] and [1], */ 142 | /* followed by the regional attribute at index [2], followed by the */ 143 | /* maximum area at index [3], followed by the remaining area constraints. */ 144 | /* Four REALs per area constraint. Note that each regional attribute is */ 145 | /* used only if you select the `A' switch, and each area constraint is */ 146 | /* used only if you select the `a' switch (with no number following), but */ 147 | /* omitting one of these switches does not change the memory layout. */ 148 | /* Input only, although the pointer is copied to the output structure for */ 149 | /* your convenience. */ 150 | /* */ 151 | /* `edgelist': An array of edge endpoints. The first edge's endpoints are */ 152 | /* at indices [0] and [1], followed by the remaining edges. Two ints per */ 153 | /* edge. Output only. */ 154 | /* `edgemarkerlist': An array of edge markers; one int per edge. Output */ 155 | /* only. */ 156 | /* `normlist': An array of normal vectors, used for infinite rays in */ 157 | /* Voronoi diagrams. The first normal vector's x and y magnitudes are */ 158 | /* at indices [0] and [1], followed by the remaining vectors. For each */ 159 | /* finite edge in a Voronoi diagram, the normal vector written is the */ 160 | /* zero vector. Two REALs per edge. Output only. */ 161 | /* */ 162 | /* */ 163 | /* Any input fields that Triangle will examine must be initialized. */ 164 | /* Furthermore, for each output array that Triangle will write to, you */ 165 | /* must either provide space by setting the appropriate pointer to point */ 166 | /* to the space you want the data written to, or you must initialize the */ 167 | /* pointer to NULL, which tells Triangle to allocate space for the results. */ 168 | /* The latter option is preferable, because Triangle always knows exactly */ 169 | /* how much space to allocate. The former option is provided mainly for */ 170 | /* people who need to call Triangle from Fortran code, though it also makes */ 171 | /* possible some nasty space-saving tricks, like writing the output to the */ 172 | /* same arrays as the input. */ 173 | /* */ 174 | /* Triangle will not free() any input or output arrays, including those it */ 175 | /* allocates itself; that's up to you. You should free arrays allocated by */ 176 | /* Triangle by calling the trifree() procedure defined below. (By default, */ 177 | /* trifree() just calls the standard free() library procedure, but */ 178 | /* applications that call triangulate() may replace trimalloc() and */ 179 | /* trifree() in triangle.c to use specialized memory allocators.) */ 180 | /* */ 181 | /* Here's a guide to help you decide which fields you must initialize */ 182 | /* before you call triangulate(). */ 183 | /* */ 184 | /* `in': */ 185 | /* */ 186 | /* - `pointlist' must always point to a list of points; `numberofpoints' */ 187 | /* and `numberofpointattributes' must be properly set. */ 188 | /* `pointmarkerlist' must either be set to NULL (in which case all */ 189 | /* markers default to zero), or must point to a list of markers. If */ 190 | /* `numberofpointattributes' is not zero, `pointattributelist' must */ 191 | /* point to a list of point attributes. */ 192 | /* - If the `r' switch is used, `trianglelist' must point to a list of */ 193 | /* triangles, and `numberoftriangles', `numberofcorners', and */ 194 | /* `numberoftriangleattributes' must be properly set. If */ 195 | /* `numberoftriangleattributes' is not zero, `triangleattributelist' */ 196 | /* must point to a list of triangle attributes. If the `a' switch is */ 197 | /* used (with no number following), `trianglearealist' must point to a */ 198 | /* list of triangle area constraints. `neighborlist' may be ignored. */ 199 | /* - If the `p' switch is used, `segmentlist' must point to a list of */ 200 | /* segments, `numberofsegments' must be properly set, and */ 201 | /* `segmentmarkerlist' must either be set to NULL (in which case all */ 202 | /* markers default to zero), or must point to a list of markers. */ 203 | /* - If the `p' switch is used without the `r' switch, then */ 204 | /* `numberofholes' and `numberofregions' must be properly set. If */ 205 | /* `numberofholes' is not zero, `holelist' must point to a list of */ 206 | /* holes. If `numberofregions' is not zero, `regionlist' must point to */ 207 | /* a list of region constraints. */ 208 | /* - If the `p' switch is used, `holelist', `numberofholes', */ 209 | /* `regionlist', and `numberofregions' is copied to `out'. (You can */ 210 | /* nonetheless get away with not initializing them if the `r' switch is */ 211 | /* used.) */ 212 | /* - `edgelist', `edgemarkerlist', `normlist', and `numberofedges' may be */ 213 | /* ignored. */ 214 | /* */ 215 | /* `out': */ 216 | /* */ 217 | /* - `pointlist' must be initialized (NULL or pointing to memory) unless */ 218 | /* the `N' switch is used. `pointmarkerlist' must be initialized */ 219 | /* unless the `N' or `B' switch is used. If `N' is not used and */ 220 | /* `in->numberofpointattributes' is not zero, `pointattributelist' must */ 221 | /* be initialized. */ 222 | /* - `trianglelist' must be initialized unless the `E' switch is used. */ 223 | /* `neighborlist' must be initialized if the `n' switch is used. If */ 224 | /* the `E' switch is not used and (`in->numberofelementattributes' is */ 225 | /* not zero or the `A' switch is used), `elementattributelist' must be */ 226 | /* initialized. `trianglearealist' may be ignored. */ 227 | /* - `segmentlist' must be initialized if the `p' or `c' switch is used, */ 228 | /* and the `P' switch is not used. `segmentmarkerlist' must also be */ 229 | /* initialized under these circumstances unless the `B' switch is used. */ 230 | /* - `edgelist' must be initialized if the `e' switch is used. */ 231 | /* `edgemarkerlist' must be initialized if the `e' switch is used and */ 232 | /* the `B' switch is not. */ 233 | /* - `holelist', `regionlist', `normlist', and all scalars may be ignored.*/ 234 | /* */ 235 | /* `vorout' (only needed if `v' switch is used): */ 236 | /* */ 237 | /* - `pointlist' must be initialized. If `in->numberofpointattributes' */ 238 | /* is not zero, `pointattributelist' must be initialized. */ 239 | /* `pointmarkerlist' may be ignored. */ 240 | /* - `edgelist' and `normlist' must both be initialized. */ 241 | /* `edgemarkerlist' may be ignored. */ 242 | /* - Everything else may be ignored. */ 243 | /* */ 244 | /* After a call to triangulate(), the valid fields of `out' and `vorout' */ 245 | /* will depend, in an obvious way, on the choice of switches used. Note */ 246 | /* that when the `p' switch is used, the pointers `holelist' and */ 247 | /* `regionlist' are copied from `in' to `out', but no new space is */ 248 | /* allocated; be careful that you don't free() the same array twice. On */ 249 | /* the other hand, Triangle will never copy the `pointlist' pointer (or any */ 250 | /* others); new space is allocated for `out->pointlist', or if the `N' */ 251 | /* switch is used, `out->pointlist' remains uninitialized. */ 252 | /* */ 253 | /* All of the meaningful `numberof' fields will be properly set; for */ 254 | /* instance, `numberofedges' will represent the number of edges in the */ 255 | /* triangulation whether or not the edges were written. If segments are */ 256 | /* not used, `numberofsegments' will indicate the number of boundary edges. */ 257 | /* */ 258 | /*****************************************************************************/ 259 | 260 | #ifndef TRIANGLE_H_INCLUDED 261 | #define TRIANGLE_H_INCLUDED 262 | 263 | #define ANSI_DECLARATORS 264 | #define VOID void 265 | #ifdef SINGLE 266 | #define REAL float 267 | #else 268 | #define REAL double 269 | #endif 270 | 271 | struct triangulateio { 272 | REAL *pointlist; /* In / out */ 273 | REAL *pointattributelist; /* In / out */ 274 | int *pointmarkerlist; /* In / out */ 275 | int numberofpoints; /* In / out */ 276 | int numberofpointattributes; /* In / out */ 277 | 278 | int *trianglelist; /* In / out */ 279 | REAL *triangleattributelist; /* In / out */ 280 | REAL *trianglearealist; /* In only */ 281 | int *neighborlist; /* Out only */ 282 | int numberoftriangles; /* In / out */ 283 | int numberofcorners; /* In / out */ 284 | int numberoftriangleattributes; /* In / out */ 285 | 286 | int *segmentlist; /* In / out */ 287 | int *segmentmarkerlist; /* In / out */ 288 | int numberofsegments; /* In / out */ 289 | 290 | REAL *holelist; /* In / pointer to array copied out */ 291 | int numberofholes; /* In / copied out */ 292 | 293 | REAL *regionlist; /* In / pointer to array copied out */ 294 | int numberofregions; /* In / copied out */ 295 | 296 | int *edgelist; /* Out only */ 297 | int *edgemarkerlist; /* Not used with Voronoi diagram; out only */ 298 | REAL *normlist; /* Used only with Voronoi diagram; out only */ 299 | int numberofedges; /* Out only */ 300 | }; 301 | 302 | #ifdef ANSI_DECLARATORS 303 | void triangulate(char *, struct triangulateio *, struct triangulateio *, 304 | struct triangulateio *); 305 | void trifree(VOID *memptr); 306 | #else /* not ANSI_DECLARATORS */ 307 | void triangulate(); 308 | void trifree(); 309 | #endif /* not ANSI_DECLARATORS */ 310 | 311 | #endif /* TRIANGLE_H_INCLUDED */ 312 | --------------------------------------------------------------------------------