コード例 #1
0
  /**
   * This method straightforwardly applies the standard definition of the numerical estimates of the
   * second order partial derivatives. See for example Section 5.7 of Numerical Recipes in C.
   */
  public double secondPartialDerivative(FittingFunction f, int i, int j, double[] p, double delt) {
    double[] arg = new double[p.length];
    System.arraycopy(p, 0, arg, 0, p.length);

    double center = f.evaluate(arg);

    arg[i] += delt;
    arg[j] += delt;
    double ff1 = f.evaluate(arg);

    arg[j] -= 2 * delt;
    double ff2 = f.evaluate(arg);

    arg[i] -= 2 * delt;
    arg[j] += 2 * delt;
    double ff3 = f.evaluate(arg);

    arg[j] -= 2 * delt;
    double ff4 = f.evaluate(arg);

    if (Double.isNaN(ff1)) {
      ff1 = center;
    }

    if (Double.isNaN(ff2)) {
      ff2 = center;
    }

    if (Double.isNaN(ff3)) {
      ff3 = center;
    }

    if (Double.isNaN(ff4)) {
      ff4 = center;
    }

    double fsSum = ff1 - ff2 - ff3 + ff4;

    return fsSum / (4.0 * delt * delt);
  }
コード例 #2
0
  /**
   * This method implements Ridder's algorithm for computing the second order partial derivatives.
   * It is a translation of the C program in section 5.7 of Numerical Recipes in C. It is more
   * robust than the above method in that it searches for a perferred value of delt. But based on
   * our experience to date with SEM fitting functions, the above method seems to be adequately
   * accurate and faster that this one.
   */
  public double secondPartialDerivativeRidr(
      FittingFunction f, int i, int j, double[] args, double delt) {

    double[] arg = new double[args.length];
    double[][] a = new double[NTAB][NTAB];
    double hh = delt;
    double errt;
    double ans = 0.0;
    double fac;

    System.arraycopy(args, 0, arg, 0, args.length);

    double center = f.evaluate(arg);

    arg[i] += delt;
    arg[j] += delt;
    double ff1 = f.evaluate(arg);

    arg[j] -= 2 * delt;
    double ff2 = f.evaluate(arg);

    arg[i] -= 2 * delt;
    arg[j] += 2 * delt;
    double ff3 = f.evaluate(arg);

    arg[j] -= 2 * delt;
    double ff4 = f.evaluate(arg);

    if (Double.isNaN(ff1)) {
      ff1 = center;
    }

    if (Double.isNaN(ff2)) {
      ff2 = center;
    }

    if (Double.isNaN(ff3)) {
      ff3 = center;
    }

    if (Double.isNaN(ff4)) {
      ff4 = center;
    }

    a[0][0] = (ff1 - ff2 - ff3 + ff4) / (4.0 * delt * delt);
    double err = BIG;

    for (int ii = 1; ii < NTAB; ii++) {
      hh /= CON;

      System.arraycopy(args, 0, arg, 0, args.length);

      arg[i] += hh;
      arg[j] += hh;
      ff1 = f.evaluate(arg);

      arg[j] -= 2 * hh;
      ff2 = f.evaluate(arg);

      arg[i] -= 2 * hh;
      arg[j] += 2 * hh;
      ff3 = f.evaluate(arg);

      arg[j] -= 2 * hh;
      ff4 = f.evaluate(arg);

      if (Double.isNaN(ff1)) {
        ff1 = center;
      }

      if (Double.isNaN(ff2)) {
        ff2 = center;
      }

      if (Double.isNaN(ff3)) {
        ff3 = center;
      }

      if (Double.isNaN(ff4)) {
        ff4 = center;
      }

      a[0][ii] = (ff1 - ff2 - ff3 + ff4) / (4.0 * hh * hh);

      fac = CON2;

      for (int jj = 1; jj < ii; jj++) {
        a[jj][ii] = (a[jj - 1][ii] * fac - a[jj - 1][ii - 1]) / (fac - 1.0);
        fac = CON2 * fac;
        errt =
            Math.max(Math.abs(a[jj][ii] - a[jj - 1][ii]), Math.abs(a[jj][ii] - a[jj - 1][ii - 1]));
        if (errt < err) {
          err = errt;
          ans = a[jj][ii];
        }
      }

      if (Math.abs(a[ii][ii] - a[ii - 1][ii - 1]) >= SAFE * err) {
        break;
      }
    }

    return ans;
  }