コード例 #1
0
ファイル: CSqMatrix.cs プロジェクト: PasaOpasen/MathClasses
        /// <summary>
        /// Замена колонны указанным вектором (для метода Крамера)
        /// </summary>
        /// <param name="ColumnNumber">Номер колонны</param>
        /// <param name="newColumn">Новая колонна</param>
        /// <returns></returns>
        public CSqMatrix ColumnSwap(int ColumnNumber, CVectors newColumn)
        {
            SqMatrix R = this.Re.ColumnSwap(ColumnNumber, newColumn.Re);
            SqMatrix I = this.Im.ColumnSwap(ColumnNumber, newColumn.Im);

            return(new CSqMatrix(R, I));
        }
コード例 #2
0
        /// <summary>
        /// Характеристический многочлен заданной матрицы
        /// </summary>
        /// <param name="M"></param>
        /// <returns></returns>
        public static Polynom CharactPol(SqMatrix M)
        {
            Polynom p = new Polynom(M.n);

            double   sum;
            SqMatrix A = new SqMatrix(M);

            //заполнение массива треков
            double[] tr = new double[A.n];
            for (int i = 0; i < A.n; i++)
            {
                tr[i] = A.Track;
                A    *= M;
            }

            p.coef[(int)p.degree] = 1 * Math.Pow(-1, A.n);
            int k = 0;

            for (int i = (int)p.degree - 1; i >= 0; i--)
            {
                sum = 0; k++;
                for (int j = 0; j < k; j++)
                {
                    sum += tr[k - j - 1] * p.coef[(int)p.degree - j];
                }
                sum      *= -1;
                sum      /= k;
                p.coef[i] = sum;
            }

            return(p);
        }
コード例 #3
0
        //public override bool Nulle()//нулевая ли матрица?
        //{
        //    for (int i = 0; i < n; i++)
        //    {
        //        for (int j = 0; j < n; j++)
        //        {
        //            if (matrix[i, j] != 0) return false;
        //        }
        //    }

        //    return true;
        //}

        /// <summary>
        /// Единичная матрица
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static SqMatrix E(int n)
        {
            SqMatrix M = new SqMatrix(n);

            for (int i = 0; i < n; i++)
            {
                M[i, i] = 1;
            }
            return(M);
        }
コード例 #4
0
        /// <summary>
        /// Единичная матрица
        /// </summary>
        public static SqMatrix I(int n)
        {
            SqMatrix A = new SqMatrix(n);

            for (int i = 0; i < n; i++)
            {
                A[i, i] = 1;
            }
            return(A);
        }
コード例 #5
0
 /// <summary>
 /// Создать матрицу как угловую подматрицу размерности k
 /// </summary>
 /// <param name="A"></param>
 /// <param name="k"></param>
 public SqMatrix(SqMatrix A, int k) : base(k, k)
 {
     for (int i = 0; i < this.n; i++)
     {
         for (int j = 0; j < this.n; j++)
         {
             this[i, j] = A[i, j];
         }
     }
 }
コード例 #6
0
 /// <summary>
 /// Подобная матрица, если задана ортогональная матрица преобразования
 /// </summary>
 /// <param name="M"></param>
 /// <returns></returns>
 public SqMatrix ConvertToSimilar(SqMatrix M, bool directly = true)
 {
     if (directly)
     {
         return((SqMatrix)(M.Transpose() * this * M));
     }
     else
     {
         return((SqMatrix)(M * this * M.Transpose()));
     }
 }
コード例 #7
0
 /// <summary>
 /// Конструктор копирования
 /// </summary>
 /// <param name="M"></param>
 public SqMatrix(SqMatrix M)
 {
     this.n      = this.m = M.n;
     this.matrix = new double[n, n];
     for (int i = 0; i < n; i++)
     {
         for (int j = 0; j < n; j++)
         {
             this[i, j] = M[i, j];
         }
     }
 }
