Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
FFT:fortran与python_Python_Fortran_Fft_Fortran90_Gfortran - Fatal编程技术网

FFT:fortran与python

FFT:fortran与python,python,fortran,fft,fortran90,gfortran,Python,Fortran,Fft,Fortran90,Gfortran,我有计算离散信号(具有两个不同频率的双正弦信号)的FFT的fortran代码,从: y=0.5*np.sin(2*np.pi*ff1*t)+0.1*np.sin(2*np.pi*ff2*t) 当我用fortran代码计算FFT并与用python计算的FFT进行比较时,我可以看到: 1。两个图中拾取的分布是由于四舍五入造成的吗?我能消除或减少它吗 python中使用的代码是: import numpy as np import matplotlib.pyplot as plt from scip

我有计算离散信号(具有两个不同频率的双正弦信号)的FFT的fortran代码,从:

y=0.5*np.sin(2*np.pi*ff1*t)+0.1*np.sin(2*np.pi*ff2*t)

当我用fortran代码计算FFT并与用python计算的FFT进行比较时,我可以看到:

1。两个图中拾取的分布是由于四舍五入造成的吗?我能消除或减少它吗

python中使用的代码是:

import numpy as np
import matplotlib.pyplot as plt
from scipy import fft

Fs = 2048    # sampling rate = number of lines in the input file
Ts = 1.0/Fs  # sampling interval
data = np.loadtxt('input.dat')
t =  data[:,0]
y    = data[:,1]

plt.subplot(2,1,1)
plt.plot(t,y,'ro')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.subplot(2,1,2)

n = len(y)                       # length of the signal
k = np.arange(n)
T = n/Fs # equal 1 
frq = k/T # two sides frequency range
freq = frq[range(n/2)]           # one side frequency range

Y = np.fft.fft(y)/n              # fft computing and normalization
Y = Y[range(n/2)]

plt.plot(freq, abs(Y), 'r-')
plt.axis([0, 20, 0, .4])
plt.xlabel('freq (Hz)')
plt.ylabel('|Y(freq)|')

plt.show()
2.我的fortran程序中fft的振幅不等于python中计算的振幅,python中计算的| Y(freq)|是否等于:

ABS(AR(I)**2+AI(I)**2)/n_tot

其中AR和AI是信号的实部和虚部,n_tot是总点数

使用的fortran代码如下所示:

 PROGRAM fft
      IMPLICIT NONE
      INTEGER, PARAMETER :: N=2048 ! tot_num of points 
      INTEGER, PARAMETER :: M=11 !! this is the exp in subroutine: N1 = 2**M
      INTEGER :: I,J
      REAL(8) :: PI,F1,T
      REAL(8), DIMENSION (N) :: AR,AI,O,time   
    !
      PI = 4.D0*DATAN(1.D0) ; F1 = 1.d0/SQRT(real(N)) 

  open(unit=6,file="input.dat")
  do i = 1,n
  read(6,*) time(i),ar(i)
  end do
!
  DO I = 1, N
    AI(I) = 0.D0
  END DO

  CALL FFT (AR,AI,N,M)
!
  OPEN(unit=6,file="output.dat")
  DO I = 1, 20
    O(I)  = I-1
    AR(I) = (F1*AR(I))**2+(F1*AI(I))**2 !! this is for the |y(freq)|
    AR(I) = dabs(AR(I)) !! absolute value of y(freq)
    WRITE(6,"(3F16.10)") O(I),AR(I)
  END DO
  CLOSE(6)

END PROGRAM fft
!
  SUBROUTINE FFT(AR,AI,N,M)
!
! An example of the fast Fourier transform subroutine with N = 2**M.
! AR and AI are the real and imaginary part of data in the input and
! corresponding Fourier coefficients in the output.
! Copyright (c) Tao Pang 1997.
!
  IMPLICIT NONE
  INTEGER, INTENT (IN) :: N,M
  INTEGER :: N1,N2,I,J,K,L,L1,L2
  REAL(8) :: PI,A1,A2,Q,U,V
  REAL(8), INTENT (INOUT), DIMENSION (N) :: AR,AI
!
  PI = 4.D0*ATAN(1.D0)
  N2 = N/2
!
  N1 = 2**M
  IF(N1.NE.N) STOP 'Indices do not match'
!
! Rearrange the data to the bit reversed order
!
  L = 1
  DO K = 1, N-1
    IF (K.LT.L) THEN
      A1    = AR(L)
      A2    = AI(L)
      AR(L) = AR(K)
      AR(K) = A1
      AI(L) = AI(K)
      AI(K) = A2
    END IF
    J   = N2
    DO WHILE (J.LT.L)
      L = L-J
      J = J/2
    END DO
    L = L+J
  END DO
