public TestSimpleIdentification()
        {
            TestName     = "Простая модель с идентификацией";
            TestFileName = "TestSimpleIdentification";


            Vector <double> mW = Exts.Vector(0, 0); Matrix <double> dW = Exts.Diag(0, 1.0);
            Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(1.0);
            Vector <double> mEta = Exts.Vector(0, 0.0); Matrix <double> dEta = Exts.Diag(0.27, 0);
            Func <int, Vector <double>, Vector <double> > phi1 = (s, x) => Exts.Vector(x[0], x[0] * x[1]);
            Func <int, Vector <double>, Matrix <double> > phi2 = (s, x) => Exts.Diag(0.0, 1.0);
            Func <int, Vector <double>, Vector <double> > psi1 = (s, x) => Exts.Vector(x[1]);
            Func <int, Vector <double>, Matrix <double> > psi2 = (s, x) => Exts.Matrix(0.1);

            RandomVector <Normal> NormalW  = new RandomVector <Normal>(mW, dW);
            RandomVector <Normal> NormalNu = new RandomVector <Normal>(mNu, dNu);
            ContinuousUniform     UniformW = new ContinuousUniform(-0.9, 0.9);

            Phi1 = phi1;
            Phi2 = phi2;
            Psi1 = psi1;
            Psi2 = psi2;
            Xi   = (s, x) => phi1(s, x) + phi2(s, x) * mW;
            Zeta = (s, x, y, k) => y - psi1(s, x) - psi2(s, x) * mNu;


            W      = (s) => NormalW.Sample();
            Nu     = (s) => NormalNu.Sample();
            DW     = dW;
            DNu    = dNu;
            X0     = () => Exts.Vector(UniformW.Sample(), 0.0);
            X0Hat  = mEta;
            DX0Hat = dEta;
        }
        public TestInverseProportionBadScalar(double bound, double _dw, double _dnu)
        {
            TestName     = "Обратнопропорциональная зависимость (неуст)";
            TestFileName = "InverseProportionBad";

            Vector <double> mW = Exts.Vector(0); Matrix <double> dW = Exts.Diag(_dw);
            Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(_dnu);
            Vector <double> mEta = Exts.Vector(3.01); Matrix <double> dEta = Exts.Diag(1.0 + 1e-6); // FOR AIT (small values are for regularization)
            //Vector<double> mEta = Exts.Vector(1.0); Matrix<double> dEta = Exts.Diag(5.0 * 1e5); // FOR IEOPR (no transit)
            Func <int, Vector <double>, Vector <double> > phi = (s, x) =>
            {
                var res = Math.Min(bound, 1.0 / Math.Pow(Math.Abs(x[0]), 2.0));
                if (double.IsNaN(res) || double.IsInfinity(res))
                {
                    return(Exts.Vector(bound));
                }
                else
                {
                    return(Exts.Vector(res));
                }
            };
            Func <int, Vector <double>, Vector <double> > psi = (s, x) => Exts.Vector(x[0]);

            //Phi1_latex = new string[] { @"min(" + bound.ToString() + @",\frac{1}{x_t^2})" };
            //Psi1_latex = new string[] { @"x_t" };

            //P_W = @"\mathcal{N}\left(" + mW.ToLatex() + ", " + mW.ToLatex() + @"\right)";
            //P_Nu = @"\mathcal{N}\left(" + mNu.ToLatex() + ", " + dNu.ToLatex() + @"\right)";
            //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

            Normal[] NormalW = new Normal[1] {
                new Normal(mW[0], Math.Sqrt(dW[0, 0]))
            };
            Normal[] NormalNu = new Normal[1] {
                new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
            };
            Normal[] NormalEta = new Normal[1] {
                new Normal(mEta[0], Math.Sqrt(dEta[0, 0]))
            };

            //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

            Phi1   = phi;
            Psi1   = psi;
            Xi     = (s, x) => phi(s, x) + mW;
            Zeta   = (s, x, y, k) => y - psi(s, x) - mNu;
            W      = (s) => Exts.Vector(NormalW[0].Sample());
            Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
            DW     = dW;
            DNu    = dNu;
            X0     = () => Exts.Vector(NormalEta[0].Sample());
            X0Hat  = mEta;
            DX0Hat = dEta;
        }
Exemple #3
0
        public TestLogisticModelZeroScalar(double bound, double _dw, double _dnu)
        {
            TestName     = "Логистическая модель с возвратом";
            TestFileName = "LogisticModelZero";

            Vector <double> mW = Exts.Vector(0); Matrix <double> dW = Exts.Diag(_dw);
            Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(_dnu);
            Vector <double> mEta = Exts.Vector(0.1); Matrix <double> dEta = Exts.Diag(0.01); // small values are for regularization
            Func <int, Vector <double>, Vector <double> > phi      = (s, x) =>
            {
                if (Math.Abs(x[0] * (1 - x[0])) < bound)
                {
                    return(Exts.Vector(x[0] * (1 - x[0])));
                }
                else
                {
                    return(Exts.Vector(0));
                }
            };
            Func <int, Vector <double>, Vector <double> > psi      = (s, x) => Exts.Vector(x[0]);
            Func <int, Vector <double>, Matrix <double> > psi_test = (s, x) => Matrix <double> .Build.Dense(1, 1, 1.0);

            //Phi1_latex = new string[] { @"x(1-x) if abs(x(1-x)) < " + bound.ToString() + "; 0 else" };
            //Psi1_latex = new string[] { @"x_t" };

            //P_W = @"\mathcal{N}\left(" + mW.ToLatex() + ", " + dW.ToLatex() + @"\right)";
            //P_Nu = @"\mathcal{N}\left(" + mNu.ToLatex() + ", " + dNu.ToLatex() + @"\right)";
            //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

            Normal[] NormalW = new Normal[1] {
                new Normal(mW[0], Math.Sqrt(dW[0, 0]))
            };
            Normal[] NormalNu = new Normal[1] {
                new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
            };
            Normal[] NormalEta = new Normal[1] {
                new Normal(mEta[0], Math.Sqrt(dEta[0, 0]))
            };

            //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

            Phi1 = phi;
            Psi1 = psi;
            //Psi2 = psi_test;
            Xi     = (s, x) => phi(s, x) + mW;
            Zeta   = (s, x, y, k) => y - psi(s, x) - mNu;
            W      = (s) => Exts.Vector(NormalW[0].Sample());
            Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
            DW     = dW;
            DNu    = dNu;
            X0     = () => Exts.Vector(NormalEta[0].Sample());
            X0Hat  = mEta;
            DX0Hat = dEta;
        }
        public TestCubicSensorScalar(double _dw, double _dnu)
        {
            TestName     = "Кубический сенсор";
            TestFileName = "CubicSensor";

            Vector <double> mW = Exts.Vector(0); Matrix <double> dW = Exts.Diag(_dw);
            Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(_dnu);
            Vector <double> mEta = Exts.Vector(0.1); Matrix <double> dEta = Exts.Diag(1.16);
            Func <int, Vector <double>, Vector <double> > phi  = (s, x) => Exts.Vector(x[0] / (1 + x[0] * x[0]));
            Func <int, Vector <double>, Vector <double> > psi  = (s, x) => Exts.Vector(Math.Pow(x[0], 3) + Math.Pow(x[0], 1));

            Func <int, Vector <double>, Matrix <double> > dpsi = (s, x) => Exts.Matrix(3.0 * Math.Pow(x[0], 2) + 1.0);

            //Phi1_latex = new string[] { @"\frac{x_t}{1 + x_t^2}"};
            //Psi1_latex = new string[] { @"x_t^3+x_t"};

            //P_W = @"\mathcal{N}\left(" + mW.ToLatex() + ", " + mW.ToLatex() + @"\right)";
            //P_Nu = @"\mathcal{N}\left(" + mNu.ToLatex() + ", " + dNu.ToLatex() + @"\right)";
            //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

            Normal[] NormalW = new Normal[1] {
                new Normal(mW[0], Math.Sqrt(dW[0, 0]))
            };
            Normal[] NormalNu = new Normal[1] {
                new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
            };
            Normal[] NormalEta = new Normal[1] {
                new Normal(mEta[0], Math.Sqrt(dEta[0, 0]))
            };

            //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

            Phi1 = phi;
            Psi1 = psi;

            dPhi = (s, x) => Exts.Diag(0.9);
            dPsi = (s, x) => Exts.Diag(1.0);

            Xi   = (s, x) => phi(s, x) + mW;
            Zeta = (s, x, y, k) => y - psi(s, x) - mNu;
            //Zeta = (s, x, y, k) => k * dpsi(s,x).Transpose() * (dpsi(s,x) * k * dpsi(s,x).Transpose() + dNu ).PseudoInverse() * (y - psi(s, x) - mNu);
            W      = (s) => Exts.Vector(NormalW[0].Sample());
            Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
            DW     = dW;
            DNu    = dNu;
            X0     = () => Exts.Vector(NormalEta[0].Sample());
            X0Hat  = mEta;
            DX0Hat = dEta;
        }
        public TestCubicSensor(double _dw, double _dnu)
        {
            TestName     = "Кубический сенсор";
            TestFileName = "CubicSensor";

            Vector <double> mW = Exts.Vector(0, 0); Matrix <double> dW = Exts.Diag(_dw, _dw);
            Vector <double> mNu = Exts.Vector(0, 0); Matrix <double> dNu = Exts.Diag(_dnu, _dnu);
            //Vector<double> mEta = Exts.Vector(100, 100); Matrix<double> dEta = Exts.Diag(100, 100);
            Vector <double> mEta = Exts.Vector(0, 0); Matrix <double> dEta = Exts.Diag(1, 1);
            Func <int, Vector <double>, Vector <double> > phi      = (s, x) => Exts.Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1]));
            Func <int, Vector <double>, Vector <double> > psi      = (s, x) => Exts.Vector(Math.Pow(x[0], 3) + Math.Pow(x[0], 1), Math.Pow(x[1], 3) + Math.Pow(x[1], 1));
            Func <int, Vector <double>, Matrix <double> > psi_test = (s, x) => Matrix <double> .Build.Dense(1, 1, 1.0);

            Psi2 = psi_test;

            //Phi1_latex = new string[] { @"\frac{x_0}{1 + x_0^2}", @"\frac{x_1}{1 + x_1^2}" };
            //Psi1_latex = new string[] { @"x_0^3+x_0", @"x_1^3+x_1" };

            //P_W = @"\mathcal{N}\left(\mathbf{0}, \mathbf{E}\right)";
            //P_Nu = @"\mathcal{N}\left(\mathbf{0}, \mathbf{E}\right)";
            //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

            Normal[] NormalW = new Normal[2] {
                new Normal(mW[0], Math.Sqrt(dW[0, 0])), new Normal(mW[1], Math.Sqrt(dW[1, 1]))
            };
            Normal[] NormalNu = new Normal[2] {
                new Normal(mNu[0], Math.Sqrt(dNu[0, 0])), new Normal(mNu[1], Math.Sqrt(dNu[1, 1]))
            };;
            Normal[] NormalEta = new Normal[2] {
                new Normal(mEta[0], Math.Sqrt(dEta[0, 0])), new Normal(mEta[1], Math.Sqrt(dEta[1, 1]))
            };;

            //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

            Phi1   = phi;
            Psi1   = psi;
            Xi     = (s, x) => phi(s, x) + mW;
            Zeta   = (s, x, y, k) => y - psi(s, x) - mNu;
            W      = (s) => Exts.Vector(NormalW[0].Sample(), NormalW[1].Sample());
            Nu     = (s) => Exts.Vector(NormalNu[0].Sample(), NormalNu[1].Sample());
            DW     = dW;
            DNu    = dNu;
            X0     = () => Exts.Vector(NormalEta[0].Sample(), NormalEta[1].Sample());
            X0Hat  = mEta;
            DX0Hat = dEta;
        }
