Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slicing an array creates a copy instead of a reference #6988

Closed
raichu opened this issue May 27, 2014 · 14 comments
Closed

Slicing an array creates a copy instead of a reference #6988

raichu opened this issue May 27, 2014 · 14 comments

Comments

@raichu
Copy link

raichu commented May 27, 2014

I'm in the middle of a migration from C++ and I'm having a hard time in understanding Julia "slices".

I have a vector a. When I do b=a[1:2] and b[1] = 10 for example, a is not affected.
That is, the "slicing" operation a[1:2] creates a copy instead of working with the original data.

Is this a bug or intended behavior?

If it is intended behavior, what is the correct way of getting a reference to a piece of the original vector? (whose type is still Vector, not SubArray; I have functions with explicit type annotations for type safety).

@raichu raichu changed the title Slicing an array Slicing an array creates a copy instead of a reference May 27, 2014
@nalimilan
Copy link
Member

This is the intended behavior, but it's probably going to change. See #5556.

For now, I think you need to use SubArrays. You could change your annotations to check for AbstratArray rather than Array: this doesn't remove much safety and makes your code more generic.

@raichu
Copy link
Author

raichu commented May 27, 2014

Well, that's disappointing.

@raichu
Copy link
Author

raichu commented May 27, 2014

How would it work exactly?
Apparently, slice and slicedim returns a copy as well.

Here's what I'm trying to do; I'm using NLopt.jl and it's API requires all the data is given as a big Vector (in my case it's of size 5_N_N). The data is actually made of 5 NxN Float64 matrices. So I need to find a way of re-interpreting the original Vector in terms of five N*N matrices. And I should be able to work on the original data (to work with NLopt's C code), not a copy of the data.

Is there a way of achieving this in Julia today?

@raichu
Copy link
Author

raichu commented May 27, 2014

Just tried reshape(sub(v, 1:N*N), N,N). This interestingly gives a copy of the array.
Using only sub or only reshape, I get a reference to the original array, but when used together, they give a copy of the data instead.
Is this not a bug?

@nalimilan
Copy link
Member

You can simply call reshape on the vector to make it a 3-d array, and then use sub to extract individual matrices from it.

@raichu
Copy link
Author

raichu commented May 27, 2014

Sorry, I'm not that familiar with Julia, what is a 3d array? How do I do that exactly? reshape(v, 5, N ,N) doesn't seem to be giving something pretty. And are you sure that it's not going to be a copy of the original data? (see my previous comment).

Also, doesn't sub give an array instead of a matrix?

@raichu
Copy link
Author

raichu commented May 27, 2014

Can you give me a working code?
If it is such a simple thing that can be done just by reshape and sub, it should be a one-liner, right?

@nalimilan
Copy link
Member

Try this, it doesn't copy the arrays:

# Vector you get from NLopt (here with 2 5x5 matrices)
julia> a = rand(2 * 25)
# 3-dimensional array holding your 5x5 matrices
julia> b = reshape(a, (5, 5, 2))
# Extract the first 5x5 matrix
julia> c = sub(b, :, :, 1)

EDIT: fix the order of dimensions.

@raichu
Copy link
Author

raichu commented May 27, 2014

Thanks, but it gives 2x5 matrix instead of a 5x5 matrix.

Chaning (2, 5, 5)->(5, 5,2) did the job.

@raichu
Copy link
Author

raichu commented May 27, 2014

Just another quick question; the type of the result is
5x5 SubArray{Int64,2,Array{Int64,3},(UnitRange{Int64},UnitRange{Int64},Int64)}

Would there be any performance penalties with this abstraction? Or is the optimizer clever enough to optimize this thing as a normal, contiguous array?

@ivarne
Copy link
Member

ivarne commented May 27, 2014

Sub arrays are not known for their performance. I think the ArrayViews from #5556, is likely to have better performance.

@kmsquire
Copy link
Member

Duplicate of #3701.

@lindahua
Copy link
Contributor

Please check out ArrayViews package at this point, which provides what you want (a performant non-copying view).

@JeffBezanson
Copy link
Member

If you need to be sure data is referenced in-place, you can hack around with pointer and pointer_to_array. Just make sure there is a reference to the original data object somewhere.
Closing as dup of #3701.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants