Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.05.2015, 00:55   #1
vorobvorob
Новичок
Джуниор
 
Регистрация: 15.05.2015
Сообщений: 2
Вопрос Друзья, помогите, пожалуйста, найти ошибку в коде C#

Ищу обратную матрицу методом Гаусса, тестирую на матрице [3,3]. Проблемы возникают уже после прямого хода: не верно считается последняя строка обратной матрицы, хотя исходная становится треугольной и все у нее как надо. Перепроверила миллион раз, не понимаю, в чем проблема

Код:
 double[,] A = new double[3, 3];
            A[0, 0] = 5; A[0, 1] = 2; A[0, 2] = 3;
            A[1, 0] = 4; A[1, 1] = 5; A[1, 2] = 6;
            A[2, 0] = 7; A[2, 1] = 8; A[2, 2] = 9;

            //обратная матрица СмОбратная
            double[,] AObrat = new double[3, 3];
            double[,] ACopy = new double[3, 3];


            //задаем обратную матрицу как единичную           
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (i == j) { AObrat[i, j] = 1; }
                    else { AObrat[i, j] = 0; }
                    ACopy[i, j] = A[i, j];    //создаем копию матрицы См
                    Console.WriteLine("ACopy[i, j] =" + ACopy[i, j]);
                }
            }
            Console.Read();

            //прямой ход
            for (int k = 0; k < 3; ++k)
            {
                double div = ACopy[k, k];
                for (int m = 0; m < 3; ++m)
                {// делим строку на выбранный элемент === 1  ф  ф
                    ACopy[k, m] /= div;
                    AObrat[k, m] /= div;
                }
                for (int i = k + 1; i < 3; ++i) //идем по столбц ниже полученой единицы
                {
                    double multi = ACopy[i, k]; //элемент, который хотим занулить
                    for (int j = 0; j < 3; ++j)// элемент по счету в строке i
                    {
                        ACopy[i, j] -=  multi * ACopy[k, j];
                        AObrat[i, j] -= multi * AObrat[k, j];
                    }
                }

            }
            Console.WriteLine("после прямого хода");         
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                     Console.WriteLine("ACopy[i, j] =" + ACopy[i, j]);
                    //Console.WriteLine("AObrat[i, j] =" + AObrat[i, j]);
                   
                }
            } Console.ReadLine();


            //обратный ход            
            for (int kk = 3 - 1; kk > 0; kk--)
            {
                ACopy[kk, 3 - 1] /= ACopy[kk, kk];
                AObrat[kk, 3 - 1] /= ACopy[kk, kk];

                for (int i = kk - 1; i + 1 > 0; i--)
                {
                    double multi2 = ACopy[i, kk];
                    for (int j = 3 - 1; j > 0; j--)
                    {
                        ACopy[i, j] -= multi2 * ACopy[kk, j];
                        AObrat[i, j] -= multi2 * AObrat[kk, j];
                    }
                }
            }

            Console.WriteLine("проверка матрицы Copy");
            double[,] Ee = new double[3, 3];
            int flagA = 0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    //Console.WriteLine("ACopy[i, j] =" + ACopy[i, j]);
                    Console.WriteLine("AObrat[i, j] =" + AObrat[i, j]);
                    if (i == j) { Ee[i, j] = 1; }
                    else { Ee[i, j] = 0; }
                    if (Ee[i, j] != ACopy[i, j]) { Console.WriteLine("i=" + i); Console.WriteLine("j=" + j); }
                    else { flagA = 1; }
                }
            }
            if (flagA == 1) { Console.WriteLine("матрица стала единичной"); }
            Console.ReadLine();


            System.Console.ReadLine();

            //проверка СмОбратной
            //CmObrat*Cm
            double[,] ProverkaA = new double[3, 3];
            for (int i = 0; i < 3; i++)//строки
            {
                for (int j = 0; j < 3; j++)//столбцы
                {
                    for (int k = 0; k < 3; k++)
                    {
                        ProverkaA[i, j] += AObrat[i, k] * A[k, j];
                    }
                }
            }

            Console.WriteLine("проверка матрицы Proverka");
            int flag11 = 0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (Math.Abs(Ee[i, j] - ProverkaA[i, j]) > 0.002) { Console.WriteLine("i=" + i, "j=" + j); }
                    else { flag11 = 1; }
                }
            }
            if (flag11 == 1) { Console.WriteLine("матрица стала единичной"); }
            Console.ReadLine();
vorobvorob вне форума Ответить с цитированием
Старый 15.05.2015, 20:02   #2
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

Код:
            //обратный ход            
            for (int kk = 3 - 1; kk > 0; kk--)
            {
                //ACopy[kk, 3 - 1] /= ACopy[kk, kk];
                //AObrat[kk, 3 - 1] /= ACopy[kk, kk];

                for (int i = kk - 1; i + 1 > 0; i--)
                {
                    double multi2 = ACopy[i, kk];
                    for (int j = 0; j < 3; j++)
                    {
                        ACopy[i, j] -= multi2 * ACopy[kk, j];
                        AObrat[i, j] -= multi2 * AObrat[kk, j];
                    }
                }
            }
И вот вам ещё метод печати матрицы, а то ваши индексы - просто жесть. Вызывать как
Код:
print(AObrat);
Код:
        static void print(double[,] m)
        {
            Console.WriteLine();
            for (var i = 0; i < m.GetLength(0); ++i)
            {
                for (var j = 0; j < m.GetLength(1); ++j)
                {
                    Console.Write("{0:0.00}\t", m[i,j]);
                }
                Console.WriteLine();
            }
        }
Изобретатель велосипедов
Selestis вне форума Ответить с цитированием
Старый 16.05.2015, 16:38   #3
vorobvorob
Новичок
Джуниор
 
Регистрация: 15.05.2015
Сообщений: 2
По умолчанию

Огромное Вам спасибо! теперь все работает)
vorobvorob вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Пожалуйста помогите найти ошибку в коде решения задачи на записи GUnt Паскаль, Turbo Pascal, PascalABC.NET 3 27.12.2008 21:09
Помогите найти ошибку в коде! alex2008ean Паскаль, Turbo Pascal, PascalABC.NET 1 27.12.2008 18:31
Помогите найти ошибку в коде, пожалуйста Gobl1n Паскаль, Turbo Pascal, PascalABC.NET 3 30.11.2008 17:44
Помогите найти ошибку в коде C++ Жека:) Помощь студентам 15 29.10.2008 11:32