Exemple #6
0
        public TestLogisticModelUniformNoiseScalar()
        {
            TestName     = "Логистическая модель с равномерным шумом";
            TestFileName = "LogisticModelUniform";

            Vector <double> mW = Exts.Vector(1e-5); Matrix <double> dW = Exts.Diag(1.0 / 3.0);
            Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(1);
            Vector <double> mEta = Exts.Vector(0.5); Matrix <double> dEta = Exts.Diag(0.01); // small values are for regularization
            Func <int, Vector <double>, Vector <double> > phi1 = (s, x) => Exts.Vector(3.0 * x[0] * (1 - x[0]));
            Func <int, Vector <double>, Matrix <double> > phi2 = (s, x) => Exts.Diag(x[0] * (1 - x[0]));
            Func <int, Vector <double>, Vector <double> > psi  = (s, x) => Exts.Vector(x[0]);

            //Phi1_latex = new string[] { @"???" };
            //Psi1_latex = new string[] { @"x_t" };

            //P_W = @"\mathcal{R}\left(0,1\right)";
            //P_Nu = @"\mathcal{N}\left(" + mNu.ToLatex() + ", " + dNu.ToLatex() + @"\right)";
            //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

            ContinuousUniform[] UniformW = new ContinuousUniform[1] {
                new ContinuousUniform(-1 + 1e-5, 1 + 1e-5)
            };
            Normal[] NormalNu = new Normal[1] {
                new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
            };
            Normal[] NormalEta = new Normal[1] {
                new Normal(mEta[0], Math.Sqrt(dEta[0, 0]))
            };

            //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

            Phi1   = phi1;
            Phi2   = phi2;
            Psi1   = psi;
            Xi     = (s, x) => phi1(s, x) + phi2(s, x) * mW;
            Zeta   = (s, x, y, k) => y - psi(s, x) - mNu;
            W      = (s) => Exts.Vector(UniformW[0].Sample());
            Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
            DW     = dW;
            DNu    = dNu;
            X0     = () => Exts.Vector(NormalEta[0].Sample());
            X0Hat  = mEta;
            DX0Hat = dEta;
        }
