Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing two-dimensional array to a function in julia

Tags:

arrays

julia

I have a three dimensional array defined as:

x=zeros(Float64,2,2,2)

I want to assign ones to x by passing x to a function, one layer at a time. The function is:

function init(p,y)
   y=ones(p,p)
end

and I will pass x as follows:

for k=1:2
   init(2,x[2,2,k])
end

but when I do that, x is zeros, not ones. Why?

julia> x
2x2x2 Array{Float64,3}:
[:, :, 1] =
 0.0  0.0
 0.0  0.0

[:, :, 2] =
 0.0  0.0
 0.0  0.0

Any idea how to get Julia to assign ones to x?

like image 342
Amal Avatar asked Sep 08 '15 19:09

Amal


3 Answers

One possible solution is to use slice, which makes a SubArray:

x = zeros(2, 2, 2)  # Float64 by default

function init!(y)
    y[:] = ones(y)  # change contents not binding
end

for k in 1:2
    init!(slice(x, :, :, k))  # use slice to get SubArray 
end

Note that you can use ones(y) to get a vector of ones of the same size as y.

A SubArray gives a view of an array, instead of a copy. In future versions of Julia, indexing an array may give this by default, but currently you must do it explicitly.

For a discussion about values vs. bindings, see

http://www.johnmyleswhite.com/notebook/2014/09/06/values-vs-bindings-the-map-is-not-the-territory/

EDIT: I hadn't seen @tholy's answer, which contains the same idea.

like image 186
David P. Sanders Avatar answered Sep 24 '22 19:09

David P. Sanders


I'm also not sure I understand the question, but slice(x, :, :, k) will take a 2d slice of x.

If you're initializing x as an array of Float64 and then hoping to assign a matrix to each element (which is what it appears you're trying to do), that won't work---the type of x won't allow it. You could make x an array of Any, and then that would be permitted.

like image 38
tholy Avatar answered Sep 23 '22 19:09

tholy


I'm not certain I understand, but if you're trying to modify x in place, you'll want to do things a little differently.

The code below should do what you need.

x = zeros(Float64, 2, 2, 2)

function init!(p, y, k) 
    y[:, :, k] = ones(Float64, p, p) 
end


for k = 1:2
   init!(2, x, k)
end

And you might also want to keep in mind that the standard convention in Julia is to include an exclamation mark in the name of a function that modifies its arguments. And if I've understood your question, then you want your init!() function to do exactly that.

like image 39
paulstey Avatar answered Sep 24 '22 19:09

paulstey