| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Fortran > [Pro] Этюды. Сюжет 2. Симметричные матрицы: |
| Автор: Cr@$h 24.9.2006, 00:55 | ||||||||||||||||
| Как известно, массивов массивов в Fortran нет. Например, в С++ и Java есть массивы указателей на массивы, но нет истинно многомерных массивов. Зато это позволяет создавать в них рваные массивы (jagged arrays), содержащие разное число элементов в каждой строке. Рваные массивы могут оказаться полезными при формировании симметричных матриц. Для того, чтобы в Fortran организовать рваные массивы, нужно создать производный тип-строку, содержащий всего один компонент -- размещаемый массив, а после объявить массив таких производных-типов-строк. Это будет массив строк, каждая из которых может размещаться со своей длиной, а значит, этот "двумерный массив" будет рваным. При выводе симметричных матриц воспользуемся расширением над стандартом языка: в дескрипторах преобразования везде вместо буквальных констант можно использовать целочисленные выражения заключённые в угловые скобки.
Здесь n и m -- целочисленные выражения. Это расширение в ряде случаев позволяет не прибегать к программированию спецификации формата. Рассматриваемое расширение, хоть и является расширением над стандартом F03 (на сколько я знаю), позволяет часто подобным образом сократить код по выводу чисел. Использовать его следует на своё усмотрение (например, не использовать для переносимости кода). Мы же воспользуемся им при выводе симметричных матриц на экран, чтобы получить элегантный код. Рассмотрим пример реализации, заполнения и вывода симметричной матрицы согласно изложенному подходу.
Вот, что будет на экране:
Прошу обратить внимание и изучить строку
Здесь переменная неявного цикла присутствует и в дескрипторе формата, т.е. для каждой строки вывода дескриптор формата будет свой -- он будет содержать разное число выводимых значений, i. Если немного доработать оператор вывода
то он будет выводить целиком симметричную матрицу:
Тут полезно сделать одно замечание. Чтобы выводить матрицу полностью, мы добавили в неявном цикле ещё один, вложенный цикл. При этом его границы и выводимые значения зависят от переменной i внешнего по отношению к нему неявного цикла: вложенный цикл добавляет для вывода i-ые элементы N - i + 1 последних строк. Первое, что хочется сделать после этого, это избавиться от вложенного цикла, добавив его выводимые значения к внешнему циклу, выражая j через i и используя сечения массива. Попробуем так преобразовать оператор полного вывода симметричной матрицы:
в оператор без вложенного неявного цикла:
Кажется, так просто, но компилятор тут же заругается: компонент справа от массива не может быть ссылкой или быть размещаемым. Думаю, это связано с тем, что не известно заранее, ссылается ли на что-то или размещен ли этот компонент. Полагаю, ни один язык в мире не способен одним оператором вывести симметричную матрицу на экран, даже.. Fortran 2003. Нам же удалось это сделать. Здесь мы рвали строки матрицы -- они имели каждая свою длину: от 1 до 24. Мы делали так. потому что так привычнее -- первый индекс отвечает за номер строки, второй -- за номр столбца. Искушённый Fortran-программист подозревает, что большая часть операций с матрицами, например, сингулярное разложение (SVD), а не какое-нибудь там исключение методом Гаусса, работает со столбцами матрицы. По этой причине можно использовать сфомированный тип не как массив строк разной длины, а как массив столбцов разной длины (достаточно заменить имя типа Row на Column). Так, в операциях над столбцами будут участвовать элементы столбцов, лежащие в памяти в одном массиве-столбце, а значит будет возможно поддержать векторизацию, задавая в операциях целиком массив-столбец. Так или иначе, что делать рваными, строки или столбцы матрицы, определяется задачей, а точнее, методом её решения. Так что feel free. Интересно посмотреть, есть ли другие удобные реализации симметричных матриц, да и обсудить, в общем. |
| Автор: Spike 26.9.2006, 12:44 |
| Насколько я помню, в памяти фортран массивы размещает именно по столбцам |
| Автор: Cr@$h 3.10.2006, 04:47 | ||
|