Exemple #7
0
        public TestLogisticModelScalar(double bound, double _dw, double _dnu)
        {
            TestName     = "Логистическая модель";
            TestFileName = "LogisticModel";

            Vector <double> mW = Exts.Vector(0); Matrix <double> dW = Exts.Diag(_dw);
            Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(_dnu);
            Vector <double> mEta = Exts.Vector(0.1); Matrix <double> dEta = Exts.Diag(0.01); // small values are for regularization
            Func <int, Vector <double>, Vector <double> > phi = (s, x) => Exts.Vector(Math.Max(-bound, Math.Min(bound, x[0] * (1 - x[0]))));
            Func <int, Vector <double>, Vector <double> > psi = (s, x) => Exts.Vector(x[0]);

            //Phi1_latex = new string[] { @"max(-" + bound.ToString() + @", min(" + bound.ToString() + @",x(1-x)))" };
            //Psi1_latex = new string[] { @"x_t" };

            //P_W = @"\mathcal{N}\left(" + mW.ToLatex() + ", " + dW.ToLatex() + @"\right)";
            //P_Nu = @"\mathcal{N}\left(" + mNu.ToLatex() + ", " + dNu.ToLatex() + @"\right)";
            //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

            Normal[] NormalW = new Normal[1] {
                new Normal(mW[0], Math.Sqrt(dW[0, 0]))
            };
            Normal[] NormalNu = new Normal[1] {
                new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
            };
            Normal[] NormalEta = new Normal[1] {
                new Normal(mEta[0], Math.Sqrt(dEta[0, 0]))
            };

            //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

            Phi1   = phi;
            Psi1   = psi;
            Xi     = (s, x) => phi(s, x) + mW;
            Zeta   = (s, x, y, k) => y - psi(s, x) - mNu;
            W      = (s) => Exts.Vector(NormalW[0].Sample());
            Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
            DW     = dW;
            DNu    = dNu;
            X0     = () => Exts.Vector(NormalEta[0].Sample());
            X0Hat  = mEta;
            DX0Hat = dEta;
        }
        static void Run(Options o, string[] args)
        {
            if (string.IsNullOrWhiteSpace(o.ScriptsFolder))
            {
                o.ScriptsFolder = "..\\..\\..\\OutputScripts\\";
            }

            Directory.CreateDirectory(o.OutputFolder);
            using (System.IO.StreamWriter outputfile = new System.IO.StreamWriter(Path.Combine(o.OutputFolder, "parameters.txt"), true))
            {
                outputfile.WriteLine($"{DateTime.Now}\t{string.Join(" ", args)}");
                outputfile.Close();
            }

            // original continuous model
            // x_t = x_0 + \int_0^t Phi_1(x_t) dt + \int_0^t Phi_2(x_t) dW_t

            // discrete model:
            // x_{t+1} = Phi_1(x_t) + Phi_2(x_t) W_t

            //observations
            // y_t = Psi_1(x_t) + Psi_2(x_t) Nu_t

            #region 3d model Ienkaran Arasaratnam, Simon Haykin, and Tom R. Hurd
            //mpdel params
            //double sigma1 = Math.Sqrt(0.2);
            //double sigma2 = 7.0 * 1e-3;
            //double sigma_r = 50;
            //double sigma_th = 0.1;
            //double sigma_ph = 0.1;

            // starting point
            //Vector<double> mEta = Exts.Vector(1000, 0, 2650, 150, 200, 0, 1.0);
            //Matrix<double> dEta = Exts.Diag(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0);
            //RandomVector<Normal> NormalEta = new RandomVector<Normal>(mEta, dEta);
            //Func<Vector<double>> X0;
            ////X0 = () => NormalEta.Sample();
            //X0 = () => mEta;

            // dynamics
            //Func<Vector<double>, Vector<double>> Phi1 = (x) => Exts.Vector(x[1], -x[6] * x[3], x[3], x[6] * x[1], x[5], 0, 0);
            //Func<Matrix<double>> Phi2 = () => Exts.Diag(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0);

            //Vector<double> mW = Exts.Vector(0, 0, 0, 0, 0, 0, 0);
            //Matrix<double> dW = Exts.Diag(1e1, Math.Pow(sigma1, 2), 1e1, Math.Pow(sigma1, 2), 1e1, Math.Pow(sigma1, 2), Math.Pow(sigma2, 2));
            //RandomVector<Normal> NormalW = new RandomVector<Normal>(mW, dW);
            //Func<Vector<double>> W;
            //W = () => NormalW.Sample();

            // observations
            //Func<Vector<double>, Vector<double>> Psi1 = (x) => Utils.cart2sphere(Exts.Vector(x[0], x[2], x[4]));
            //Func<Matrix<double>> Psi2 = () => Exts.Diag(1.0, 1.0, 1.0);
            //Vector<double> mNu = Exts.Vector(0, 0, 0);
            //Matrix<double> dNu = Exts.Diag(Math.Pow(sigma_r, 2), Math.Pow(sigma_th, 2), Math.Pow(sigma_ph, 2));

            ////Vector<double> X_R2 = Exts.Vector(0, 0);
            ////Vector<double> mNu = Exts.Vector(0, 0, 0, 0);
            ////Matrix<double> dNu = Exts.Diag(Math.Pow(0.1 * Math.PI / 180, 2), Math.Pow(50, 2), Math.Pow(0.1 * Math.PI / 180, 2), Math.Pow(50, 2));
            ////Func<double, Vector<double>, Vector<double>> Psi1 = (s, x) => Exts.Stack(Utils.cart2pol(Exts.Vector(x[0], x[1]) - X_R1), Utils.cart2pol(Exts.Vector(x[0], x[1]) - X_R2));
            ////Func<double, Vector<double>, Matrix<double>> Psi2 = (s, x) => Exts.Diag(1.0, 1.0, 1.0, 1.0);

            //RandomVector<Normal> NormalNu = new RandomVector<Normal>(mNu, dNu);
            //Func<Vector<double>> Nu;
            //Nu = () => NormalNu.Sample();

            //double h_state = 0.01;
            //double h_obs = 0.01;
            //double T = 1.0 + h_state / 2;

            #endregion


            #region 2d model with acceleration

            // model params
            double Alpha_n = o.alpha; // 0.05;
            double Beta_n  = o.beta;  //1.0;
            double Gamma_n = o.gamma; //0.5;

            // starting point
            Vector <double>         mEta        = Exts.Vector(0, 25000, 400, 10 * Math.PI / 180, Gamma_n / Alpha_n);
            Matrix <double>         dEta        = Exts.Diag(Math.Pow(o.DX0, 2), Math.Pow(o.DX0, 2), Math.Pow(115, 2), Math.Pow(15 * Math.PI / 180, 2), Math.Pow(Beta_n, 2) / 2 / Alpha_n);
            RandomVector <Normal>   NormalEta   = new RandomVector <Normal>(mEta, dEta);
            ContinuousUniform       UniformEtaV = new ContinuousUniform(200, 600);
            Func <Vector <double> > X0;
            X0 = () =>
            {
                var x = NormalEta.Sample();
                x[2] = UniformEtaV.Sample();
                return(x);
            };

            // dynamics
            Func <Vector <double>, Vector <double> > Phi1 = (x) => Exts.Vector(x[2] * Math.Cos(x[3]), x[2] * Math.Sin(x[3]), 0, x[4] / x[2], -Alpha_n * x[4] + Gamma_n);
            Func <Matrix <double> > Phi2 = () => Exts.Diag(0, 0, 0, 0, 1.0);

            Vector <double>         mW      = Exts.Vector(0, 0, 0, 0, 0);
            Matrix <double>         dW      = Exts.Diag(0, 0, 0, 0, Math.Pow(Beta_n, 2));
            Normal                  NormalW = new Normal(mW[4], Math.Sqrt(dW[4, 4]));
            Func <Vector <double> > W;
            W = () => Exts.Vector(0, 0, 0, 0, NormalW.Sample());

            // observations
            Vector <double> X_R1 = Exts.Vector(-10000, 10000);   // first radar location
            Vector <double> X_R2 = Exts.Vector(0, 0);            // second radar location

            Func <Vector <double>, Vector <double> > Psi1 = (x) => Exts.Stack(Utils.cart2pol(Exts.Vector(x[0], x[1]) - X_R1), Utils.cart2pol(Exts.Vector(x[0], x[1]) - X_R2));
            Func <Matrix <double> > Psi2 = () => Exts.Diag(1.0, 1.0, 1.0, 1.0);

            Vector <double>         mNu      = Exts.Vector(0, 0, 0, 0);
            Matrix <double>         dNu      = Exts.Diag(Math.Pow(0.1 * Math.PI / 180, 2), Math.Pow(50, 2), Math.Pow(0.1 * Math.PI / 180, 2), Math.Pow(50, 2));
            RandomVector <Normal>   NormalNu = new RandomVector <Normal>(mNu, dNu);
            Func <Vector <double> > Nu;
            Nu = () => NormalNu.Sample();



            //discretization
            double h_state = o.h_state; //0.01;
            double h_obs   = o.h_obs;   //1.0;
            double T       = o.T + h_state / 2;

            Func <int, Vector <double>, Vector <double> > Phi1_discr = (i, x) =>
            {
                Vector <double> xx = x;
                for (double s = h_state; s < h_obs + h_state / 2; s += h_state)
                {
                    xx += h_state * Phi1(xx);
                }
                return(xx);
            };
            Func <int, Vector <double>, Matrix <double> > Phi2_discr = (i, x) => Math.Sqrt(h_obs) * Phi2();
            Func <int, Vector <double>, Vector <double> > Psi1_discr = (i, x) => Psi1(x);
            Func <int, Vector <double>, Matrix <double> > Psi2_discr = (i, x) => Psi2();

            // derivatives for the Extended Kalman Filter
            Func <Vector <double>, Matrix <double> > dPhi = (x) => Matrix <double> .Build.Dense(5, 5, new double[5 * 5] {
                0, 0, 0, 0, 0,
                0, 0, 0, 0, 0,
                Math.Cos(x[3]), Math.Sin(x[3]), 0, -x[4] / Math.Pow(x[2], 2), 0,
                -x[2] * Math.Sin(x[3]), x[2] * Math.Cos(x[3]), 0, 0, 0,
                0, 0, 0, 1.0 / x[2], -Alpha_n
            }); // Column-major order

            Func <Vector <double>, Matrix <double> > dPsi = (x) =>
            {
                var x1   = x - X_R1.Stack(Exts.Vector(0, 0, 0));
                var r1r1 = x1[0] * x1[0] + x1[1] * x1[1];
                var r1   = Math.Sqrt(r1r1);
                var x2   = x - X_R2.Stack(Exts.Vector(0, 0, 0));
                var r2r2 = x2[0] * x2[0] + x2[1] * x2[1];
                var r2   = Math.Sqrt(r2r2);
                return(Matrix <double> .Build.Dense(4, 5, new double[5 * 4] {
                    -x1[1] / r1r1, x1[0] / r1, -x2[1] / r2r2, x2[0] / r2,
                    x1[0] / r1r1, x1[1] / r1, x2[0] / r2r2, x2[1] / r2,
                    0, 0, 0, 0,
                    0, 0, 0, 0,
                    0, 0, 0, 0
                })); // Column-major order
            };
            Func <int, Vector <double>, Matrix <double>, (Vector <double>, Matrix <double>)> Ricatti = (i, x, P) =>
            {
                Vector <double> xx = x;
                Matrix <double> PP = P;
                for (double s = h_state; s < h_obs + h_state / 2; s += h_state)
                {
                    PP += h_state * (dPhi(xx) * PP + PP * dPhi(xx).Transpose() + Phi2() * dW * Phi2().Transpose());
                    xx += h_state * (Phi1(xx) + Phi2() * mW);
                }
                return(xx, PP);
            };

            //trivial estimate
            Func <int, Vector <double>, Vector <double>, Matrix <double>, (Vector <double>, Matrix <double>)> DummyEstimate = (i, y, x, P) =>
            {
                Vector <double> xx = x;
                Matrix <double> PP = P;
                for (double s = h_state; s < h_obs + h_state / 2; s += h_state)
                {
                    PP += h_state * (dPhi(xx) * PP + PP * dPhi(xx).Transpose() + Phi2() * dW * Phi2().Transpose());
                    xx += h_state * (Phi1(xx) + Phi2() * mW);
                }
                return((0.5 * (Utils.pol2cart(Exts.Vector(y[0], y[1])) + X_R1 + Utils.pol2cart(Exts.Vector(y[2], y[3])) + X_R2)).Stack(Exts.Vector(xx[2], xx[3], xx[4])), PP);
            };

            #endregion

            int N = (int)(T / h_obs);

            Func <DiscreteVectorModel> ModelGenerator = () =>
            {
                DiscreteVectorModel model = null;

                int             n                 = 0;
                double          h_tolerance       = h_state / 2.0;
                double          t_nextobservation = h_obs;
                Vector <double> State             = X0();
                Vector <double> Obs;

                model = new DiscreteVectorModel(Phi1_discr, Phi2_discr, Psi1_discr, Psi2_discr, (i) => W(), (i) => Nu(), X0(), true);
                //for (double s = 0; s < T; s += h_obs)
                //{
                //    model.Step();
                //}
                for (double s = h_state; s < T; s += h_state)
                {
                    if (s > 0)
                    {
                        State = State + h_state * Phi1(State) + Math.Sqrt(h_state) * Phi2() * W();
                    }
                    if (Math.Abs(s - t_nextobservation) < h_tolerance)
                    {
                        Obs = Psi1(State) + Psi2() * Nu();
                        t_nextobservation += h_obs;

                        n++;
                        model.Trajectory.Add(n, new Vector <double>[] { State, Obs });
                    }
                }
                return(model);
            };

            // filter params file names
            string CMNFFileName = Path.Combine(o.OutputFolder, "cmnf.params");
            if (!string.IsNullOrWhiteSpace(o.CMNFFileName))
            {
                CMNFFileName = o.CMNFFileName;
            }
            string BCMNFFileName = Path.Combine(o.OutputFolder, "bcmnf.params");
            if (!string.IsNullOrWhiteSpace(o.BCMNFFileName))
            {
                BCMNFFileName = o.BCMNFFileName;
            }
            string UKFFileName = Path.Combine(o.OutputFolder, "ukf.params");
            if (!string.IsNullOrWhiteSpace(o.UKFFileName))
            {
                UKFFileName = o.UKFFileName;
            }
            string UKFOptStepwiseNMFileName = Path.Combine(o.OutputFolder, "ukfoptstepwiseNM.params");
            if (!string.IsNullOrWhiteSpace(o.UKFStepwiseNelderMeadFileName))
            {
                UKFOptStepwiseNMFileName = o.UKFStepwiseNelderMeadFileName;
            }
            string UKFOptIntegralNMFileName = Path.Combine(o.OutputFolder, "ukfoptintegralNM.params");
            if (!string.IsNullOrWhiteSpace(o.UKFIntegralNelderMeadFileName))
            {
                UKFOptIntegralNMFileName = o.UKFIntegralNelderMeadFileName;
            }
            string UKFOptStepwiseRandFileName = Path.Combine(o.OutputFolder, "ukfoptstepwiserand.params");
            if (!string.IsNullOrWhiteSpace(o.UKFStepwiseRandomShootFileName))
            {
                UKFOptStepwiseRandFileName = o.UKFStepwiseRandomShootFileName;
            }
            string UKFOptIntegralRandFileName = Path.Combine(o.OutputFolder, "ukfoptintegralrand.params");
            if (!string.IsNullOrWhiteSpace(o.UKFIntegralRandomShootFileName))
            {
                UKFOptIntegralRandFileName = o.UKFIntegralRandomShootFileName;
            }

            // filters
            List <(FilterType, string)> filters = new List <(FilterType, string)>();
            if (o.CMNF)
            {
                filters.Add((FilterType.CMNF, CMNFFileName));
            }
            if (o.BCMNF)
            {
                filters.Add((FilterType.BCMNF, BCMNFFileName));
            }
            if (o.MCMNF)
            {
                filters.Add((FilterType.MCMNF, string.Empty));
            }
            if (o.UKF)
            {
                filters.Add((FilterType.UKFNoOptimization, UKFFileName));
            }
            if (o.UKFStepwiseNelderMead)
            {
                filters.Add((FilterType.UKFStepwise, UKFOptStepwiseNMFileName));
            }
            if (o.UKFIntegralNelderMead)
            {
                filters.Add((FilterType.UKFIntegral, UKFOptIntegralNMFileName));
            }
            if (o.UKFStepwiseRandomShoot)
            {
                filters.Add((FilterType.UKFStepwiseRandomShoot, UKFOptStepwiseRandFileName));
            }
            if (o.UKFIntegralRandomShoot)
            {
                filters.Add((FilterType.UKFIntegralRandomShoot, UKFOptIntegralRandFileName));
            }
            if (o.EKF)
            {
                filters.Add((FilterType.EKF, string.Empty));
            }
            if (o.Dummy)
            {
                filters.Add((FilterType.Dummy, string.Empty));
            }


            // test environment
            TestEnvironmentVector testEnv = new TestEnvironmentVector()
            {
                TestName     = "Target tracking",
                TestFileName = "TargetTracking",
                Phi1         = Phi1_discr,
                Phi2         = Phi2_discr,
                Psi1         = Psi1_discr,
                Psi2         = Psi2_discr,
                dPhi         = (i, x) => dPhi(x),
                dPsi         = (i, x) => dPsi(x),
                Xi           = (i, x) => Phi1_discr(i, x) + Phi2_discr(i, x) * mW,
                //Zeta = (i, x, y, k) => (y - Psi1_discr(i, x) - Psi2_discr(i, x) * mNu).Stack(Utils.pol2cart(Exts.Vector(y[0], y[1]))+X_R1).Stack(Utils.pol2cart(Exts.Vector(y[2], y[3]))+X_R2),
                Zeta  = (i, x, y, k) => (y - Psi1_discr(i, x) - Psi2_discr(i, x) * mNu),
                Alpha = (i, x) => Phi1_discr(i, x) + Phi2_discr(i, x) * mW,
                Gamma = (i, x, y) => (y).Stack(Utils.pol2cart(Exts.Vector(y[0], y[1])) + X_R1).Stack(Utils.pol2cart(Exts.Vector(y[2], y[3])) + X_R2),
                //Gamma = (i, x, y) => y - Psi1_discr(i, x) - Psi2_discr(i, x) * mNu,
                nMCMNF         = o.MCMNFTrainCount,
                W              = (i) => W(),
                Nu             = (i) => Nu(),
                DW             = dW,
                DNu            = dNu,
                X0             = () => X0(),
                X0Hat          = mEta,
                DX0Hat         = dEta,
                Predict        = Ricatti,
                DummyEstimate  = DummyEstimate,
                ModelGenerator = ModelGenerator
            };

            if (o.Bulk)
            {
                testEnv.GenerateBundleSamples(o.T, o.TrainCount, o.OutputFolder);
            }
            else
            {
                testEnv.Initialize(o.T, o.TrainCount, o.OutputFolder, filters, o.Save, o.Load);
                if (o.Sift)
                {
                    testEnv.Sifter = (x) => Math.Sqrt(x[0] * x[0] + x[1] * x[1]) > o.SiftBound;
                }
                if (o.Aggregate)
                {
                    testEnv.Aggregate(o.OutputFolder, o.OutputFolder, !o.NoBin, !o.NoText);
                }
                if (!o.Skip)
                {
                    if (o.SamplesCount == 0)
                    {
                        testEnv.GenerateBundles(o.BundleCount, o.TestCount, o.OutputFolder, o.Parallel, o.ParallelismDegree, !o.NoBin, !o.NoText);
                        if (!o.NoPython)
                        {
                            testEnv.RunScript(Path.Combine(o.ScriptsFolder, "estimate_statistics.py"), o.OutputFolder);
                        }
                    }
                    else
                    {
                        if (o.SamplesCount == 1)
                        {
                            testEnv.GenerateOne(o.OutputFolder);
                            if (!o.NoPython)
                            {
                                testEnv.RunScript(Path.Combine(o.ScriptsFolder, "estimate_sample.py"), o.OutputFolder);
                                testEnv.RunScript(Path.Combine(o.ScriptsFolder, "trajectory.py"), o.OutputFolder);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < o.SamplesCount; i++)
                            {
                                testEnv.GenerateOne(o.OutputFolder, i);
                            }
                        }
                    }
                }
            }
        }
