Julia macros may treat variable and literals differently? - julia

Hi fellow Julia users,
Why does this
using HDF5, JLD
s = "It would take me 48 hours to recompute this."
filename_no_ext = "eric_demo_file"
#save filename_no_ext
readdir()
#load "eric_demo_file"
evaluate differently from this?
using HDF5, JLD
s = "It would take me 48 hours to recompute this."
filename_no_ext = "eric_demo_file"
#save filename_no_ext
readdir()
#load filename_no_ext

Macros are very different beasts compared to functions. One of the differences is that they do not evaluate their arguments: http://docs.julialang.org/en/latest/manual/metaprogramming/#macro-invocation
It is important to emphasize that macros receive their arguments as expressions, literals, or symbols.
To see the implications compare the 2 outputs (left as an exercise):
julia> macroexpand(:(#load filename_no_ext))
julia> macroexpand(:(#load "eric_demo_file"))

Related

Julia: methods and DataArrays.DataArray

I would like to write a function fun1 with a DataArrays.DataArray y as unique argument. y can be either an integer or a float (in vector or in matrix form).
I have tried to follow the suggestions I have found in stackoverflow (Functions that take DataArrays and Arrays as arguments in Julia) and in the official documentation (http://docs.julialang.org/en/release-0.5/manual/methods/). However, I couldn't write a code enought flexible to deal with the uncertainty around y.
I would like to have something like (but capable of handling numerical DataArrays.DataArray):
function fun1(y::Number)
println(y);
end
Any suggestion?
One options can be to define:
fun1{T<:Number}(yvec::DataArray{T}) = foreach(println,yvec)
Then,
using DataArrays
v = DataArray(rand(10))
w = DataArray(rand(1:10,10))
fun1(v)
#
# elements of v printed as Flaot64s
#
fun1(w)
#
# elements of w printed as Ints
#
A delicate but recurring point to note is the invariance of Julia parametric types which necessitate defining a parametric function. A look at the documentation regarding types should clarify this concept (http://docs.julialang.org/en/release-0.4/manual/types/#types).

Passing character as variable name in R

I am trying to solve an implicit equation in R using multiroot function from package rootSolve.
I am reading the implicit equation from a text file using parse. Also, the variable to be solved for is read from a text file as a character.
For using multiroot,
multiroot(function, initial_guess, ....))
we have to generate a function from the read equation. I did this by
fun <- function(op) {fun <- eval(expr.im)}
op = as.name(opim.names)
where expr.im is the read implicit equation as an expression from the text file, and opim.names is the variable to be solved for, as character.
But the problem arises when I pass the variable op to be solved as a symbol to the function. It gives an error saying that the object
"variable to be solved for" not found.
I think that the variable symbol is not being passed correctly in the function.
Please tell me how to do it correctly.
Since a lot of stuff is going on in my code, I cannot post the whole thing here.
Let me just state a small example for it.
var.name = "x1" # This is what I read from the text file #
var.sym = as.name(var.name)
func <- function(var.sym){
func = x1^2 # the expression x1^2 is also read from a text file #
} # I am trying to solve the implicit equation x1^2 = 0 #
initial_guess = 1
root = multiroot(f=func, start = initial_guess)
As requested by nicola here's what I want -
I have a text file giving me the name of the variable and its initial guess.
I read the variable name (say "x") and the initial guess value (say 1) into variables var (character) and guess(numeric).
I also have another text file containing the following equation -
x^3-1
I read this as an expression in the variable expr.
I want to find the solution to the implicit equation expr.
(The text files can have different names of variables and correspondingly an implicit expression in another file)
As you know, for using the multiroot function, we need to have a function.
The problem is I am not able to pass the variable name stored in var to the function.
Any further clarification will be given if asked.
You can build your function in the following way.
#input: function expression, variable names and initial guess
expr<-"x^3-1"
var.name<-"x"
initial.guess<-2
#we build an "empty" function
func<-function() {}
#now we set the formal arguments and the body of the function
formals(func)<-eval(parse(text=paste0("alist(",paste(var.name,collapse="=,"),"=)")))
body(func)<-parse(text=expr)
#we can see that func is correctly defined
func
#function (x)
#x^3 - 1
#now we can call multiroot
multiroot(func,initial.guess)
#$root
#[1] 1
#$f.root
#[1] 3.733019e-08
#$iter
#[1] 6
#$estim.precis
#[1] 3.733019e-08
You need a little more care if you are dealing with function of more than one variable. See ?multiroot to check how to pass the arguments. Basically you have to pass just one argument which is a vector of all the function arguments. It shouldn't be difficult if you take some time to see how I managed to build func. If you are exclusively dealing with one variable function, you should use the base uniroot function.
Not able to understand the description fully. But to answer the heading, you can try this procedure-
a = "random_string"
b = "a"
eval(parse(text = b))
[1] "random_string"

Why doesn't rm(ls()) work and "list" is needed?

I just got started learning R with the "datacamp" site and I ran into a syntax misunderstanding at the beginning.
It says that rm(list = ls()) is a very useful command to clear everything from your workspace but I don't understand what list = is for.
a. They haven't yet taught me the meaning of = in R and I didn't find an explanation at the documentation. = is like <-? What's the difference?
b. If the input of rm() can be a list of variables names, and the output of ls() is a list of var names, why can't I just use rm(ls())?
Passing arguments by position vs name
The = symbol plays a special role in naming arguments to a function call.
Consider two essentially identical functions:
f <- function(..., y=3) (2+sum(...))^y
g <- function(y=3, ...) (2+sum(...))^y
If y= is not named, the results are generally different:
f(y=5) # 32
g(y=5) # 32
f(5) # 343
g(5) # 32
rm is like f -- type ?rm to see -- so if you want to call rm(list = ls()), write it out in full.
Representing object names
In most of R, if you write f(g()), evaluation flows naturally:
g() is evaluated to 8 and substituted into f(g()) for f(8)
f(8) is evaluated to 1000
rm breaks this pattern in its unnamed ... arguments, which basically just exist for interactive use. Only manually typed variable names are allowed.† As a result, rm(ls()) won't run.
Hadley Wickham provides another nice example:
ggplot2 <- "plyr"
library(ggplot2) # loads ggplot2, not plyr!
† Okay, you can use the ... without manually typed names, like
do.call(library, as.list(ggplot2)) # loads plyr!
but don't mess with that unless you know what you're doing.

Generate identical random numbers in R and Julia

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

Is there an R port of the testing software QuickCheck?

Now that I find myself spending so much time programming in R, I really want to get back to automated testing (which I learned to do by habit in Perl). Besides being user-friendly, I would also be particularly interested in being able to generate random inputs for tests like Perl's Test::LectroTest or Haskell's QuickCheck. Is there anything similar for R?
See the R package quickcheck on GitHub.
Like Test::LectroTest, the R package quickcheck is a port of QuickCheck, which Koen Claessen and John Hughes wrote for Haskell.
In addition to QuickCheck features, quickcheck also gives a nod to Hadley Wickam's popular testthat R package, by intentionally incorporating his "expectation" functions (which they call "assertions"). In addition to numerical and string tests are tests for failures and warnings, etc.
Here is a simple example using it:
library(quickcheck)
my_square <- function(x){x^2} # the function to test
test( function(x = rinteger()) min(my_square(x)) >= 0 )
# Pass function (x = rinteger())
# min(my_square(x)) >= 0
# [1] TRUE
test( function(x = rdouble())
all.equal(
my_square(x),
x^2
)
)
# Pass function (x = rdouble())
# all.equal(my_square(x), x^2)
# [1] TRUE
The first test ensures that anything generated by my_square is positive. The second test actually replicates the functionality of my_square and checks every output to make sure it is correct.
Note that rinteger() produces a vector of any length consisting of integer values. Other randomly generated input data can be produced using functions like rcharacter, rdouble, and rmatrix.

Resources