0

我正在为双三次插值编写一个非常标准的程序。出于某种原因,如果我将 Xincrement 和 Yincrement 设置得太小,for 循环就会过早退出一次。不知道为什么会这样。我将 Yincrement 和 Xincrement 设置为主,如果它们是 0.25 或更高,那么它工作正常,但如果我将它降低到 0.2 或更低,它会提前停止一个循环。此外,最后 3 个 for 循环是搞砸的。

这是我的代码:

public static double ApplyKernel(double [] Row, double Location, int R) {
  double s1; double s2; double s3; double s4;
  double Kernel;
  double s = Location%1;
  s1 = -.5*Math.pow(s+1,3)+2.5*Math.pow(s+1,2)-4*(s+1)+2;
  s2 = 1.5*Math.pow(s,3)-2.5*Math.pow(s,2)+1;
  s3 = 1.5*Math.pow(1-s,3)-2.5*Math.pow(1-s,2)+1;
  s4 = -.5*Math.pow(2-s,3)+2.5*Math.pow(2-s,2)-4*(2-s)+2;
  if(s==0) {
    Kernel = Row[(int)(Location)];
      } else {
    Kernel = s1*Row[(int)(Location-1)]+s2*Row[(int)Location]+s3*Row[(int)   (Location+1)]+s4*Row[(int)(Location+2)];
  }  
return Kernel;      
}

public static double[][] zValues(double [][] ExtendP,  int R, double X, double Y, double    Xincrement, double Yincrement) throws FileNotFoundException
{
  String phFileName = "Data37.txt";
  PrintStream phOutput = new PrintStream( phFileName );

  double[][] zValues = new double[(int)(R/Xincrement)+1][(int)(R/Yincrement)+1];
  double[] row = new double[R+3];
  for (double i = 1; i<=(R+1); i += Xincrement) {
    phOutput.println(";");
    for (int j = 0; j<R+3; j++) {
      row[j] = ApplyKernel(ExtendP[j], i, R);
    }
    for(double k = 1; k<=(R+1); k += Yincrement) {
        zValues[(int)((i-1)/Xincrement)][(int)((k-1)/Yincrement)] = ApplyKernel(row, k, R);
        phOutput.printf("(%.2f,%.2f) = %.3f ", k, i, ApplyKernel(row, k, R));  
      }
    }


  return zValues;
}

让我知道你们是否知道为什么会发生这种情况

4

3 回答 3

1

主要建议:不要使用double. 通过反复添加,您会累积错误,并且在某些情况下,您会遇到围栏问题。

而是使用一个迭代int并使用适当的公式在单个计算步骤中得出您的双精度值。这将简单地涉及整数的适当缩放。

于 2013-06-06T20:02:15.290 回答
0

当你在循环这样的代码时,你真的应该用ints它来做循环。整数是精确的,不会被近似。

由于表示双精度数的近似性质,使用双精度数循环会导致舍入错误或只是不精确。随着您不断修改变量,此错误会变得更大。

于 2013-06-06T20:02:38.520 回答
0

看起来像一个浮点错误。由于Ris 是类型int并且 i,k 是 double 类型,因此可能存在理论上相等的比较,但由于浮点精度可能不会评估为如此。

于 2013-06-06T20:03:29.693 回答