/// <summary> /// This is faster for longer span /// </summary> /// <param name="data"></param> /// <param name="average"></param> /// <param name="periodic"></param> /// <param name="variance"></param> /// <returns></returns> public static double Next(double[] data, ref double average, ref List <double> periodic, ref double variance) { double[] PDR = MonteCarloSimulation.PeriodicChange(data, ref periodic); average = AMath.Average(PDR, average); variance = AMath.Variance(PDR, average, variance, false); double Drift = average - (variance / 2.0); double StandardDeviation = Math.Sqrt(variance); //AMath.StandarDeviation(Variance); return(data.Last() * Math.Exp(Drift + StandardDeviation * AExcel.NORMSINV(AMath.Random()))); }
/// <summary> /// this is faster for short span /// Simulates next value of double set /// </summary> /// <param name="data"></param> /// <returns>future random output</returns> public static double Next(double[] data) { if (data == null || data.Length <= 0) { return(double.NaN); } double[] PFR = MonteCarloSimulation.PeriodicChange(data); double Averange = AMath.Average(PFR); double Variance = AMath.Variance(PFR, Averange, false); double Drift = Averange - (Variance / 2.0); double StandardDeviation = Math.Sqrt(Variance); //AMath.StandarDeviation(Variance); return(data.Last() * Math.Exp(Drift + StandardDeviation * AExcel.NORMSINV(AMath.Random()))); }
public static double[] PeriodicChange(double[] data, ref List <double> last) { int length = data.Length; double[] output = new double[length - 1]; if (last.Count == 0) { output = MonteCarloSimulation.PeriodicChange(data); } else { int LN1 = data.Length - 1; last.Add(Math.Log(data[LN1] / data[LN1 - 1])); output = last.ToArray(); } return(output); }