Exemplo n.º 1
0
 private static void ScalaAdd(Matrix m, int src, int dst, Fraction s)
 {
     for (int i = 0; i < m.columns; i++)
     {
         m.data[dst, i] = FractionOperators.Add(m.data[dst, i], FractionOperators.Multiply(s, m.data[src, i]));
     }
 }
Exemplo n.º 2
0
 private static void ScalaRow(Matrix m, int r, Fraction s)
 {
     for (int i = 0; i < m.columns; i++)
     {
         m.data[r, i] = FractionOperators.Multiply(m.data[r, i], s);
     }
 }
Exemplo n.º 3
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.º 4
0
        public static Fraction Length(List <TokenType> parameters)
        {
            Vector v = parameters[0] as Vector;

            Vector.CheckNumberic(v);

            if (v is Vec2 vec2)
            {
                return(Fraction.Sqrt(FractionOperators.Add(FractionOperators.Multiply(vec2.X, vec2.X), FractionOperators.Multiply(vec2.Y, vec2.Y))));
            }
            if (v is Vec3 vec3)
            {
                return(Fraction.Sqrt(FractionOperators.Add(FractionOperators.Add(FractionOperators.Multiply(vec3.X, vec3.X), FractionOperators.Multiply(vec3.Y, vec3.Y)), FractionOperators.Multiply(vec3.Z, vec3.Z))));
            }
            return(null);
        }
Exemplo n.º 5
0
        public static Fraction Det(List <TokenType> parameters)
        {
            Matrix m = parameters[0] as Matrix;

            Matrix.CheckNumbericMatrix(m);
            Matrix.CheckSquareMatrix(m);
            m = GaussBot(m, true, true);

            Fraction det = 1;

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

            return(det);
        }
Exemplo n.º 6
0
        public static Vector Normalize(List <TokenType> parameters)
        {
            Vector v = parameters[0] as Vector;

            Vector.CheckNumberic(v);

            Fraction len = Length(parameters);

            if (v is Vec2 vec2)
            {
                return(new Vec2(FractionOperators.Divide(vec2.X, len), FractionOperators.Divide(vec2.Y, len)));
            }
            if (v is Vec3 vec3)
            {
                return(new Vec3(FractionOperators.Divide(vec3.X, len), FractionOperators.Divide(vec3.Y, len), FractionOperators.Divide(vec3.Z, len)));
            }
            return(null);
        }
Exemplo n.º 7
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.º 8
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);
        }