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

时间:2019-03-15 04:44:45

标签: matrix fortran complex-numbers built-in

我有一个复杂的矩阵,由下式给出:

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

让我们假设这个矩阵是nxn。如何对矩阵的每个条目进行共轭?有内在的功能吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

正如Mitch所说,有一个标量函数:https://gcc.gnu.org/onlinedocs/gfortran/CONJG.html

编译器应该能够轻松地将其自动向量化到数组中;只是对虚部的符号位进行异或。您不需要内部函数即可利用SIMD 1

无论如何,即时执行此操作非常便宜;仅对数组(或2D矩阵)执行一个单独的循环以应用此操作可能是个坏主意,除非您要多次重复读取该数组多次。通过将共轭折叠为下一步操作,可以提高计算强度(每次加载/存储数据或将其放入缓存的ALU操作)。

或者在对块进行下一个操作之前对其进行缓存块化并对其进行共轭。


脚注1:   尽管对于复杂的real8,SIMD甚至仅在矢量宽度大于128位= 16字节=一个复杂的real8的大小时才有用。如果仅此而已,那么不妨仅使用标量xor。如果不将结果用于其他任何东西,则x86编译器可以仅使用xor dword [rdi+12], 1<<31,而该指针指向RDI中的复杂real8。但是,对于AVX或更宽的版本,您可以执行256位vxorps的操作,一次翻转两个复杂real8中的高位。或类似地使用ARM SVE。