`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库,它要快得多。