Skip to content

Demo of how Fortran code could be included in an R package

License

Notifications You must be signed in to change notification settings

coolbutuseless/simplefortran

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simplefortran - demo package for calling C code with .C()

simplefortran is a small demo package showing how Fortran code could be included in a package and called with .Fortran()

This is one of a series of small demo packages for
calling other languages from R:

Rough comparison of .C(), .Call(), {Rcpp} (and .Fortran())

.C() .Call() Rcpp
Overview No real understanding of R objects Need to understand SEXP macros & internals C++ classes hide the complexity of the SEXP internals
What code? Basic C code. Numeric calcs. Complex C code. Can manipulate R objects from C Complex C and C++ code involving numerics and R objects
Pros Simple to understand and use Simple. No unnecessary copying. Great documentation. Wrapping of R objects very intuitive.
Cons Too simple for most interesting things Need to understand SEXP & R internals
Cons Performs copying of data to call functions
Demo R package {simplec} {simplecall} {simplercpp}
Compiled size 17 kB 17 kB 92 kB (stripping can bring this down: see issue1)
.Fortran()
Overview No real understanding of R objects
What code? Basic Fortran code. Numeric calcs.
Pros Simple to understand and use
Cons Too simple for most interesting things
Cons Performs copying of data to call functions
Cons Need to know Fortran!
Demo R package {simplefortran}
Compiled size 17 kB

Installation

You can install from GitHub with:

# install.package('remotes')
remotes::install_github('coolbutuseless/simplefortran)

What’s in the box?

Package contains 2 Fortran functions, and 2 functions in R which call the Fortran functions using .Fortran().

Fortran function R function
subroutine add_(x, y, answer) add_Fortran(x, y)
subroutine mul_(x, y, answer) mul_Fortran(x, y)

What’s in the R functions?

  • A call using .Fortran()
  • First argument is the Fortran function name e.g. add_
  • x and y arguments are passed through from the R function
  • the third argument to the function is space in which to store the result i.e. numeric(1)
  • .Fortran() returns as many arguments as you gave it originally
  • We only want to return the actual result, which is the third argument, hence [[3]]
  • @useDynLib [packagename] [Fortran function name] is used to generate the NAMESPACE entry useDynLib(simplefortran, add_)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#' Add two numbers
#'
#' @param x,y numbers to add
#'
#' @useDynLib simplefortran add_
#' @export
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
add_Fortran <- function(x, y) {
  .Fortran(add_, x, y, numeric(1))[[3]]
}

What’s in the Fortran functions?

  • Actual result must be stored in one of the arguments
        subroutine add_(x, y, answer)
c
c add 2 numbers
c
        double precision x, y, answer

        answer = x + y

        end

How do R variables map to Fortran variables?

R Fortran
logical INTEGER
integer INTEGER
double DOUBLE PRECISION
complex DOUBLE COMPLEX
character CHARACTER(255)
raw (none)

What does the Fortran function look like in R?

  • An object of class NativeSymbolInfo
  • Holds an externalptr to the loaded function
simplefortran:::add_
#> $name
#> [1] "add_"
#> 
#> $address
#> <pointer: 0x1055e3ec0>
#> attr(,"class")
#> [1] "NativeSymbol"
#> 
#> $dll
#> NULL
#> 
#> attr(,"class")
#> [1] "NativeSymbolInfo"

Resources

Acknowledgements

  • R Core for developing and maintaining such a wonderful language.
  • CRAN maintainers, for patiently shepherding packages onto CRAN and maintaining the repository

About

Demo of how Fortran code could be included in an R package

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published