using IStation.Numerics.LinearAlgebra; namespace IStation.Numerics.Optimization { public class NonlinearMinimizationResult { public IObjectiveModel ModelInfoAtMinimum { get; } /// /// Returns the best fit parameters. /// public Vector MinimizingPoint => ModelInfoAtMinimum.Point; /// /// Returns the standard errors of the corresponding parameters /// public Vector StandardErrors { get; private set; } /// /// Returns the y-values of the fitted model that correspond to the independent values. /// public Vector MinimizedValues => ModelInfoAtMinimum.ModelValues; /// /// Returns the covariance matrix at minimizing point. /// public Matrix Covariance { get; private set; } /// /// Returns the correlation matrix at minimizing point. /// public Matrix Correlation { get; private set; } public int Iterations { get; } public ExitCondition ReasonForExit { get; } public NonlinearMinimizationResult(IObjectiveModel modelInfo, int iterations, ExitCondition reasonForExit) { ModelInfoAtMinimum = modelInfo; Iterations = iterations; ReasonForExit = reasonForExit; EvaluateCovariance(modelInfo); } private void EvaluateCovariance(IObjectiveModel objective) { objective.EvaluateAt(objective.Point); // Hessian may be not yet updated. var Hessian = objective.Hessian; if (Hessian == null || objective.DegreeOfFreedom < 1) { Covariance = null; Correlation = null; StandardErrors = null; return; } Covariance = Hessian.PseudoInverse() * objective.Value / objective.DegreeOfFreedom; if (Covariance != null) { StandardErrors = Covariance.Diagonal().PointwiseSqrt(); var correlation = Covariance.Clone(); var d = correlation.Diagonal().PointwiseSqrt(); var dd = d.OuterProduct(d); Correlation = correlation.PointwiseDivide(dd); } else { StandardErrors = null; Correlation = null; } } } }