whole arrays pass by reference while matrix columns by value?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

whole arrays pass by reference while matrix columns by value?

Alexandros Fakos
Hi,

a=rand(10,2)
b=rand(10)
sort!(b) modifies b
but sort!(a[:,1]) does not modify the first column of matrix a 

why is that? Does this mean that i cannot write functions that modify their arguments and apply it to columns of matrices?

Is trying to modify columns of matrices bad programming style? Is there a better alternative?
 How much more memory am I allocating if my functions return output instead of modifying their arguments (matlab background - I am completely unaware of memory allocation issues)? 

Thanks,
Alex
Reply | Threaded
Open this post in threaded view
|

Re: whole arrays pass by reference while matrix columns by value?

John Myles White
Everything is pass by sharing.

But array indexing by slices creates copies. 0.5 has better support for creating views.

--John

On Wednesday, September 7, 2016 at 5:00:00 PM UTC-7, Alexandros Fakos wrote:
Hi,

a=rand(10,2)
b=rand(10)
sort!(b) modifies b
but sort!(a[:,1]) does not modify the first column of matrix a 

why is that? Does this mean that i cannot write functions that modify their arguments and apply it to columns of matrices?

Is trying to modify columns of matrices bad programming style? Is there a better alternative?
 How much more memory am I allocating if my functions return output instead of modifying their arguments (matlab background - I am completely unaware of memory allocation issues)? 

Thanks,
Alex
Reply | Threaded
Open this post in threaded view
|

Re: whole arrays pass by reference while matrix columns by value?

vavasis
In 0.4, you can use the sub function to operate on a row or column of an array in place.  See the example below.  The expression a[:,1] in your example makes a copy of the column of a.  The sub function instead makes a view of the existing array.  Therefore, it does not allocate any new memory for the array, although it does create a small object on the heap to keep track of the subarray.  The creation of this small object is usually not an issue unless you use sub in an inner loop to obtain a view of a small subarray (so that the memory allocation of the sub object outweights the benefit of not copying the entries).

-- Steve Vavasis



julia> a = [6 7 ; 4 5]
2x2 Array{Int64,2}:
 6  7
 4  5

julia> sort!(sub(a,1:2,1))
2-element SubArray{Int64,1,Array{Int64,2},Tuple{UnitRange{Int64},Int64},2}:
 4
 6

julia> a
2x2 Array{Int64,2}:
 4  7
 6  5





On Wednesday, September 7, 2016 at 8:03:21 PM UTC-4, John Myles White wrote:
Everything is pass by sharing.

But array indexing by slices creates copies. 0.5 has better support for creating views.

--John

On Wednesday, September 7, 2016 at 5:00:00 PM UTC-7, Alexandros Fakos wrote:
Hi,

a=rand(10,2)
b=rand(10)
sort!(b) modifies b
but sort!(a[:,1]) does not modify the first column of matrix a 

why is that? Does this mean that i cannot write functions that modify their arguments and apply it to columns of matrices?

Is trying to modify columns of matrices bad programming style? Is there a better alternative?
 How much more memory am I allocating if my functions return output instead of modifying their arguments (matlab background - I am completely unaware of memory allocation issues)? 

Thanks,
Alex
Reply | Threaded
Open this post in threaded view
|

Re: whole arrays pass by reference while matrix columns by value?

Chris Rackauckas
In reply to this post by Alexandros Fakos
You allocate memory for the entire array that you pass back. So if A is nxn, and instead of modifying it in-place, you create function takes in A, creates an Anew, and returns that, notice that you will have done an nxn array of memory allocation. As you can see, this will happen with every function call and adds up fast. That's why the MATLAB "vectorized" way of doing this isn't very efficient (when you have fast looping to modify things in place). 

That doesn't mean don't do it, it means write in-place updating functions when you can. It takes a little more forethought since you are changing what you already have, so if you use that same array in the future without realizing you change the values, it will break code. However, Julia always allows you to do B = copy(A) when you need to.

Generally, this means: worry about performance in your "inner loops" that take up all of the other time, and then write the easiest to maintain code for the parts which don't take up as much time.

And expanding on what John said in example form: A = B saves the reference of B to A, so A is essentially a view to A (modifying A modifies B, they are the same location in memory). A[:,i] = B[:,i] does slicing on the right side of the = sign, so it made a copy, so modifying A[:,i] doesn't modify B[:,i]. Note that A[:] on the left-side is a view, so A[:] = ones(N) is an in-place update (Julia is smart enough to not allocate here, at least last time I checked). These same rules apply when passing to a function. And instead of slicing/copying with B[:,i], you can use view(B,:,i) to not copy and instead get something that points directly to the memory of B.

And while we're at it, in the latest versions (v0.6, some of this hasn't been implemented yet), you can broadcast everything, so

A .= B .+ C .* sin.(E)

would make a for loop that fuses and assigns to A in-place (that's the .=, which changes it to A[i] = ... just like how other operators broadcast)

While this may seem like a lot at first, one you get used to this, these tools help you write much faster code (since you can essentially eliminate temporaries but still have elegant looking code!).

On Wednesday, September 7, 2016 at 5:00:00 PM UTC-7, Alexandros Fakos wrote:
Hi,

a=rand(10,2)
b=rand(10)
sort!(b) modifies b
but sort!(a[:,1]) does not modify the first column of matrix a 

why is that? Does this mean that i cannot write functions that modify their arguments and apply it to columns of matrices?

Is trying to modify columns of matrices bad programming style? Is there a better alternative?
 How much more memory am I allocating if my functions return output instead of modifying their arguments (matlab background - I am completely unaware of memory allocation issues)? 

Thanks,
Alex
Reply | Threaded
Open this post in threaded view
|

Re: whole arrays pass by reference while matrix columns by value?

Alexandros Fakos
In reply to this post by Alexandros Fakos
thank you all for your helpful suggestions!
alex

On Wednesday, September 7, 2016 at 7:00:00 PM UTC-5, Alexandros Fakos wrote:
Hi,

a=rand(10,2)
b=rand(10)
sort!(b) modifies b
but sort!(a[:,1]) does not modify the first column of matrix a 

why is that? Does this mean that i cannot write functions that modify their arguments and apply it to columns of matrices?

Is trying to modify columns of matrices bad programming style? Is there a better alternative?
 How much more memory am I allocating if my functions return output instead of modifying their arguments (matlab background - I am completely unaware of memory allocation issues)? 

Thanks,
Alex