public ModelErrors Calculate(IReadOnlyList <double[]> indices) { // TODO: use prepared indexes var factors = _nodes.Factors(); var resultPosition = _nodes.FindIndex(x => x.IsResult); var formated = _regressionIndexListFormatter.FormatIndexList(indices); var given = indices.Skip(indices.Count - formated.Count).Select(x => x[resultPosition]); var calculated = formated.Select(x => _equationBuilder.Calculate(factors, x)); var yAverage = given.Average(); var count = formated.Count; var epsilons = given.Zip(calculated, (givenValue, calculatedValue) => new { EpsilonCalculated = givenValue - calculatedValue, EpsilonAverage = givenValue - yAverage }); var eSquared = epsilons.Sum(x => x.EpsilonCalculated * x.EpsilonCalculated); var eAverage = epsilons.Sum(x => x.EpsilonAverage * x.EpsilonAverage); var determination = 1 - eSquared / eAverage; var dw = epsilons.Skip(1).Zip(epsilons, (e1, e2) => e1.EpsilonCalculated - e2.EpsilonCalculated).Sum(x => x * x) / eSquared; var skp = Math.Sqrt(eSquared / count); var sapp = epsilons.Zip(given, (x, y) => Math.Abs(x.EpsilonCalculated) / Math.Abs(y)).Sum() / count; var theil = skp / (Math.Sqrt(given.Sum(x => x * x) / count) + Math.Sqrt(calculated.Sum(x => x * x) / count)); return(new ModelErrors(determination, eSquared, dw, skp, sapp, theil)); }
public double[] Solve(IReadOnlyList <double[]> indices) { var indexList = _regressionIndexListFormatter.FormatIndexList(indices); var solver = new LMSolver(); var optimizationResult = solver.Minimize( (p, r) => { indexList.AsParallel() .Select((x, i) => new { Result = _equationBuilder.Calculate(x, p), Row = i }) .ForAll(x => r[x.Row] = x.Result); }, new double[indexList.First().Length], indexList.Count); return(optimizationResult.OptimizedParameters); }