如何在Fortran 90中获得nxn矩阵的共轭?

问题描述 投票:1回答:2

我有一个复杂的矩阵给出:

complex(rdp) :: a(:,:)

我们假设这个矩阵是nxn。我如何结合矩阵的每个条目?这有内在的功能吗?

matrix fortran complex-numbers built-in
2个回答
1
投票

Fortran标准具有CONJG内在。方便的是它是一个elemental内在的,这意味着如果你为它提供一个数组参数而不是一个标量,它将对数组的每个元素进行操作。例如。

program conjgtest
  use iso_fortran_env, only: real64
  implicit none
  real(real64) :: r(2, 4)
  complex(real64) :: c(2,2)
  call random_number(r)
  c = cmplx(r(:, 1:2), r(:, 3:4), real64)
  print *, c
  print *, "conjugate:"
  print *, conjg(c)
end program conjgtest

0
投票

正如米奇评论的那样,有一个标量函数:https://gcc.gnu.org/onlinedocs/gfortran/CONJG.html

编译器应该能够轻松地在数组上自动向量化;它只是对想象部分的符号位进行异或。您不需要内部函数来利用SIMD1。

无论如何,在飞行中这样做会非常便宜;除非你要多次重新读取这个数组,否则在数组(或2D矩阵)上进行单独循环只是为了应用这个操作可能是个坏主意。通过将共轭折叠成您下次执行的任何操作,增加计算强度(每次加载/存储数据的ALU操作,或者将其带入缓存)。

或者缓存阻塞矩阵并在将该块提供给下一个操作之前共轭一大块。


脚注1:虽然对于复杂的real8,SIMD甚至只适用于宽度大于128位= 16字节的矢量宽度=一个复数real8的大小。如果这就是你所拥有的,你可能只使用标量xor。如果没有将结果用于其他任何事情,x86编译器可以使用xor dword [rdi+12], 1<<31给出指向RDI中的复杂real8的指针。但是对于AVX或更广泛的,你可以做一个256位的vxorps,它可以同时翻转两个复杂的real8中的高位。或者类似于ARM SVE。

© www.soinside.com 2019 - 2024. All rights reserved.