예제 #1
0
        public static void Jacobi(MatrixR A, double tolerance, out MatrixR x, out VectorR lambda)
        {
            MatrixR AA           = A.Clone();
            int     n            = A.GetCols();
            int     maxTransform = 5 * n * n;
            MatrixR matrix       = new MatrixR(n, n);
            MatrixR R            = matrix.Identity();
            MatrixR R1           = R;
            MatrixR A1           = A;

            lambda = new VectorR(n);
            x      = R;

            double maxTerm = 0.0;
            int    I, J;

            do
            {
                maxTerm = MaxTerm(A, out I, out J);
                Transformation(A, R, I, J, out A1, out R1);
                A = A1;
                R = R1;
            }while (maxTerm > tolerance);

            x = R;
            for (int i = 0; i < n; i++)
            {
                lambda[i] = A[i, i];
            }

            for (int i = 0; i < n - 1; i++)
            {
                int    index = i;
                double d     = lambda[i];
                for (int j = i + 1; j < n; j++)
                {
                    if (lambda[j] > d)
                    {
                        index = j;
                        d     = lambda[j];
                    }
                }
                if (index != i)
                {
                    lambda = lambda.GetSwap(i, index);
                    x      = x.GetColSwap(i, index);
                }
            }
        }
예제 #2
0
        public static MatrixR Tridiagonalize(MatrixR A)
        {
            int     n  = A.GetCols();
            MatrixR A1 = new MatrixR(n, n);

            A1 = A.Clone();
            double h, g, unorm;

            for (int i = 0; i < n - 2; i++)
            {
                VectorR u = new VectorR(n - i - 1);
                for (int j = i + 1; j < n; j++)
                {
                    u[j - i - 1] = A[i, j];
                }
                unorm = u.GetNorm();
                if (u[0] < 0.0)
                {
                    unorm = -unorm;
                }
                u[0] += unorm;

                for (int j = i + 1; j < n; j++)
                {
                    A[j, i] = u[j - i - 1];
                }

                h = VectorR.DotProduct(u, u) * 0.5;

                VectorR v  = new VectorR(n - i - 1);
                MatrixR a1 = new MatrixR(n - i - 1, n - i - 1);
                for (int j = i + 1; j < n; j++)
                {
                    for (int k = i + 1; k < n; k++)
                    {
                        a1[j - i - 1, k - i - 1] = A[j, k];
                    }
                }
                v  = MatrixR.Transform(a1, u) / h;
                g  = VectorR.DotProduct(u, v) / (2.0 * h);
                v -= g * u;

                for (int j = i + 1; j < n; j++)
                {
                    for (int k = i + 1; k < n; k++)
                    {
                        A[j, k] = A[j, k] - v[j - i - 1] * u[k - i - 1] - u[j - i - 1] * v[k - i - 1];
                    }
                }
                A[i, i + 1] = -unorm;
            }
            Alpha    = new double[n];
            Beta     = new double[n - 1];
            Alpha[0] = A[0, 0];
            for (int i = 1; i < n; i++)
            {
                Alpha[i]    = A[i, i];
                Beta[i - 1] = A[i - 1, i];
            }

            MatrixR V = new MatrixR(n, n);

            V = V.Identity();

            for (int i = 0; i < n - 2; i++)
            {
                VectorR u = new VectorR(n - i - 1);
                for (int j = i + 1; j < n; j++)
                {
                    u[j - i - 1] = A.GetColVector(i)[j];
                }
                h = VectorR.DotProduct(u, u) * 0.5;
                VectorR v  = new VectorR(n - 1);
                MatrixR v1 = new MatrixR(n - 1, n - i - 1);
                for (int j = 1; j < n; j++)
                {
                    for (int k = i + 1; k < n; k++)
                    {
                        v1[j - 1, k - i - 1] = V[j, k];
                    }
                }

                v = MatrixR.Transform(v1, u) / h;

                for (int j = 1; j < n; j++)
                {
                    for (int k = i + 1; k < n; k++)
                    {
                        V[j, k] -= v[j - 1] * u[k - i - 1];
                    }
                }
            }
            return(V);
        }