/// <summary> /// Differentiation of a two dimensional function df/dy. /// </summary> public static double dfdy(IFunction2D f, double x, double y, out double abserr) { // adapted from gsl_diff_central const double GSL_SQRT_DBL_EPSILON = 1.4901161193847656e-08; /* Construct a divided difference table with a fairly large step * size to get a very rough estimate of f'''. Use this to estimate * the step size which will minimize the error in calculating f'. */ int i, k; double h = GSL_SQRT_DBL_EPSILON, a3, temp; double[] a = new double[4], d = new double[4]; /* Algorithm based on description on pg. 204 of Conte and de Boor * (CdB) - coefficients of Newton form of polynomial of degree 3. */ for (i = 0; i < 4; i++) { a[i] = y + (i - 2) * h; d[i] = f.f(x, a[i]); } for (k = 1; k < 5; k++) { for (i = 0; i < 4 - k; i++) { d[i] = (d[i + 1] - d[i]) / (a[i + k] - a[i]); } } /* Adapt procedure described on pg. 282 of CdB to find best * value of step size. */ a3 = Math.Abs(d[0] + d[1] + d[2] + d[3]); if (a3 < 100 * GSL_SQRT_DBL_EPSILON) { a3 = 100 * GSL_SQRT_DBL_EPSILON; } h = Math.Pow(GSL_SQRT_DBL_EPSILON / (2 * a3), 1.0 / 3.0); if (h > 100 * GSL_SQRT_DBL_EPSILON) { h = 100 * GSL_SQRT_DBL_EPSILON; } abserr = Math.Abs(100.0 * a3 * h * h); temp = y + h; GetH(y, ref h, temp); return((f.f(x, y + h) - f.f(x, y - h)) / (2 * h)); }
public Noise2DFunction(IFunction2D baseNoise, double scale) { _baseNoise = baseNoise; _scale = scale; }
/// <summary> /// An alias for the routine <see cref="dfdy(IFunction2D, double, double, out double)"/>. /// </summary> public static double diffy(IFunction2D f, double x, double y, out double abserr) { return(dfdy(f, x, y, out abserr)); }