Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Алгоритмы > Решение СЛАУ в виде сжатой матрицы |
Автор: alexgorbach 13.5.2013, 22:01 | ||||
Добрый день. Помогите написать алгоритм для задачи. Есть матрица жесткости, большая, симметричная, ленточная, вот такого вида: http://firepic.org/ Красная и синяя область симметричны между собой, серые области - нулевые. Так как большинство элементов матрицы нулевые, храню матрицу в сжатом виде, сдвинув каждую строку до упора влево, причем в силу симметрии храню только верхнюю половину значащих элементов (красную область). Примерно так: http://firepic.org/ Так вот. Решаю систему методом Гаусса. Приписываю к этой матрице столбец свободных членов и передаю эту матрицу на обработку в мой метод, который должен бы решить систему и на место столбца свободных членов записать вектор в ответом, но! Работает неправильно. Я понимаю, почему, но не могу додуматься, как исправить. Код метода на C#:
tapeWidth - ширина ленты, то бишь, ширина матрицы (не расширенной), w, h - ширина и высота расширенной матрицы. Проблема, как я понимаю, в прямом ходе:
Здесь я вычисляю коэффициент, на который нужно умножить строку, чтобы при вычитании получить ноль в одной из последующих строк. Так как я храню только половину матрицы, то в числителе дроби выбираю не элемент, стоящий под главной диагональю, а симметричный ему над главной диагональю (я храню только верхнюю половину ленты). Проблема в том, что после первого прохода (когда ведущая строка имеет номер 0), разные строки меняются по-разному (от них отнимается первая строка, умноженная на разные коэффициенты), и при последующих проходах элемент, симметричный нужному для вычисления коэффициента x, уже не будет равен тому, который подразумевается (который как бы под диагональю), и матрица преобразуется неправильно. Сложно объяснил, но надеюсь, кто-нибудь поймет. Спасибо откликнувшимся. |
Автор: Pavia 13.5.2013, 22:34 |
Надо смотреть в сторону ленточных алгоритмов. Я только в полных матрицах специализируюсь. Думаю Гаус не подойдёт нужно применять ортогональные преобразования как в методе Якоби. Гаусс симметрию нарушает в отличие от ортогонального преобразования в методе Якоби. |
Автор: alexgorbach 13.5.2013, 22:46 |
Pavia, хм, тогда, быть может, стоит избрать другой способ хранения данных матрицы? Ибо мне советовали применять именно метод Гаусса, потому как система хорошо обусловлена и на главной диагонали стоят максимальные элементы, причем ненулевые. Гаусс отлично подходит для матрицы такого вида, только вот подходит ли он для выбранного способа хранения... |
Автор: Фантом 13.5.2013, 23:11 |
А чем не годится прогонка? |
Автор: alexgorbach 13.5.2013, 23:18 |
Фантом, прогонка чего? Не совсем понял... |
Автор: Pavia 14.5.2013, 08:02 |
Есть такой алгоритм прогонки. http://ru.wikipedia.org/wiki/Метод_прогонки По сути тот же метод Гауса применённый к трёхдиагональной матрице. К ленточной матрицы можно применить преобразование отражения(разновидность ортогонального) и свести её к трёх диагональной. A*x=y Разумеется при сведение матрицы к трёх диагональной операция умножения применяют над вектором "y". |
Автор: Mirkes 14.5.2013, 10:31 |
Действительно, у вас на выбор два подхода: 1. Развернуть матрицу и использовать любые методы (Гаусса и тп) 2. Использовать методы сохраняющие симметрию (ортогональные разложения, прогонка и т.п.) Решите что для Вас лучше и дейстщуйте. |