I am having trouble handling reals in Fortran, which I use together with R. The following code is written in Fortran:
Subroutine realtest(lol)
implicit none
Real lol
lol = 10.0
End
I compile with the command R CMD SHLIB realtest.f. If I run the shared object in R as:
dyn.load("realtest.so")
res <- .Fortran("realtest",lol= as.numeric(1.2))
The resulting value of lol is 1.2, but it should have been 10. If I do the whole thing with Integers instead, I get the correct value 10.
Try using double precision instead of real; the following works for me:
! realtest.f90
!
subroutine realtest(x)
implicit none
double precision, intent(inout) :: x
x = 10.0
end subroutine realtest
From R,
dyn.load("realtest.so")
res <- .Fortran("realtest", x = as.double(1.2))
res
# $x
# [1] 10
You should declare lol as real*8 since R uses double-precision floating-point number.
Related
I'm running Function Accuracy Test tool (in Julia 1.7.2 on 64-bit Ubuntu 18.04) and test sin() function. Problem is the result sin(x...) and sin(big, x)...) which function calls gives.
Here's an example of few input values (Float16):
( Range: -0.7853982f0:1.570798f-6:0.7853982f0 )
x -0.7853982
Comparison: sin(x...) -0.70710677 vs sin(map(big, x)...) -0.7071067966408574982218873068639201062404313604169267415232690981467895117867091
x -0.78539664
Comparison: sin(x...) -0.7071057 vs sin(map(big, x)...) -0.7071057008219710592610583916121386335507498121453599174530436043153324651900249
x -0.785395
Comparison: sin(x...) -0.70710456 vs sin(map(big, x)...) -0.7071045628544069335831518159655666916535017380441150694175707960861677701383995
x -0.7853935
Comparison: sin(x...) -0.7071035 vs sin(map(big, x)...) -0.7071034670320587628440324684003875993008018017656187324934698375469763027284935
Debug data for the first x value:
Wolfram|Alpha (and Octave) gives different results:
sin(-0.7853982) = -0.707106807068459559730712471249650919086696271494555843865775956...
sin(-0.78539664)= -0.707105703981060877385398550052561039837195399228112767226085558...
sin(-0.785395) = -0.707104544323222201909737214474462553610953144479787635566743062...
sin(-0.7853935) = -0.707103483658899645499967038364728301664644014034519844381265599...
Octave results are equal with Wolfram|Alpha.
Which results are correct?
How (with what number type) can I get equal results from Julia?
This is just you taking the sin of different numbers. -0.7853982f0!=-0.7853982!=big"-0.7853982". The key is that most numbers with decimals aren't exactly representable as binary floating point numbers. -0.7853982f0 is the closest Float32 to the decimal number. -0.7853982 is the closest Float64 value, and big"-0.7853982" is the closest BigFloat. The way FunctionAccuracyTests works is it tests the function against the bigfloat version of x, not the bigfloat version of the decimal number that x was close to. This is what you want for testing accuracy of functions, but is a little confusing here.
I am having trouble handling reals in Fortran, which I use together with R. The following code is written in Fortran:
Subroutine realtest(lol)
implicit none
Real lol
lol = 10.0
End
I compile with the command R CMD SHLIB realtest.f. If I run the shared object in R as:
dyn.load("realtest.so")
res <- .Fortran("realtest",lol= as.numeric(1.2))
The resulting value of lol is 1.2, but it should have been 10. If I do the whole thing with Integers instead, I get the correct value 10.
Try using double precision instead of real; the following works for me:
! realtest.f90
!
subroutine realtest(x)
implicit none
double precision, intent(inout) :: x
x = 10.0
end subroutine realtest
From R,
dyn.load("realtest.so")
res <- .Fortran("realtest", x = as.double(1.2))
res
# $x
# [1] 10
You should declare lol as real*8 since R uses double-precision floating-point number.
This is a follow up of my previous question. The difference is that instead of a one dimensional array i want to get a 2 dimensional array.
I have the following Fortran subroutine:
subroutine test(d, i, nMCd, DF, X)
integer, intent(in) :: d, i, nMCd
double precision, intent(in), dimension(i,nMCd) :: DF
double precision, intent(out), dimension(i,nMCd) :: X
X = DF + DF
end subroutine test
In R the code is simple:
input <- data.frame(A=c(11,12), B=c(21, 22))
input + input
and I get a 2 by 2 data frame
I am able to compile it for R load it and run it.
system("R CMD SHLIB ./Fortran/mytest.f90")
dyn.load("./Fortran/mytest.so")
X <- .Fortran("test", d = as.integer(1), i = nrow(input), nMCd = ncol(input), DF = unlist(input), X = numeric(nrow(input)*ncol(input)))$X
But I get a vector of length 4 instead of a 2x2 matrix or data frame. I tried X = numeric(nrow(input), ncol(input)) but it does not work
The only solution I can think is running after I run the fortran function
matrix(X,nrow = nrow(input),ncol = ncol(input))
Thanks!
I've reviewed the documentation for .Fortran, .Call and "Writing R extensions" and have not found any instances where a Fortran subroutine returns a matrix. Furthermore, there is no matrix type in the ?.Fortran help page, so I think my comment(s) might be the best solution:
in R you can also coerce a vector to matrix by adding a dimension: dim(X) <- c(2,2).
Or even with more generality: dim(X) <- dim(input)
Obviously I cannot claim this to be from high authority, since I've not done any Fortran programming before. If you were interested in writing code that interacts with R objects in place, you might want to consider studying the data.table package's code. Most such efforts use C or C++. You might also consider the Rcpp or inline package interfaces. The Fortran interface is mostly used to take advantage of the many numerical functions that have been bullet proofed.
I'd like to generate identical random numbers in R and Julia. Both languages appear to use the Mersenne-Twister library by default, however in Julia 1.0.0:
julia> using Random
julia> Random.seed!(3)
julia> rand()
0.8116984049958615
Produces 0.811..., while in R:
set.seed(3)
runif(1)
produces 0.168.
Any ideas?
Related SO questions here and here.
My use case for those who are interested: Testing new Julia code that requires random number generation (e.g. statistical bootstrapping) by comparing output to that from equivalent libraries in R.
That is an old problem.
Paul Gilbert addressed the same issue in the late 1990s (!!) when trying to assert that simulations in R (then then newcomer) gave the same result as those in S-Plus (then the incumbent).
His solution, and still the golden approach AFAICT: re-implement in fresh code in both languages as the this the only way to ensure identical seeding, state, ... and whatever else affects it.
Pursuing the RCall suggestion made by #Khashaa, it's clear that you can set the seed and get the random numbers from R.
julia> using RCall
julia> RCall.reval("set.seed(3)")
RCall.NilSxp(16777344,Ptr{Void} #0x0a4b6330)
julia> a = zeros(Float64,20);
julia> unsafe_copy!(pointer(a), RCall.reval("runif(20)").pv, 20)
Ptr{Float64} #0x972f4860
julia> map(x -> #printf("%20.15f\n", x), a);
0.168041526339948
0.807516399072483
0.384942351374775
0.327734317164868
0.602100674761459
0.604394054040313
0.124633444240317
0.294600924244151
0.577609919011593
0.630979274399579
0.512015897547826
0.505023914156482
0.534035353455693
0.557249435689300
0.867919487645850
0.829708693316206
0.111449153395370
0.703688358888030
0.897488264366984
0.279732553754002
and from R:
> options(digits=15)
> set.seed(3)
> runif(20)
[1] 0.168041526339948 0.807516399072483 0.384942351374775 0.327734317164868
[5] 0.602100674761459 0.604394054040313 0.124633444240317 0.294600924244151
[9] 0.577609919011593 0.630979274399579 0.512015897547826 0.505023914156482
[13] 0.534035353455693 0.557249435689300 0.867919487645850 0.829708693316206
[17] 0.111449153395370 0.703688358888030 0.897488264366984 0.279732553754002
** EDIT **
Per the suggestion by #ColinTBowers, here's a simpler/cleaner way to access R random numbers from Julia.
julia> using RCall
julia> reval("set.seed(3)");
julia> a = rcopy("runif(20)");
julia> map(x -> #printf("%20.15f\n", x), a);
0.168041526339948
0.807516399072483
0.384942351374775
0.327734317164868
0.602100674761459
0.604394054040313
0.124633444240317
0.294600924244151
0.577609919011593
0.630979274399579
0.512015897547826
0.505023914156482
0.534035353455693
0.557249435689300
0.867919487645850
0.829708693316206
0.111449153395370
0.703688358888030
0.897488264366984
0.279732553754002
See:
?set.seed
"Mersenne-Twister":
From Matsumoto and Nishimura (1998). A twisted GFSR with period 2^19937 - 1 and equidistribution in 623 consecutive dimensions (over the whole period). The ‘seed’ is a 624-dimensional set of 32-bit integers plus a current position in that set.
And you might see if you can link to the same C code from both languages. If you want to see the list/vector, type:
.Random.seed
In MatLab/Octave you could send a command "format long g" and have default numerical output in the REPL formatted like the following:
octave> 95000/0.05
ans = 1900000
Is it possible to get a similar behavior in Julia? Currently with julia
Version 0.3.0-prerelease+3930 (2014-06-28 17:54 UTC)
Commit bdbab62* (6 days old master)
x86_64-redhat-linux
I get the following number format.
julia> 95000/0.05
1.9e6
You can use the #printf macro to format. It behaves like the C printf, but unlike printf for C the type need not agree but is rather converted as necessary. For example
julia> using Printf
julia> #printf("Integer Format: %d",95000/0.05);
Integer Format: 1900000
julia> #printf("As a String: %s",95000/0.05);
As a String: 1.9e6
julia> #printf("As a float with column sized larger than needed:%11.2f",95000/0.05);
As a float with column sized larger than needed: 1900000.00
It is possible to use #printf as the default mechanism in the REPL because the REPL is implemented in Julia in Base.REPL, and in particular the following function:
function display(d::REPLDisplay, ::MIME"text/plain", x)
io = outstream(d.repl)
write(io, answer_color(d.repl))
writemime(io, MIME("text/plain"), x)
println(io)
end
To modify the way Float64 is displayed, you merely need to redefine writemime for Float64.
julia> 95000/0.05
1.9e6
julia> Base.Multimedia.writemime(stream,::MIME"text/plain",x::Float64)=#printf("%1.2f",x)
writemime (generic function with 13 methods)
julia> 95000/0.05
1900000.00