Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Решение СЛАУ в виде сжатой матрицы 
:(
    Опции темы
alexgorbach
Дата 13.5.2013, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 28.11.2012

Репутация: нет
Всего: нет



Добрый день. Помогите написать алгоритм для задачи.
Есть матрица жесткости, большая, симметричная, ленточная, вот такого вида:
user posted image
Красная и синяя область симметричны между собой, серые области - нулевые.
Так как большинство элементов матрицы нулевые, храню матрицу в сжатом виде, сдвинув каждую строку до упора влево, причем в силу симметрии храню только верхнюю половину значащих элементов (красную область). Примерно так:
user posted image
Так вот. Решаю систему методом Гаусса. Приписываю к этой матрице столбец свободных членов и передаю эту матрицу на обработку в мой метод, который должен бы решить систему и на место столбца свободных членов записать вектор в ответом, но! Работает неправильно. Я понимаю, почему, но не могу додуматься, как исправить.
Код метода на C#:
Код
public static bool Solve(double[,] M)
        {
            #region{Прямой ход}
            int rowCount = h;

            for (int i = 0; i + 1 < rowCount; i++)
            {
                for (int j = i + 1; j < Math.Min(i + tapeWidth, rowCount); j++)
                {
                    double x = M[i, j - i] / M[i, 0];
                    for (int p = 0; p < w - j + i - 1; p++)
                    {
                        M[j, p] -= M[i, j - i + p] * x;
                    }
                    M[j, w - 1] -= M[i, w - 1] * x;
                }
            }
            #endregion

            #region{Обратный ход}
            int k = 0; //индекс последнего значащего элемента в строке
            for (int row = rowCount - 1; row >= 0; row--)
            {
                for (int i = 1; i <= k; i++)
                {
                    M[row, w - 1] -= M[row, i] * M[row + i, w - 1];
                }
                M[row, w - 1] /= M[row, 0]; 
                if(k < w - 1)
                    k++;
            }
            return true;
            #endregion
        }

tapeWidth - ширина ленты, то бишь, ширина матрицы (не расширенной),
w, h - ширина и высота расширенной матрицы.

Проблема, как я понимаю, в прямом ходе: 
Код
double x = M[i, j - i] / M[i, 0];

Здесь я вычисляю коэффициент, на который нужно умножить строку, чтобы при вычитании получить ноль в одной из последующих строк. Так как я храню только половину матрицы, то в числителе дроби выбираю не элемент, стоящий под главной диагональю, а симметричный ему над главной диагональю (я храню только верхнюю половину ленты).
Проблема в том, что после первого прохода (когда ведущая строка имеет номер 0), разные строки меняются по-разному (от них отнимается первая строка, умноженная на разные коэффициенты), и при последующих проходах элемент, симметричный нужному для вычисления коэффициента x, уже не будет равен тому, который подразумевается (который как бы под диагональю), и матрица преобразуется неправильно. Сложно объяснил, но надеюсь, кто-нибудь поймет.
Спасибо откликнувшимся.


PM MAIL   Вверх
Pavia
Дата 13.5.2013, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 6.12.2008

Репутация: 11
Всего: 12



Надо смотреть в сторону ленточных алгоритмов. Я только в полных матрицах специализируюсь.
Думаю Гаус  не подойдёт нужно применять ортогональные преобразования как в методе Якоби.
Гаусс симметрию нарушает в отличие от ортогонального преобразования в методе Якоби.

Это сообщение отредактировал(а) Pavia - 13.5.2013, 22:40
PM MAIL   Вверх
alexgorbach
Дата 13.5.2013, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 28.11.2012

Репутация: нет
Всего: нет



Pavia, хм, тогда, быть может, стоит избрать другой способ хранения данных матрицы? Ибо мне советовали применять именно метод Гаусса, потому как система хорошо обусловлена и на главной диагонали стоят максимальные элементы, причем ненулевые. Гаусс отлично подходит для матрицы такого вида, только вот подходит ли он для выбранного способа хранения...
PM MAIL   Вверх
Фантом
Дата 13.5.2013, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 2
Всего: 49



А чем не годится прогонка?
PM   Вверх
alexgorbach
Дата 13.5.2013, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 28.11.2012

Репутация: нет
Всего: нет



Фантом, прогонка чего? Не совсем понял...
PM MAIL   Вверх
Pavia
Дата 14.5.2013, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 6.12.2008

Репутация: 11
Всего: 12



Есть такой алгоритм прогонки.
http://ru.wikipedia.org/wiki/Метод_прогонки
По сути тот же метод Гауса применённый к трёхдиагональной матрице.
К ленточной матрицы можно применить преобразование отражения(разновидность ортогонального) и свести её к трёх диагональной.

A*x=y
Разумеется при сведение матрицы к трёх диагональной операция умножения применяют над вектором "y".

Это сообщение отредактировал(а) Pavia - 14.5.2013, 08:04
PM MAIL   Вверх
Mirkes
Дата 14.5.2013, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 4
Всего: 17



Действительно, у вас на выбор два подхода:
1. Развернуть матрицу и использовать любые методы (Гаусса и тп)
2. Использовать методы сохраняющие симметрию (ортогональные разложения, прогонка и т.п.)
Решите что для Вас лучше и дейстщуйте.


--------------------
Mirkes
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0877 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.