Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

4. Массивы

4.12.2. Умножение векторов и матриц

DOT_PRODUCT(vector_a, vector_b) - функция возвращает скалярное произведение векторов vector_a и vector_b, равное сумме произведений их элементов с равными значениями индексов.

vector_a - одномерный массив целого, вещественного, комплексного или логического типа.

vector_b - одномерный массив того же размера, что и массив vector_a. Должен быть логического типа, если массив vector_a логического типа. Должен быть числовым (целым, вещественным или комплексным), если массив vector_a числовой. В последнем случае тип vector_b может отличаться от типа vector_a.

Возвращаемое число равно:

SUM(vector_a * vector_b), если vector_a целого или вещественного типа. Результат имеет целый тип, если оба аргумента целого типа; комплексный, если vector_b комплексного типа, и вещественный в противном случае;

SUM(CONJG(vector_a) * vector_b), если vector_a комплексного типа,

то и результат также является комплексным числом;

ANY(vector_a .AND. vector_b),

если

аргументы логического

типа,

то и результат имеет логический тип.

 

 

Если размер векторов равен нулю,

то и результат равен

нулю

или .FALSE. в случае логического типа.

 

 

Пример:

 

 

 

print *, dot_product((/ 1, 2, 3 /), (/ 4, 5, 6 /))

!

32

 

MATMUL(matrix_a, matrix_b) - выполняет по принятым в линейной алгебре правилам умножение матриц целого, вещественного, комплексного и логического типа.

matrix_a - одномерный или двумерный массив целого, вещественного, комплексного или логического типа.

matrix_b – массив логического типа, если matrix_a - логический массив; числовой массив, если matrix_a - числовой массив. В последнем случае тип matrix _b может отличаться от типа matrix_a.

По крайней мере один из массивов matrix_a и matrix_b должен быть двумерным.

Возможны 3 случая:

matrix_a имеет форму (n, m), а matrix_b имеет форму (m, k). Тогда результат имеет форму (n, k), а значение элемента (i, j) равно

SUM(matrix_a(i, :) * matrix_b(:, j));

matrix_a имеет форму (m), а matrix_b имеет форму (m, k). Тогда результат имеет форму (k), а значение элемента (j) равно

SUM(matrix_a * matrix_b(:, j));

145

О. В. Бартеньев. Современный ФОРТРАН

matrix_a имеет форму (n, m), а matrix_b имеет форму (m). Тогда результат имеет форму (n), а значение элемента (i) равно

SUM(matrix_a(i, :) * matrix_b).

Для логических массивов функция ANY эквивалентна функции SUM,

а.AND. эквивалентен произведению (*).

Пример:

integer a(2, 3), b(3, 2), c(2), d(3), e(2, 2), f(3), g(2) a = reshape((/ 1, 2, 3, 4, 5, 6 /), (/ 2, 3 /))

b = reshape((/ 1, 2, 3, 4, 5, 6 /), (/ 3, 2 /))

! Массив a:

1

3

5

!

2

4

6

! Массив b:

1

4

 

!

2

5

 

!

3

6

 

c = (/ 1, 2 /)

 

 

 

 

d = (/ 1, 2, 3 /)

! Результат:

 

 

 

e = matmul(a, b)

22

49

 

 

!

28

64

 

f = matmul(c, a)

! Результат:

5

11

17

g = matmul(a, d)

! Результат:

22

28

 

Из линейной алгебры известно, что произведением вектор-столбца x на вектор-строку yT является матрица

 

x

 

 

 

 

 

 

 

1

 

 

 

 

 

 

A =

x2

 

(y y

2

... y

m

)= xyT Rm×n .

 

 

 

1

 

 

 

...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

xm

 

 

 

 

 

В Фортране ее вернет встроенная функция MATMUL. Правда, для обеспечения ее работоспособности потребуется преобразовать вектор x в массив формы (/ m, 1 /), а вектор yT - в массив формы (/ 1, n /):

integer(4), parameter :: m = 3, n = 5 integer(4) :: i, j

real(4) :: x(m) = (/ 1.0, 2.0, 3.0 /)

real(4) :: y(n) = (/ 5.0, 6.0, 7.0, 8.0, 9.0 /) real(4) :: a(m, n) = 0.0

a = matmul(reshape(x, shape = (/ m, 1 /)), reshape(y, shape = (/ 1, n /))) do i = 1, m ! Вывод результата

print '(1x, 10f6.2)', a(i, :) end do

! Тот же результат, но быстрее, даст вложенный цикл do j = 1, n

do i = 1, m

a(i, j) = x(i) * y(j) end do

end do

146