Beispiel #1
0
        /// <summary>
        /// Return the component of the vector perpendicular to all the vectors in the vector space spanned by vlist
        /// </summary>
        /// <param name="vlist">a set of vectors perpendicular to each other</param>
        /// <returns>the vector perpendicular to all the vectors in the vector space spanned by vlist</returns>
        public IVector ProjectOrthogonal(IEnumerable <IVector> vlist)
        {
            IVector b = this;

            foreach (IVector v in vlist)
            {
                b = b.Minus(b.ProjectAlong(v));
            }

            return(b);
        }
Beispiel #2
0
        public IVector ProjectOrthogonal(List <IVector> vlist, out Dictionary <int, double> alpha)
        {
            IVector b = this;
            double  sigma;

            alpha = new Dictionary <int, double>();
            alpha[vlist.Count] = 1;

            for (int i = 0; i < vlist.Count; ++i)
            {
                IVector v       = vlist[i];
                IVector b_along = b.ProjectAlong(v, out sigma);
                b        = b.Minus(b_along);
                alpha[i] = sigma;
            }

            return(b);
        }
        public IMatrix Minus(IMatrix rhs)
        {
            Debug.Assert(RowCount == rhs.RowCount);
            Debug.Assert(ColCount == rhs.ColCount);

            HashSet <int> allRows = new HashSet <int>();

            foreach (int k in mInternal.Keys)
            {
                allRows.Add(k);
            }
            foreach (int k in rhs.RowKeys)
            {
                allRows.Add(k);
            }

            IMatrix result = this.Zero(mRowKeys, mColKeys, mDefaultVal);

            foreach (int k in allRows)
            {
                IVector row1 = this[k];
                IVector row2 = rhs[k];
                if (row1 == null)
                {
                    result[k] = row2.Multiply(-1);
                }
                else if (row2 == null)
                {
                    result[k] = row1.Clone();
                }
                else
                {
                    result[k] = row1.Minus(row2);
                }
            }

            return(result);
        }
Beispiel #4
0
 /// <summary>
 /// 采用观测值和近似值初始化。
 /// </summary>
 /// <param name="Observation">观测值</param>
 /// <param name="Approx">近似值</param>
 public AdjustVector(IVector Observation, IVector Approx)
     : base((Observation.Minus(Approx)))
 {
     this.Observation = Observation;
     this.Approx      = Approx;
 }
        /// <summary>
        /// Get the point in the vector space which is closest to b
        /// </summary>
        /// <param name="b">A vector which may be outside the vector space</param>
        /// <returns>Return point in the vector space closest to b</returns>
        public IVector GetClosedPoint(IVector b)
        {
            IVector b_orth = b.ProjectOrthogonal(mOrthogonalBasis);

            return(b.Minus(b_orth));
        }
