Exemplo n.º 1
0
        // copy = 행렬을 copy후 계산할것인가?
        // allowMulNeg = Switching이 홀수번 이루어지면 자동으로 첫 행에 * -1
        public static Matrix GaussBot(Matrix m, bool copy, bool allowMulNeg)
        {
            bool   found = false, neg = false;
            int    r = 0, c = 0;
            Matrix ret = copy ? new Matrix(m) : m;

            while (r < m.rows && c < m.columns)
            {
                for (int i = r; i < m.rows; i++)
                {
                    if (((Fraction)m.data[i, c]).GetValue() != 0)
                    {
                        if (i != r)
                        {
                            Switching(ret, i, r);
                            Console.WriteLine("Switch " + i + ", " + r);
                            neg = !neg;
                        }
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    c++;
                    continue;
                }
                else
                {
                    Fraction src = ret.data[r, c] as Fraction;
                    for (int j = r + 1; j < m.rows; j++)
                    {
                        Fraction val = ret.data[j, c] as Fraction;
                        if (val.GetValue() != 0)
                        {
                            Fraction frac = FractionOperators.Negative(FractionOperators.Divide(val, src));
                            ScalaAdd(ret, r, j, frac);
                            Console.WriteLine("Add " + r + "*" + frac + " -> " + j);
                        }
                    }
                }

                r++; c++;
            }

            if (neg && allowMulNeg)
            {
                ScalaRow(ret, 0, -1);
            }

            return(ret);
        }
Exemplo n.º 2
0
        public static Matrix GaussTop(Matrix m, bool copy)
        {
            int    r = m.rows - 1, c = m.columns - 1;
            Matrix ret = copy ? new Matrix(m) : m;

            while (r >= 0 && c >= 0)
            {
                int swcnt = 0;
                for (int i = r; i >= 0; i--)
                {
                    if (((Fraction)ret.data[i, c]).GetValue() != 0)
                    {
                        if (i != r)
                        {
                            Switching(ret, i, r);
                        }
                        swcnt++;
                        break;
                    }
                }

                if (swcnt == 0)
                {
                    c--;
                    continue;
                }
                else
                {
                    Fraction src = ret.data[r, c] as Fraction;
                    for (int j = r - 1; j >= 0; j--)
                    {
                        Fraction val = ret.data[j, c] as Fraction;
                        if (val.GetValue() != 0)
                        {
                            ScalaAdd(ret, r, j, FractionOperators.Negative(FractionOperators.Divide(val, src)));
                        }
                    }
                }

                r--; c--;
            }

            return(ret);
        }
Exemplo n.º 3
0
        public static Matrix Inverse(List <TokenType> parameters)
        {
            Matrix m = parameters[0] as Matrix;

            Matrix.CheckNumbericMatrix(m);
            Matrix.CheckSquareMatrix(m);

            Matrix mat = Matrix.CreateUnsafeMatrix(m.rows, m.columns * 2);

            for (int r = 0; r < m.rows; r++)
            {
                for (int c = 0; c < m.columns; c++)
                {
                    mat.data[r, c] = m.data[r, c];
                }
                for (int c = m.columns; c < m.columns * 2; c++)
                {
                    if (c == r + m.columns)
                    {
                        mat.data[r, c] = new Fraction(1);
                    }
                    else
                    {
                        mat.data[r, c] = new Fraction(0);
                    }
                }
            }

            GaussBot(mat, false, false);

            Fraction det = 1;

            for (int i = 0; i < mat.rows; i++)
            {
                det = FractionOperators.Multiply(det, mat.data[i, i]);
            }

            if (det.GetValue() == 0)
            {
                throw new ExprCoreException("행렬식이 0인 행렬은 inverse를 구할 수 없습니다.");
            }

            for (int i = mat.rows - 1; i >= 0; i--)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    ScalaAdd(mat, i, j, FractionOperators.Negative(FractionOperators.Divide(mat.data[j, i], mat.data[i, i])));
                }
                ScalaRow(mat, i, FractionOperators.Divide(new Fraction(1), mat.data[i, i]));
            }

            Matrix ret = Matrix.CreateUnsafeMatrix(m.rows, m.columns);

            for (int r = 0; r < m.rows; r++)
            {
                for (int c = 0; c < m.columns; c++)
                {
                    ret.data[r, c] = mat.data[r, m.rows + c];
                }
            }

            return(ret);
        }