Exemple #9
0
        public TestSampledRegression(double _dnu)
        {
            {
                TestName     = "Модель семплированной регрессии";
                TestFileName = "SampledRegression";

                Vector <double> a = Exts.Vector(0.3, 0.4, 0.7);
                Vector <double> b = Exts.Vector(1.4, 3.0, 3.0);
                Vector <double> c = Exts.Vector(0.9, 1.5, 2.5);
                Vector <double> d = Exts.Vector(0.33, 0.37, 0.3);
                Vector <double> m = Exts.Vector(b[0] / (1 - a[0]), b[1] / (1 - a[1]), b[2] / (1 - a[2]));
                Vector <double> S = Exts.Vector(c[0] / Math.Sqrt(1 - a[0] * a[0]), c[1] / Math.Sqrt(1 - a[1] * a[1]), c[2] / Math.Sqrt(1 - a[2] * a[2]));

                Func <double, int> I = x =>
                {
                    if (x < 3)
                    {
                        return(0);
                    }
                    else if (x < 7)
                    {
                        return(1);
                    }
                    else
                    {
                        return(2);
                    }
                };

                Vector <double> mW = Exts.Vector(0); Matrix <double> dW = Exts.Diag(1.0);
                Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(_dnu);
                Vector <double> mEta = Exts.Vector(0); Matrix <double> dEta = Exts.Diag(1.0);
                Func <int, Vector <double>, Vector <double> > phi1 = (s, x) => Exts.Vector(a[I(x[0])] * x[0] + b[I(x[0])]);
                Func <int, Vector <double>, Matrix <double> > phi2 = (s, x) => Exts.Matrix(c[I(x[0])]);
                Func <int, Vector <double>, Vector <double> > psi  = (s, x) => Exts.Vector(x[0]);

                //Phi1_latex = new string[] { @"a^T e(x_t) x_t + b^T e(x_t)" };
                //Phi2_latex = new string[][] { new string[] { @"c^T e(x_t)" } };
                //Psi1_latex = new string[] { @"x_t" };

                //P_W = @"\mathcal{N}\left(" + mW.ToLatex() + ", " + dW.ToLatex() + @"\right)";
                //P_Nu = @"\mathcal{N}\left(" + mNu.ToLatex() + ", " + dNu.ToLatex() + @"\right)";
                //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

                Normal[] NormalW = new Normal[1] {
                    new Normal(mW[0], Math.Sqrt(dW[0, 0]))
                };
                Normal[] NormalNu = new Normal[1] {
                    new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
                };
                Normal[] NormalEta = new Normal[1] {
                    new Normal(mEta[0], Math.Sqrt(dEta[0, 0]))
                };

                //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

                Phi1 = phi1;
                Phi2 = phi2;
                Psi1 = psi;
                //Xi = (s, x) => phi1(s, x) + phi2(s, x) * mW;
                Xi = (s, x) =>
                {
                    double num = 0;
                    double den = 0;
                    for (int i = 0; i < a.Count; i++)
                    {
                        num += d[i] * Normal.PDF(m[i], S[i], x[0]) * (a[i] * x[0] + b[i]);
                        den += d[i] * Normal.PDF(m[i], S[i], x[0]);
                    }
                    return(Exts.Vector(num / den));
                };
                Zeta   = (s, x, y, k) => y - psi(s, x) - mNu;
                W      = (s) => Exts.Vector(NormalW[0].Sample());
                Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
                DW     = dW;
                DNu    = dNu;
                X0     = () => Exts.Vector(NormalEta[0].Sample());
                X0Hat  = mEta;
                DX0Hat = dEta;
            }
        }
        public HopefullyTheLastTestSwitchingObservationsIdentification(double _dnu)
        {
            {
                TestName     = "Надеюсь, последняя модель с переключающимися каналами наблюдений и идентификацией";
                TestFileName = "HopefullyTheLastSwitchingObservationsIdentification";

                Vector <double> sig = Exts.Vector(1.0, 4.0, 10.0);


                double l1 = -0.6745;
                double l2 = 0.6745;

                Func <double, int> I = x =>
                {
                    if (x < l1)
                    {
                        return(0);
                    }
                    else if (x < l2)
                    {
                        return(1);
                    }
                    else
                    {
                        return(2);
                    }
                };

                Func <double, double> F = x =>
                {
                    return(0.4 - x * Math.Exp(-0.3 * x * x));
                };

                //Vector<double> f = Exts.Vector(Normal.CDF(m, S, l1), Normal.CDF(m, S, l2) - Normal.CDF(m, S, l1), 1.0 - Normal.CDF(m, S, l2));
                Vector <double> f = Exts.Vector(0.25, 0.5, 0.25);

                Vector <double> mW = Exts.Vector(0, 0); Matrix <double> dW = Exts.Diag(1e-5, 1.0);
                Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(1e-5);
                Vector <double> mEta = Exts.Vector(0, 0.0); Matrix <double> dEta = Exts.Diag(0.27, 1e-5);
                Func <int, Vector <double>, Vector <double> > phi1 = (s, x) => Exts.Vector(x[0], x[0] * F(x[1]));
                Func <int, Vector <double>, Matrix <double> > phi2 = (s, x) => Exts.Diag(1.0, sig[I(x[1])]);
                Func <int, Vector <double>, Vector <double> > psi1 = (s, x) => Exts.Vector(x[1]);
                Func <int, Vector <double>, Matrix <double> > psi2 = (s, x) => Exts.Matrix(1.0);

                Normal[] NormalW = new Normal[2] {
                    new Normal(mW[0], Math.Sqrt(dW[0, 0])), new Normal(mW[1], Math.Sqrt(dW[1, 1]))
                };
                Normal[] NormalNu = new Normal[1] {
                    new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
                };
                ContinuousUniform UniformW = new ContinuousUniform(-0.9, 0.9);

                Phi1 = phi1;
                Phi2 = phi2;
                Psi1 = psi1;
                Psi2 = psi2;
                Xi   = (s, x) => phi1(s, x) + phi2(s, x) * mW;
                Zeta = (s, x, y, k) => y - psi1(s, x) - psi2(s, x) * mNu;


                W      = (s) => Exts.Vector(NormalW[0].Sample(), NormalW[1].Sample());
                Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
                DW     = dW;
                DNu    = dNu;
                X0     = () => Exts.Vector(UniformW.Sample(), 0.0);
                X0Hat  = mEta;
                DX0Hat = dEta;
            }
        }
        public TestSwitchingObservationsIdentification(double _dnu)
        {
            {
                TestName     = "Модель с переключающимися каналами наблюдений и идентификацией";
                TestFileName = "SwitchingObservationsIdentification";

                double a = 0.8;
                double b = 0.2;
                double c = 6.0;
                //Vector<double> d = Exts.Vector(10.0, 1.0, 1.0);
                //Vector<double> sig = Exts.Vector(1.0, 1.0, 10.0);
                Vector <double> d   = Exts.Vector(4.0, 1.0, 0.5);
                Vector <double> sig = Exts.Vector(1.0, 1.0, 3.0);
                double          m   = b / (1 - a);
                double          S   = Math.Sqrt(c * c / (1 - a * a));


                double l1 = -0.6745;
                double l2 = 0.6745;

                Func <double, int> I = x =>
                {
                    if (x < l1)
                    {
                        return(0);
                    }
                    else if (x < l2)
                    {
                        return(1);
                    }
                    else
                    {
                        return(2);
                    }
                };

                //Vector<double> f = Exts.Vector(Normal.CDF(m, S, l1), Normal.CDF(m, S, l2) - Normal.CDF(m, S, l1), 1.0 - Normal.CDF(m, S, l2));
                Vector <double> f = Exts.Vector(0.25, 0.5, 0.25);



                Vector <double> mW = Exts.Vector(0, 0, a); Matrix <double> dW = Exts.Diag(1.0, 1.0, 0.04 / 3.0);
                Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(_dnu);
                Vector <double> mEta = Exts.Vector(0, 0.0, a); Matrix <double> dEta = Exts.Diag(1.0, 1.0, 0.04 / 3.0);
                Func <int, Vector <double>, Vector <double> > phi1 = (s, x) => Exts.Vector(x[2] * x[0] + b, 0, 0);
                Func <int, Vector <double>, Matrix <double> > phi2 = (s, x) => Exts.Diag(c, 1.0, 1.0);
                Func <int, Vector <double>, Vector <double> > psi1 = (s, x) => Exts.Vector(d[I(x[1])] * x[0]);
                Func <int, Vector <double>, Matrix <double> > psi2 = (s, x) => Exts.Matrix(sig[I(x[1])]);

                Normal[] NormalW = new Normal[2] {
                    new Normal(mW[0], Math.Sqrt(dW[0, 0])), new Normal(mW[1], Math.Sqrt(dW[1, 1]))
                };
                Normal[] NormalNu = new Normal[1] {
                    new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
                };
                Normal[] NormalEta = new Normal[2] {
                    new Normal(mEta[0], Math.Sqrt(dEta[0, 0])), new Normal(mEta[1], Math.Sqrt(dEta[1, 1]))
                };
                ContinuousUniform UniformW = new ContinuousUniform(a - 0.2, a + 0.2);
                //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

                Phi1 = phi1;
                Phi2 = phi2;
                Psi1 = psi1;
                Psi2 = psi2;
                Xi   = (s, x) => phi1(s, x) + phi2(s, x) * mW;
                //Zeta = (s, x, y, k) => y - psi1(s, x) - psi2(s, x) * mNu;

                Zeta = (s, x, y, k) =>
                {
                    double num = 0;
                    double den = 0;
                    for (int i = 0; i < d.Count; i++)
                    {
                        double xi = k[0, 0] * d[i] / (d[i] * d[i] * k[0, 0] + sig[i] * sig[i]) * (y[0] - d[i] * x[0]);
                        num += f[i] * Normal.PDF(d[i] * x[0], Math.Sqrt(d[i] * d[i] * k[0, 0] + sig[i] * sig[i]), y[0]) * xi;
                        den += f[i] * Normal.PDF(d[i] * x[0], Math.Sqrt(d[i] * d[i] * k[0, 0] + sig[i] * sig[i]), y[0]);
                    }
                    return(Exts.Vector(num / den));
                };

                W      = (s) => Exts.Vector(NormalW[0].Sample(), NormalW[1].Sample(), UniformW.Sample());
                Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
                DW     = dW;
                DNu    = dNu;
                X0     = () => Exts.Vector(NormalEta[0].Sample(), NormalEta[1].Sample(), UniformW.Sample());
                X0Hat  = mEta;
                DX0Hat = dEta;
            }
        }
        public TestSwitchingObservations(double _dnu)
        {
            {
                TestName     = "Модель с переключающимися каналами наблюдений";
                TestFileName = "SwitchingObservations";

                double a = 0.8;
                double b = 0.2;
                double c = 6.0;
                //Vector<double> d = Exts.Vector(10.0, 1.0, 1.0);
                //Vector<double> sig = Exts.Vector(1.0, 1.0, 10.0);
                Vector <double> d   = Exts.Vector(4.0, 1.0, 0.5);
                Vector <double> sig = Exts.Vector(1.0, 1.0, 3.0);
                double          m   = b / (1 - a);
                double          S   = Math.Sqrt(c * c / (1 - a * a));


                double l1 = -0.6745;
                double l2 = 0.6745;

                Func <double, int> I = x =>
                {
                    if (x < l1)
                    {
                        return(0);
                    }
                    else if (x < l2)
                    {
                        return(1);
                    }
                    else
                    {
                        return(2);
                    }
                };

                //Vector<double> f = Exts.Vector(Normal.CDF(m, S, l1), Normal.CDF(m, S, l2) - Normal.CDF(m, S, l1), 1.0 - Normal.CDF(m, S, l2));
                Vector <double> f = Exts.Vector(0.25, 0.5, 0.25);



                Vector <double> mW = Exts.Vector(0, 0.0); Matrix <double> dW = Exts.Diag(1.0, 1.0);
                Vector <double> mNu = Exts.Vector(0); Matrix <double> dNu = Exts.Diag(_dnu);
                Vector <double> mEta = Exts.Vector(0, 0.0); Matrix <double> dEta = Exts.Diag(1.0, 1.0); // FOR AIT
                //Vector<double> mEta = Exts.Vector(1.0, 0.0); Matrix<double> dEta = Exts.Diag(100.0, 1.0); // FOR IEOPR (no transit)
                Func <int, Vector <double>, Vector <double> > phi1 = (s, x) => Exts.Vector(a * x[0] + b, 0);
                Func <int, Vector <double>, Matrix <double> > phi2 = (s, x) => Exts.Diag(c, 1.0);
                Func <int, Vector <double>, Vector <double> > psi1 = (s, x) => Exts.Vector(d[I(x[1])] * x[0]);
                Func <int, Vector <double>, Matrix <double> > psi2 = (s, x) => Exts.Matrix(sig[I(x[1])]);

                //Phi1_latex = new string[] { @"a x_t + b", "0" };
                //Phi2_latex = new string[][] { new string[] { @"c", "0" }, new string[] { @"0", "1" }};
                //Psi1_latex = new string[] { @"d^T * e(x^1_t) * x_t" };
                //Psi2_latex = new string[][] { new string[] { @"\sigma^T * e(x^1_t)" } };

                //P_W = @"\mathcal{N}\left(" + mW.ToLatex() + ", " + dW.ToLatex() + @"\right)";
                //P_Nu = @"\mathcal{N}\left(" + mNu.ToLatex() + ", " + dNu.ToLatex() + @"\right)";
                //P_Eta = @"\mathcal{N}\left(" + mEta.ToLatex() + ", " + dEta.ToLatex() + @"\right)";

                Normal[] NormalW = new Normal[2] {
                    new Normal(mW[0], Math.Sqrt(dW[0, 0])), new Normal(mW[1], Math.Sqrt(dW[1, 1]))
                };
                Normal[] NormalNu = new Normal[1] {
                    new Normal(mNu[0], Math.Sqrt(dNu[0, 0]))
                };
                Normal[] NormalEta = new Normal[2] {
                    new Normal(mEta[0], Math.Sqrt(dEta[0, 0])), new Normal(mEta[1], Math.Sqrt(dEta[1, 1]))
                };

                //Expression<Func<int, Vector<double>, Vector<double>>> expr = (s, x) => Vector(x[0] / (1 + x[0] * x[0]), x[1] / (1 + x[1] * x[1])); ;

                Phi1 = phi1;
                Phi2 = phi2;
                Psi1 = psi1;
                Psi2 = psi2;
                Xi   = (s, x) => phi1(s, x) + phi2(s, x) * mW;
                //Zeta = (s, x, y, k) => y - psi1(s, x) - psi2(s, x) * mNu;

                Zeta = (s, x, y, k) =>
                {
                    double num = 0;
                    double den = 0;
                    for (int i = 0; i < d.Count; i++)
                    {
                        double xi = k[0, 0] * d[i] / (d[i] * d[i] * k[0, 0] + sig[i] * sig[i]) * (y[0] - d[i] * x[0]);
                        num += f[i] * Normal.PDF(d[i] * x[0], Math.Sqrt(d[i] * d[i] * k[0, 0] + sig[i] * sig[i]), y[0]) * xi;
                        den += f[i] * Normal.PDF(d[i] * x[0], Math.Sqrt(d[i] * d[i] * k[0, 0] + sig[i] * sig[i]), y[0]);
                    }
                    return(Exts.Vector(num / den));
                };

                W      = (s) => Exts.Vector(NormalW[0].Sample(), NormalW[1].Sample());
                Nu     = (s) => Exts.Vector(NormalNu[0].Sample());
                DW     = dW;
                DNu    = dNu;
                X0     = () => Exts.Vector(NormalEta[0].Sample(), NormalEta[1].Sample());
                X0Hat  = mEta;
                DX0Hat = dEta;
            }
        }
        static void Run(Options o, string[] args)
        {
            if (string.IsNullOrWhiteSpace(o.OutputFolder))
            {
                o.OutputFolder = Settings.Default.OutputFolder;
            }

            if (string.IsNullOrWhiteSpace(o.PlotsFolder))
            {
                o.PlotsFolder = Settings.Default.LatexFolder;
            }

            if (string.IsNullOrWhiteSpace(o.ScriptsFolder))
            {
                o.ScriptsFolder = Settings.Default.ScriptsFolder;
            }

            if (string.IsNullOrWhiteSpace(o.TemplatesFolder))
            {
                o.TemplatesFolder = Settings.Default.LatexFolder;
            }

            if (new[] { "sphere", "polar", "polartwo" }.Contains(o.Model))
            {
                #region sphere
                if (o.Model == "sphere")
                {
                    int             N = o.N;
                    Vector <double> mX = Exts.Vector(30, 40, 100); Matrix <double> KX = Exts.Diag(30 * 30, 30 * 30, 30 * 30);
                    Vector <double> mNu = Exts.Vector(0, 0, 0); Matrix <double> KNu = Exts.Diag(30 * 30, Math.Pow(5 * Math.PI / 180.0, 2.0), Math.Pow(5 * Math.PI / 180.0, 2.0));
                    Normal[]        NormalX = new Normal[3] {
                        new Normal(mX[0], Math.Sqrt(KX[0, 0])), new Normal(mX[1], Math.Sqrt(KX[1, 1])), new Normal(mX[2], Math.Sqrt(KX[2, 2]))
                    };
                    Normal[] NormalNu = new Normal[3] {
                        new Normal(mNu[0], Math.Sqrt(KNu[0, 0])), new Normal(mNu[1], Math.Sqrt(KNu[1, 1])), new Normal(mNu[2], Math.Sqrt(KNu[2, 2]))
                    };;

                    TestEnvironmentStatic testSphere = new TestEnvironmentStatic
                    {
                        Phi    = x => Utils.cart2sphere(x),
                        InvPhi = y => Utils.sphere2cart(y),
                        W      = () => Exts.Vector(NormalX[0].Sample(), NormalX[1].Sample(), NormalX[2].Sample()),
                        Nu     = () => Exts.Vector(NormalNu[0].Sample(), NormalNu[1].Sample(), NormalNu[2].Sample()),
                        MX     = mX,
                        KX     = KX,
                        KNu    = KNu
                    };

                    testSphere.Initialize(N, o.OutputFolder);
                    Vector <double> mErr;
                    Matrix <double> KErr;
                    Matrix <double> KErrTh;
                    Vector <double> mErr_inv;
                    Matrix <double> KErr_inv;
                    Matrix <double> KErrTh_inv;
                    Vector <double> mErr_lin;
                    Matrix <double> KErr_lin;
                    Matrix <double> KErrTh_lin;
                    Vector <double> mErr_UT;
                    Matrix <double> KErr_UT;
                    Matrix <double> KErrTh_UT;

                    string fileName_alldata = Path.Combine(o.OutputFolder, "test_sphere_alldata.txt");
                    testSphere.GenerateBundle(N, out mErr, out KErr, out KErrTh, out mErr_inv, out KErr_inv, out KErrTh_inv, out mErr_lin, out KErr_lin, out KErrTh_lin, out mErr_UT, out KErr_UT, out KErrTh_UT, fileName_alldata);


                    string fileName = Path.Combine(o.OutputFolder, "test_sphere.txt");
                    using (System.IO.StreamWriter outputfile = new System.IO.StreamWriter(fileName))
                    {
                        //outputfile.WriteLine($"P = {P}");
                        outputfile.WriteLine($"mErr = {mErr}");
                        outputfile.WriteLine($"KErr = {KErr}");
                        outputfile.WriteLine($"KErrTh = {KErrTh}");

                        //outputfile.WriteLine($"P_inv = {P_inv}");
                        outputfile.WriteLine($"mErr_inv = {mErr_inv}");
                        outputfile.WriteLine($"KErr_inv = {KErr_inv}");
                        outputfile.WriteLine($"KErrTh_inv = {KErrTh_inv}");

                        //outputfile.WriteLine($"P_lin = {P_lin}");
                        outputfile.WriteLine($"mErr_lin = {mErr_lin}");
                        outputfile.WriteLine($"KErr_lin = {KErr_lin}");
                        outputfile.WriteLine($"KErrTh_lin = {KErrTh_lin}");

                        //outputfile.WriteLine($"P_UT = {P_UT}");
                        outputfile.WriteLine($"mErr_UT = {mErr_UT}");
                        outputfile.WriteLine($"KErr_UT = {KErr_UT}");
                        outputfile.WriteLine($"KErrTh_UT = {KErrTh_UT}");

                        outputfile.Close();
                    }
                }
                #endregion

                #region polar
                if (o.Model == "polar")
                {
                    int N = o.N;

                    Vector <double> mX = Exts.Vector(300, 400); Matrix <double> KX = Exts.Diag(30 * 30, 30 * 30);
                    //Vector<double> mX = Exts.Vector(30000, 40000); Matrix<double> KX = Exts.Diag(100 * 100, 100 * 100);
                    //Vector<double> mX = Exts.Vector(30000, 40000); Matrix<double> KX = Exts.Diag(4500 * 4500, 4500 * 4500);
                    Vector <double> mNu = Exts.Vector(0, 0); Matrix <double> KNu = Exts.Diag(Math.Pow(5 * Math.PI / 180.0, 2.0), 30 * 30);
                    Normal[]        NormalX = new Normal[2] {
                        new Normal(mX[0], Math.Sqrt(KX[0, 0])), new Normal(mX[1], Math.Sqrt(KX[1, 1]))
                    };
                    Normal[] NormalNu = new Normal[2] {
                        new Normal(mNu[0], Math.Sqrt(KNu[0, 0])), new Normal(mNu[1], Math.Sqrt(KNu[1, 1]))
                    };;

                    //Console.WriteLine(mX.ToLine());

                    TestEnvironmentStatic testPolar = new TestEnvironmentStatic
                    {
                        Phi    = x => Utils.cart2pol(x),
                        InvPhi = y => Utils.pol2cart(y),
                        W      = () => Exts.Vector(NormalX[0].Sample(), NormalX[1].Sample()),
                        Nu     = () => Exts.Vector(NormalNu[0].Sample(), NormalNu[1].Sample()),
                        MX     = mX,
                        KX     = KX,
                        KNu    = KNu
                    };

                    testPolar.Initialize(N, o.OutputFolder);
                    Vector <double> mErr;
                    Matrix <double> KErr;
                    Matrix <double> KErrTh;
                    Vector <double> mErr_inv;
                    Matrix <double> KErr_inv;
                    Matrix <double> KErrTh_inv;
                    Vector <double> mErr_lin;
                    Matrix <double> KErr_lin;
                    Matrix <double> KErrTh_lin;
                    Vector <double> mErr_UT;
                    Matrix <double> KErr_UT;
                    Matrix <double> KErrTh_UT;

                    string fileName_alldata = Path.Combine(o.OutputFolder, "test_polar_alldata.txt");
                    testPolar.GenerateBundle(N, out mErr, out KErr, out KErrTh, out mErr_inv, out KErr_inv, out KErrTh_inv, out mErr_lin, out KErr_lin, out KErrTh_lin, out mErr_UT, out KErr_UT, out KErrTh_UT, fileName_alldata);


                    string fileName = Path.Combine(o.OutputFolder, "test_polar.txt");
                    using (System.IO.StreamWriter outputfile = new System.IO.StreamWriter(fileName))
                    {
                        //outputfile.WriteLine($"P = {P}");
                        outputfile.WriteLine($"mErr = {mErr}");
                        outputfile.WriteLine($"KErr = {KErr}");
                        outputfile.WriteLine($"KErrTh = {KErrTh}");

                        //outputfile.WriteLine($"P_inv = {P_inv}");
                        outputfile.WriteLine($"mErr_inv = {mErr_inv}");
                        outputfile.WriteLine($"KErr_inv = {KErr_inv}");
                        outputfile.WriteLine($"KErrTh_inv = {KErrTh_inv}");

                        //outputfile.WriteLine($"P_lin = {P_lin}");
                        outputfile.WriteLine($"mErr_lin = {mErr_lin}");
                        outputfile.WriteLine($"KErr_lin = {KErr_lin}");
                        outputfile.WriteLine($"KErrTh_lin = {KErrTh_lin}");

                        //outputfile.WriteLine($"P_UT = {P_UT}");
                        outputfile.WriteLine($"mErr_UT = {mErr_UT}");
                        outputfile.WriteLine($"KErr_UT = {KErr_UT}");
                        outputfile.WriteLine($"KErrTh_UT = {KErrTh_UT}");

                        outputfile.Close();
                    }
                }
                #endregion

                #region polartwo
                if (o.Model == "polartwo")
                {
                    int             N = o.N;
                    Vector <double> secondpoint = Exts.Vector(-10000, 10000);
                    Vector <double> mX = Exts.Vector(30000, 40000); Matrix <double> KX = Exts.Diag(2000 * 2000, 2000 * 2000);
                    Vector <double> mNu = Exts.Vector(0, 0, 0, 0);
                    Matrix <double> KNu = Exts.Diag(Math.Pow(0.1 * Math.PI / 180.0, 2.0),
                                                    50 * 50,
                                                    Math.Pow(0.1 * Math.PI / 180.0, 2.0),
                                                    50 * 50);
                    Normal[] NormalX = new Normal[2] {
                        new Normal(mX[0], Math.Sqrt(KX[0, 0])), new Normal(mX[1], Math.Sqrt(KX[1, 1]))
                    };
                    Normal[] NormalNu = new Normal[4] {
                        new Normal(mNu[0], Math.Sqrt(KNu[0, 0])),
                        new Normal(mNu[1], Math.Sqrt(KNu[1, 1])),
                        new Normal(mNu[2], Math.Sqrt(KNu[2, 2])),
                        new Normal(mNu[3], Math.Sqrt(KNu[3, 3]))
                    };

                    //Console.WriteLine(mX.ToLine());

                    TestEnvironmentStatic testPolar = new TestEnvironmentStatic
                    {
                        Phi    = x => Exts.Stack(Utils.cart2pol(x), Utils.cart2pol(x - secondpoint)),
                        InvPhi = y => Exts.Stack(Utils.pol2cart(Exts.Vector(y[0], y[1])), Utils.pol2cart(Exts.Vector(y[2], y[3])) + secondpoint),
                        W      = () => Exts.Vector(NormalX[0].Sample(), NormalX[1].Sample()),
                        Nu     = () => Exts.Vector(NormalNu[0].Sample(), NormalNu[1].Sample(), NormalNu[2].Sample(), NormalNu[3].Sample()),
                        //Nu = () => Exts.Vector(0,0,0,0),
                        MX  = mX,
                        KX  = KX,
                        KNu = KNu
                    };

                    testPolar.Initialize(N, o.OutputFolder);
                    Vector <double> mErr;
                    Matrix <double> KErr;
                    Matrix <double> KErrTh;
                    Vector <double> mErr_inv;
                    Matrix <double> KErr_inv;
                    Matrix <double> KErrTh_inv;
                    Vector <double> mErr_lin;
                    Matrix <double> KErr_lin;
                    Matrix <double> KErrTh_lin;
                    Vector <double> mErr_UT;
                    Matrix <double> KErr_UT;
                    Matrix <double> KErrTh_UT;

                    string fileName_alldata = Path.Combine(o.OutputFolder, "test_polartwo_alldata.txt");
                    testPolar.GenerateBundle(N, out mErr, out KErr, out KErrTh, out mErr_inv, out KErr_inv, out KErrTh_inv, out mErr_lin, out KErr_lin, out KErrTh_lin, out mErr_UT, out KErr_UT, out KErrTh_UT, fileName_alldata);


                    string fileName = Path.Combine(o.OutputFolder, "test_polartwo.txt");
                    using (System.IO.StreamWriter outputfile = new System.IO.StreamWriter(fileName))
                    {
                        //outputfile.WriteLine($"P = {P}");
                        outputfile.WriteLine($"mErr = {mErr}");
                        outputfile.WriteLine($"KErr = {KErr}");
                        outputfile.WriteLine($"KErrTh = {KErrTh}");

                        //outputfile.WriteLine($"P_inv = {P_inv}");
                        outputfile.WriteLine($"mErr_inv = {mErr_inv}");
                        outputfile.WriteLine($"KErr_inv = {KErr_inv}");
                        outputfile.WriteLine($"KErrTh_inv = {KErrTh_inv}");

                        //outputfile.WriteLine($"P_lin = {P_lin}");
                        outputfile.WriteLine($"mErr_lin = {mErr_lin}");
                        outputfile.WriteLine($"KErr_lin = {KErr_lin}");
                        outputfile.WriteLine($"KErrTh_lin = {KErrTh_lin}");

                        //outputfile.WriteLine($"P_UT = {P_UT}");
                        outputfile.WriteLine($"mErr_UT = {mErr_UT}");
                        outputfile.WriteLine($"KErr_UT = {KErr_UT}");
                        outputfile.WriteLine($"KErrTh_UT = {KErrTh_UT}");

                        outputfile.Close();
                    }
                }
                #endregion
            }
            else
            {
                TestEnvironmentVector testEnv = new TestEnvironmentVector();

                if (o.Model == "cubic")
                {
                    testEnv = new TestCubicSensorScalar(o.DW, o.DNu);
                }
                if (o.Model == "invprop-good")
                {
                    testEnv = new TestInverseProportionGoodScalar(o.Bound, o.DW, o.DNu);
                }
                if (o.Model == "invprop-bad")
                {
                    testEnv = new TestInverseProportionBadScalar(o.Bound, o.DW, o.DNu);
                }
                if (o.Model == "logreg-simple")
                {
                    testEnv = new TestLogisticModelScalar(o.Bound, o.DW, o.DNu);
                }
                if (o.Model == "logreg-zero")
                {
                    testEnv = new TestLogisticModelZeroScalar(o.Bound, o.DW, o.DNu);
                }
                if (o.Model == "logreg-uniform")
                {
                    testEnv = new TestLogisticModelUniformNoiseScalar();
                }
                if (o.Model == "samplereg")
                {
                    testEnv = new TestSampledRegression(o.DNu);
                }
                if (o.Model == "switchingobs")
                {
                    testEnv = new TestSwitchingObservations(o.DNu);
                }
                if (o.Model == "switchingobsident")
                {
                    switch (o.IdentNumber)
                    {
                    case 1: testEnv = new AnotherTestSwitchingObservationsIdentification(o.DNu); break;

                    case 2: testEnv = new YetAnotherTestSwitchingObservationsIdentification(o.DNu); break;

                    case 3: testEnv = new HopefullyTheLastTestSwitchingObservationsIdentification(o.DNu); break;

                    default: testEnv = new TestSwitchingObservationsIdentification(o.DNu); break;
                    }
                }
                if (o.Model == "simpleident")
                {
                    testEnv = new TestSimpleIdentification();
                }

                string CMNFFileName = Path.Combine(o.OutputFolder, "cmnf.params");
                if (!string.IsNullOrWhiteSpace(o.CMNFFileName))
                {
                    CMNFFileName = o.CMNFFileName;
                }
                string BCMNFFileName = Path.Combine(o.OutputFolder, "bcmnf.params");
                if (!string.IsNullOrWhiteSpace(o.BCMNFFileName))
                {
                    BCMNFFileName = o.BCMNFFileName;
                }

                string UKFFileName = Path.Combine(o.OutputFolder, "ukf.params");
                if (!string.IsNullOrWhiteSpace(o.UKFFileName))
                {
                    UKFFileName = o.UKFFileName;
                }
                string UKFOptStepwiseNMFileName = Path.Combine(o.OutputFolder, "ukfoptstepwiseNM.params");
                if (!string.IsNullOrWhiteSpace(o.UKFStepwiseNelderMeadFileName))
                {
                    UKFOptStepwiseNMFileName = o.UKFStepwiseNelderMeadFileName;
                }
                string UKFOptIntegralNMFileName = Path.Combine(o.OutputFolder, "ukfoptintegralNM.params");
                if (!string.IsNullOrWhiteSpace(o.UKFIntegralNelderMeadFileName))
                {
                    UKFOptIntegralNMFileName = o.UKFIntegralNelderMeadFileName;
                }
                string UKFOptStepwiseRandFileName = Path.Combine(o.OutputFolder, "ukfoptstepwiserand.params");
                if (!string.IsNullOrWhiteSpace(o.UKFStepwiseRandomShootFileName))
                {
                    UKFOptStepwiseRandFileName = o.UKFStepwiseRandomShootFileName;
                }
                string UKFOptIntegralRandFileName = Path.Combine(o.OutputFolder, "ukfoptintegralrand.params");
                if (!string.IsNullOrWhiteSpace(o.UKFIntegralRandomShootFileName))
                {
                    UKFOptIntegralRandFileName = o.UKFIntegralRandomShootFileName;
                }

                List <(FilterType, string)> filters = new List <(FilterType, string)>();
                if (o.CMNF)
                {
                    filters.Add((FilterType.CMNF, CMNFFileName));
                }
                if (o.BCMNF)
                {
                    testEnv.Alpha = testEnv.Xi;
                    testEnv.Gamma = (t, x, y) => y;
                    filters.Add((FilterType.BCMNF, BCMNFFileName));
                }
                if (o.MCMNF)
                {
                    testEnv.nMCMNF = o.MCMNFTrainCount;
                    filters.Add((FilterType.MCMNF, string.Empty));
                }
                if (o.UKF)
                {
                    filters.Add((FilterType.UKFNoOptimization, UKFFileName));
                }
                if (o.UKFStepwiseNelderMead)
                {
                    filters.Add((FilterType.UKFStepwise, UKFOptStepwiseNMFileName));
                }
                if (o.UKFIntegralNelderMead)
                {
                    filters.Add((FilterType.UKFIntegral, UKFOptIntegralNMFileName));
                }
                if (o.UKFStepwiseRandomShoot)
                {
                    filters.Add((FilterType.UKFStepwiseRandomShoot, UKFOptStepwiseRandFileName));
                }
                if (o.UKFIntegralRandomShoot)
                {
                    filters.Add((FilterType.UKFIntegralRandomShoot, UKFOptIntegralRandFileName));
                }
                if (o.EKF)
                {
                    filters.Add((FilterType.EKF, string.Empty));
                }
                if (o.Dummy)
                {
                    filters.Add((FilterType.Dummy, string.Empty));
                }

                using (System.IO.StreamWriter outputfile = new System.IO.StreamWriter(Path.Combine(o.OutputFolder, "parameters.txt"), true))
                {
                    outputfile.WriteLine($"{DateTime.Now}\t{string.Join(" ", args)}");
                    outputfile.Close();
                }

                if (o.Bulk)
                {
                    testEnv.GenerateBundleSamples(o.T, o.TrainCount, o.OutputFolder);
                }
                else
                {
                    testEnv.Initialize(o.T, o.TrainCount, o.OutputFolder, filters, o.Save, o.Load);

                    if (o.Aggregate)
                    {
                        testEnv.Aggregate(o.OutputFolder, o.OutputFolder, !o.NoBin, !o.NoText);
                    }
                    if (!o.Skip)
                    {
                        testEnv.GenerateBundles(o.BundleCount, o.TestCount, o.OutputFolder, o.Parallel, o.ParallelismDegree, !o.NoBin, !o.NoText);
                        //if (o.BundleCount > 1)
                        //    testEnv.GenerateBundles(o.BundleCount, o.TestCount, o.OutputFolder, o.Parallel, o.ParallelismDegree);
                        //else
                        //    testEnv.GenerateBundle(o.TestCount, o.OutputFolder);

                        if (o.SamplesCount == 1)
                        {
                            testEnv.GenerateOne(o.OutputFolder);
                        }
                        else
                        {
                            for (int i = 0; i < o.SamplesCount; i++)
                            {
                                testEnv.GenerateOne(o.OutputFolder, i);
                            }
                        }
                        //testEnv.GenerateReport(o.TemplatesFolder, o.PlotsFolder);
                    }
                    if (!o.NoPython)
                    {
                        testEnv.ProcessResults(o.OutputFolder, o.ScriptsFolder, o.PlotsFolder);
                    }
                }
            }
        }