int main (int argc, char *argv[]) { const int ARRAY_SIZE = argc - 1; double TV[ARRAY_SIZE]; int i; int check = 0; /* * Expecting XSIZE arguments */ if (argc != (XSIZE + 1)) { return 1; } for (i = 0; i < argc - 1; ++i) { TV[i] = atof (argv[i + 1]); } newtonMethod(TV, &check); /* printf("Check value = %i\n", check); for (i = 0; i < argc - 1; ++i) { printf("%lf ", TV[i]); } printf("\n"); */ return 0; }
int main() { const int MAX_STEP = 1000; // 最大迭代次数 double EP = 1.0E-12; // 牛顿迭代精度 double sigmaEP = 1.0E-7; // 最小二乘拟合精度 double x[11], y[21], t[11][21], u[11][21], v[11][21], w[11][21]; // 初始化变量x, y for (int i = 0; i < 11; i++) { x[i] = 0.08 * i; } for (int i = 0; i < 21; i++) { y[i] = 0.5 + 0.05 * i; } /* 步骤一:Newton法解非线性方程组F(t,u,v,w) = 0 */ for (int i = 0; i < 11; i++) { for (int j = 0; j < 21; j++) { newtonMethod(x + i, y + j, t[i] + j, u[i] + j, v[i] + j, w[i] + j, MAX_STEP, EP); } } /* 步骤二:分片二次代数插值求z = f(ti,ui) */ double * * z = new double *[11]; for (int i = 0; i < 11; i++) { z[i] = new double[21]; } double p, q; for (int i = 1; i < 5; i++) { for (int j = 1; j < 5; j++) { // 在片上遍历搜索满足插值条件的(t,u)点 for (int k = 0; k < 11; k++) { for (int l = 0; l < 21; l++) { p = min(max(t[k][l], 0.11), 0.9); q = min(max(u[k][l], 0.21), 1.8); if (0.2 * i - 0.1 < p && p <= 0.2 * i + 0.1 && 0.4 * j - 0.2 < q && q <= 0.4 * j + 0.2) { // 由(x[i], y[j]) 得到的(t[i][j], u[i][j]) , 插值得到z[i][j] z[k][l] = pieceInterp(i, j, t[k][l], u[k][l]); } } } } } // 输出数表(x, y, f(x,y)) printf("\n数表( x, y, f(x,y) ):\n"); for (int i = 0; i < 11; i++) { for (int j = 0; j < 21; j++) { printf("( %f\t,\t%f\t,\t%.12e )\n",x[i], y[j], z[i][j]); } } /* 步骤三:遍历k=2,3,...,将(xi,yj,zij)代入最小二乘曲面拟合得到z = p(x,y),当满足精度要求时,迭代结束,返回k和sigma*/ double sigma; double * * C = NULL; int N = 0; printf("\nk和相应sigma的值:\n"); for (int k = 1; k < 10; k++) { // 动态创建k+1 * k+1 的二维数组 C = new double *[k + 1]; for (int i = 0; i < k + 1; i++) { C[i] = new double[k + 1]; } // 最小二乘曲面拟合,得到系数矩阵C computeC(C, 11, 21, k + 1, x, y, z); // 计算sigma sigma = computeSigma(C, k + 1, x, y, z); // 打印k和sigma的值 printf("k = %d , sigma = %.12e\n", k, sigma); // 判断sigma是否符合精度要求 if (sigma <= sigmaEP) { N = k; // 输出系数矩阵 printf("\nk = %d时, 系数矩阵为:\n", N); for (int i = 0; i < k + 1; i++) { for (int j = 0; j < k + 1; j++) { printf("%.12e\t", C[i][j]); } printf("\n"); } break; } // 释放矩阵C的内存 for (int i = 0; i < k + 1; i++) { delete[] C[i]; } delete[] C; } /* 观察效果*/ #if DEBUG double xstar[8], ystar[5], tstar[8][5], ustar[8][5], vstar[8][5], wstar[8][5]; for (int i = 1; i < 9; i++) { xstar[i - 1] = 0.1 * i; } for (int j = 1; j < 6; j++) { ystar[j - 1] = 0.5 + 0.2 * j; } for (int i = 0; i < 8; i++) { for (int j = 0; j < 5; j++) { newtonMethod(xstar + i, ystar + j, tstar[i] + j, ustar[i] + j, vstar[i] + j, wstar[i] + j, MAX_STEP, EP); } } double * * zstar = new double *[8]; for (int i = 0; i < 11; i++) { zstar[i] = new double[5]; } double pstar, qstar; for (int i = 1; i < 5; i++) { for (int j = 1; j < 5; j++) { for (int k = 0; k < 8; k++) { for (int l = 0; l < 5; l++) { pstar = min(max(tstar[k][l], 0.11), 0.9); qstar = min(max(ustar[k][l], 0.21), 1.8); if (0.2 * i - 0.1 < pstar && pstar <= 0.2 * i + 0.1 && 0.4 * j - 0.2 < qstar && qstar <= 0.4 * j + 0.2) { zstar[k][l] = pieceInterp(i, j, tstar[k][l], ustar[k][l]); } } } } } printf("\n数表( x*, y*, f(x*,y*), p(x*,y*) ):\n"); for (int i = 0; i < 8; i++) { for (int j = 0; j < 5; j++) { printf("( %f\t,\t%f\t,\t%.12e\t,\t%.12e )\n", xstar[i], ystar[j], zstar[i][j], computePxy(C, N + 1, xstar[i], ystar[j])); } } #endif /* 释放内存*/ for (int i = 0; i < 11; i++) { delete[] z[i]; } delete[] z; for (int i = 0; i < N + 1; i++) { delete[] C[i]; } delete[] C; // end getchar(); return 0; }