コード例 #1
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 //copy constructor
 public NMMatrix(NMMatrix A)
 {
     _matrix = new double[A.N, A.M];
     _n = A.N;
     _m = A.M;
     for (int i = 0; i < A.N; i++)
         for (int j = 0; j < A.M; j++)
             _matrix[i, j] = A[i, j];
 }
コード例 #2
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public NMMatrix ExtractMatrix(int col, int coln)
 {
     NMMatrix A = new NMMatrix(N, coln);
     for (int i = 0; i < N; i++)
         for (int j = 0; j < coln; j++)
             A[i, j] = this[i, col + j];
     return A;
 }
コード例 #3
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public NMMatrix Transpose()
 {
     //make shallow copy, so both transposed and untransposed matrix may be used in same calculation
     NMMatrix A = new NMMatrix();
     A._matrix = _matrix;
     A._m = _m;
     A._n = _n;
     A._transpose = !_transpose;
     return A;
 }
コード例 #4
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public NMMatrix Augment(NVector V)
 {
     if (N != V.N) throw new Exception("NMMatrix.Concatenate: incompatable sizes");
     NMMatrix B = new NMMatrix(N, M + 1);
     for (int i = 0; i < N; i++)
     {
         for (int j = 0; j < M; j++)
             B[i, j] = this[i, j];
         B[i, M] = V[i];
     }
     return B;
 }
コード例 #5
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public NMMatrix Augment(NMMatrix A)
 {
     if (N != A.N) throw new Exception("NMMatrix.Concatenate: incompatable sizes");
     NMMatrix B = new NMMatrix(N, M + A.M);
     for (int i = 0; i < N; i++)
     {
         for (int j = 0; j < M; j++)
             B[i, j] = this[i, j];
         for (int j = 0; j < A.M; j++)
             B[i, M + j] = A[i, j];
     }
     return B;
 }
コード例 #6
0
ファイル: Program.cs プロジェクト: DOPS-CCI/CCI_project
 static void Main2(string[] args)
 {
     NVector A = new NVector(new double[] { 1, 3, 5, -2, 0 });
     NVector B = new NVector(new double[] { -1, -2, 3, 1, 2 });
     NVector C = A + B;
     Console.WriteLine("A =" + A.ToString("0.000"));
     Console.WriteLine("B =" + B.ToString("0.000"));
     Console.WriteLine("A+B =" + C.ToString("0.000"));
     double p = A.Dot(B);
     NMMatrix E = A.Cross(B);
     Console.WriteLine("A x B =" + E.ToString("0.000"));
     E[4, 0] = -2;
     E[4, 1] = 3;
     E[4, 2] = 5;
     E[4, 3] = -5;
     E[4, 4] = 7;
     E[0, 0] = -7;
     E[1, 3] = -3;
     E[3, 4] = -3.5;
     E[2, 4] = -2;
     NMMatrix H = new NMMatrix(new double[,] { { 5, 3, -2 ,1}, { 0, 3, 2,-3 }, { 4, 2, 3,2 }, { -6, 2, 8,-5 } });
     Console.WriteLine("H =" + H.ToString("0.000"));
     NVector V = new NVector(new double[] { 1, -1, 3, -2 });
     Console.WriteLine("V =" + V.ToString("0.000"));
     Console.WriteLine(" V / H =" + (V / H).ToString("0.0000"));
     NMMatrix HI = H.Inverse();
     Console.WriteLine("Inverse H =" + HI.ToString("0.000"));
     Console.WriteLine("H * HI " + (H * HI).ToString("0.00000"));
     Console.ReadKey();
     NVector F = C / E;
     NMMatrix G = E.Inverse();
     NMMatrix N = (G * E - NMMatrix.I(5)).Apply((LinearAlgebra.F)Math.Abs);
     double e = N.Max();
     Console.WriteLine((e*1E15).ToString("0.00"));
     Console.ReadKey();
 }
コード例 #7
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public NMMatrix Apply(F func)
 {
     NMMatrix A = new NMMatrix(this);
     for (int i = 0; i < A.N; i++)
         for (int j = 0; j < A.M; j++)
             A[i, j] = func(A[i, j]);
     return A;
 }
コード例 #8
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public static NMMatrix operator -(NMMatrix A, NMMatrix B)
 {
     if (A.N != B.N || A.M != B.M) throw new Exception("NMMatrix.Add: incompatable sizes");
     NMMatrix C = new NMMatrix(A);
     for (int i = 0; i < A.N; i++)
         for (int j = 0; j < A.M; j++)
             C._matrix[i, j] -= B[i, j];
     return C;
 }
コード例 #9
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public static NMMatrix operator /(NMMatrix A, double b)
 {
     NMMatrix C = new NMMatrix(A.N, A.M);
     for (int i = 0; i < A.N; i++)
         for (int j = 0; j < A.M; j++)
             C._matrix[i, j] = A[i, j] / b;
     return C;
 }
コード例 #10
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public static NMMatrix operator *(NMMatrix A, NMMatrix B)
 {
     if (A.M != B.N ) throw new Exception("NMMatrix.Mul: incompatable sizes");
     NMMatrix C = new NMMatrix(A.N, B.M);
     for (int i = 0; i < A.N; i++)
         for (int j = 0; j < B.M; j++)
         {
             double c = 0D;
             for (int k = 0; k < A.M; k++)
                 c += A[i, k] * B[k, j];
             C._matrix[i, j] = c;
         }
     return C;
 }
コード例 #11
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public static NMMatrix operator *(double a, NMMatrix B)
 {
     NMMatrix C = new NMMatrix(B);
     for (int i = 0; i < B.N; i++)
         for (int j = 0; j < B.M; j++)
             C._matrix[i, j] *= a;
     return C;
 }
コード例 #12
0
 private NMMatrix Jacobian(NVector p, NVector y)
 {
     NVector ps = new NVector(p); //save a copy
     NMMatrix J = new NMMatrix(m, n); //creating a new J from scratch
     double del_p;
     for (int j = 0; j < n; j++)
     {
         del_p = Math.Max(dp[j] * Math.Abs(p[j]), dp[j]);
         p[j] = ps[j] + del_p;
         NVector y1 = func(t, p);
         if (dp[j] != 0D) //forward or backward difference
             J.ReplaceColumn(j, (y1 - y) / del_p);
         else //central difference
         {
             p[j] = ps[j] - del_p;
             J.ReplaceColumn(j, (y1 - func(t, p)) / (2D * del_p));
         }
         p[j] = ps[j]; //restore this value
     }
     return J;
 }
コード例 #13
0
 private NMMatrix Broyden(NVector p_old, NVector y_old, NMMatrix J, NVector p, NVector y)
 {
     NVector h = p - p_old;
     J = J + (y - y_old - J * h).Cross(h) / h.Dot(h);
     return J;
 }
コード例 #14
0
        public NVector Calculate(NVector par_initial, NVector t, NVector y_dat)
        {
            _result = 0;
            m = t.N;
            if (par_initial.N != n) throw new Exception("LevenbergMarquardt.Calculate: size mismatch parms");
            this.p = par_initial;
            this.t = t;
            if (y_dat.N != m) throw new Exception("LevenbergMarquardt.Calculate: size mismatch t-y");
            this.y_dat = y_dat;

            //            weight_sq = (m - n + 1) / y_dat.Dot(y_dat);
            DOF = (double)(m - n + 1);

            //initalize Jacobian and related matrices
            y_hat = func(t, p);
            y_old = y_hat;
            if (Jfunc == null)
                J = Jacobian(p, y_hat);
            else
                J = Jfunc(t, p);
            NVector delta_y = y_dat - y_hat;
            X2 = delta_y.Dot(delta_y);
            JtJ = J.Transpose() * J;
            Jtdy = J.Transpose() * delta_y;

            iteration = 0;

            if (Jtdy.Abs().Max() < eps[0])
            {
                _result = 1;
                return p; //Good guess!!!
            }
            if (updateType == UpdateType.Marquardt)
                lambda = 0.01D;
            else
                lambda = 0.01D * JtJ.Diag().Max();

            bool stop = false;

            /************************** Begin Main loop ***********************/
            // y_hat = vector of y estimates for current value of parameters
            // y_try = vector of y estimates for current trial value of parameters
            // y_dat = given dependent values (fixed)
            // y_old = vector of y estimates for previous value of parameters (used in Broyden estimate of J)
            // t = given independent values (fixed)
            // p = current accepted estimate of parameters
            // h = last calculated (trial) increment for the parameters
            // p_try = current trial value for the parameters
            // p_old = previous accepted value of parameters (used in Broyden estimate of J)
            // X2 = chi^2 of last accepted estimate
            // X2_try = chi^2 of current trial estimate
            // J = current estimate of Jacobian at p

            while (!stop)
            {
                iteration++;

                NVector h;
                if (updateType == UpdateType.Marquardt)
                    h = Jtdy / (JtJ + lambda * JtJ.Diag().Diag());
                else
                    h = Jtdy / (JtJ + lambda * NMMatrix.I(n));

                NVector p_try = (p + h).Max(p_min).Min(p_max);

                NVector y_try = func(t, p_try);
                delta_y = y_dat - y_try;

                double X2_try = delta_y.Dot(delta_y);

                if (updateType == UpdateType.Quadratic)
                {
                    alpha = Jtdy.Dot(h) / ((X2_try - X2) / 2D + 2D * Jtdy.Dot(h));
                    h = h * alpha;
                    p_try = (p_try + h).Max(p_min).Min(p_max);
                    delta_y = y_dat - func(t, p_try);
                    X2_try = delta_y .Dot(delta_y);
                }
                dX2 = X2_try - X2;

                double rho = -dX2 / (2D * (lambda * h + Jtdy).Dot(h));

                if (dX2 < 0D) //found a better estimate
                {
                    X2 = X2_try;
                    p_old = p;
                    p = p_try;
                    y_old = y_hat;
                    y_hat = y_try;

                    if (iteration % (2 * n) == 0) //|| dX2 > 0 or is it rho > ep[3] ?
                        if (Jfunc == null)
                            J = Jacobian(p, y_hat);
                        else
                            J = Jfunc(t, p);
                    else
                        J = J + (y_hat - y_old - J * h).Cross(h) / h.Dot(h); //Broyden rank-1 update of J

                    JtJ = J.Transpose() * J;
                    Jtdy = J.Transpose() * delta_y;

                    switch (updateType)
                    {
                        case UpdateType.Marquardt:
                            lambda = Math.Max(lambda / lambda_DN_fac, 1E-7);
                            break;
                        case UpdateType.Quadratic:
                            lambda = Math.Max(lambda / (1 + alpha), 1E-7);
                            break;
                        case UpdateType.Nielsen:
                            lambda = lambda * Math.Max(1D / 3D, 1D - Math.Pow(2D * rho - 1D, 3));
                            nu = 2D;
                            break;
                    }

                    if (Jtdy.Abs().Max() < eps[0] && iteration > 2)
                    {
                        _result = 1;
                        stop = true;
                    }
                    else if ((h / p).Abs().Max() < eps[1] && iteration > 2)
                    {
                        _result = 2;
                        stop = true;
                    }
                    else if (X2 / (m - n + 1) < eps[2] && iteration > 2)
                    {
                        _result = 3;
                        stop = true;
                    }
                }
                else //Not a better estimate
                {
                    if (iteration % (2 * n) == 0) //update J every 2n th no matter what
                    {
                        if (Jfunc == null)
                            J = Jacobian(p, y_hat);
                        else
                            J = Jfunc(t, p);
                        JtJ = J.Transpose() * J;
                        Jtdy = J.Transpose() * (y_dat - y_hat);
                    }

                    switch (updateType)
                    {
                        case UpdateType.Marquardt:
                            lambda = Math.Min(lambda * lambda_UP_fac, 1E7);
                            break;
                        case UpdateType.Quadratic:
                            lambda = lambda + Math.Abs(dX2 / (2D * alpha));
                            break;
                        case UpdateType.Nielsen:
                            lambda = lambda * nu;
                            nu *= 2D;
                            break;
                    }
                }

                if (iteration > MaxIter && !stop)
                {
                    _result = -1;
                    return p;
                }
            }
            /************************** End Main loop ************************/

            return p;
        }