コード例 #8
0
        //операторы
        //сложение
        public static SqMatrix operator +(SqMatrix A, SqMatrix B)
        {
            SqMatrix C = new SqMatrix(A.n);

            for (int i = 0; i < A.n; i++)
            {
                for (int j = 0; j < A.n; j++)
                {
                    C[i, j] = A[i, j] + B[i, j];
                }
            }
            return(C);
        }
コード例 #9
0
        //Умножение на число
        public static SqMatrix operator *(SqMatrix A, double Ch)
        {
            SqMatrix q = new SqMatrix(A.n);

            for (int i = 0; i < A.n; i++)
            {
                for (int j = 0; j < A.n; j++)
                {
                    q[i, j] = A[i, j] * Ch;
                }
            }
            return(q);
        }
コード例 #10
0
        //вычитание
        public static SqMatrix operator -(SqMatrix A, SqMatrix B)
        {
            SqMatrix R = new SqMatrix(A.n);

            for (int i = 0; i < A.n; i++)
            {
                for (int j = 0; j < A.n; j++)
                {
                    R[i, j] = A[i, j] - B[i, j];
                }
            }
            return(R);
        }
コード例 #11
0
        /// <summary>
        /// Подматрица размерности len
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        public SqMatrix SubMatrix(int len)
        {
            SqMatrix r = new SqMatrix(len);

            for (int i = 0; i < len; i++)
            {
                for (int j = 0; j < len; j++)
                {
                    r[i, j] = this[i, j];
                }
            }
            return(r);
        }
コード例 #12
0
        /// <summary>
        /// Квадратная подматрица, порождённая пересечением таких строк и столбцов
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <remarks>Нумерация строк должна начинаться с единицы</remarks>
        public SqMatrix SubMatrix(params int[] m)
        {
            SqMatrix M = new SqMatrix(m.Length);

            for (int i = 0; i < m.Length; i++)
            {
                for (int j = 0; j < m.Length; j++)
                {
                    M[i, j] = this[m[i] - 1, m[j] - 1];
                }
            }
            return(M);
        }
コード例 #13
0
ファイル: CSqMatrix.cs プロジェクト: PasaOpasen/MathClasses
        private static Complex[,] mas(SqMatrix A, SqMatrix B)
        {
            var res = new Complex[A.RowCount, A.ColCount];

            for (int i = 0; i < A.RowCount; i++)
            {
                for (int j = 0; j < A.ColCount; j++)
                {
                    res[i, j] = A[i, j] + Complex.I * B[i, j];
                }
            }
            return(res);
        }
コード例 #14
0
        /// <summary>
        /// Перевод матрицы в одномерный массив
        /// </summary>
        /// <param name="M"></param>
        /// <returns></returns>
        public static double[] ToDoubleMas(SqMatrix M)
        {
            double[] res = new double[M.m * M.m];
            int      y   = 0;

            for (int i = 0; i < M.n; i++)
            {
                for (int j = 0; j < M.m; j++)
                {
                    res[y++] = M[i, j];
                }
            }
            return(res);
        }
コード例 #15
0
        /// <summary>
        /// Является ли матрица положительно определённой
        /// </summary>
        /// <returns></returns>
        public bool IsPositCertain()
        {
            //if (!this.IsSymmetric()) return false;

            for (int i = 0; i < this.n; i++)
            {
                SqMatrix M = new SqMatrix(this, i + 1);
                double   s = M.Det;
                if (s <= 0)
                {
                    return(false);
                }
            }
            return(true);
        }
