Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

terminat0r



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору


Код:
 
 
 
!-----------------------------------------------------------------------
!Main program
!-----------------------------------------------------------------------
program    test
![specification part]
implicit none
 
integer, parameter :: rsp = kind(1.0)
integer, parameter :: rdp = selected_real_kind(2*precision(1.0_rsp))
real(rdp), allocatable, dimension(:) :: x,y
real(rdp) :: width
integer :: pulse_type, polarity
 
integer :: i, mult,n
real(rdp), parameter :: pi=3.14159265358979323846264338327950288419716939937510_rdp
 
real(rdp):: a,b,c,xi
 
open(20,file="sin.dat", status="unknown", action="write")
n=100000
mult=3.0_rdp
do i=1,n
xi=(mult*pi)*dble(i)/dble(n)
write(20,'(2E24.16)') xi,sin(xi)
enddo
close(20)
 
write(*,*) "exact width for sine=", 4.0_rdp*pi/6.0_rdp
 
call init_pulse ("sin.dat",x,y )
call fwhm(x,y, width, pulse_type, polarity)
write(*,*) "width=", width
write(*,*) "pulse_type=",pulse_type
write(*,*) "polarity=",polarity
 
 
open(20,file="gaussian.dat", status="unknown", action="write")
n=100000
mult=3.0_rdp
 
 a=1.0_rdp/sqrt(2.0_rdp*pi)
 b=0.d0
 c=1
do i=-n,n
xi=mult*dble(i)/dble(n)
write(20,'(2E24.16)') xi ,a*exp(-((xi-b)**2)/(2.0_rdp*c**2))
enddo
close(20)
 
write(*,*) "exact width for gaussian=", 2.0_rdp*sqrt(2.0_rdp*log(2.0_rdp))*c
 
call init_pulse ("gaussian.dat",x,y )
call fwhm(x,y, width, pulse_type, polarity)
write(*,*) "width=", width
write(*,*) "pulse_type=",pulse_type
write(*,*) "polarity=",polarity
 
 contains
 
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
subroutine init_pulse (fname,x,y )
implicit none
character(len=*)::fname
real(rdp), allocatable, dimension(:) :: x,y
integer, parameter :: find=20
integer :: nl,k,ios
real(rdp) ::a,b
 
open(find,file=fname, status="unknown", action="read")
 
nl=0 !number of lines
!detect number of lines in screen.dat
do
   read(find,*, iostat=ios) a,b
   if (ios /= 0) then  
    write(*,*) "Detected number of lines in file =",nl
    exit
   else
    nl=nl+1
   endif
end do
 
 
!go back to start
rewind(find,iostat=ios)
if (ios/=0) then !something is wrong
  write(*,*) "cannot rewind file. STOP"
  stop
endif
 
if (allocated(x)) deallocate(x)
if (allocated(y)) deallocate(y)
 
allocate(x(1:nl))
allocate(y(1:nl))
 
  do k=1,nl
     read(find,*) x(k),y(k)
  enddo
close(find)
 
 
end subroutine init_pulse
 
 
 
!-----------------------------------------------------------------------
! full-width at half-maximum (fwhm) of the waveform y(x)
! and its polarity.
!  
! polarity=+-1 polarity of the pulse
! pulse_type=+1 pulse is impulse or rectangular with 2 edges
! pulse_type=0 step-like pulse, no second edge
!-----------------------------------------------------------------------
subroutine fwhm(x,y, width, pulse_type, polarity)  
implicit none
real(rdp), dimension(:),  intent(in):: x,y
real(rdp) ,  intent(out):: width
integer ,  intent(out):: pulse_type, polarity
 
real(rdp) :: maxval_y,minval_y,interp,t_lead,t_trail
integer :: maxloc_y(1),minloc_y(1)
real(rdp), parameter :: lev_half=0.5_rdp
integer :: n,c_index,i  
 
!initial bad values
polarity=0
pulse_type=0
width=0.0_rdp
 
 
! find index of center (max or min) of pulse
maxval_y=maxval(y)
maxloc_y=maxloc(y)
minval_y=minval(y)
minloc_y=minloc(y)
 
n=size(y)
 
!simple checks
if(n<3) then  
write(*,*) "Warning from fwhm: dimension of signal <",n  
return
endif
 
if(abs(maxval_y)<tiny(1.0_rdp) .and. abs(minval_y)<tiny(1.0_rdp)) then  
write(*,*) "Warning from fwhm: no signal"  
return
endif
 
i=1
if(y(i)/maxval_y<lev_half) then
 c_index=maxloc_y(i)
 polarity=1
else
 c_index=minloc_y(i)
 polarity=-1
endif
 
!position from the left is between y(i-1) & y(i)
do i=2,n-1
if (sign(1.0_rdp,y(i)/maxval_y-lev_half)/= sign(1.0_rdp,y(i-1)/maxval_y-lev_half))  then  
write(*,*)" i in exit=",i
exit
endif
 
if(i==n-1) then  
write(*,*) "Warning from fwhm: problem in signal, no edge"  
return !problem, no edge
endif
 
end do
 
interp=(lev_half-y(i-1)/maxval_y)/(y(i)/maxval_y-y(i-1)/maxval_y)
t_lead=x(i-1)+interp*(x(i)-x(i-1))
 
! search for the next position starting from center of the pulse
do i=c_index+1,n-1
if (sign(1.0_rdp,y(i)/maxval_y-lev_half)/= sign(1.0_rdp,y(i-1)/maxval_y-lev_half)) then  
exit
endif  
 
if(i==n-1) then  
write(*,*) "Warning from fwhm: problem in signal, step-like pulse, no second edge"  
return !problem, step-like pulse, no second edge
endif
 
end do
 
!ok pulse is impulse or rectangular with 2 edges
pulse_type=1
interp=(lev_half-y(i-1)/maxval_y)/(y(i)/maxval_y-y(i-1)/maxval_y)
t_trail=x(i-1)+interp*(x(i)-x(i-1))
width=t_trail-t_lead
 
 
end subroutine fwhm
 
 
end program test
 
 

 

Всего записей: 2084 | Зарегистр. 31-03-2002 | Отправлено: 17:14 29-11-2011 | Исправлено: terminat0r, 17:18 29-11-2011
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru