Различие скалярных и векторных конструкций

Поскольку forall не цикл, а перечисление параллельных процессов, то напрашивающаяся аналогия с циклом ограниченна.

В ряде случаев операторы do и forall одинаковы по действию. Тривиальный пример:

Integer, dimension(1:4) :: A

A=0 ! параллельные действия

forall (i=1:4) ! параллельные действия

A(i)=0

End forall

doi=1,4 ! последовательные действия

A(i)=0

End do

Простой пример, из книги Немнюгина, иллюстрирующий разницу между do и forall

1. Используется оператор Do

integer,dimension(1:4):: A=(/ 1,2,3,4 /)

Do i=2,3 ! последовательные действия

A(i) = A(i-1) + A(i) + A(i+1)

Enddo

Получим

A(2) = A( 1) + A(2) + A(3)=1+2+3=6

A(3) = A( 2) + A(3) + A(4)=6+3+4=13 ! A( 2)=6 - изменившееся значение

2. Оператор forall, перечисляющий параллельные процессы над исходными значениями массива, – те же по виду действия дают другой ответ

forall (i=2:3 ) ! параллельные действия

A(i)=A(i-1)+A(i)+A(i+1) !подставляется значение A( 2)=2

! то же по-другому A(i)=sum(A(i-1:i+1)) - проясняет суть дела

End forall

Получим

A(2) = A( 1) + A2) + A(3)=1+2+3=6

A(3) = A( 2) + A(3) + A(4)=2+3+4=9 ! A( 2)=2 исходное значение

A(2:3) = (/ sum(A(1:3)) , sum(A(2:4)) - всё разъясняет: берем старые значения, а заносим новые значения A

и ни к чему здесь forall -это чисто академический стиль

Нетрудно заметить внешнее сходство Do - цикл и forall -как бы цикл по параллельным процессам. Не проходит аналогия forall с циклом foreach из языка PHP.

Есть кардинальное отличиецикла и перечисления параллельных процессовforall:

- doзадает последовательность действий, которые выполняются над скалярами либо целиком векторами;

- forall задает параллельные действия, которые выполняются над компонентами векторов, матриц, многомерных массивов, секциями с непременным требованием конформности условия и действий;

- doработает с текущими значениями массивов, а forall как бы работает с двойной памятью - использует стартовые значения массивов, а формирует новые значения.

 

Парафлоид – один оператор вместо двадцати

В этом разделе показан более сложный пример вычисления парафлоида -квадратной матрицы минимальных расстояний между вершинами ориентированного графа с взвешенными дугами. Граф задан квадратной матрицей инцидентности. Строки и столбцы матрицы соответствуют вершинам графа. Инцидентные дуги соответствуют положительным компонентам матрицы. Схематично показано вычисление меры близости вершин графа по методу Флойда.

Таблица 29.

Пример вычисления парафлоида в операторе forall

A J  
i parafloid(i,j) = minval( A(i,:)+A(:,j) ) A(i,:)- строка i
  A(:,j)- столбец j  

С целью упрощения на схеме не показаны условия положительной определенности, дополнительно прописанные в оператореforall.

 

Парафлоид - единственный выполняемый оператор
program parafloida

Implicit none

integer,parameter:: N=10

! A - взвешенная входная матрица инцидентности

integer,dimension(1:n,1:n) :: A=1, parafloid

! парафлоид parafloid - выходная матрица мин. расстояний

integer i,j

forall( i=1:n, j=1:n, i/=j ) &

parafloid(i,j) = minval( A(i,:)+A(:,j), &

mask = A(i,:)>0 .and. A(:,j)>0 )

write(6,1) (parafloid(i,:),i=1,n)

1 format(1x,<n>i3)

end program parafloida

Попробуйте написать программу paraseqva с помощью традиционных конструкций – и Вы увидите, что она будет на порядок сложнее: вместо одного оператора - программа из 20 операторов.


 

program paraseqva ! взвешенная входная матрица инцидентности

Implicit none

integer,parameter:: N=10

integer,dimension(1:n,1:n) :: A=1, parafloid

! парафлоид - выходная матрица мин. расстояний

integer i,j

integer,dimension(1:n) :: str,stlb, summa

integer parafloidMin,i1

open(6,file='parafloid.txt')

do i=1,N

A(i,i)=0

Enddo

do i=1,N

do j=1,N

if(i/=j) then

parafloidMin = huge(0) ! #7fffffff

do i1=1,N

str=A(i,i1); stlb=A(i1,j); summa(i1)=str(i1)+stlb(i1)

Enddo

do i1=1,N

if(str(i1)==0 .or. stlb(i1)==0) cycle

if(summa(i1)<parafloidMin) parafloidMin = summa(i1)

Enddo

parafloid(i,j) = parafloidMin

Else

parafloid(i,j) = 0

Endif

Enddo

Enddo

write(6,1) (parafloid(i,:),i=1,N)

1 format(1x,<N>i3)

end program paraseqva

Пример парафлоида – многогранный:

- A(i,:)- i-ая строка и A(:,j)- j-ый столбец заданы секциями двумерного массива, образующими векторы;

- конформные векторы A(i,:)иA(:,j)- суммируются A(i,:)+A(:,j), образуя новый вектор положительно определенных крестообразных сумм;

- из сумм выбирается минимум при помощи итоговой функции minVal, формируя элемент парафлоида;

- forall задаёт перебор в пространстве секции, совпадающей с положительно определёнными недиагональными элементами матрицы;

- данныйforall имеет объём вычислений, пропорциональный O (N3).








Дата добавления: 2016-02-13; просмотров: 1013;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.013 сек.