コード例 #16
0
        /// <summary>
        /// Замена столбца матрицы на указанный вектор (для метода Крамера)
        /// </summary>
        /// <param name="ColumnNumber">Номер стоблца, начиная с 1</param>
        /// <param name="NewColumn">Сам вектор (если вектор)</param>
        /// <remarks>Если вектор короткий, заменится лишь часть колонны, а если длинный, будет исключение</remarks>
        /// <returns></returns>
        public SqMatrix ColumnSwap(int ColumnNumber, Vectors NewColumn)
        {
            SqMatrix mat = new SqMatrix(this);

            if (ColumnNumber > mat.ColCount || ColumnNumber <= 0 || NewColumn.Deg > mat.RowCount)
            {
                throw new Exception("В матрице нет столбца с таким номером либо вектор слишком длинный");
            }
            ColumnNumber--;
            for (int i = 0; i < NewColumn.Deg; i++)
            {
                mat[i, ColumnNumber] = NewColumn[i];
            }
            return(mat);
        }
コード例 #17
0
ファイル: CSqMatrix.cs プロジェクト: PasaOpasen/MathClasses
        /// <summary>
        /// Обратная матрица по Гауссу
        /// </summary>
        /// <returns></returns>
        public CSqMatrix Invert(bool correct = false)
        {
            CSqMatrix mResult = SqMatrix.E(this.ColCount);
            CSqMatrix mCur = new CSqMatrix(this);
            CVectors  rTmp, eTmp;

            for (int i = 0; i < this.ColCount; i++) //Цикл по строкам сверху-вниз
            {
                int max = MaxLine(i, i);
                if (max != i)
                {
                    rTmp = mCur.GetLine(max);
                    eTmp = mResult.GetLine(max);
                    mCur.MinusVector(i, rTmp * (-1));
                    mResult.MinusVector(i, eTmp * (-1));

                    //Complex y = new Complex(mCur[i, max]);
                    //mCur.DivByLine(i, y);
                    //mResult.DivByLine(i, y);
                }

                //Заединичить вервую строку
                Complex dItem = new Complex(mCur[i, i]);
                mCur.DivByLine(i, dItem);
                mResult.DivByLine(i, dItem);

                rTmp = mCur.GetLine(i);
                eTmp = mResult.GetLine(i);
                //Забить нулями вертикаль
                for (int j = 0; j < this.ColCount; j++)
                {
                    if (i != j)
                    {
                        Complex con = new Complex(mCur[j, i]);
                        mCur.MinusVector(j, rTmp * con);
                        mResult.MinusVector(j, eTmp * con);
                    }
                }
                //mCur.PrintMatrix(); Console.WriteLine();
                //mResult.PrintMatrix(); Console.WriteLine();
            }

            if (!correct)
            {
                return(mResult);
            }
            return(ReverseCorrect(this, mResult, 1e-16, 100));
        }
コード例 #18
0
        /// <summary>
        /// Полином от матрицы
        /// </summary>
        /// <param name="A"></param>
        /// <returns></returns>
        public SqMatrix Value(SqMatrix A)
        {
            SqMatrix I   = SqMatrix.I(A.n);
            SqMatrix sum = this.coef[(int)this.degree] * I;

            if (this.degree > 0)
            {
                for (int i = (int)(this.degree - 1); i >= 0; i--)
                {
                    sum *= A;
                    sum += this.coef[i] * I;
                }
            }

            return(sum);
        }
コード例 #19
0
        //произведение
        public static SqMatrix operator *(SqMatrix A, SqMatrix B)
        {
            SqMatrix r = new SqMatrix(A.n);

            for (int i = 0; i < A.n; i++)
            {
                for (int j = 0; j < A.n; j++)
                {
                    for (int k = 0; k < B.n; k++)
                    {
                        r[i, j] += A[i, k] * B[k, j];
                    }
                }
            }
            return(r);
        }
コード例 #20
0
        /// <summary>
        /// Уточнение обратной матрицы
        /// </summary>
        /// <param name="A">Исходная матрица</param>
        /// <param name="Reverse">Обратная марица</param>
        /// <param name="eps">Точность</param>
        /// <returns></returns>
        public static SqMatrix ReverseCorrect(SqMatrix A, SqMatrix Reverse, double eps = 0.001, int stepcount = 1000, bool existnorm = false)
        {
            SqMatrix E = SqMatrix.E(A.RowCount), R = new SqMatrix(Reverse);
            int      i = 0;

            if ((E - A * R).CubeNorm < 1 || existnorm)
            {
                while ((E - A * R).CubeNorm > eps && i < stepcount)
                {
                    R *= (2 * E - A * R);
                    //(E - A * R).CubeNorm.Show();
                    i++;
                }
            }
            return(R);
        }
コード例 #21
0
 static ODU()
 {
     E1        = new SqMatrix(2);
     E1[1, 1]  = 1;
     E2        = new SqMatrix(3);
     E2[1, 0]  = 0.5; E2[1, 1] = 0.5; E2[2, 2] = 1;
     H         = new SqMatrix(4);
     H[1, 0]   = 1.0 / 3; H[1, 1] = 1.0 / 3; H[2, 0] = 2.0 / 3; H[2, 2] = 2.0 / 3; H[3, 1] = 1.0 / 4; H[3, 3] = 3.0 / 4;
     RK3       = new SqMatrix(4);
     RK3[1, 0] = 0.5; RK3[1, 1] = 0.5; RK3[2, 0] = 1; RK3[2, 2] = 1; RK3[3, 1] = 1.0 / 6; RK3[3, 2] = 4.0 / 6; RK3[3, 3] = 1.0 / 6;
     Rk4       = new SqMatrix(5);
     Rk4[1, 0] = 0.5; Rk4[1, 1] = 0.5; Rk4[2, 0] = 0.5; Rk4[2, 2] = 0.5; Rk4[3, 0] = 1; Rk4[3, 3] = 1; Rk4[4, 1] = 1.0 / 6; Rk4[4, 2] = 2.0 / 6; Rk4[4, 3] = 2.0 / 6; Rk4[4, 4] = 1.0 / 6;
     P38       = new SqMatrix(5);
     P38[1, 0] = 1.0 / 3; P38[1, 1] = 1.0 / 3; P38[2, 0] = 2.0 / 3; P38[2, 1] = -1.0 / 3; P38[2, 2] = 1; P38[3, 0] = 1; P38[3, 1] = 1; P38[3, 2] = -1; P38[3, 3] = 1; P38[4, 1] = 1.0 / 8; P38[4, 2] = 3.0 / 8; P38[4, 3] = 3.0 / 8; P38[4, 4] = 1.0 / 8;
     F         = new Matrix(5, 4);
     F[1, 0]   = 1; F[1, 1] = 1; F[2, 0] = 0.5; F[2, 1] = 0.25; F[2, 2] = 0.25; F[3, 1] = 0.5; F[3, 2] = 0.5; F[4, 1] = 1.0 / 6; F[4, 2] = 1.0 / 6; F[4, 3] = 4.0 / 6;
     C         = new Matrix(6, 5);
     C[1, 0]   = 0.25; C[1, 1] = 0.25; C[2, 0] = 0.5; C[2, 2] = 0.5; C[3, 0] = 1; C[3, 1] = 1; C[3, 3] = -2; C[3, 4] = 2; C[4, 1] = 1; C[4, 2] = -2; C[4, 3] = 2; C[5, 1] = 1.0 / 6; C[5, 3] = 4.0 / 6; C[5, 4] = 1.0 / 6;
 }
