public static MinimizationResult OfFunction(Func <Vector <double>, double> function, Vector <double> initialGuess, double tolerance = 1e-8, int maxIterations = 1000) { var objective = ObjectiveFunction.Value(v => function(v)); var result = NelderMeadSimplex.Minimum(objective, initialGuess, tolerance, maxIterations); return(result); }
/// <summary> /// Find vector x that minimizes the function f(x) using the Nelder-Mead Simplex algorithm. /// For more options and diagnostics consider to use <see cref="NelderMeadSimplex"/> directly. /// </summary> public static (double P0, double P1, double P2, double P3) OfFunction(Func <double, double, double, double, double> function, double initialGuess0, double initialGuess1, double initialGuess2, double initialGuess3, double tolerance = 1e-8, int maxIterations = 1000) { var objective = ObjectiveFunction.Value(v => function(v[0], v[1], v[2], v[3])); var result = NelderMeadSimplex.Minimum(objective, CreateVector.Dense(new[] { initialGuess0, initialGuess1, initialGuess2, initialGuess3 }), tolerance, maxIterations); return(result.MinimizingPoint[0], result.MinimizingPoint[1], result.MinimizingPoint[2], result.MinimizingPoint[3]); }
//RegressionResult double runCalculation(SimplexConstant[] consts) { ObjectiveFunctionDelegate objFunc = new ObjectiveFunctionDelegate(minimizeAngle); RegressionResult result = NelderMeadSimplex.Regress(consts, tolerance, maxEvals, objFunc); return(result.Constants[0]); }
public void OptimizeIsocenterPosition() { var V = Vector <double> .Build; double[] x0 = new double[3] { OptimizedIsocenterX, OptimizedIsocenterY, OptimizedIsocenterZ }; var x0Vec = V.Dense(x0); Func <Vector <double>, double> func = (Vector <double> x) => MaximumDistanceFromRoiCenterOfMasses(x); var objectiveFunction = ObjectiveFunction.Value(func); var solver = new NelderMeadSimplex(ConvergenceTorelance, MaximumIterations); MinimizationResult = solver.FindMinimum(objectiveFunction, x0Vec); MinimizationResultNumberOfIterations = MinimizationResult.Iterations; MinimizationResultReasonForExit = MinimizationResult.ReasonForExit.ToString(); var minPoint = MinimizationResult.MinimizingPoint; MaximumDistance = MaximumDistanceFromRoiCenterOfMasses(minPoint); OptimizedIsocenterX = minPoint[0]; OptimizedIsocenterY = minPoint[1]; OptimizedIsocenterZ = minPoint[2]; }
/// <summary> /// Find vector x that minimizes the function f(x) using the Nelder-Mead Simplex algorithm. /// For more options and diagnostics consider to use <see cref="NelderMeadSimplex"/> directly. /// </summary> public static double OfScalarFunction(Func <double, double> function, double initialGuess, double tolerance = 1e-8, int maxIterations = 1000) { var objective = ObjectiveFunction.Value(v => function(v[0])); var result = NelderMeadSimplex.Minimum(objective, CreateVector.Dense(new[] { initialGuess }), tolerance, maxIterations); return(result.MinimizingPoint[0]); }
public double[] Minimize(Function function, IDistance distance) { var f = new NelderMeadSimplex(1e-15, 100000); var p0 = Vector <double> .Build.Dense(function.GetParametersValues()); var e = f.FindMinimum(new MinimizedFunction(function, distance), p0); return(e.MinimizingPoint.ToArray()); }
/// <summary> /// Test to see if we can fit a parabola /// </summary> public static void SimplexTest1() { Console.WriteLine("Starting SimplexTest1"); SimplexConstant[] constants = new SimplexConstant[] { new SimplexConstant(3, 1), new SimplexConstant(5, 1) }; double tolerance = 1e-6; int maxEvals = 1000; ObjectiveFunctionDelegate objFunction = new ObjectiveFunctionDelegate(_objFunction1); RegressionResult result = NelderMeadSimplex.Regress(constants, tolerance, maxEvals, objFunction); _printResult(result); }
public void NMS_FindMinimum_Rosenbrock_Easy() { var obj = ObjectiveFunction.Value(RosenbrockFunction.Value); var solver = new NelderMeadSimplex(Tolerance * 0.1, maximumIterations: 1000); var initialGuess = new DenseVector(new[] { 1.2, 1.2 }); var result = solver.FindMinimum(obj, initialGuess); Assert.That(Math.Abs(result.MinimizingPoint[0] - 1.0), Is.LessThan(Tolerance)); Assert.That(Math.Abs(result.MinimizingPoint[1] - 1.0), Is.LessThan(Tolerance)); }
/// <summary> /// Test on the Rosenbrock function /// </summary> public static void SimplexTest2() { Console.WriteLine("\n\nStarting SimplexTest2"); // we are regressing for frequency, amplitude, and phase offset SimplexConstant[] constants = new SimplexConstant[] { new SimplexConstant(-1.2, .1), new SimplexConstant(1, .1)}; double tolerance = 1e-10; int maxEvals = 1000; ObjectiveFunctionDelegate objFunction = new ObjectiveFunctionDelegate(_objFunction2); RegressionResult result = NelderMeadSimplex.Regress(constants, tolerance, maxEvals, objFunction); _printResult(result); }
/// <summary> /// Test to see if we can fit a parabola /// </summary> private static void _simplexTest1() { Console.WriteLine("Starting SimplexTest1"); SimplexConstant[] nss = new SimplexConstant[] { new SimplexConstant(0, 1), new SimplexConstant(0, 1), new SimplexConstant(0, 1), new SimplexConstant(0, 1), new SimplexConstant(1, 1), new SimplexConstant(1, 1) }; double[] tt = { 5.0, 10.0, 15.0, 20.0, 25.0 }; double[] Y = { 0.001770949, 0.008396027, 0.013860686, 0.019379306, 0.023731833 }; double tolerance = 1e-6; int maxEvals = 1000; ObjectiveFunctionDelegate objFunction = new ObjectiveFunctionDelegate(_objFunction1); RegressionResult result = NelderMeadSimplex.Regress(nss, tt, Y, tolerance, maxEvals, objFunction); _printResult(result); }
public void SymmetricalOneDimensionalFunction() { var minimizer = new NelderMeadSimplex(Tolerance * 0.1, 500); var initialVec = Vector.Build.DenseOfEnumerable(new[] { 1.0 }); var objFunc = ObjectiveFunction.Value(xSq); var min = minimizer.FindMinimum(objFunc, initialVec); var xForMinimum = min.MinimizingPoint.ToArray(); var minimum = xSq(min.MinimizingPoint); Assert.AreEqual(1.0, minimum, Tolerance, "Minimal function value is not as expected."); Assert.AreEqual(0.0, xForMinimum[0], Tolerance, "x at minimum is not as expected."); }
private void TuneLanguageModel(string lmPrefix, IList <IReadOnlyList <string> > tuneTargetCorpus, int ngramSize) { if (tuneTargetCorpus.Count == 0) { return; } var simplex = new NelderMeadSimplex(0.1, 200, 1.0); MinimizationResult result = simplex.FindMinimum(w => CalculatePerplexity(tuneTargetCorpus, lmPrefix, ngramSize, w), Enumerable.Repeat(0.5, ngramSize * 3)); WriteLanguageModelWeightsFile(lmPrefix, ngramSize, result.MinimizingPoint); Stats.LanguageModelPerplexity = result.ErrorValue; }
/// <summary> /// <para>Unscented transform parameters optimization procedure.</para> /// <para>The OptimizationMethod param determines the optimization method:</para> /// <para>- OptimizationMethod.RandomShoot - parameters are randomly sampled and the best sample is chosen as optimal; /// <para>- OptimizationMethod.NelderMeed - parameters are optimized with non-gradient Nelder-Meed method.</para> /// <para>The UTOptimizationType type param determines the relation between the optimized variable and the unscented tranform params (see UTParams and its constructors for details). </para> /// <para>- If type is UTOptimizationType.ImplicitAlpha, then the optimized variable is saclar [alpha0];</para> /// <para>- If type is UTOptimizationType.ImplicitAlphaBetaKappa, then optimized variable is a vector [alpha, beta, kappa];</para> /// <para>- If type is UTOptimizationType.Explicit, then then optimized variable is a vector [lambda, wm0, wc0, wi]. ///TODO it is not correct to define the parameters of the unsctnted transform arbitraty, they have to be interdependent, so that the mean and cov would be transformed correctly.</para> /// </summary> /// <param name="method">Unscented transform parameters optimization method</param> /// <param name="type">Unscented transform parameters definition type</param> /// <param name="Phi1">State transformation: a nonlinear function which determines the dynamics: x_{t+1} = Phi_1(x_t) + Phi_2(x_t) W_t</param> /// <param name="Phi2">Noise multiplicator in the dynamics equation: x_{t+1} = Phi(x_t) + W_t</param> /// <param name="Psi1">Observations transformation: a nonlinear function which determines the relation between the state and the observations: y_t = Psi_1(x_t) + Psi_2(x_t) Nu_t</param> /// <param name="Psi2">Noise multiplicator in the observations equation: y_t = Psi_1(x_t) + Psi_2(x_t) Nu_t</param> /// <param name="Mw">Mean of the noise in the dynamics equation </param> /// <param name="Rw">Covariance matrix of the state disturbances</param> /// <param name="Mnu">Mean of the noise in the obseration equation </param> /// <param name="Rnu">Convariance matrix of the observation noise</param> /// <param name="Crit">Criterion: a function which determines the quality of the unscented Kalman filter. Depends on the sample covariance of the estimation error on the last step: val = Crit(Cov(X_T-Xhat_T,X_T-Xhat_T)) </param> /// <param name="T">The upper bound of the observation interval</param> /// <param name="models">Discrete vector model samples</param> /// <param name="xhat0">Initial condition</param> /// <param name="DX0Hat">Initial condition covariance</param> /// <param name="outputFolder">The results are saved to this folder in file "UT_optimization_{type}.txt"</param> static (double, UTParams, UTParams) UTParmsOptimize(OptimizationMethod method, UTDefinitionType type, Func <int, Vector <double>, Vector <double> > Phi1, Func <int, Vector <double>, Matrix <double> > Phi2, Func <int, Vector <double>, Vector <double> > Psi1, Func <int, Vector <double>, Matrix <double> > Psi2, Vector <double> Mw, Matrix <double> Rw, Vector <double> Mnu, Matrix <double> Rnu, Func <Matrix <double>, double> Crit, int T, DiscreteVectorModel[] models, Vector <double> xhat0, Matrix <double> DX0Hat, string outputFolder) { (int n, Vector <double> lowerBound, Vector <double> upperBound, Vector <double> initialGuess, string filename) = DefineOptimizationParameters(type, xhat0, string.IsNullOrWhiteSpace(outputFolder) ? null : Path.Combine(outputFolder, "UT_optimization_{type}.txt")); double min = double.MaxValue; Vector <double> argmin = Exts.Stack(initialGuess, initialGuess); switch (method) { case OptimizationMethod.RandomShoot: var OptimumRandom = RandomOptimizer.Minimize((x) => CalculateSampleCriterion(Phi1, Phi2, Psi1, Psi2, Mw, Rw, Mnu, Rnu, Crit, x, T, models, xhat0, DX0Hat), Exts.Stack(lowerBound, lowerBound), Exts.Stack(upperBound, upperBound), 100, 100, filename); min = OptimumRandom.min; argmin = OptimumRandom.argmin; break; case OptimizationMethod.NelderMeed: NelderMeadSimplex optimizer = new NelderMeadSimplex(1e-3, 100); var objective = ObjectiveFunction.Value((x) => CalculateSampleCriterion(Phi1, Phi2, Psi1, Psi2, Mw, Rw, Mnu, Rnu, Crit, x, T, models, xhat0, DX0Hat)); try { var optimumNM = optimizer.FindMinimum(objective, Exts.Stack(initialGuess, initialGuess)); min = optimumNM.FunctionInfoAtMinimum.Value; argmin = optimumNM.MinimizingPoint; } catch (Exception e) { Console.WriteLine($"Optimizer faild, using the initail guess ({e.Message})"); argmin = Exts.Stack(initialGuess, initialGuess); } break; default: // no optimization by default break; } return(min, new UTParams(xhat0.Count, argmin.Take(n).ToArray()), new UTParams(xhat0.Count, argmin.Skip(n).Take(n).ToArray())); }
public void Execute() { NelderMeadSimplex solver = new NelderMeadSimplex(jobConvergenceTolerance, jobMaxIterations); var V = Vector <double> .Build; var meJob = this; var f1 = new Func <Vector <double>, double>(angleVec => RobotController.ErrorFunction(meJob.targetPos, meJob.targetRot, angleVec.ToArray(), meJob.jobAngleMins.ToArray(), meJob.jobAngleMaxes.ToArray(), meJob.jobBasePos, meJob.jobBaseRot, meJob.jobRotAxes.ToArray(), meJob.jobTransAxes.ToArray(), meJob.jobStartOffsets.ToArray())); var obj = ObjectiveFunction.Value(f1); MinimizationResult result; try { result = solver.FindMinimum(obj, V.DenseOfArray(jobAngles.ToArray())); for (int i = 0; i < 5; i++) { if (result.FunctionInfoAtMinimum.Value > jobDistanceThreshold) { f1 = new Func <Vector <double>, double>(angleVec => RobotController.ErrorFunction(meJob.targetPos, meJob.targetRot, angleVec.ToArray(), meJob.jobAngleMins.ToArray(), meJob.jobAngleMaxes.ToArray(), meJob.jobBasePos, meJob.jobBaseRot, meJob.jobRotAxes.ToArray(), meJob.jobTransAxes.ToArray(), meJob.jobStartOffsets.ToArray())); obj = ObjectiveFunction.Value(f1); MinimizationResult result2; try { result2 = solver.FindMinimum(obj, V.DenseOfArray(jobAngles.ToArray()) + (V.Random(jobAngles.Length) * (i + 1) * (i + 1) * (i + 1))); if (result2 != null && result2.FunctionInfoAtMinimum.Value < result.FunctionInfoAtMinimum.Value) { result = result2; } } catch (MaximumIterationsException e) { Debug.Log(e); } } else { break; } } jobAngles.CopyFrom(result.MinimizingPoint.ToArray()); } catch (MaximumIterationsException e) { Debug.Log(e); } }
// Run cost minimization Vector3 IDecisionManager.getNextDesiredPoint() { // What are the variables to minimize (position) SimplexConstant[] constants = new SimplexConstant[] { new SimplexConstant(this.sensorModule.gps.position.x, 1), new SimplexConstant(this.sensorModule.gps.position.y, 1), new SimplexConstant(this.sensorModule.gps.position.z, 1) }; double tolerance = 1e-30; int maxEvals = 10000; // What's the objective function ObjectiveFunctionDelegate objFunction = new ObjectiveFunctionDelegate(_objFunction1); RegressionResult result = NelderMeadSimplex.Regress(constants, tolerance, maxEvals, objFunction); Vector3 r = new Vector3((float)result.Constants[0], (float)result.Constants[1], (float)result.Constants[2]); // Debug.Log (result.TerminationReason.ToString ()); return(r); }
public void Minimize() { SetCoefficients(); Console.WriteLine("Starting minimization..."); SimplexConstant[] constants = new SimplexConstant[Coefficients.Length]; for (int i = 0; i < Coefficients.Length; i++) { constants[i] = new SimplexConstant(Coefficients[i], Math.Abs(Coefficients[i]) / 2); } double tolerance = 1e-6; int maxEvals = 1000; ObjectiveFunctionDelegate objFunction = new ObjectiveFunctionDelegate(SpiderObjectiveFunction); RegressionResult result = NelderMeadSimplex.Regress(constants, tolerance, maxEvals, objFunction); Coefficients = result.Constants; PrintCoefficients(Coefficients); }
public void Mgh_Tests(TestFunctions.TestCase test_case) { var obj = new MghObjectiveFunction(test_case.Function, true, true); var result = NelderMeadSimplex.Minimum(obj, test_case.InitialGuess, 1e-8, 1000); if (test_case.MinimizingPoint != null) { Assert.That((result.MinimizingPoint - test_case.MinimizingPoint).L2Norm(), Is.LessThan(1e-3)); } var val1 = result.FunctionInfoAtMinimum.Value; var val2 = test_case.MinimalValue; var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2)); var abs_err = Math.Abs(val1 - val2); var rel_err = abs_err / abs_min; var success = (abs_min <= 1 && abs_err < 1e-3) || (abs_min > 1 && rel_err < 1e-3); Assert.That(success, "Minimal function value is not as expected."); }
void Start() { angles = new double[Joints.Length]; angleMins = new float[Joints.Length]; angleMaxes = new float[Joints.Length]; rotAxes = new Vector3[Joints.Length]; transAxes = new Vector3[Joints.Length]; startOffsets = new Vector3[Joints.Length]; for (int i = 0; i < Joints.Length; i++) { angleMins[i] = Joints[i].GetComponent <SimpleRobotJoint>().minVal * 360; angleMaxes[i] = Joints[i].GetComponent <SimpleRobotJoint>().maxVal * 360; rotAxes[i] = Joints[i].GetComponent <SimpleRobotJoint>().rotateAxis; transAxes[i] = Joints[i].GetComponent <SimpleRobotJoint>().translateAxis; startOffsets[i] = Joints[i].GetComponent <SimpleRobotJoint>().StartOffset; } solver = new NelderMeadSimplex(convergenceTolerance, MaxIterations); ikJobHandle = new JobHandle(); }
public ThotSmtParameters Tune(ThotSmtParameters parameters, IReadOnlyList <IReadOnlyList <string> > tuneSourceCorpus, IReadOnlyList <IReadOnlyList <string> > tuneTargetCorpus, ThotTrainProgressReporter reporter, SmtBatchTrainStats stats) { float sentLenWeight = parameters.ModelWeights[7]; int numFuncEvals = 0; double Evaluate(Vector weights) { ThotSmtParameters newParameters = parameters.Clone(); newParameters.ModelWeights = weights.Select(w => (float)w).Concat(sentLenWeight).ToArray(); newParameters.Freeze(); double quality = CalculateBleu(newParameters, tuneSourceCorpus, tuneTargetCorpus); numFuncEvals++; if (numFuncEvals < MaxFunctionEvaluations && ProgressIncrementInterval > 0 && numFuncEvals % ProgressIncrementInterval == 0) { reporter.Step(); } else { reporter.CheckCanceled(); } return(quality); }; var simplex = new NelderMeadSimplex(ConvergenceTolerance, MaxFunctionEvaluations, 1.0); MinimizationResult result = simplex.FindMinimum(Evaluate, parameters.ModelWeights.Select(w => (double)w).Take(7)); stats.TranslationModelBleu = 1.0 - result.ErrorValue; ThotSmtParameters bestParameters = parameters.Clone(); bestParameters.ModelWeights = result.MinimizingPoint.Select(w => (float)w).Concat(sentLenWeight).ToArray(); bestParameters.Freeze(); return(bestParameters); }
public ThotSmtParameters Tune(ThotSmtParameters parameters, IReadOnlyList <IReadOnlyList <string> > tuneSourceCorpus, IReadOnlyList <IReadOnlyList <string> > tuneTargetCorpus, SmtBatchTrainStats stats, IProgress <ProgressStatus> progress) { float sentLenWeight = parameters.ModelWeights[7]; int numFuncEvals = 0; double Evaluate(Vector weights) { ThotSmtParameters newParameters = parameters.Clone(); newParameters.ModelWeights = weights.Select(w => (float)w).Concat(sentLenWeight).ToArray(); newParameters.Freeze(); double quality = CalculateBleu(newParameters, tuneSourceCorpus, tuneTargetCorpus); numFuncEvals++; int currentStep = Math.Min(numFuncEvals, MaxProgressFunctionEvaluations); progress.Report(new ProgressStatus(currentStep, MaxProgressFunctionEvaluations)); return(quality); }; progress.Report(new ProgressStatus(0, MaxFunctionEvaluations)); var simplex = new NelderMeadSimplex(ConvergenceTolerance, MaxFunctionEvaluations, 1.0); MinimizationResult result = simplex.FindMinimum(Evaluate, parameters.ModelWeights.Select(w => (double)w).Take(7)); stats.TranslationModelBleu = 1.0 - result.ErrorValue; ThotSmtParameters bestParameters = parameters.Clone(); bestParameters.ModelWeights = result.MinimizingPoint.Select(w => (float)w).Concat(sentLenWeight).ToArray(); bestParameters.Freeze(); if (result.FunctionEvaluationCount < MaxProgressFunctionEvaluations) { progress.Report(new ProgressStatus(1.0)); } return(bestParameters); }
private void optimizeVolumes(Individual individual) { //Initialization for optimizer double p = 0; double[] organWeightsInit = null; uint numberOfTry = 0; _objectiveWeight = individual.InputWeight; while (p == 0) { //Random organ weight organWeightsInit = organWeightsFrom(createRandomOrgansVolumesFrom(individual, getOrganVolumeForIndividual)); //skale skin organWeightsInit[_skinIndex] = getDefaultSkinWeight(_muSigmas[_skinIndex]); //compensate with fat to get our target weight updateFatWeight(organWeightsInit); p = probabilityOrgans(organWeightsInit); numberOfTry++; if (numberOfTry > _maxIterations) { throw new CannotCreateIndividualWithConstraintsException(_reportGenerator.StringReportFor(individual.OriginData)); } } //Start optimization var result = NelderMeadSimplex.Regress(simplexConstantFrom(organWeightsNonFatFrom(organWeightsInit)), 1e-6, 10000, probabilityOrgansWrapper); //Retrieve results and scale fat volume to match objective bodyweight var organWeights = organWeightsWithFatFrom(transformedWeights(result.Constants)); setOrganVolumesTo(individual, organVolumesFrom(organWeights)); }
protected override CalibrationCurve FitPoints(IList <WeightedPoint> weightedPoints) { double?bestLod = null; double bestScore = double.MaxValue; var xValues = weightedPoints.Select(pt => pt.X).Distinct().OrderBy(x => x).ToArray(); for (int i = 0; i < xValues.Length - 1; i++) { var simplexConstant = new NelderMeadSimplex.SimplexConstant((xValues[i] + xValues[i + 1]) / 2, (xValues[i + 1] - xValues[i]) / 4); var regressionResult = NelderMeadSimplex.Regress(new[] { simplexConstant }, 0, 50, constants => LodObjectiveFunction(constants[0], weightedPoints)); if (regressionResult.ErrorValue < bestScore) { bestLod = regressionResult.Constants[0]; bestScore = regressionResult.ErrorValue; } } if (!bestLod.HasValue) { return(LinearFit(weightedPoints)); } return(GetCalibrationCurveWithLod(bestLod.Value, weightedPoints)); }
/// <summary> /// <para>Unscented transform parameters stepwize optimization procedure.</para> /// <para>The OptimizationMethod param determines the optimization method:</para> /// <para>- OptimizationMethod.RandomShoot - parameters are randomly sampled and the best sample is chosen as optimal; /// <para>- OptimizationMethod.NelderMeed - parameters are optimized with non-gradient Nelder-Meed method.</para> /// <para>The UTOptimizationType type param determines the relation between the optimized variable and the unscented tranform params (see UTParams and its constructors for details). </para> /// <para>- If type is UTOptimizationType.ImplicitAlpha, then the optimized variable is saclar [alpha0];</para> /// <para>- If type is UTOptimizationType.ImplicitAlphaBetaKappa, then optimized variable is a vector [alpha, beta, kappa];</para> /// <para>- If type is UTOptimizationType.Explicit, then then optimized variable is a vector [lambda, wm0, wc0, wi]. ///TODO it is not correct to define the parameters of the unsctnted transform arbitraty, they have to be interdependent, so that the mean and cov would be transformed correctly.</para> /// </summary> /// <param name="method">Unscented transform parameters optimization method</param> /// <param name="type">Unscented transform parameters definition type</param> /// <param name="Phi1">State transformation: a nonlinear function which determines the dynamics: x_{t+1} = Phi_1(x_t) + Phi_2(x_t) W_t</param> /// <param name="Phi2">Noise multiplicator in the dynamics equation: x_{t+1} = Phi(x_t) + W_t</param> /// <param name="Psi1">Observations transformation: a nonlinear function which determines the relation between the state and the observations: y_t = Psi_1(x_t) + Psi_2(x_t) Nu_t</param> /// <param name="Psi2">Noise multiplicator in the observations equation: y_t = Psi_1(x_t) + Psi_2(x_t) Nu_t</param> /// <param name="Mw">Mean of the noise in the dynamics equation </param> /// <param name="Rw">Covariance matrix of the state disturbances</param> /// <param name="Mnu">Mean of the noise in the obseration equation </param> /// <param name="Rnu">Convariance matrix of the observation noise</param> /// <param name="Crit">Criterion: a function which determines the quality of the unscented Kalman filter. Depends on the sample covariance of the estimation error on the last step: val = Crit(Cov(X_T-Xhat_T,X_T-Xhat_T)) </param> /// <param name="T">The upper bound of the observation interval</param> /// <param name="models">Discrete vector model samples</param> /// <param name="xhat0">Initial condition</param> /// <param name="DX0Hat">Initial condition covariance</param> /// <param name="outputFolder">The results are saved to this folder in file "UT_optimization_{type}.txt"</param> static (double, UTParams[], UTParams[]) UTParmsOptimizeStepwise(OptimizationMethod method, UTDefinitionType type, Func <int, Vector <double>, Vector <double> > Phi1, Func <int, Vector <double>, Matrix <double> > Phi2, Func <int, Vector <double>, Vector <double> > Psi1, Func <int, Vector <double>, Matrix <double> > Psi2, Vector <double> Mw, Matrix <double> Rw, Vector <double> Mnu, Matrix <double> Rnu, Func <Matrix <double>, double> Crit, int T, DiscreteVectorModel[] models, Vector <double> xhat0, Matrix <double> DX0Hat, string outputFolder) { UTParams[] pForecast = new UTParams[T]; UTParams[] pCorrect = new UTParams[T]; (int n, Vector <double> lowerBound, Vector <double> upperBound, Vector <double> initialGuess, string filename) = DefineOptimizationParameters(type, xhat0, string.IsNullOrWhiteSpace(outputFolder) ? null : Path.Combine(outputFolder, "UT_stepwise_ptimization_{type}.txt")); Vector <double>[] xHatU = models.Select(x => xhat0).ToArray(); Matrix <double>[] PHatU = models.Select(x => DX0Hat).ToArray(); double min = double.MaxValue; Console.WriteLine($"UKF estimate parameters start"); DateTime start = DateTime.Now; for (int t = 1; t < T; t++) //Parallel.For(0, T, new ParallelOptions() { MaxDegreeOfParallelism = System.Environment.ProcessorCount }, t => { DateTime startiteration = DateTime.Now; min = double.MaxValue; Vector <double> argmin = initialGuess; switch (method) { case OptimizationMethod.RandomShoot: var OptimumRandom = RandomOptimizer.Minimize((x) => CalculateSampleStepwiseCriterion(Phi1, Phi2, Psi1, Psi2, Mw, Rw, Mnu, Rnu, Crit, x, t, models, xHatU, PHatU), Exts.Stack(lowerBound, lowerBound), Exts.Stack(upperBound, upperBound), 100, 100, filename); min = OptimumRandom.min; argmin = OptimumRandom.argmin; break; case OptimizationMethod.NelderMeed: NelderMeadSimplex optimizer = new NelderMeadSimplex(1e-3, 100); var objective = ObjectiveFunction.Value((x) => CalculateSampleStepwiseCriterion(Phi1, Phi2, Psi1, Psi2, Mw, Rw, Mnu, Rnu, Crit, x, t, models, xHatU, PHatU)); try { var optimumNM = optimizer.FindMinimum(objective, Exts.Stack(initialGuess, initialGuess)); min = optimumNM.FunctionInfoAtMinimum.Value; argmin = optimumNM.MinimizingPoint; } catch (Exception e) { Console.WriteLine($"Optimizer faild, using the initail guess ({e.Message})"); argmin = Exts.Stack(initialGuess, initialGuess); } break; } pForecast[t] = new UTParams(xhat0.Count, argmin.Take(n).ToArray()); pCorrect[t] = new UTParams(xhat0.Count, argmin.Skip(n).Take(n).ToArray()); for (int i = 0; i < models.Count(); i++) { (xHatU[i], PHatU[i]) = Step(Phi1, Phi2, Psi1, Psi2, Mw, Rw, Mnu, Rnu, pForecast[t], pCorrect[t], t, models[i].Trajectory[t][1], xHatU[i], PHatU[i]); } Console.WriteLine($"UKF estimate parameters for t={t}, done in {(DateTime.Now - startiteration).ToString(@"hh\:mm\:ss\.fff")}"); } // }); DateTime finish = DateTime.Now; Console.WriteLine($"UKF estimate parameters finished in {(finish - start).ToString(@"hh\:mm\:ss\.fff")}"); return(min, pForecast, pCorrect); }
protected override OptimizationRunProperties RunOptimization() { var result = NelderMeadSimplex.Regress(createSimplexConstants(), ConvergenceTolerance, MaxEvaluation, values => _objectiveFunc(ParameterValuesFrom(values)).TotalError); return(new OptimizationRunProperties(result.EvaluationCount)); }
/// <summary> /// <para>Unscented transform parameters optimization procedure.</para> /// <para>The OptimizationMethod param determines the optimization method:</para> /// <para>- OptimizationMethod.RandomShoot - parameters are randomly sampled and the best sample is chosen as optimal; /// <para>- OptimizationMethod.NelderMeed - parameters are optimized with non-gradient Nelder-Meed method.</para> /// <para>The UTOptimizationType type param determines the relation between the optimized variable and the unscented tranform params (see UTParams and its constructors for details). </para> /// <para>- If type is UTOptimizationType.ImplicitAlpha, then the optimized variable is saclar [alpha0];</para> /// <para>- If type is UTOptimizationType.ImplicitAlphaBetaKappa, then optimized variable is a vector [alpha, beta, kappa];</para> /// <para>- If type is UTOptimizationType.Explicit, then then optimized variable is a vector [lambda, wm0, wc0, wi]. ///TODO it is not correct to define the parameters of the unsctnted transform arbitraty, they have to be interdependent, so that the mean and cov would be transformed correctly.</para> /// </summary> /// <param name="method">Unscented transform parameters optimization method</param> /// <param name="type">Unscented transform parameters definition type</param> /// <param name="Phi">Transformation: a nonlinear function which determines the transformation of the random vector variable: y = Phi(x) + nu</param> /// <param name="Crit">Criterion: a function which determines the quality of the unscented transform estimate. Depends on the sample covariance of the estimation error: val = Crit(Cov(X-Xhat,X-Xhat)) </param> /// <param name="X">Array of initial variable x samples</param> /// <param name="Y">Array of transformed variable y = Phi(x) + nu samples</param> /// <param name="mX">Mean of x</param> /// <param name="KX">Cov of x</param> /// <param name="KNu">Cov of the noize nu</param> /// <param name="outputFolder">If needed, the results or the random sampling (OptimizationMethod.RandomShoot) are saved to this folder in file "UT_optimization_{type}.txt"</param> /// <returns>Returns touple (the best criteron value, the parameters of the unscented transform with best estimation quality)</returns> static (double, UTParams) UTParmsOptimize(OptimizationMethod method, UTDefinitionType type, Func <Vector <double>, Vector <double> > Phi, Func <Matrix <double>, double> Crit, Vector <double>[] X, Vector <double>[] Y, Vector <double> mX, Matrix <double> KX, Matrix <double> KNu, string outputFolder = null ) { int n; string filename = string.IsNullOrWhiteSpace(outputFolder) ? null : Path.Combine(outputFolder, "UT_optimization_{type}.txt"); Vector <double> lowerBound; Vector <double> upperBound; Vector <double> initialGuess; switch (type) { case UTDefinitionType.ImplicitAlpha: n = 1; lowerBound = Exts.Vector(1 - 2 / mX.Count); upperBound = Exts.Vector(1); initialGuess = Exts.Vector(0.5); filename = filename.Replace("{type}", "ImplicitAlpha"); break; case UTDefinitionType.ImplicitAlphaBetaKappa: n = 3; lowerBound = Exts.Vector(0, 0, 3.0 - mX.Count - 2.0); upperBound = Exts.Vector(5, 5, 3.0 - mX.Count + 2.0); initialGuess = Exts.Vector(0.5, 2.0, 3.0 - mX.Count); filename = filename.Replace("{type}", "ImplicitABK"); break; case UTDefinitionType.Explicit: n = 4; lowerBound = Exts.Vector(-10, -10, -10, -10); upperBound = Exts.Vector(10, 10, 10, 10); initialGuess = Exts.Vector((new UTParams(mX.Count, 0.5, 2.0, 3.0 - mX.Count)).Params); filename = filename.Replace("{type}", "Explicit"); break; default: n = 0; lowerBound = null; upperBound = null; initialGuess = null; break; } double min = double.MaxValue; Vector <double> argmin = initialGuess; switch (method) { case OptimizationMethod.RandomShoot: var OptimumRandom = RandomOptimizer.Minimize((p) => CalculateSampleCriterion(Phi, Crit, p, X, Y, mX, KX, KNu), lowerBound, upperBound, 1000, 1000, filename); min = OptimumRandom.min; argmin = OptimumRandom.argmin; break; case OptimizationMethod.NelderMeed: NelderMeadSimplex optimizer = new NelderMeadSimplex(1e-3, 100); var objective = ObjectiveFunction.Value((p) => CalculateSampleCriterion(Phi, Crit, p, X, Y, mX, KX, KNu)); var optimumNM = optimizer.FindMinimum(objective, initialGuess); min = optimumNM.FunctionInfoAtMinimum.Value; argmin = optimumNM.MinimizingPoint; break; } return(min, new UTParams(mX.Count, argmin.AsArray())); }
private ResultData CalculateHalfLife(ICollection <ProcessedRowData> rowDatas) { IEnumerable <ProcessedRowData> filteredRowDatas; if (EvviesFilter != EvviesFilterEnum.None) { var applicableRowDatas = new List <ProcessedRowData>(); var values = new Dictionary <double, List <double> >(); var filteredRowDataList = new List <ProcessedRowData>(); foreach (var rowData in rowDatas) { Debug.Assert(RejectReason.EvviesFilter != rowData.RejectReason); if (null != rowData.RejectReason) { continue; } var value = rowData.Turnover; if (!value.HasValue || double.IsNaN(value.Value) || double.IsInfinity(value.Value)) { continue; } var timePoint = GetTimePoint(rowData.RawRowData); if (!timePoint.HasValue) { filteredRowDataList.Add(rowData); continue; } List <double> list; if (!values.TryGetValue(timePoint.Value, out list)) { list = new List <double>(); values.Add(timePoint.Value, list); } list.Add(value.Value); applicableRowDatas.Add(rowData); } if (EvviesFilter == EvviesFilterEnum.Oct2011) { foreach (var entry in values.ToArray()) { var statistics = new Statistics(entry.Value.ToArray()); var min = statistics.Median() - 3 * statistics.StdDev(); var max = statistics.Median() + 3 * statistics.StdDev(); if (statistics.Median() + 2 * statistics.StdDev() >= .99) { // Throw away any values of 100% or 99% if they are more than 2 SD above the median. max = Math.Min(.99, max); } var newValues = entry.Value.Where(v => v >= min && v <= max).ToList(); if (newValues.Count != entry.Value.Count) { values[entry.Key] = newValues; } } } var cutoffs = new Dictionary <double, KeyValuePair <double, double> >(); foreach (var entry in values) { var statistics = new Statistics(entry.Value.ToArray()); var mean = statistics.Mean(); var stdDev = statistics.StdDev(); double cutoff; if (EvviesFilter == EvviesFilterEnum.TwoStdDev) { cutoff = 2 * stdDev; } else { if (stdDev / mean < .3) { cutoff = 2 * stdDev; } else { cutoff = stdDev; } } cutoffs.Add(entry.Key, new KeyValuePair <double, double>(mean - cutoff, mean + cutoff)); } foreach (var rowData in applicableRowDatas) { var cutoff = cutoffs[GetTimePoint(rowData.RawRowData).Value]; var value = rowData.Turnover; rowData.EvviesFilterMin = cutoff.Key; rowData.EvviesFilterMax = cutoff.Value; // Only apply Evvie's Filter to rows that has a time point. if (GetTimePoint(rowData.RawRowData).HasValue) { if (value.Value < cutoff.Key || value.Value > cutoff.Value) { Debug.Assert(null == rowData.RejectReason); rowData.RejectReason = RejectReason.EvviesFilter; continue; } } filteredRowDataList.Add(rowData); } filteredRowDatas = filteredRowDataList; } else { filteredRowDatas = rowDatas.Where(rowData => null == rowData.RejectReason).ToArray(); } if (HalfLifeSettings.SimpleLinearRegression) { var timePoints = new List <double>(); var logValues = new List <double>(); foreach (var rowData in filteredRowDatas) { if (null != rowData.RejectReason) { continue; } double?logValue = Math.Log(1 - rowData.Turnover.Value); if (!logValue.HasValue || double.IsNaN(logValue.Value) || double.IsInfinity(logValue.Value)) { rowData.RejectReason = RejectReason.ValueOutOfRange; continue; } double?timePoint = GetTimePoint(rowData.RawRowData); if (!timePoint.HasValue || ExcludedTimePoints.Contains(timePoint.Value)) { rowData.RejectReason = RejectReason.NoTimePoint; continue; } logValues.Add(logValue.Value); timePoints.Add(timePoint.Value); } var statsTimePoints = new Statistics(timePoints.ToArray()); var statsLogValues = new Statistics(logValues.ToArray()); double rateConstant, stDevRateConstant, rateConstantError, yIntercept; double?rSquared = null; if (FixedInitialPercent) { rateConstant = statsLogValues.SlopeWithoutIntercept(statsTimePoints); stDevRateConstant = Statistics.StdDevSlopeWithoutIntercept(statsLogValues, statsTimePoints); rateConstantError = stDevRateConstant * GetErrorFactor(timePoints.Count - 1); yIntercept = 0; } else { rateConstant = statsLogValues.Slope(statsTimePoints); stDevRateConstant = Statistics.StdDevB(statsLogValues, statsTimePoints); rateConstantError = stDevRateConstant * GetErrorFactor(timePoints.Count - 2); yIntercept = Statistics.Intercept(statsLogValues, statsTimePoints); rSquared = Math.Pow(Statistics.R(statsLogValues, statsTimePoints), 2); } return(new ResultData { RateConstant = rateConstant, RateConstantStdDev = stDevRateConstant, RateConstantError = rateConstantError, PointCount = timePoints.Count, YIntercept = yIntercept, RSquared = rSquared, RowDatas = rowDatas.ToArray(), FilteredRowDatas = filteredRowDatas.ToArray(), }); } else { var dataPoints = new List <KeyValuePair <double, double> >(); foreach (var rowData in filteredRowDatas) { double?time = rowData.RawRowData.MsDataFile.TimePoint; double?y; y = 1 - rowData.Turnover; if (!y.HasValue || !time.HasValue) { continue; } dataPoints.Add(new KeyValuePair <double, double>(time.Value, y.Value)); } var timePoints = Workspace.MsDataFiles.Select(msDataFile => msDataFile.TimePoint) .Where(timePoint => timePoint.HasValue).ToList(); var resultData = new ResultData { PointCount = dataPoints.Count, FilteredRowDatas = filteredRowDatas.ToArray(), RowDatas = rowDatas.ToArray(), }; if (resultData.RowDatas.Count == 0 || timePoints.Count == 0) { resultData.RateConstant = double.NaN; resultData.YIntercept = double.NaN; return(resultData); } NelderMeadSimplex.SimplexConstant[] initialParameters; double convergenceTolerance = 0; int maxEvaluations = 1000; if (FixedInitialPercent) { timePoints.Add(0); double timePointDifference = timePoints.Max().Value - timePoints.Min().Value; initialParameters = new[] { new NelderMeadSimplex.SimplexConstant(1 / timePointDifference, 1.0 / 10 / timePointDifference) }; var regressionResult = NelderMeadSimplex.Regress(initialParameters, convergenceTolerance, maxEvaluations, constants => SumOfResidualsSquared( x => Math.Exp(-constants[0] * x), dataPoints)); resultData.RateConstant = -regressionResult.Constants[0]; } else { double timePointDifference = timePoints.Max().Value - timePoints.Min().Value; initialParameters = new[] { new NelderMeadSimplex.SimplexConstant(1 / timePointDifference, 1.0 / 10 / timePointDifference), new NelderMeadSimplex.SimplexConstant(0, .1), }; var regressionResult = NelderMeadSimplex.Regress(initialParameters, convergenceTolerance, maxEvaluations, constants => SumOfResidualsSquared(x => Math.Exp(-constants[0] * x + constants[1]), dataPoints)); resultData.RateConstant = -regressionResult.Constants[0]; resultData.YIntercept = regressionResult.Constants[1]; } return(resultData); } }