2017-03-15 34 views
0

複素数の平方係数|z|^2を計算するFortranに固有の関数がありますかzFortranでの複素数の絶対値二乗

そうでない場合は、以下の方法よりも計算が簡単ですか?

REAL(z, precision_specifier)**2 + AIMAG(z)**2 
+1

です。[abs(z)** 2]を使用できます([こちら](https://gcc.gnu.org/onlinedocs/gcc-3.4.4/g77/Abs-Intrinsic参照)。 html)) –

+0

私はポイントが高価なsqrtを避けることだと思います。 – Ross

+0

実数の平方根を計算して再び平方根にするため、非効率的です。 – norio

答えて

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歳未満の人、アルコールやその他のパフォーマンスを損なう薬品の影響を受けている人は使用しないでください。

0

楽しみのためだけに、ここではインライン化されているのを期待して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% rez% imは(6-のgfortranとのifort-16でまだ)...すぐに来ることを願っています

+0

'transfer'、ステートメント関数、いつ狂気の終わりになるのですか? –

+0

これをもっときれいにしたいのであれば、 'real(z、dp)'は 'real(z)'と同じ効果で置き換えることができます。 – francescalus

+0

real(z)also worked ... o:これはzと同じ種類が返ってくるかわかりませんでした... – roygvib

1

ただ、よく知られた式(a+i*b)*(a-i*b) = a^2 + b^2

SquaredModulus = real part of (Z * CONJG(Z)) 
を活用

CONJGはcomplex conjugate

+0

@francescalus実数部に関するメモを追加しました – MBo

+0

あなたの編集はあなたの答えを間違ってしまった - 複素共役の実数倍に等しくない。 – Ross

+0

@Ross括弧が追加されました。 – MBo