コード例 #22
0
        /// <summary>
        /// Обратная матрица по Гауссу
        /// </summary>
        /// <returns></returns>
        public SqMatrix Invert()
        {
            SqMatrix mResult = SqMatrix.E(this.ColCount);

            /*
             * Получать "1" на элементе главной диагонали, а потом
             * Занулять оставшиеся элементы
             * */
            SqMatrix mCur = new SqMatrix(this);

            //mCur.PrintMatrix(); Console.WriteLine();
            //mResult.PrintMatrix(); Console.WriteLine();

            for (int i = 0; i < this.ColCount; i++) //Цикл по строкам сверху-вниз
            {
                //Заединичить вервую строку
                double dItem = mCur[i, i];
                mCur.DivByLine(i, dItem);
                mResult.DivByLine(i, dItem);

                //mCur.PrintMatrix(); Console.WriteLine();
                //mResult.PrintMatrix(); Console.WriteLine();

                Vectors rTmp = mCur.GetLine(i);
                Vectors eTmp = mResult.GetLine(i);
                //Забить нулями вертикаль
                for (int j = 0; j < this.ColCount; j++)
                {
                    if (i != j)
                    {
                        double con = mCur[j, i];
                        mCur.MinusVector(j, rTmp * con);
                        mResult.MinusVector(j, eTmp * con);
                    }
                }
                //mCur.PrintMatrix(); Console.WriteLine();
                //mResult.PrintMatrix(); Console.WriteLine();
            }

            return(mResult);
        }
コード例 #23
0
ファイル: CSqMatrix.cs プロジェクト: PasaOpasen/MathClasses
        /// <summary>
        /// Уточнение обратной матрицы
        /// </summary>
        /// <param name="A">Исходная матрица</param>
        /// <param name="Reverse">Обратная марица</param>
        /// <param name="eps">Точность</param>
        /// <returns></returns>
        public static CSqMatrix ReverseCorrect(CSqMatrix A, CSqMatrix Reverse, double eps = 0.001, int stepcount = 1000, bool existnorm = false)
        {
            CSqMatrix E = new CSqMatrix(SqMatrix.E(A.RowCount)), E2 = E * 2, R = new CSqMatrix(Reverse), Rold = new CSqMatrix(Reverse);
            int       i = 0;//i.Show();
            double    epsold = (E - A * R).CubeNorm, epsnew = epsold;

            //if (epsold < 1 || existnorm)
            while (epsnew > eps && i < stepcount)
            {
                R *= (E2 - A * R);//epsold.Show();
                //(E - A * R).CubeNorm.Show();
                epsold = epsnew;
                epsnew = (E - A * R).CubeNorm;
                if (epsnew >= epsold) /*$"{epsold} {epsnew}".Show();*/ return {
                    (Rold);
                }
                Rold = new CSqMatrix(R);
                i++;
            }
            return(R);
        }
コード例 #24
0
        /// <summary>
        /// Минор элемента матрицы (точнее, алгебраическое дополнение)
        /// </summary>
        /// <returns></returns>
        public double Minor(int i, int j)
        {
            if ((i >= n) || (j >= n))
            {
                throw new Exception("Вызов элемента, которого нет в матрице");
            }
            if (this.n <= 1)
            {
                throw new Exception("Размерность матрицы слишком мала");
            }
            if (this.n == 2)
            {
                return(Math.Pow(-1, i + j) * this[3 - i - 2, 3 - j - 2]);
            }
            //int Inew = i--,Jnew=j--;
            SqMatrix M = new SqMatrix(this.n - 1);
            int      a = 0, b = 0;

            for (int ii = 0; ii < this.n; ii++)
            {
                if (ii != i)
                {
                    for (int jj = 0; jj < this.n; jj++)
                    {
                        if (jj != j)
                        {
                            M[a, b] = this[ii, jj]; //Console.WriteLine("{0} {1} {2} {3}", a,b,ii,jj);
                            b++;
                        }
                    }
                    a++; b = 0;
                }
            }
            //M.PrintMatrix();
            return(Math.Pow(-1, i + 1 + j + 1) * M.Det);
        }
コード例 #25
0
ファイル: CSqMatrix.cs プロジェクト: PasaOpasen/MathClasses
 /// <summary>
 /// Конструктор по действительной и мнимой части матрицы
 /// </summary>
 /// <param name="R"></param>
 /// <param name="I"></param>
 public CSqMatrix(SqMatrix R, SqMatrix I) : this(mas(R, I))
 {
 }