コード例 #15
0
ファイル: NVector.cs プロジェクト: DOPS-CCI/CCI_project
 public NMMatrix Cross(NVector A)
 {
     NMMatrix C = new NMMatrix(_n, A._n);
     for (int i = 0; i < _n; i++)
         for (int j = 0; j < A._n; j++)
             C[i,j] += _vector[i] * A._vector[j];
     return C;
 }
コード例 #16
0
ファイル: NMMatrix.cs プロジェクト: DOPS-CCI/CCI_project
 public static NMMatrix I(int n)
 {
     NMMatrix A = new NMMatrix(n, n);
     for (int i = 0; i < n; i++)
         A._matrix[i, i] = 1D;
     return A;
 }
コード例 #17
0
ファイル: NVector.cs プロジェクト: DOPS-CCI/CCI_project
 public NMMatrix Diag()
 {
     NMMatrix A = new NMMatrix(_n, _n);
     for (int i = 0; i < _n; i++)
         A[i, i] = _vector[i];
     return A;
 }
コード例 #18
0
ファイル: Program.cs プロジェクト: DOPS-CCI/CCI_project
 static NMMatrix Jfunc(NVector t, NVector p)
 {
     double eat;
     double ebt;
     NMMatrix J = new NMMatrix(t.N, p.N);
     for (int i = 0; i < t.N; i++)
     {
         double t0 = t[i] - p[5];
         if (t0 < 0D)
             J[i, 2] = 1D;
         else
         {
             eat = Math.Exp(-p[3] * t0);
             ebt = Math.Exp(-p[4] * t0);
             J[i, 0] = ebt * (1D - eat);
             J[i, 1] = 1D - ebt;
             J[i, 2] = ebt;
             J[i, 3] = p[0] * t0 * eat * ebt;
             J[i, 4] = -ebt * t0 * (p[0] * (1D - eat) + p[2] - p[1]);
             J[i, 5] = ebt * (p[0] * (p[4] * (1D - eat) - p[3] * eat) + (p[2] - p[1]) * p[4]);
         }
     }
     return J;
 }