/// <summary> /// 回傳數列中最明顯的 Change Point。 /// </summary> /// <param name="d">The numeric array which use to run change point procedure. Missing value (1.23456E+30) element is not allow in the array.</param> /// <param name="conf">The confidence level used to test whether it is a significant change point</param> /// <param name="N">Number of boostrap</param> /// <returns></returns> public static ChangePointInfo ChangePointOnSingleCase(double[] d, double conf = 0.9, int N = 1000) { if (d.Length < 7) { return new ChangePointInfo() { Index = -1 } } ; if (d.Any(x => x >= MtbTools.MISSINGVALUE)) { throw new ArgumentException("數列中包含遺失值"); } LinearAlgebra.Vector <double> xs = LinearAlgebra.Vector <double> .Build.DenseOfArray(d); double xbar = xs.Average(); xs = xs - xbar; //Xi-Xbar LinearAlgebra.Vector <double> si = LinearAlgebra.Vector <double> .Build.DenseOfArray(MathTool.PartialSum(xs.ToArray())); int changepointindex = si.AbsoluteMaximumIndex(); double sdiff = si.Maximum() - si.Minimum(); double[] Sdiff_boostrap = new double[N]; for (int i = 0; i < N; i++) { double[] si_boostrap = MathTool.PartialSum(MathTool.RandomSample(xs.ToArray()).Cast <double>().ToArray()); Sdiff_boostrap[i] = si_boostrap.Max() - si_boostrap.Min(); } double confLv = (double)Sdiff_boostrap.Where(x => x < sdiff).Count() / N; if (confLv < conf) { return new ChangePointInfo() { Index = -1 } } ; //Not significant return(new ChangePointInfo() { Index = changepointindex, Sdiff = sdiff, ConfidenceLevel = confLv }); }
/// <summary> /// 計算數列各元素的累積和 /// </summary> /// <param name="x">要處理的陣列,合法的輸入是 double[]</param> /// <returns></returns> public static double[] PartialSum(double[] x) { LinearAlgebra.Vector <double> vx = LinearAlgebra.Double.DenseVector.OfArray(x); int row = vx.Count; int col = row; LinearAlgebra.Matrix <double> lmat = LinearAlgebra.Matrix <double> .Build.Dense(row, col, 1); lmat = lmat.LowerTriangle(); LinearAlgebra.Vector <double> result = lmat.Multiply(vx); return(result.ToArray()); }