I have no experience with incorporating Fortran code and am probably doing something pretty stupid. I want to use the following Fortran subroutine (not written by me) in the file SSFcoef.f subroutine SSFcoef(nmax,nu,A,nrowA,ncolA) implicit double precision(a-h,o-z) implicit integer (i-n) integer l,i,nmax double precision nu,A(0:nmax,0:nmax) A(0,0) = 1D0 do l=1,nmax do i=1,l-1 A(l,i) = (-nu+i+l-1D0)*A(l-1,i)+A(l-1,i-1) end do A(l,0) = (-nu+l-1D0)*A(l-1,0) A(l,l) = 1D0 end do return end I created a dll (this is windows) using R CMD SHLIB SSFcoef.f Then my R code is: ### Load the compiled shared library in. dyn.load("SSFcoef.dll") ### Write a function that calls the Fortran subroutine SSFcoef <- function(nmax, nu){ .Fortran("SSFcoef", as.integer(nmax), as.integer(nu) )$A } SSFcoef(10,2) which when run gives > SSFcoef(10,2) NULL I am pretty sure the problem is that I am not dealing with the matrix A properly. I also tried this on linux and got a segfault. Can anyone supply the appropriate modification to my call (and possibly to the subroutine) to make this work? David Scott -- _________________________________________________________________ David Scott Department of Statistics The University of Auckland, PB 92019 Auckland 1142, NEW ZEALAND Phone: +64 9 923 5055, or +64 9 373 7599 ext 85055 Email: d.scott at auckland.ac.nz, Fax: +64 9 373 7018 Director of Consulting, Department of Statistics
On 18/06/2010 9:59 AM, David Scott wrote:> I have no experience with incorporating Fortran code and am probably > doing something pretty stupid. > > I want to use the following Fortran subroutine (not written by me) in > the file SSFcoef.f > > subroutine SSFcoef(nmax,nu,A,nrowA,ncolA) > implicit double precision(a-h,o-z) > implicit integer (i-n) > integer l,i,nmax > double precision nu,A(0:nmax,0:nmax) > A(0,0) = 1D0 > do l=1,nmax > do i=1,l-1 > A(l,i) = (-nu+i+l-1D0)*A(l-1,i)+A(l-1,i-1) > end do > A(l,0) = (-nu+l-1D0)*A(l-1,0) > A(l,l) = 1D0 > end do > return > end > > > I created a dll (this is windows) using R CMD SHLIB SSFcoef.f > > Then my R code is: > > ### Load the compiled shared library in. > dyn.load("SSFcoef.dll") > > ### Write a function that calls the Fortran subroutine > SSFcoef <- function(nmax, nu){ > .Fortran("SSFcoef", > as.integer(nmax), > as.integer(nu) > )$A > } > > SSFcoef(10,2) > > which when run gives > > > SSFcoef(10,2) > NULL > > I am pretty sure the problem is that I am not dealing with the matrix A > properly. I also tried this on linux and got a segfault. > > Can anyone supply the appropriate modification to my call (and possibly > to the subroutine) to make this work?Two problems: Your subroutine takes 5 arguments, you're only passing two. You didn't name your arguments, but are trying to retrieve A by name. So this will get you closer (it's untested, so there might still be problems...): SSFcoef <- function(nmax, nu){ .Fortran("SSFcoef", as.integer(nmax), as.integer(nu), A = numeric((nmax+1)^2), nrowA = as.integer(nmax+1), # These are unused... ncolA = as.integer(nmax+1) )$A } Duncan Murdoch
On Sat, 19 Jun 2010, David Scott wrote:> I have no experience with incorporating Fortran code and am probably doing > something pretty stupid.Surely you saw in the posting guide that R-help is not the place for questions about C, C++, Fortran code? Diverting to R-devel.> I want to use the following Fortran subroutine (not written by me) in theWell, it is not Fortran 77 but Fortran 95, and so needs to be given a .f95 extension to be sure to work.> file SSFcoef.f > > subroutine SSFcoef(nmax,nu,A,nrowA,ncolA) > implicit double precision(a-h,o-z) > implicit integer (i-n) > integer l,i,nmax > double precision nu,A(0:nmax,0:nmax) > A(0,0) = 1D0 > do l=1,nmax > do i=1,l-1 > A(l,i) = (-nu+i+l-1D0)*A(l-1,i)+A(l-1,i-1) > end do > A(l,0) = (-nu+l-1D0)*A(l-1,0) > A(l,l) = 1D0 > end do > return > end > > > I created a dll (this is windows) using R CMD SHLIB SSFcoef.f > > Then my R code is: > > ### Load the compiled shared library in. > dyn.load("SSFcoef.dll") > > ### Write a function that calls the Fortran subroutine > SSFcoef <- function(nmax, nu){ > .Fortran("SSFcoef", > as.integer(nmax), > as.integer(nu) > )$A > }That does not match. nrowA and ncolA are unused, so you need SSFcoef <- function(nmax, nu){ .Fortran("SSFcoef", as.integer(nmax), as.integer(nu), A = matrix(0, nmax+1, nmax+1), 0L, 0L)$A }> > SSFcoef(10,2) > > which when run gives > >> SSFcoef(10,2) > NULL > > I am pretty sure the problem is that I am not dealing with the matrix A > properly. I also tried this on linux and got a segfault. > > Can anyone supply the appropriate modification to my call (and possibly to > the subroutine) to make this work? > > David Scott > > > -- > _________________________________________________________________ > David Scott Department of Statistics > The University of Auckland, PB 92019 > Auckland 1142, NEW ZEALAND > Phone: +64 9 923 5055, or +64 9 373 7599 ext 85055 > Email: d.scott at auckland.ac.nz, Fax: +64 9 373 7018 > > Director of Consulting, Department of Statistics > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Prof Brian Ripley wrote:> > Well, it is not Fortran 77 but Fortran 95, and so needs to be given a > .f95 extension to be sure to work. >I think most compilers only distinguish two fortran file extensions: .f or .f90. .f denotes fixed-form source code while .f90 denotes free-form. Some compilers also take the capitalized versions, .F and .F90, to indicate source code that must be run through a preprocessor. It is a little weird, but Fortran file extensions have nothing to do with the year of the language standard the code is to be compiled against. David Scott wrote:> > file SSFcoef.f > subroutine SSFcoef(nmax,nu,A,nrowA,ncolA) > implicit double precision(a-h,o-z) > implicit integer (i-n) > integer l,i,nmax > double precision nu,A(0:nmax,0:nmax) > A(0,0) = 1D0 > do l=1,nmax > do i=1,l-1 > A(l,i) = (-nu+i+l-1D0)*A(l-1,i)+A(l-1,i-1) > end do > A(l,0) = (-nu+l-1D0)*A(l-1,0) > A(l,l) = 1D0 > end do > return > end > I created a dll (this is windows) using R CMD SHLIB SSFcoef.f > Then my R code is: > > ### Load the compiled shared library in. > dyn.load("SSFcoef.dll") > > ### Write a function that calls the Fortran subroutine > SSFcoef <- function(nmax, nu){ > .Fortran("SSFcoef", > as.integer(nmax), > as.integer(nu) > )$A > } > > SSFcoef(10,2) > > which when run gives > >> SSFcoef(10,2) > NULL > > I am pretty sure the problem is that I am not dealing with the matrix A > properly. I also tried this on linux and got a segfault. > > Can anyone supply the appropriate modification to my call (and possibly to > the subroutine) to make this work? >When calling a Fortran function for R, for each argument that appears in the subroutine declaration: subroutine subName(...arg list...) You *must* provide a matching input to the .Fortran() call: .Fortran("subName", ...arg list...) In the case of arrays that are filled by the Fortran subroutine, just pass an empty vector of the appropriate length- perhaps created using the double() function. -Charlie ----- Charlie Sharpsteen Undergraduate-- Environmental Resources Engineering Humboldt State University -- View this message in context: http://r.789695.n4.nabble.com/Re-R-Use-of-Fortran-tp2260362p2261266.html Sent from the R devel mailing list archive at Nabble.com.