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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/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
`munmap_chunk():Fortran Fourier transform中的无效指针`和SIGABRT_Fortran_Fft_Sigabrt - Fatal编程技术网

`munmap_chunk():Fortran Fourier transform中的无效指针`和SIGABRT

`munmap_chunk():Fortran Fourier transform中的无效指针`和SIGABRT,fortran,fft,sigabrt,Fortran,Fft,Sigabrt,对于我硕士学位的项目,我必须编制一个程序来计算信号的傅里叶变换。 我打开一个.dat文件的数据,然后我必须使用一个子例程来计算我的信号的傅里叶变换,并以数组的形式返回它。我计算傅里叶变换的实部和虚部 “npts”是我的正弦波中的点数 “nbft”是我的傅里叶变换的频率数 “temps”在法语中的意思是“时间”** 如果傅里叶变换的实部是“F_卷轴” “F_im”是虚部 “delta_nu”是时间分辨率 “freq”是频率 “信号”是正弦波值 我试着翻译程序,这样你就可以理解我想做什么 一切似

对于我硕士学位的项目,我必须编制一个程序来计算信号的傅里叶变换。
我打开一个.dat文件的数据,然后我必须使用一个子例程来计算我的信号的傅里叶变换,并以数组的形式返回它。我计算傅里叶变换的实部和虚部

  • “npts”是我的正弦波中的点数
  • “nbft”是我的傅里叶变换的频率数
  • “temps”在法语中的意思是“时间”**
  • 如果傅里叶变换的实部是“F_卷轴”
  • “F_im”是虚部
  • “delta_nu”是时间分辨率
  • “freq”是频率
  • “信号”是正弦波值
我试着翻译程序,这样你就可以理解我想做什么

一切似乎都很好,但我不断收到错误信号。
我认为问题在我的子程序中,在步骤2,但我无法找到解决问题的方法。

这是我的密码:

program puissance_sinus1_nom
                    !!!!! MAIN PROGRAM !!!!!

! DECLARATION OF CONSTANTS AND VARIABLES 
implicit none
integer :: i, ios=0, npts, nbft
double precision, dimension(:), allocatable :: freq, puis
double precision, dimension(:), allocatable :: temps, signal

! INSTRUCTIONS
! 1. Open the file
open(25, file='sinus1_nom.dat', status='old', &
         action='read', iostat=ios)

! 2. Lines count
read(25,*)npts        ! The number of points (npts) is indicated
                      ! in the 1st line of the file I open
allocate(temps(npts))
allocate(signal(npts))
write(*,*)" "

do i = 1,npts
   read(25,*)temps(i),signal(i)
enddo


if (mod(npts,2) .eq. 0) then
   nbft = npts/2 +1
else
   nbft = (npts +1)/2
endif

write(*,*)"Number of frequencies :",nbft
write(*,*) " "
write(*,*) " "

! 3. Use of subroutine
allocate(freq(nbft))
allocate(puis(nbft))
call calcul_fourier(npts,signal,temps,nbft,freq,puis)


! Close everything
deallocate(freq)
deallocate(puis)
deallocate(temps)
deallocate(signal)

close(25)
end program puissance_sinus1_nom

                    !!!!! SUBROUTINE !!!!!

subroutine calcul_fourier(npts,signal,temps,nbft,freq,puis)
! DECLARATION OF VARIABLES
implicit none 
integer :: i, k
double precision :: delta_nu, pi=4*atan(1.)
double precision, dimension(nbft) :: F_reel, F_im

integer, intent(in) :: npts, nbft
double precision, dimension(npts), intent(in) :: temps, signal
double precision, dimension(nbft), intent(out) :: freq, puis

! INSTRUCTIONS
! 1. Frequency resolution calculation
delta_nu = (1./temps(npts))*1.d6
write(*,*)"delta_nu = ",delta_nu," micro Hz"

! 2. Calculation of real and imaginary parts of Fourier transform
do k=1, nbft
   freq(k) = (k-1)*delta_nu
enddo

do k=0, nbft+1
   F_reel(k) = 0
   F_im(k) = 0
   do i=1, npts
   F_reel(k) = F_reel(k) + (2./npts)*signal(i)*cos(2*pi*freq(k)*temps(i))
   F_im(k) = F_im(k) + (2./npts)*signal(i)*sin(2*pi*freq(k)*temps(i))
   enddo
   write(*,*)F_reel(k)    ! display to see if it works
enddo

write(*,*) " "
write(*,*) " "
write(*,*) " "

! 3. power calculation (magnitude^2)
do k=1,nbft
   puis(k) = F_reel(k)**2 + F_im(k)**2
enddo

end subroutine calcul_fourier
我使用
write(*,*)F_reel(k)
来显示傅里叶变换实部的值,以检查程序是否正确运行,我希望它返回它计算的所有值

然而,我一直得到这样的信息:

*** Error in `./puissance_sinus1_nom.x': munmap_chunk(): invalid pointer: 0x0000000000e07d10 ***

Program received signal SIGABRT: Process abort signal.

Backtrace for this error:
#0  0x7F4E9392D407
#1  0x7F4E9392DA1E
#2  0x7F4E92E4A0DF
#3  0x7F4E92E4A067
#4  0x7F4E92E4B447
#5  0x7F4E92E881B3
#6  0x7F4E92E8D98D
#7  0x4013A6 in calcul_fourier_
#8  0x401C0A in MAIN__ at puissance_sinus1_nom.f90:?
Abandon
显然我做错了什么,但我看不出是什么。
你知道吗

你的循环

do k=0, nbft+1
   F_reel(k) = 0
   F_im(k) = 0
   do i=1, npts
   F_reel(k) = F_reel(k) + (2./npts)*signal(i)*cos(2*pi*freq(k)*temps(i))
   F_im(k) = F_im(k) + (2./npts)*signal(i)*sin(2*pi*freq(k)*temps(i))
   enddo
   write(*,*)F_reel(k)    ! display to see if it works
enddo
访问索引
0
nbft+1
,但数组声明为从
1
nbft

double precision, dimension(nbft) :: F_reel, F_im
这是一个错误,您不能越界访问数组

编译器可以找到此错误。只需启用错误检查,对gfortran使用
-Wall-fcheck=all
等标志,或对Intel使用
-warn-check
。请参阅编译器手册


顺便说一句,根据定义计算傅里叶变换效率很低,您应该使用快速傅里叶变换(FFT)。您可以使用许多库。

欢迎使用。一定要拿着书读。编译程序进行调试总是很重要的。首先,要获得有意义的回溯,应该使用
-g
标志。然后,要获取错误检查和其他警告,请使用标志,如gfortran的
-Wall-fcheck=all
,或英特尔的
-warn-check
。请参阅编译器手册。您的子例程
子例程calcul\u fourier
是外部的。它不在模块中(首选!),也不在程序内部(学习包含)。这样很容易出错。所有子程序都应该放在一个模块中以避免错误。谢谢弗拉基米尔,你解决了我的问题!我不知道如何调试我的程序,老师没有告诉我我能够调试,也没有告诉我如何调试。谢谢你对如何调试的解释,谢谢!实际上,作为项目的一部分,我必须自己创建一个傅里叶变换。但是下次我肯定会用FFT。谢谢。考虑使用FFT库,它要快得多。