Пример #1
0
        /// <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()));
        }
Пример #2
0
        /// <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()));
        }
Пример #3
0
        /// <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);
        }