Julia, use of map to run a function multiple times, - loops

I have some code that runs fine and does what I want, although there may be a simpler more elegant solution, this works :
round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))
However when I try to execute it multiple times, using map, it throws an error saying it doesn't like the Int16 specification, so this:
map(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
throws this error
ERROR: MethodError: objects of type Int16 are not callable
I just want to run it twice (in this case) and sum the results. Why is it unhappy? Thx. J

The first argument to map is a function. So, with your code, Julia is trying to make a function call:
round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))()
But the output of round(Int16, ...) isn't a function, it's a number, so you cannot call it. That's why the error says "objects of type Int16 are not callable." You could fix this by using an anonymous function:
map(() -> round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
But the "Julian" way to do this is to use a comprehension:
[round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2]
EDIT:
If you are going to sum the results, then you can use something that looks like a comprehension but is called a generator expression. This is basically everything above with the [ ] around the expression. A generator expression can be used directly in functions like sum or mean, etc.
sum(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2)
The advantage to generator expressions is that they don't allocate the memory for the full array. So, if you did this 100 times and used the sum approach above, you wouldn't need to allocate space for 100 numbers.
This goes beyond the original question, but OP wanted to use the sum expression where the 2 in 1:2 is a 1-element vector. Of course, if the input is always a 1-element vector, then I recommend first(x) like the comments. But this is a nice opportunity to show the importance of breaking things down into functions frequently in Julia. For example, you could take the entire sum expression and define a function
generatenumbers(n::Integer) = sum(... for _ in 1:n)
where n is a scalar. Then if you have some odd array expression for n (1-element vector, many such ns in a multi-dim array, etc.), you can just do:
generatenumbers.(ns)
# will apply to each element and return same shape as ns
If the de-sugaring logic is more complex than applying element-wise, you can even define:
generatenumbers(ns::AbstractArray) = # ... something more complex
The point is to define an "atomic" function that expresses the statement or task you want clearly, then use dispatch to apply it to more complicated data-structures that appear in practical code. This is a common design pattern in Julia (not the only option, but an effective one).

Adding on the answer from #darsnack.
If you want to run it multiple times in order to keep the results (it wasn't clear from the question). Then you could also ask rand to produce a vector by doing the following (and also making the type conversion through the floor call).
Moving from:
map(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
to:
floor.(Int16, rand(TruncatedNormal(150,20,50,250), 2))
The documentation is here.

Related

Applying Julia function to nested array of arrays

Is there a simpler way to do apply a function in Julia to nested array than defining a new function? - e.g. for this simple example:
a = collect(1:10)
b = [ a*i for i in 100:100:400]
arraylog(x) = log.(x) ## Need to define an extra function to do the inner array?
arraylog.(b)
I would use a comprehension just like you used it to define b: [log.(x) for x in b].
The benefit of this approach is that such code should be easy to read later.
EDIT
Referring to the answer by Tasos actually a comprehension implicitly defines an anonymous function that is passed to Base.Generator. In this use case a comprehension and map should be largely equivalent.
I assumed that MR_MPI-BGC wanted to avoid defining an anonymous function.
If it were allowed one could also use a double broadcast like this:
(x->log.(x)).(b)
which is even shorer but I thought that it would not be very readable in comparison to a comprehension.
You could define it as a lambda instead.
Obviously the distinction may be moot, depending on how you're using this later in your code, but if all you want is to not waste a line in your code for the sake of conciseness, you could easily dump this inside a map statement, for instance:
map( x->log.(x), b )
or, if you prefer do syntax:
map(b) do x
log.(x)
end
PS. I'm not familiar with a syntax which allows the broadcasted version of a function to be plugged directly into map, but if one exists it would be even cleaner than a lambda here ... but alas 'map( log., b )' is not valid syntax.

Iterating for `setindex!`

I have some specially-defined arrays in Julia which you can think of being just a composition of many arrays. For example:
type CompositeArray{T}
x::Vector{T}
y::Vector{T}
end
with an indexing scheme
getindex(c::CompositeArray,i::Int) = i <= length(c) ? c.x[i] : c.y[i-length(c.x)]
I do have one caveat: the higher indexing scheme just goes to x itself:
getindex(c::CompositeArray,i::Int...) = c.x[i...]
Now the iterator through these can easily be made as the chain of the iterator on x and then on y. This makes iterating through the values have almost no extra cost. However, can something similar be done for iteration to setindex!?
I was thinking of having a separate dispatch on CartesianIndex{2} just for indexing x vs y and the index, and building an eachindex iterator for that, similar to what CatViews.jl does. However, I'm not certain how that will interact with the i... dispatch, or whether it will be useful in this case.
In addition, will broadcasting automatically use this fast iteration scheme if it's built on eachindex?
Edits:
length(c::CompositeArray) = length(c.x) + length(c.y)
In the real case, x can be any AbstractArray (and thus has a linear index), but since only the linear indexing is used (except for that one user-facing getindex function), the problem really boils down to finding out how to do this with x a Vector.
Making X[CartesianIndex(2,1)] mean something different from X[2,1] is certainly not going to end well. And I would expect similar troubles from the fact that X[100,1] may mean something different from X[100] or if length(X) != prod(size(X)). You're free to break the rules, but you shouldn't be surprised when functions in Base and other packages expect you to follow them.
The safe way to do this would be to make eachindex(::CompositeArray) return a custom iterator over objects that you control entirely. Maybe just throw a wrapper around and forward methods to CartesianRange and CartesianIndex{2} if that data structure is helpful. Then when you get one of these custom index types, you know that SplitIndex(CartesianIndex(1,2)) is indeed intending to refer to the first element in the second array.

Racket: Macro outputs something weird instead of an array

My aim is to populate an array in compile phase (i.e. in a macro), and use it in execution phase. For some reason, though, object returned by a macro is not recognized by Racket as an array. To illustrate the problem, shortest code showing this behaviour:
(require (for-syntax math/array))
(require math/array)
(define-syntax (A stx)
(datum->syntax stx `(define a ,(array #[#[1 2] #[3 4]]))))
(A)
After execution of this macro, 'a' is something, but I don't know what it is. It is not an array ((array? a) -> #f) nor a string, array-ref is not working on it, obviously, but it prints as: (array #[#[1 2] #[3 4]]). "class-of" from the "swindle" module claims it is "primitive-class:unknown-primitive", for what it's worth.
I have tried outputting a vector instead of an array, but it works as expected, i.e. resulting value is a vector in execution phase.
I have tried using CommonLisp style defmacro from "compatibility" module, thinking that this may have something to do do with datum->syntax transformation, but this changed nothing.
I have tested this on Win7 with Racket 6.5 and 6.7, as well as on Linux with Racket 6.7 - problem persists.
Any ideas?
update
Thanks to great answers and suggestions, I came up with following solution:
(require (for-syntax math/array))
(require math/array)
(define-syntax (my-array stx)
(syntax-case stx ()
[(_ id)
(let
([arr (build-array
#(20 20)
(lambda (ind)
(let
([x (vector-ref ind 1)]
[y (vector-ref ind 0)])
(list 'some-symbol x y (* x y)))))])
(with-syntax ([syn-arr (eval (read (open-input-string (string-append "#'" (format "~v" arr)))))])
#'(define id syn-arr)))]))
(my-array A)
I'm not sure if this is proper Racket (I welcome all suggestions on code improvement) but here is how it works:
Array is built and stored in "arr" variable. It is then printed to string, prepended with #' (so that this string represents syntax object now) and evaluated as code. This effectively converts array to syntax object, that can be embedded in macro output.
Advantage of this approach is, that every object that can be written out and then read back by Racket can be output by macro. Disadvantage is, that some objects can't (I'm looking at you, custom struct!) and therefore additional string-creating function may be required in some cases.
First of all, don’t use datum->syntax like that. You’re throwing away all hygiene information there, so if someone was using a different language where define was called something else (like def, for example), that would not work. For a principled introduction to Racket macros, consider reading Fear of Macros.
Second of all, the issue here is that you are creating what is sometimes known as “3D syntax”. 3D syntax should probably be an error in this context, but the gist is that there is only a small set of things that you can safely put inside of a syntax object:
a symbol
a number
a boolean
a character
a string
the empty list
a pair of two pieces of valid syntax
a vector of valid syntax
a box of valid syntax
a hash table of valid syntax keys and values
a prefab struct containing exclusively valid syntax
Anything else is “3D syntax”, which is illegal as the output of a macro. Notably, arrays from math/array are not permitted.
This seems like a rather extreme limitation, but the point is that the above list is simply the list of things that can end up in compiled code. Racket does not know how to serialize arbitrary things to bytecode, which is reasonable: it wouldn’t make much sense to embed a closure in compiled code, for example. However, it’s perfectly reasonable to produce an expression that creates an array, which is what you should do here.
Writing your macro more properly, you would get something like this:
#lang racket
(require math/array)
(define-syntax (define-simple-array stx)
(syntax-case stx ()
[(_ id)
#'(define id (array #(#(1 2) #(3 4))))]))
(define-simple-array x)
Now, x is (array #[#[1 2] #[3 4]]). Note that you can remove the for-syntax import of math/array, since you are no longer using it at compile time, which makes sense: macros just manipulate bits of code. You only need math/array at runtime to create the actual value you end up with.

Explanation of splat

While reading about Julia on http://learnxinyminutes.com/docs/julia/ I came across this:
# You can define functions that take a variable number of
# positional arguments
function varargs(args...)
return args
# use the keyword return to return anywhere in the function
end
# => varargs (generic function with 1 method)
varargs(1,2,3) # => (1,2,3)
# The ... is called a splat.
# We just used it in a function definition.
# It can also be used in a fuction call,
# where it will splat an Array or Tuple's contents into the argument list.
Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # produces a Set of Arrays
Set([1,2,3]...) # => Set{Int64}(1,2,3) # this is equivalent to Set(1,2,3)
x = (1,2,3) # => (1,2,3)
Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # a Set of Tuples
Set(x...) # => Set{Int64}(2,3,1)
Which I'm sure is a perfectly good explanation, however I fail to grasp the main idea/benefits.
From what I understand so far:
Using a splat in a function definition allows us to specify that we have no clue how many input arguments the function will be given, could be 1, could be 1000. Don't really see the benefit of this, but at least I understand (I hope) the concept of this.
Using a splat as an input argument to a function does... What exactly? And why would I use it? If I had to input an array's contents into the argument list, I would use this syntax instead: some_array(:,:) (for 3D arrays i would use some_array(:,:,:) etc.).
I think part of the reason why I don't understand this is that I'm struggling with the definition of tuples and arrays, are tuples and arrays data types (like Int64 is a data type) in Julia? Or are they data structures, and what is a data structure? When I hear array I typically think about a 2D matrix, perhaps not the best way to imagine arrays in a programming context?
I realize that you could probably write entire books about what a data structure is, and I could certainly Google it, however I find that people with a profound understanding of a subject are able to explain it in a much more succinct (and perhaps simplified) way then let's say the wikipedia article could, which is why I'm asking you guys (and girls).
You seem like you get the mechanism and how/what they do but are struggling with what you would use it for. I get that.
I find them useful for things where I need to pass an unknown number of arguments and don't want to have to bother constructing an array first before passing it in when working with the function interactively.
for instance:
func geturls(urls::Vector)
# some code to retrieve URL's from the network
end
geturls(urls...) = geturls([urls...])
# slightly nicer to type than building up an array first then passing it in.
geturls("http://google.com", "http://facebook.com")
# when we already have a vector we can pass that in as well since julia has method dispatch
geturls(urlvector)
So a few things to note. Splat's allow you to turn an iterable into an array and vice versa. See the [urls...] bit above? Julia turns that into a Vector with the urls tuple expanded which turns out to be much more useful than the argument splatting itself in my experience.
This is just 1 example of where they've proved useful to me. As you use julia you'll run across more.
It's mostly there to aid in designing api's that feel natural to use.

matlab: structural data and multi-level indexing

I have a simple problem with structures.
Lets create:
x(1).a(:, :) = magic(2);
x(2).a(:, :) = magic(2)*2;
x(3).a(:, :) = magic(2)*3;
how to list a(1, 1) from all x-es?
i wanted to do it like:
x(1, :).a(1,1)
but there is an error "Scalar index required for this type of multi-level indexing."
How to approach it? I know I can do it with a loop, but that's probably the worst solution :)
Thanks!
This is not the best datastructure to use if this is the sort of query you'd like to make on it, precisely because this sort of indexing cannot be done directly.
However, here is one approach that works:
cellfun(#(X) X(1,1), {x.a})
The syntax {x.a} converts x from a 'struct array' into a cell array. Then we use cellfun to apply a function as a map over the cell array. The anonymous function #(X) X(1,1) takes one argument X and returns X(1,1).
You can also get your data in this way:
B = cat(3,x.a);
out = reshape(B(1,1,:),1,[]);
By the way, loops are not evil. Sometimes they are even faster than vectorized indexation. Try it both ways, see what suits you best in terms of:
Speed - use the profiler to check
Code clarity - depends on the context. Sometimes vectorized code looks better, sometimes the opposite.

Resources