Reputation: 784
I want to use a fortran program in R, but I get errors when running the R program. The fortran code has REAL variables with 2 dimensions. A test code for fortran looks like: test_inside_program.f90:
program testprogram
implicit none
interface
SUBROUTINE testm(testvar, thelength)
IMPLICIT NONE
REAL, INTENT(IN), DIMENSION(:) :: testvar
INTEGER, INTENT(IN) :: thelength
END SUBROUTINE testm
end interface
REAL, DIMENSION(:),ALLOCATABLE :: testvar
INTEGER :: i
allocate(testvar(3))
DO i = 1,2
testvar(i) = i
ENDDO
call testm(testvar, 3)
write(*,*) 'program finished'
end program testprogram
SUBROUTINE testm(testvar,thelength)
IMPLICIT NONE
INTEGER, INTENT(IN) :: thelength
REAL, INTENT(IN), DIMENSION(:) :: testvar
write(*,*) 'program cont. X'
write(*,*)' THe testvar 1st variable is', testvar
END SUBROUTINE testm
I want to call the subroutine testm from R. Of course I would like to maintain the dimensions. Therefore I generated following test code in R: test.r
dyn.load("test_inside_program.so")
is.loaded("testm")
dd <- c(5,2,3)
.Fortran("testm",as.single(dd),as.integer(3))
I would appreciate your help! I generate the .so with
R CMD SHLIB test_inside_program.f90
Upvotes: 1
Views: 990
Reputation:
You can't declare an assumed shape array here, since R won't know how to pass such an array (it's not just a pointer to data, it must come together with dimensions).
This will work:
subroutine testm(testvar,thelength)
implicit none
integer, intent(in) :: thelength
real, intent(in), dimension(thelength) :: testvar
write(*,*) 'program cont. x'
write(*,*) 'length=', thelength
write(*,*) 'testvar=', testvar
end subroutine testm
Also, depending on your needs, you may consider declaring double precision arrays in your program and passing them "as is" from R (it's the default numeric type). For integers, you may also write 3L directly in R, thus, for single and double, it goes like this:
.Fortran("testm", as.single(dd), 3L)
.Fortran("testm", dd, 3L)
Upvotes: 1
Reputation: 784
Okay, problem solved! subroutines in fortran:
SUBROUTINE testm(testvar, thelength)
IMPLICIT NONE
INTEGER, INTENT(IN) :: thelength
REAL, INTENT(IN), DIMENSION(thelength) :: testvar
END SUBROUTINE testm
in R
dd <- c(5.5,2,3.3)
#length(dd)
print("call fortran routine")
.Fortran("testm",as.single(dd),as.integer(3))
I dont know why it did not work before :o
Upvotes: 0