예제 #1
0
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;
}
예제 #2
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;
}