!
! Perform additions at all levels with reordered data
!
  L2 = 1
  DO L = 1, M
    Q  =  0.D0
    L1 =  L2
    L2 =  2*L1
    DO K = 1, L1
      U   =  DCOS(Q)
      V   = -DSIN(Q)
      Q   =  Q + PI/L1
      DO J = K, N, L2
        I     =  J + L1
        A1    =  AR(I)*U-AI(I)*V
        A2    =  AR(I)*V+AI(I)*U
        AR(I) =  AR(J)-A1
        AR(J) =  AR(J)+A1
        AI(I) =  AI(J)-A2
        AI(J) =  AI(J)+A2
      END DO
    END DO
  END DO
END SUBROUTINE FFT

在Python脚本中,实际上| Y(freq)|与实际信号
Y
振幅的一半相关,而这在fortran程序中是不正确的

在Python代码的以下几行中

Y = np.fft.fft(y)/n 
plot(freq, abs(Y), 'r-')
Y
是从FFT获得的复杂数组,因此
abs(Y)
是由
|Y[i]|
和| z |=sqrt(Re{z}^2+Im{z}^2)组成的数组。但是,在下面的Fortran代码行中

AR(I) = (F1*AR(I))**2+(F1*AI(I))**2     !! this is for the |y(freq)|
AR(I) = dabs(AR(I))                     !! absolute value of y(freq)
(其中
F1=1/sqrt(N)
),
sqrt()
在实部和虚部平方相加后缺失。因此,将这些行替换为

AR(I) = sqrt( AR(I)**2 + AI(I)**2 ) / N
给出预期结果(假设
FFT()
具有与
np.FFT.FFT()
相同的规范化)。例如,
AR(6)
AR(9)
变为0.25和0.05,这与从Python获得的结果一致


下面是一些代码比较(只是为了好玩!),它们给出了相同的结果

Python:

from numpy import pi, sin
N = 2048
t = np.linspace( 0.0, 1.0, N+1 )[:-1]
y = 0.5 * sin(2 * pi * 5 * t) + 0.1 * sin(2 * pi * 8 * t)
z = np.fft.fft( y )

for i in range( 10 ) + range( N-9, N ):
    print ("%4d" + "%16.10f" * 3) % \
        ( i, z[i].real, z[i].imag, abs( z[i] ) / N )
Fortran:

time = [( dble(i-1) / dble(N), i=1,N )]
AR   = 0.5d0 * sin(2 * pi * 5 * time) + 0.1d0 * sin(2 * pi * 8 * time)
AI   = 0.0d0

call FFT (AR,AI,N,M)

do i = 1, N
    if ( i > 10 .and. i < N-8 ) cycle
    print "(i4, 3f16.10)", &
            i-1, AR(i), AI(i), sqrt( AR(i)**2 + AI(i)**2 ) / N
enddo

在Python代码的以下几行中

Y = np.fft.fft(y)/n 
plot(freq, abs(Y), 'r-')
Y
是从FFT获得的复杂数组,因此
abs(Y)
是由
|Y[i]|
和| z |=sqrt(Re{z}^2+Im{z}^2)组成的数组。但是,在下面的Fortran代码行中

AR(I) = (F1*AR(I))**2+(F1*AI(I))**2     !! this is for the |y(freq)|
AR(I) = dabs(AR(I))                     !! absolute value of y(freq)
(其中
F1=1/sqrt(N)
),
sqrt()
在实部和虚部平方相加后缺失。因此,将这些行替换为

AR(I) = sqrt( AR(I)**2 + AI(I)**2 ) / N
给出预期结果(假设
FFT()
具有与
np.FFT.FFT()
相同的规范化)。例如,
AR(6)
AR(9)
变为0.25和0.05,这与从Python获得的结果一致


下面是一些代码比较(只是为了好玩!),它们给出了相同的结果

Python:

from numpy import pi, sin
N = 2048
t = np.linspace( 0.0, 1.0, N+1 )[:-1]
y = 0.5 * sin(2 * pi * 5 * t) + 0.1 * sin(2 * pi * 8 * t)
z = np.fft.fft( y )

for i in range( 10 ) + range( N-9, N ):
    print ("%4d" + "%16.10f" * 3) % \
        ( i, z[i].real, z[i].imag, abs( z[i] ) / N )
Fortran:

time = [( dble(i-1) / dble(N), i=1,N )]
AR   = 0.5d0 * sin(2 * pi * 5 * time) + 0.1d0 * sin(2 * pi * 8 * time)
AI   = 0.0d0

call FFT (AR,AI,N,M)

do i = 1, N
    if ( i > 10 .and. i < N-8 ) cycle
    print "(i4, 3f16.10)", &
            i-1, AR(i), AI(i), sqrt( AR(i)**2 + AI(i)**2 ) / N
enddo

显然,它们的标准化程度不同。这与其说是一个编程问题,不如说是一个研究您正在使用的软件包的文档的问题。显然,它们的标准化方式不同。这与其说是一个编程问题,不如说是一个研究您正在使用的软件包的文档的问题。