Beispiel #6
0
        public override double[] Solve()
        {
            int m = A.RowCount;
            int n = A.ColCount;

            Debug.Assert(m >= n);
            
            IVector t = new SparseVector(n);
            for (int i = 0; i < m; ++i)
            {
                t[i] = 0;
            }
            IVector s = new SparseVector(n);
            IVector sy = new SparseVector(n);
            for (int i = 0; i < n; ++i)
            {
                s[i] = 0;
            }
            IVector s_old = s;

            IMatrix U; // U is a m x m orthogonal matrix 
            IMatrix Vt; // V is a n x n orthogonal matrix
            IMatrix Sigma; // Sigma is a m x n diagonal matrix with non-negative real numbers on its diagonal 
            SVD.Factorize(A, out U, out Sigma, out Vt); // A is a m x n matrix
           
            IMatrix Ut = U.Transpose();
            IMatrix V = Vt.Transpose();
           

            //SigmaInv is obtained by replacing every non-zero diagonal entry by its reciprocal and transposing the resulting matrix
            IMatrix SigmaInv = new SparseMatrix(m, n);
            for (int i = 0; i < n; ++i) // assuming m >= n
            {
                double sigma_i = Sigma[i, i];
                if (sigma_i < epsilon) // model matrix A is rank deficient
                {
                    throw new Exception("Near rank-deficient model matrix");
                }
                SigmaInv[i, i] = 1.0 / sigma_i;
            }
            SigmaInv = SigmaInv.Transpose();

            double[] W = new double[m];

            for (int j = 0; j < mMaxIters; ++j)
            {
                Console.WriteLine("j: {0}", j);

                IVector z = new SparseVector(m);
                double[] g = new double[m];
                double[] gprime = new double[m];

                for (int k = 0; k < m; ++k)
                {
                    g[k] = mLinkFunc.GetInvLink(t[k]);
                    gprime[k] = mLinkFunc.GetInvLinkDerivative(t[k]);

                    z[k] = t[k] + (b[k] - g[k]) / gprime[k];
                }

                int tiny_weight_count = 0;
                for (int k = 0; k < m; ++k)
                {
                    double w_kk = gprime[k] * gprime[k] / GetVariance(g[k]);
                    W[k] = w_kk;
                    if (w_kk < double.Epsilon * 2)
                    {
                        tiny_weight_count++;
                    }
                }

                if (tiny_weight_count > 0)
                {
                    Console.WriteLine("Warning: tiny weights encountered, (diag(W)) is too small");
                }

                s_old = s;

                IMatrix UtW = new SparseMatrix(m, m);
                for (int k = 0; k < m; ++k)
                {
                    for (int k2 = 0; k2 < m; ++k2)
                    {
                        UtW[k, k2] = Ut[k, k2] * W[k];
                    }
                }

                IMatrix UtWU = UtW.Multiply(U); // m x m positive definite matrix
                IMatrix L; // m x m lower triangular matrix
                Cholesky.Factorize(UtWU, out L);
                
                IMatrix Lt = L.Transpose(); // m x m upper triangular matrix

                IVector UtWz = UtW.Multiply(z); // m x 1 vector

                // (Ut * W * U) * s = Ut * W * z
                // L * Lt * s = Ut * W * z (Cholesky factorization on Ut * W * U)
                // L * sy = Ut * W * z, Lt * s = sy 
                s = new SparseVector(n);
                for (int i = 0; i < n; ++i)
                {
                    s[i] = 0;
                    sy[i] = 0;
                }

                // forward solve sy for L * sy = Ut * W * z
                for (int i = 0; i < n; ++i)  // since m >= n
                {
                    double cross_prod = 0;
                    for (int k = 0; k < i; ++k)
                    {
                        cross_prod += L[i, k] * sy[k];
                    }
                    sy[i] = (UtWz[i] - cross_prod) / L[i, i];
                }
                // backward solve s for Lt * s = sy
                for (int i = n - 1; i >= 0; --i) 
                {
                    double cross_prod = 0;
                    for (int k = i + 1; k < n; ++k)
                    {
                        cross_prod += Lt[i, k] * s[k];
                    }
                    s[i] = (sy[i] - cross_prod) / Lt[i, i];
                }


                t = U.Multiply(s);

                if ((s_old.Minus(s)).Norm(2) < mTol)
                {
                    break;
                }
            }

            IVector x = V.Multiply(SigmaInv).Multiply(Ut).Multiply(t);

            mX = new double[n];
            for (int i = 0; i < n; ++i)
            {
                mX[i] = x[i];
            }

            UpdateStatistics(W);

            return X;
        }
