複素数の平方係数|z|^2
を計算するFortranに固有の関数がありますかz
?Fortranでの複素数の絶対値二乗
そうでない場合は、以下の方法よりも計算が簡単ですか?
REAL(z, precision_specifier)**2 + AIMAG(z)**2
複素数の平方係数|z|^2
を計算するFortranに固有の関数がありますかz
?Fortranでの複素数の絶対値二乗
そうでない場合は、以下の方法よりも計算が簡単ですか?
REAL(z, precision_specifier)**2 + AIMAG(z)**2
いいえ、Fortran標準では、このような組み込みルーチンは定義されていません。また、私が知っている限り、現在広く使われているコンパイラのどれもがこのようなルーチンを提供していません。 OPは本当に高価SQRTを避けたい、と彼女の既存のソリューションを好きではない場合
は、OPは試みることができる:
real :: rslt
real, dimension(2) :: parts
complex :: z
...
parts = transfer(z, parts)
rslt = dot_product(parts, parts)
または、同じ宣言与えられ、これは
好まれるかもしれないがrslt = dot_product(transfer(z, parts), transfer(z, parts))
いつものように、パフォーマンスが重要な場合は、それを測定してください。
もっと簡単ですか?あなたが決める。
いつものように、transfer
は、18歳未満の人、アルコールやその他のパフォーマンスを損なう薬品の影響を受けている人は使用しないでください。
楽しみのためだけに、ここではインライン化されているのを期待してABS2を()定義する(古き良き??)文関数を使用するには、いくつかの試みが...(ちょうど試し、その使用を推奨していない!)です
program main
implicit none
integer, parameter :: dp = kind(0.0d0)
complex(dp) z
real(dp) abs2
abs2(z) = real(z)**2 + aimag(z)**2 ! (could be included or macro-ed??)
! abs2(z) = conjg(z) * z ! maybe slower
! abs2(z) = z % re**2 + z % im**2 ! near future
! intrinsic :: abs2 ! best solution
z = (1.0_dp, 2.0_dp)
print *, abs(z)**2
print *, abs2(z)
print *, abs(z + 1.0_dp)**2
print *, abs2(z + 1.0_dp)
end program
Result:
5.0000000000000009
5.0000000000000000
8.0000000000000018
8.0000000000000000
私は
z% re
と
z% im
は(6-のgfortranとのifort-16でまだ)...すぐに来ることを願っています
'transfer'、ステートメント関数、いつ狂気の終わりになるのですか? –
これをもっときれいにしたいのであれば、 'real(z、dp)'は 'real(z)'と同じ効果で置き換えることができます。 – francescalus
real(z)also worked ... o:これはzと同じ種類が返ってくるかわかりませんでした... – roygvib
ただ、よく知られた式(a+i*b)*(a-i*b) = a^2 + b^2
SquaredModulus = real part of (Z * CONJG(Z))
を活用
CONJGはcomplex conjugate
です。[abs(z)** 2]を使用できます([こちら](https://gcc.gnu.org/onlinedocs/gcc-3.4.4/g77/Abs-Intrinsic参照)。 html)) –
私はポイントが高価なsqrtを避けることだと思います。 – Ross
実数の平方根を計算して再び平方根にするため、非効率的です。 – norio