コード例 #1
0
        public static AasenDecomposition LTLDecompose3(SymmetricMatrix M)
        {
            // Aasen's method, now with pivoting

            int n = M.Dimension;

            double[] a = new double[n];
            double[] b = new double[n - 1];
            SquareMatrix L = new SquareMatrix(n);
            for (int i = 0; i < n; i++) L[i, i] = 1.0;

            // working space for d'th column of H = T L^T
            double[] h = new double[n];

            // first row
            a[0] = M[0, 0];
            if (n > 1) b[0] = M[1, 0];
            for (int i = 2; i < n; i++) L[i, 1] = M[i, 0] / b[0];

            PrintLTLMatrices(h, a, b, L);

            // second row
            if (n > 1) {
                a[1] = M[1, 1];
                if (n > 2) b[1] = M[2, 1] - L[2, 1] * a[1];
                for (int i = 3; i < n; i++) L[i, 2] = (M[i, 1] - L[i, 1] * a[1]) / b[1];
            }

            PrintLTLMatrices(h, a, b, L);

            for (int d = 0; d < n; d++) {

                Console.WriteLine("d = {0}", d);

                // compute h (d'th row of T L^T)
                if (d == 0) {
                    h[0] = M[0, 0];
                } else if (d == 1) {
                    h[0] = b[0];
                    h[1] = M[1, 1];
                } else {
                    h[0] = b[0] * L[d, 1];
                    h[1] = b[1] * L[d, 2] + a[1] * L[d, 1];
                    h[d] = M[d, d] - L[d, 1] * h[1];
                    for (int i = 2; i < d; i++) {
                        h[i] = b[i] * L[d, i + 1] + a[i] * L[d, i] + b[i - 1] * L[d, i - 1];
                        h[d] -= L[d, i] * h[i];
                    }
                }

                // compute alpha (d'th diagonal element of T)
                if ((d == 0) || (d == 1)) {
                    a[d] = h[d];
                } else {
                    a[d] = h[d] - b[d - 1] * L[d, d - 1];
                }

                Console.WriteLine("before pivot");
                PrintMatrix(M);
                PrintMatrix(L);

                // find the pivot
                if (d < (n - 1)) {
                    int p = d + 1;
                    double q = M[p, d];
                    for (int i = d + 2; i < n; i++) {
                        if (Math.Abs(M[i, d]) > Math.Abs(q)) {
                            p = i;
                            q = M[i, d];
                        }
                    }

                    Console.WriteLine("pivot = {0}", p);

                    // symmetricly permute the pivot element to M[d+1,d]
                    if (p != d + 1) {

                        // symmetricly permute the pivot element to M[d+1, d]
                        // we have to be a bit careful here, because some permutations will be done
                        // automatically by our SymmetricMatrix class due to symmetry
                        for (int i = 0; i < n; i++) {
                            if ((i == p) || (i == d + 1)) continue;
                            double t = M[d + 1, i];
                            M[d + 1, i] = M[p, i];
                            M[p, i] = t;
                        }
                        double tt = M[d + 1, d + 1];
                        M[d + 1, d + 1] = M[p, p];
                        M[p, p] = tt;

                        // also reorder the affected previously computed elements of L
                        for (int i = 1; i <= d; i++) {
                            double t = L[d + 1, i];
                            L[d + 1, i] = L[p, i];
                            L[p, i] = t;
                        }

                        Console.WriteLine("after pivot");
                        PrintMatrix(M);
                        PrintMatrix(L);

                    }

                }

                // compute beta (d'th subdiagonal element of T)
                if (d < (n - 1)) {
                    b[d] = M[d + 1, d];
                    for (int i = 0; i <= d; i++) {
                        Console.WriteLine("n={0} d={1} i={2}", n, d, i);
                        b[d] -= L[d + 1, i] * h[i];
                    }
                }

                // compute (d+1)'th column of L
                for (int i = d + 2; i < n; i++) {
                    L[i, d + 1] = M[i, d];
                    for (int j = 0; j <= d; j++) L[i, d + 1] -= L[i, j] * h[j];
                    L[i, d + 1] = L[i, d + 1] / b[d];
                }

                PrintLTLMatrices(h, a, b, L);

            }

            Console.WriteLine("Reconstruct");
            SymmetricMatrix T = new SymmetricMatrix(n);
            for (int i = 0; i < n; i++) {
                T[i, i] = a[i];
            }
            for (int i = 0; i < (n - 1); i++) {
                T[i + 1, i] = b[i];
            }
            SquareMatrix A = L * T * L.Transpose();
            PrintMatrix(A);

            SymmetricMatrix D = new SymmetricMatrix(n);
            for (int i = 0; i < n; i++) {
                D[i, i] = a[i];
            }
            for (int i = 0; i < (n - 1); i++) {
                D[i + 1, i] = b[i];
            }
            for (int c = 1; c < (n - 1); c++) {
                for (int r = c + 1; r < n; r++) {
                    D[r, c - 1] = L[r, c];
                }
            }
            AasenDecomposition LTL = new AasenDecomposition(D);
            return (LTL);
        }