Beispiel #7
0
        public override double[] Solve()
        {
            int m = A.RowCount;
            int n = A.ColCount;

            Debug.Assert(m >= n);

            IVector s  = new SparseVector(n);
            IVector sy = new SparseVector(n);

            for (int i = 0; i < n; ++i)
            {
                s[i] = 0;
            }

            IVector t = new SparseVector(m);

            for (int i = 0; i < m; ++i)
            {
                t[i] = 0;
            }

            double[] g      = new double[m];
            double[] gprime = new double[m];

            IMatrix Q;
            IMatrix R;

            QR.Factorize(A, out Q, out R); // A is m x n, Q is m x n orthogonal matrix, R is n x n (R will be upper triangular matrix if m == n)

            IMatrix Qt = Q.Transpose();

            IVector W = null;

            for (int j = 0; j < mMaxIters; ++j)
            {
                IVector z = new SparseVector(m);

                for (int k = 0; k < m; ++k)
                {
                    g[k]      = mLinkFunc.GetInvLink(t[k]);
                    gprime[k] = mLinkFunc.GetInvLinkDerivative(t[k]);

                    z[k] = t[k] + (b[k] - g[k]) / gprime[k];
                }

                W = new SparseVector(m);
                double w_kk_min = double.MaxValue;
                for (int k = 0; k < m; ++k)
                {
                    double g_variance = GetVariance(g[k]);
                    double w_kk       = gprime[k] * gprime[k] / (g_variance);
                    W[k]     = w_kk;
                    w_kk_min = System.Math.Min(w_kk, w_kk_min);
                }

                if (w_kk_min < System.Math.Sqrt(double.Epsilon))
                {
                    Console.WriteLine("Warning: Tiny weights encountered, min(diag(W)) is too small");
                }

                IVector s_old = s;


                IMatrix WQ = new SparseMatrix(m, n); // W * Q
                IVector Wz = new SparseVector(m);    // W * z
                for (int k = 0; k < m; k++)
                {
                    Wz[k] = z[k] * W[k];
                    for (int k2 = 0; k2 < m; ++k2)
                    {
                        WQ[k, k2] = Q[k, k2] * W[k];
                    }
                }

                IMatrix QtWQ = Qt.Multiply(WQ); // a n x n positive definite matrix, therefore can apply Cholesky
                IVector QtWz = Qt.Multiply(Wz);

                IMatrix L;
                Cholesky.Factorize(QtWQ, out L);

                IMatrix Lt = L.Transpose();

                // (Qt * W * Q) * s = Qt * W * z;
                // L * Lt * s = Qt * W * z (Cholesky factorization on Qt * W * Q)
                // L * sy = Qt * W * z, Lt * s = sy
                // Now forward solve sy for L * sy = Qt * W * z
                // Now backward solve s for Lt * s = sy
                s = new SparseVector(n);
                for (int i = 0; i < n; ++i)
                {
                    s[i]  = 0;
                    sy[i] = 0;
                }

                //forward solve sy for L * sy = Qt * W * z
                //Console.WriteLine(L);
                for (int i = 0; i < n; ++i)
                {
                    double cross_prod = 0;
                    for (int k = 0; k < i; ++k)
                    {
                        cross_prod += L[i, k] * sy[k];
                    }
                    sy[i] = (QtWz[i] - cross_prod) / L[i, i];
                }
                //backward solve s for U * s = sy
                for (int i = n - 1; i >= 0; --i)
                {
                    double cross_prod = 0;
                    for (int k = i + 1; k < n; ++k)
                    {
                        cross_prod += Lt[i, k] * s[k];
                    }
                    s[i] = (sy[i] - cross_prod) / Lt[i, i];
                }

                t = Q.Multiply(s);

                double cost = (s_old.Minus(s)).Norm(2);
                if (j % 100 == 0)
                {
                    Console.WriteLine("Iteration: {0}, Cost: {1}", j, cost);
                }

                if (cost < mTol)
                {
                    break;
                }
            }

            mX = new double[n];

            //backsolve x for R * x = Qt * t
            IVector c = Qt.Multiply(t);

            for (int i = n - 1; i >= 0; --i) // since m >= n
            {
                double cross_prod = 0;
                for (int j = i + 1; j < n; ++j)
                {
                    cross_prod += R[i, j] * mX[j];
                }
                mX[i] = (c[i] - cross_prod) / R[i, i];
            }

            UpdateStatistics(W);

            return(X);
        }