interface - Wrap fortran program for use in R -


i working r, need lot of number crunching, want in fortran. relatively new r , newbie fortran... have working r program, optimize. created fortran program solving system of ode's, keep in subroutine. additionally use module called aux.f90 store parameters , function creates signal fed equations. works intended , data saved in .txt file.

what create r front-end tosses fortran program parameters, such length of simulation or number of steps used in solution. fortran heavy lifting, saves results in file , can use r visualize data file. see fortran code below:

! auxiliary module contains parameters module aux implicit none  integer,parameter :: n = 2**8       ! number of steps  real(kind=4) :: jout = 0.5          ! normal metabolism real(kind=4) :: alp = 4.0           ! factor growth real(kind=4) :: bet = 1.0           ! benefit value real(kind=4) :: etay = 0.1          ! cost value y real(kind=4) :: etaz = 0.10         ! cost value z real(kind=4) :: h  = 3.0            ! hill coefficient real(kind=4) :: kx = 0.07           ! saturation coefficient real(kind=4) :: t1 = 0.0, t2 = 30.0 ! start , end point of simulation  contains                            ! function f(t) create step signal  real(kind=4) function f(t)     implicit none     real(kind=4), intent(in)  :: t  ! taking time value     real(kind=4)              :: tt      !real(kind=4), intent(out) :: s  ! giving out signal      real(kind=4) :: period = 5      ! defining period length      tt = modulo(t,period)          ! signal function         if (tt > 0.5*period)              f = 1         else             f = 0         endif end function  end module aux  ! program solving ode system , giving output fileprogram ffl program ffl use aux         ! use module aux implicit none integer                     :: m,j          ! iteration variable real(kind=4), dimension(6)  :: b =(/0.0, 0.2, 0.4, 0.6, 0.8, 1.0/) ! expression real(kind=4)                :: dt                                  ! time resolution real(kind=4), dimension(n)  :: t                                   ! time vector real(kind=4), dimension(4)  :: x_new, x_aux, y_new, y_aux, q0      ! vectors   ! computing time vector  dt=(t2-t1)/real(n) ! calculating time resolution t(1) = t1          ! setting first time value t1 = 0  m = 1,n         ! filling time vector     t(m) = t(m-1)+dt end open(unit = 10,file = 'ffl.txt', status = 'unknown') j=1,6     k = b(j)     ! initial conditions     q0(1) = 0   ! x     q0(2) = k   ! y     q0(3) = 0   ! z     q0(4) = 0   ! w      !open(unit = 10,file = 'ffl.txt', status = 'unknown')     x_new = q0                ! set initial conditions     write(10,*)t(1),x_new(1),x_new(2),x_new(3),x_new(4) ! saving data      m = 2,n         ! solving second order method          call derivate(t(m-1),x_new,y_new) ! call derivate routine         x_aux = x_new + dt*y_new          call derivate(t(m),x_aux,y_aux)         x_new = x_new + 0.5*dt*(y_new+y_aux)         write(10,*)t(m),x_new(1),x_new(2),x_new(3),x_new(4) ! saving data      end  end  close(10) end program ffl  ! subroutine derivate gives system of ode's solved  subroutine derivate(time,y,z) use aux              ! use module aux implicit none real(kind=4), intent(in)               :: time ! input: time vector   real(kind=4), dimension(4), intent(in) :: y    ! input: initial conditions vector real(kind=4), dimension(4), intent(out):: z    ! output: results vector  z(1) = f(time)-y(1)                                                             !dx/dt  z(2) = k+(1-k)*((1+kx)*(y(1)**h))/((y(1)**h)+kx)-y(2)                           !dy/dt z(3) = ((1+kx)*(y(1)**h)/((y(1)**h)+kx)*((1+kx)*(y(2)**h))/((y(2)**h)+kx)-y(3)) !dz/dt z(4) = f(time)*y(3)-etay*(k+(1-k)*((1+kx)*(y(1)**h))/((y(1)**h)+kx)) &          !dw/dt        -etaz*(((1+kx)*(y(1)**h))/((y(1)**h)+kx)*((1+kx)*(y(2)**h))/((y(2)**h)+kx))  

end subroutine derivate

i have read "writing r extensions" document, did not find helpful...

now questions: since r needs fortran subroutine, create wrapper subroutine in fortran makes use of existing files, can call r. however, can't find way create wrapper subroutine in first place. possible call actual program in subroutine? couldn't find helpful online.

a program supposed linked executable, can't call subroutine - or call executable (with system in gfortran), directly r.

the easy way call fortran r .fortran r function, calls fortran subroutine (not function, nor program).

the basic steps :

  • compile fortran dll, exporting subroutines need (of course may wrappers other subroutines or functions)
  • put dll in directory in system path
  • from r, load dll dyn.load
  • call subroutine .fortran.

if use gfortran, may install rtools, has need. if want use compiler, may have trouble, names.

from comment user2188538's answer, see know these steps, careful symbol names. .fortran help: use .fortran care compiled fortran 9x code: may not work if fortran 9x compiler used differs fortran 77 compiler used when configuring r, if subroutine name not lower-case or includes underscore. possible use .c , necessary symbol-name translation yourself.

also, suspect wrapper subroutine should not reside inside module, or may have trouble names. limitation wrapper function, must visible r.

you can check exported names in dll (send objdump -x your.so file , exported symbols). , check in r, is.loaded("your.symbol"), after loading dll. aware usually, gfortran appends underscore names, whereas it's not needed when call .fortran r. described above, may use .c instead (but then, remember fortran arguments passed reference).

to check understand whole process, suggest test on trivial example, such unique subroutine mysub(x,y,z) z=x+y. when 1 runs, can elaborate on call more complex routines.

edit should not use assumed-shape or deferred-shape arrays, when pass arrays arguments r fortran, assumed-size arrays, is, usual array passing in fortran 77. because r knows how pass pointer raw data, whereas assumed-shape , deferred-shape need more information, , r not know data structure that.

for example, can that:

subroutine mysub(n, a)     real :: a(n, n)     ... end subroutine 

but amost fail:

subroutine mysub(a)     real :: a(:, :)     ... end subroutine 

also, can't pass function arguments r fortran, need special data structure callback (under hood, r scheme dialect, , uses s-expressions). may in c, through .c or .call (see .call , r internals).


Comments

Popular posts from this blog

c++ - How to add Crypto++ library to Qt project -

jQuery Mobile app not scrolling in Firefox -

How to use vim as editor in Matlab GUI -