[Test] public void FromLinearRegression() { { var pts = new v2[] { new v2(0, 15), new v2(1, 13), new v2(2, 10), new v2(3, 7), new v2(4, 4), new v2(5, 1), }; var m = Monic.FromLinearRegression(pts); //Assert.True(Math_.FEql(m.A, 0.689393937587738)); //Assert.True(Math_.FEql(m.B, -6.10151338577271)); } { var pts = new v2[] { new v2(0, 15), new v2(1, 13), new v2(2, 10), new v2(3, 7), new v2(4, 4), new v2(5, 1), new v2(6, 5), new v2(7, 8), new v2(8, 13), new v2(9, 19), }; var q = Quadratic.FromLinearRegression(pts); Assert.True(Math_.FEql((float)q.A, 0.689394f)); Assert.True(Math_.FEql((float)q.B, -6.10151672f)); Assert.True(Math_.FEql((float)q.C, 17.3090973f)); } }
/// <summary>Return a polynomial approximation of the indicator values or null if no decent approximation could be made. 'order' is polynomial order (i.e. 1 or 2)</summary> public Extrapolation Extrapolate(int order, int history_count, Idx?idx_ = null, int series = 0) { var idx = idx_ ?? IdxLast; // Get the points to fit too var range = Instrument.IndexRange(idx - history_count, idx); var points = range .Where(x => Maths.IsFinite(Source[series][(int)(x - IdxFirst)])) .Select(x => new v2((float)x, (float)Source[series][(int)(x - IdxFirst)])) .ToArray(); // Require a minimum number of points if (points.Length <= order) { return(null); } // Create a curve using linear regression var curve = (IPolynomial)null; switch (order) { default: throw new Exception("Unsupported polynomial order"); case 2: curve = Quadratic.FromLinearRegression(points); break; case 1: curve = Monic.FromLinearRegression(points); break; } // Measure the confidence in the fit. // Map the error range to [0,+1], where > 0.5 is "good" var rms = Math.Sqrt(points.Sum(x => Maths.Sqr(x.y - curve.F(x.x)))); var conf = 1.0 - Maths.Sigmoid(rms, Instrument.MCS * 0.2); return(new Extrapolation(curve, conf)); }