Passing functions in R as .Fortran arguments - r

After spending some days already searching for something like this on the internet, I still couldn't manage to find anything describing this problem. Reading through the (otherwise quite recommendable) 'Writing R Extensions' dind't offer a solution as well. Thus, here's my most urgent question:
Is it possible to pass functions (for simplicity's sake, assume a simple R function - in reality, the problem is even uglier) as function/subroutine parameters to Fortran via .Fortran(...) call - and if so, how?
I wrote two simple functions in order to test this, first a Fortran subroutine (tailored to use the function I originally intended to pass, thus the kinda weird dimensions in the interface):
subroutine foo(o, x)
implicit none
interface
subroutine o(t, y, param, f)
double precision, intent(in) :: t
double precision, dimension(58), intent(in) :: y, param
double precision, dimension(22), intent(out) :: f
end subroutine
end interface
double precision, dimension(22), intent(out) :: x
double precision, dimension(58) :: yt, paramt
integer :: i
do i = 1, 58
yt(i) = rand(0)
paramt(i) = rand(1)
end do
call o(dble(4.2), yt, paramt, x)
end subroutine
and a simple R function to pass to the above function:
asdf <- function(a, s, d, f){x <- c(a, s, d, f)}
Calling .Fortran("foo", asdf, vector(mode="numeric", length=22)) yields
Error: invalid mode (closure) to pass to Fortran (arg 1) and passing "asdf" (as a string) results in a segfault, as the argument obviously doesn't fit the expected type (namely, a function).
FYI, I don't expect the code to do anything meaningful (that would be the task of another function), I mainly would like to know, whether passing functions (or function pointers) from R is possible at all or wether I better give up on this approach instantly and look for something that might work.
Thanks in advance,
Dean

You can't pass R objects via .Fortran. You would need to use the .Call or .External interface to pass the R objects to C/C++ code.
You could write a C/C++ wrapper for your R function, which you could then call from your Fortran code (see Calling-C-from-FORTRAN-and-vice-versa in Writing R Extensions).

Related

Fortran epsilon function equivalent in Julia

I'm starting to learn Julia, and I was wondering if there is an equivalent function in Julia that is doing the same as the epsilon function in Fortran.
In Fortran, the epsilon function of variable x gives the smallest number of the same kind of x that satisfies 1+epsilon(x)>1
I thought the the function eps() in Julia would be something similar, so I tried
eps(typeof(x))
but I got the error:
MethodError: no method matching eps(::Type{Int64})
Is there any other function that resembles the Fortran one that can be used on the different variables of the code?
If you really need eps to work for both Float and Int types, you can overload a method of eps for Int by writing Base.eps(Int) = one(Int). Then your code will work. This is okay for personal projects, but not a good idea for code you intend to share.
As the docstring for eps says:
help?> eps
eps(::Type{T}) where T<:AbstractFloat
eps()
eps is only defined for subtypes of AbstractFloat i.e. floating point numbers. It seems that your variable x is an integer variable, as the error message says no method matching eps(::Type{Int64}). It doesn't really make sense to define an eps for integers since the "the smallest number of the same kind of x that satisfies 1 + epsilon(x) > 1" is always going to be 1 for integers.
If you did want to get a 1 of the specific type of integer you have, you can use the one function instead:
julia> x = UInt8(42)
0x2a
julia> one(typeof(x))
0x01
It seems like what you actually want is
eps(x)
not
eps(typeof(x))
The former is exactly equivalent to your Fortran function.

Fast multi-dimensional Walsh-Hadamard transforms in Julia?

I was looking for a fast implementation of FWHT(Fast Walsh-Hadamard transformation) to understand it and implement it in python (implementation should be able to handle an n-dimensional array and should be able to apply the transformation on any specific set of dimensions).
I came across the Julia implementation (https://github.com/stevengj/Hadamard.jl) which seems to be pretty good but as I am new to Julia I am not able to understand a part of the code:
for (Tr,Tc,fftw,lib) in ((:Float64,:Complex128,"fftw",FFTW.libfftw),
(:Float32,:Complex64,"fftwf",FFTW.libfftwf))
#eval function Plan_Hadamard{N}(X::StridedArray{$Tc,N}, Y::StridedArray{$Tc,N},
region, flags::Unsigned, timelimit::Real,
bitreverse::Bool)
set_timelimit($Tr, timelimit)
dims, howmany = dims_howmany(X, Y, [size(X)...], region)
dims = hadamardize(dims, bitreverse)
plan = ccall(($(string(fftw,"_plan_guru64_dft")),$lib),
PlanPtr,
(Int32, Ptr{Int}, Int32, Ptr{Int},
Ptr{$Tc}, Ptr{$Tc}, Int32, UInt32),
size(dims,2), dims, size(howmany,2), howmany,
X, Y, FFTW.FORWARD, flags)
set_timelimit($Tr, NO_TIMELIMIT)
if plan == C_NULL
error("FFTW could not create plan") # shouldn't normally happen
end
return cFFTWPlan{$Tc,FFTW.FORWARD,X===Y,N}(plan, flags, region, X, Y)
end
#eval function Plan_Hadamard{N}(X::StridedArray{$Tr,N}, Y::StridedArray{$Tr,N},
region, flags::Unsigned, timelimit::Real,
bitreverse::Bool)
set_timelimit($Tr, timelimit)
dims, howmany = dims_howmany(X, Y, [size(X)...], region)
dims = hadamardize(dims, bitreverse)
kind = Array{Int32}(size(dims,2))
kind[:] = R2HC
plan = ccall(($(string(fftw,"_plan_guru64_r2r")),$lib),
PlanPtr,
(Int32, Ptr{Int}, Int32, Ptr{Int},
Ptr{$Tr}, Ptr{$Tr}, Ptr{Int32}, UInt32),
size(dims,2), dims, size(howmany,2), howmany,
X, Y, kind, flags)
set_timelimit($Tr, NO_TIMELIMIT)
if plan == C_NULL
error("FFTW could not create plan") # shouldn't normally happen
end
return r2rFFTWPlan{$Tr,(map(Int,kind)...),X===Y,N}(plan, flags, region, X, Y)
end
end
In the above code what is the plan variable, how is it used, and where can I find its implementation?
What are the inputs in the curly braces for the below line?
cFFTWPlan{$Tc,FFTW.FORWARD,X===Y,N}
This is constructing an FFTW "plan" to perform a multidimensional FFT. The cFFTWPlan type is a wrapper around the C fftw_plan pointer, and is implemented in the FFTW.jl module. The arguments in curly braces are Julia type parameters: in this case, indicating the number type (Tc), the FFTW transform direction FORWARD, whether the transform is in-place (X===Y), and the dimensionality of the transform (N). There are two methods here, one for an FWHT of complex-number data that creates a cFFTWPlan (which calls fftw_plan_guru_dft) and one for real-number data that creates an r2rFFTWPlan (which calls fftw_plan_guru_r2r). (These internal types of FFTW.jl are undocumented. The low-level C calls directly to the FFTW library are documented in the FFTW manual.
It should, in principle, be possible to make similar calls to FFTW for NumPy arrays. However, the existing pyFFTW wrappers don't seem to support FFTW's r2r transforms (needed for FWHTs of real data), so you'd have to add that.
Or you could call the Julia Hadamard.jl module from Python via the pyjulia package. Or you could use some other Python FWHT package, like https://github.com/FALCONN-LIB/FFHT

Calling .Fortran from R with helper functions

I have a two-part question that might brush on preferred habits, and whether I'm unnecessarily complicating a problem. I've been using .C and learned .Call to do the heavy lifting from R. I wanted to do a comparison with .Fortran, and so I've been learning it as I go. Therefore, my issue may be due to my limited Fortran knowledge.
There are several functions implemented in R that I'd like to translate to Fortran that are related to each other. Rather than hash out the details of the problem I've created a minimum synonymous example that's impractical but a good illustration.
I have two functions and two related subroutines to find the magnitude and squared-magnitude, which make the entirety of the file:
! Actual functions
real function sumofsquaresfun (x,y)
implicit none
real :: x,y
sumofsquaresfun=x*x+y*y
end function sumofsquaresfun
real function magnitudefun(x,y)
implicit none
real :: x,y,tmp
tmp=sumofsquaresfun(x,y)
magnitudefun=sqrt(tmp)
end function magnitudefun
! Wrappers for R accessibility since R requires subroutines
subroutine sumofsquares(x,y,answer)
implicit none
real :: x,y
real answer
answer=sumofsquaresfun(x,y)
end subroutine sumofsquares
subroutine magnitude(x,y,answer)
implicit none
real :: x,y
real answer
answer=magnitudefun(x,y)
end subroutine magnitude
Suppose that both subroutines are useful when I'm in R, so keeping the two separate is important.
When I try t compile using
R CMD SHLIB fortrancode.f95
I have several errors the same two types of errors:
Error: Return type mismatch of function 'sumofsquaresfun' at (1) (UNKNOWN/REAL(4))
Error: Function 'sumofsquaresfun' at (1) has no IMPLICIT type
etc.
My questions in order of importance:
Even if feasible, is this the preferred approach to such a problem? Should I be using modules instead? I've seen this discussion (using a Fortran module in R?) and the related one by the same OP but don't know if involving modules is necessary/optimal.
If what I am trying to do is the correct way, what causes these embarrassing errors?
I like to use functions because that's what they're meant for, but am I being too much of a purist by creating the subroutine wrappers? Is it better style to just do away with them so I only have the two subroutines?
Many thanks!
This is more of a Fortran question than an R question.
You haven't declared the functions in your subroutines.
Do it like this and it should compile.
! Actual functions
real function sumofsquaresfun (x,y)
implicit none
real :: x,y
sumofsquaresfun=x*x+y*y
end function sumofsquaresfun
real function magnitudefun(x,y)
implicit none
real :: x,y,tmp
real sumofsquaresfun
tmp=sumofsquaresfun(x,y)
magnitudefun=sqrt(tmp)
end function magnitudefun
! Wrappers for R accessibility since R requires subroutines
subroutine sumofsquares(x,y,answer)
implicit none
real :: x,y
real answer
real sumofsquaresfun
answer=sumofsquaresfun(x,y)
end subroutine sumofsquares
subroutine magnitude(x,y,answer)
implicit none
real :: x,y
real answer
real magnitudefun
answer=magnitudefun(x,y)
end subroutine magnitude
Warning: You are using real but don't forget that R uses double precision. real is single precision. You should use something like real*8 or the Fortran95 equivalent of that.

Fortran Pointer arithmetic

That's my first question post ever ... don't be cruel, please.
My problem is the following. I'd like to assign a fortran pointer as an expression. I think that's not possible by simple fortran techniques. But since new fortran versions seem to provide ways to handle things used in C and C++ (like c_ptr and c_f_pointer ... ), maybe someone knows a way to solve my problem. (I have not really in idea about C, but I read that pointer arithmetic is possible in C)
To make things more clear, here is the code which came to my mind immediately but isn't working:
program pointer
real(8),target :: a
real(8),pointer :: b
b=>a*2.0d0 ! b=>a is of course working
do i=1,10
a=dble(i)*2.0d0
write(*,*)b
end do
end program
I know that there are ways around this issue, but in the actual program, all of which came to my mind, would lead to much longer computation time and/or quite wiered code.
Thanks, a lot, in advance!
Best, Peter
From Michael Metcalf,
Pointers are variables with the POINTER attribute; they are not a distinct data type (and so no 'pointer arithmetic' is possible).
They are conceptually a descriptor listing the attributes of the objects (targets) that the pointer may point to, and the address, if any, of a target. They have no associated storage until it is allocated or otherwise associated (by pointer assignment, see below):
So your idea of b=>a*2 doesn't work because b is being assigned to a and not given the value of a.
Expression, in general (there two and a half very significant exceptions), are not valid pointer targets. Evaluation of an expression (in general) yields a value, not an object.
(The exceptions relate to the case where the overall expression results in a reference to a function with a data pointer result - in that case the expression can be used on the right hand side of a pointer assignment statement, or as the actual argument in a procedure reference that correspond to a pointer dummy argument or [perhaps - and F2008 only] in any context where a variable might be required, such as the left hand side of an ordinary assignment statement. But your expressions do not result in such a function reference and I don't think the use cases are relevant to what you wnt to do. )
I think you want the value of b to change as the "underlying" value of a changes, as per the form of the initial expression. Beyond the valid pointer target issue, this requires behaviour contrary to one of the basic principles of the language (most languages really) - evaluation of an expression uses the value of its primaries at the time the expression is evaluation - subsequent changes in those primaries do not result in a change in the historically evaluated value.
Instead, consider writing a function that calculates b based on a.
program pointer
IMPLICIT NONE
real(8) :: a
do i=1,10
a=dble(i)*2.0d0
write(*,*) b(a)
end do
contains
function b(x)
real(kind(a)), intent(in) :: x
real(kind(a)) :: b
b = 2.0d0 * x
end function b
end program
Update: I'm getting closer to what I wanted to have (for those who are interested):
module test
real,target :: a
real, pointer :: c
abstract interface
function func()
real :: func
end function func
end interface
procedure (func), pointer :: f => null ()
contains
function f1()
real,target :: f1
c=>a
f1 = 2.0*c
return
end function f1
end module
program test_func_ptrs
use test
implicit none
integer::i
f=>f1
do i=1,10
a=real(i)*2.0
write(*,*)f()
end do
end program test_func_ptrs
I would be completely satisfied if I could find a way to avoid the dummy arguments (at least in when I'm calling f).
Additional information: The point is that I want to define different functions f1 and deside before starting the loop, what f is going to be inside of the loop (depending on whatever input).
Pointer arithmetic, in the sense of calculating address offsets from a pointer, is not allowed in Fortran. Pointer arithmetic can easily cause memory errors and the authors of Fortran considered it unnecessary. (One could do it via the back door of interoperability with C.)
Pointers in Fortran are useful for passing procedures as arguments, setting up data structures such as linked lists (e.g., How can I implement a linked list in fortran 2003-2008), etc.

R & Fortran call

I don't have experience with Fortran, but I am trying to run a very simple loop in that language by calling it from R via the .Fortran() function. Whenever I run the last line of the R code that is pasted below, the R gui crashes and I get no result. I am interest in bringing back the vector of real values x from Fortran into R for further analysis. g is a numeric value between 0 and 1, and n an integer, and they are both supplied by the user in R.
Any help would be much appreciated! Best,
Vincent
Fortran code saved in bar.f:
subroutine bar(n, g, x)
integer n
double precision g
double precision x(n)
integer i
x(1)=1
do 100 i = 2, n
x(i) = x(i-1) * g + 1
100 continue
end
Compiling the DLL in Cygwin with gfortran:
gfortran -shared -obar.dll bar.f
R code:
dyn.load("d:/bar.dll")
is.loaded("bar")
.Fortran("bar", n=as.integer(15), g=as.double(5), x=as.double(rnorm(5)))
When I compile your code, I can execute the call to .Fortran once. When I run it a second time, it crashes. However, I noticed that if I make the vector passed for x the same length as the integer passed for n suggests it should be, i.e:
.Fortran('bar', n = as.integer(15), g = as.double (5), x = as.double(rnorm(15)) )
I can run the function as many times as I want. So the problem may be that you are telling the Fortran routine it has a vector of length 15 to work with, but are only sending in a vector of length 5. This could be causing the Fortran routine to access memory it is not supposed to which would explain a crash.
Since it looks like you are generating all values of x in the routine anyway, you could skip generating random numbers and just send in an empty vector using R's double(n) function, where n is the length of the empty vector you want to generate:
.Fortran('bar', n = as.integer(15), g = as.double(5), x = double(15))
integer and character are useful functions that return vectors like double.
Also some friendly suggestions concerning Fortran style since you mention you are just getting started with the language:
It might be wise to name your files with a .f90 extension---files ending in .f are assumed by most compilers to adhere to the old "fixed-form" format which is a PITA as it was designed to be used on punch cards.
The Do 100 ... 100 continue statements are an style of ending loops in Fortran 77. The modern equivalent is Do .. end do.
With Fortran functions and subroutines, it is wise to declare the "intent" of variables passing in and out of the routine. The available intent declarations are:
intent(in): Signifies variables that are entering the routine only as inputs. Once inside the routine, they should be treated as parameters and the compiler will raise an error if any attempt is made to change them.
intent(out): Signifies variables whose values should be generated inside the routine as outputs. The compiler will issue a warning if an intent out variable is not assigned within the routine.
intent(inout): Signifies variables that may enter the routine carrying a certain set of values and leave the routine with different values.
Setting intents on variables will help the compiler generate warnings and errors that may save you some bug hunting.
Fortran has a default behavior where any variable not declared in the header of the routine will be an integer if its name starts with i-n and real otherwise. This can cause misspelled variable names to "magically" become variables without the compiler batting an eye or telling you. Setting implicit none at the top of your routines disables this behavior and allows the compiler to notify you of mistakes that can be very hard to track down otherwise.
A version of your subroutine that takes these suggestions into account would look like the following:
subroutine bar(n, g, x)
implicit none
integer, intent(in):: n
double precision, intent(in):: g
double precision, intent(inout):: x(n)
integer:: i
x(1) = 1
do i = 2, n
x(i) = x(i - 1) * g + 1
end do
end subroutine bar
Also, it is useful to let R compile your libraries using the SHLIB subcommand of R CMD:
R CMD SHLIB -o bar.dll bar.f90
This will compile your programs against the R libraries which contain useful functions---such as BLAS routines, stats routines and methods that can print information to the R console. See Writing R Extensions, Section 6 for more info.
Hope this helps!

Resources