コード例 #2
0
        public static AasenDecomposition LTLDecompose3(SymmetricMatrix M)
        {
            // Aasen's method, now with pivoting

            int n = M.Dimension;

            double[]     a = new double[n];
            double[]     b = new double[n - 1];
            SquareMatrix L = new SquareMatrix(n);

            for (int i = 0; i < n; i++)
            {
                L[i, i] = 1.0;
            }

            // working space for d'th column of H = T L^T
            double[] h = new double[n];

            // first row
            a[0] = M[0, 0];
            if (n > 1)
            {
                b[0] = M[1, 0];
            }
            for (int i = 2; i < n; i++)
            {
                L[i, 1] = M[i, 0] / b[0];
            }

            PrintLTLMatrices(h, a, b, L);

            // second row
            if (n > 1)
            {
                a[1] = M[1, 1];
                if (n > 2)
                {
                    b[1] = M[2, 1] - L[2, 1] * a[1];
                }
                for (int i = 3; i < n; i++)
                {
                    L[i, 2] = (M[i, 1] - L[i, 1] * a[1]) / b[1];
                }
            }

            PrintLTLMatrices(h, a, b, L);

            for (int d = 0; d < n; d++)
            {
                Console.WriteLine("d = {0}", d);

                // compute h (d'th row of T L^T)
                if (d == 0)
                {
                    h[0] = M[0, 0];
                }
                else if (d == 1)
                {
                    h[0] = b[0];
                    h[1] = M[1, 1];
                }
                else
                {
                    h[0] = b[0] * L[d, 1];
                    h[1] = b[1] * L[d, 2] + a[1] * L[d, 1];
                    h[d] = M[d, d] - L[d, 1] * h[1];
                    for (int i = 2; i < d; i++)
                    {
                        h[i]  = b[i] * L[d, i + 1] + a[i] * L[d, i] + b[i - 1] * L[d, i - 1];
                        h[d] -= L[d, i] * h[i];
                    }
                }

                // compute alpha (d'th diagonal element of T)
                if ((d == 0) || (d == 1))
                {
                    a[d] = h[d];
                }
                else
                {
                    a[d] = h[d] - b[d - 1] * L[d, d - 1];
                }

                Console.WriteLine("before pivot");
                PrintMatrix(M);
                PrintMatrix(L);

                // find the pivot
                if (d < (n - 1))
                {
                    int    p = d + 1;
                    double q = M[p, d];
                    for (int i = d + 2; i < n; i++)
                    {
                        if (Math.Abs(M[i, d]) > Math.Abs(q))
                        {
                            p = i;
                            q = M[i, d];
                        }
                    }

                    Console.WriteLine("pivot = {0}", p);

                    // symmetricly permute the pivot element to M[d+1,d]
                    if (p != d + 1)
                    {
                        // symmetricly permute the pivot element to M[d+1, d]
                        // we have to be a bit careful here, because some permutations will be done
                        // automatically by our SymmetricMatrix class due to symmetry
                        for (int i = 0; i < n; i++)
                        {
                            if ((i == p) || (i == d + 1))
                            {
                                continue;
                            }
                            double t = M[d + 1, i];
                            M[d + 1, i] = M[p, i];
                            M[p, i]     = t;
                        }
                        double tt = M[d + 1, d + 1];
                        M[d + 1, d + 1] = M[p, p];
                        M[p, p]         = tt;

                        // also reorder the affected previously computed elements of L
                        for (int i = 1; i <= d; i++)
                        {
                            double t = L[d + 1, i];
                            L[d + 1, i] = L[p, i];
                            L[p, i]     = t;
                        }

                        Console.WriteLine("after pivot");
                        PrintMatrix(M);
                        PrintMatrix(L);
                    }
                }

                // compute beta (d'th subdiagonal element of T)
                if (d < (n - 1))
                {
                    b[d] = M[d + 1, d];
                    for (int i = 0; i <= d; i++)
                    {
                        Console.WriteLine("n={0} d={1} i={2}", n, d, i);
                        b[d] -= L[d + 1, i] * h[i];
                    }
                }

                // compute (d+1)'th column of L
                for (int i = d + 2; i < n; i++)
                {
                    L[i, d + 1] = M[i, d];
                    for (int j = 0; j <= d; j++)
                    {
                        L[i, d + 1] -= L[i, j] * h[j];
                    }
                    L[i, d + 1] = L[i, d + 1] / b[d];
                }

                PrintLTLMatrices(h, a, b, L);
            }


            Console.WriteLine("Reconstruct");
            SymmetricMatrix T = new SymmetricMatrix(n);

            for (int i = 0; i < n; i++)
            {
                T[i, i] = a[i];
            }
            for (int i = 0; i < (n - 1); i++)
            {
                T[i + 1, i] = b[i];
            }
            SquareMatrix A = L * T * L.Transpose();

            PrintMatrix(A);


            SymmetricMatrix D = new SymmetricMatrix(n);

            for (int i = 0; i < n; i++)
            {
                D[i, i] = a[i];
            }
            for (int i = 0; i < (n - 1); i++)
            {
                D[i + 1, i] = b[i];
            }
            for (int c = 1; c < (n - 1); c++)
            {
                for (int r = c + 1; r < n; r++)
                {
                    D[r, c - 1] = L[r, c];
                }
            }
            AasenDecomposition LTL = new AasenDecomposition(D);

            return(LTL);
        }