/// <summary> /// Evaluates the inverse complementary error function. /// </summary> /// <param name="p"></param> /// <returns></returns> public static double inverfc(double p) { if (p >= 2.0) { return(-100.0); } if (p <= 0.0) { return(100.0); } double pp = (p < 1.0) ? p : 2.0 - p; double t = Math.Sqrt(-2.0 * Math.Log(pp / 2.0)); double x = -0.70711 * ((2.30753 + t * 0.27061) / (1.0 + t * (0.99229 + t * 0.04481)) - t); for (int j = 0; j < 2; j++) { double err = erfc(x) - pp; x += err / (1.12837916709551257 * Math.Exp(-MathTool.Sqr(x)) - x * err); } return(p < 1.0 ? x : -x); }
/// <summary> /// Calculates the moving standard deviation. /// </summary> /// <remarks> /// NaN items in the sequence are ignores. /// </remarks> /// <param name="sequence"></param> /// <param name="period"></param> /// <param name="strict">Require at least period good values</param> /// <returns>The moving standard deviation</returns> public static IEnumerable <double> StandardDeviation(IEnumerable <double> sequence, int period, bool strict = false) { double[] buffer = new double[period]; int cursor = 0; int count = 0; double sum = 0.0; double stddev = double.NaN; for (int i = 0; i < period; ++i) { buffer[i] = double.NaN; } foreach (double value in sequence) { if (!double.IsNaN(value)) { #region update buffer and sum if (double.IsNaN(buffer[cursor])) { count = Math.Min(count + 1, period); } else { sum -= buffer[cursor]; } buffer[cursor] = value; cursor = (cursor + 1) % period; sum += value; #endregion #region update stddev if (count > period || !strict) { double mean = sum / (double)count; double t = 0.0; for (int i = 0; i < period; ++i) { if (!double.IsNaN(buffer[i])) { t += MathTool.Sqr(buffer[i] - mean); } } stddev = Math.Sqrt(t / (double)count); } else { stddev = double.NaN; } #endregion } yield return(stddev); } }
public static List <int> Flatten(int index, int count, Func <int, double> X, Func <int, double> Y, double resolution) { List <int> ret = new List <int>(); Flatten(ret, X, Y, index, count - 1, MathTool.Sqr(resolution)); ret.Add(count - 1); return(ret); }
public static double GreatCircleDistance(Point start, Point end) { double cosφs = Math.Cos(MathTool.Radians(start.Y)); double sinφs = Math.Sin(MathTool.Radians(start.Y)); double sinφf = Math.Sin(MathTool.Radians(end.Y)); double cosφf = Math.Cos(MathTool.Radians(end.Y)); double cosΔλ = Math.Cos(MathTool.Radians(end.X - start.X)); double sinΔλ = Math.Sin(MathTool.Radians(end.X - start.X)); return(Math.Atan2(MathTool.Sqr(cosφf * sinΔλ) + MathTool.Sqr(cosφs * sinφf - sinφs * cosφf * cosΔλ), sinφs * sinφf + cosφs * cosφf * cosΔλ)); }
public static double[] Minimise(Func <double[], double> function, double[] pp, double tolerance) { int n = pp.Length; int ITMAX = 200; double TINY = 1.0e-25; double[,] ximat = new double[n, n]; for (int i = 0; i < n; i++) { ximat[i, i] = 1.0; } double[] p = new double[n]; double[] pt = new double[n]; double[] ptt = new double[n]; double[] xi = new double[n]; double fret = function(p); for (int i = 0; i < n; ++i) { p[i] = pp[i]; pt[i] = p[i]; } for (int i = 0; ; ++i) { double fp = fret; double fptt; int ibig = 0; double del = 0.0; for (int j = 0; j < n; ++j) { for (int k = 0; k < n; ++k) { xi[k] = ximat[k, j]; } fptt = fret; fret = linmin(function, p, xi); if (fptt - fret > del) { del = fptt - fret; ibig = j + 1; } } if (2.0 * (fp - fret) <= tolerance * (Math.Abs(fp) + Math.Abs(fret)) + TINY) { return(p); } if (i == ITMAX) { return(null); //throw ("powell exceeding maximum iterations."); } for (int j = 0; j < n; j++) { ptt[j] = 2.0 * p[j] - pt[j]; xi[j] = p[j] - pt[j]; pt[j] = p[j]; } fptt = function(ptt); if (fptt < fp) { double t = 2.0 * (fp - 2.0 * fret + fptt) * MathTool.Sqr(fp - fret - del) - del * MathTool.Sqr(fp - fptt); if (t < 0.0) { fret = linmin(function, p, xi); for (int j = 0; j < n; j++) { ximat[j, ibig - 1] = ximat[j, n - 1]; ximat[j, n - 1] = xi[j]; } } } } }
private static double Distance2(Point p0, Point p1) { return(MathTool.Sqr(p1.X - p0.X) + MathTool.Sqr(p1.Y - p0.Y)); }