从矩阵中减去一个向量(按行)
Subtract a vector from a matrix (row-wise)
假设我在 fortran 中有一个矩阵 A,它是 (n,m),还有一个向量 B,它是 (1,米)。我想在不使用循环的情况下从 A 的所有行中减去向量 B。
到目前为止,我只能通过循环来完成:
PROGRAM Subtract
IMPLICIT NONE
REAL, DIMENSION(250,5) :: A
INTEGER, DIMENSION(1,5) :: B
INTEGER :: i
B(1,1) = 1
B(1,2) = 2
B(1,3) = 3
B(1,4) = 4
B(1,5) = 5
CALL RANDOM_NUMBER(A)
do i=1,250
A(i,:) = A(i,:) - B(1,:)
end do
end program
但这非常低效。例如。在 matlab 中,可以使用函数 reptmat 在一行中完成。
关于更好的方法有什么建议吗?
您可以为此使用 spread
:
A = A - spread( B(1,:), 1, 250 )
请注意 Fortran 是列优先的,因此 B(1,:)
通常在内存中不连续,因此会创建一个临时数组。
[这是你的情况,因为你只有一列 - 但仍然值得一提。 ]
同理,遍历A
的第一个索引是低效的。
如果您转置矩阵,它可能会加快很多速度。
然后,循环解决方案甚至可能比使用 spread
的解决方案更快。 (但这取决于编译器。)
假设我在 fortran 中有一个矩阵 A,它是 (n,m),还有一个向量 B,它是 (1,米)。我想在不使用循环的情况下从 A 的所有行中减去向量 B。
到目前为止,我只能通过循环来完成:
PROGRAM Subtract
IMPLICIT NONE
REAL, DIMENSION(250,5) :: A
INTEGER, DIMENSION(1,5) :: B
INTEGER :: i
B(1,1) = 1
B(1,2) = 2
B(1,3) = 3
B(1,4) = 4
B(1,5) = 5
CALL RANDOM_NUMBER(A)
do i=1,250
A(i,:) = A(i,:) - B(1,:)
end do
end program
但这非常低效。例如。在 matlab 中,可以使用函数 reptmat 在一行中完成。 关于更好的方法有什么建议吗?
您可以为此使用 spread
:
A = A - spread( B(1,:), 1, 250 )
请注意 Fortran 是列优先的,因此 B(1,:)
通常在内存中不连续,因此会创建一个临时数组。
[这是你的情况,因为你只有一列 - 但仍然值得一提。 ]
同理,遍历A
的第一个索引是低效的。
如果您转置矩阵,它可能会加快很多速度。
然后,循环解决方案甚至可能比使用 spread
的解决方案更快。 (但这取决于编译器。)