Function modifying argument Julia
up vote
1
down vote
favorite
I have a mutable composite type,
mutable struct MyType
x::Array{Float64}
end
And I have a function which I would like to modify it in place,
function f(z::MyType)
newx = z.x + 1
z.x = newx
return z
end
This does not seem to work to update z. What am I missing?
julia-lang
add a comment |
up vote
1
down vote
favorite
I have a mutable composite type,
mutable struct MyType
x::Array{Float64}
end
And I have a function which I would like to modify it in place,
function f(z::MyType)
newx = z.x + 1
z.x = newx
return z
end
This does not seem to work to update z. What am I missing?
julia-lang
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have a mutable composite type,
mutable struct MyType
x::Array{Float64}
end
And I have a function which I would like to modify it in place,
function f(z::MyType)
newx = z.x + 1
z.x = newx
return z
end
This does not seem to work to update z. What am I missing?
julia-lang
I have a mutable composite type,
mutable struct MyType
x::Array{Float64}
end
And I have a function which I would like to modify it in place,
function f(z::MyType)
newx = z.x + 1
z.x = newx
return z
end
This does not seem to work to update z. What am I missing?
julia-lang
julia-lang
asked Nov 19 at 15:05
nfernand
100118
100118
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
z.x
is an array so one must write z.x .+ 1
(note the extra dot) to indicate element-wise addition.
function f(z::MyType)
newx = z.x .+ 1
z.x = newx
return z
end
This function does update z
:
julia> z = MyType(rand(1:10, 4))
MyType([10.0, 7.0, 2.0, 2.0])
julia> f(z)
MyType([11.0, 8.0, 3.0, 3.0])
julia> z
MyType([11.0, 8.0, 3.0, 3.0])
julia> @btime f($z);
886.115 ns (4 allocations: 208 bytes)
The allocations are (at least) understood from the fact that it allocate a new array newx
(a copy of z.x
where every element is increased by one) which is then set to be the new array assigned to z.x
. The original array, which was assigned to z.x
before, is now lost (and will be gc'ed).
What you presumably want to do is modify the array that is assigned to z.x
in-place without creating an intermediate array. This can be achieved by writing
function f(z::MyType)
z.x .= z.x .+ 1 # or equivalently z.x .+= 1
return z
end
Note the .=
instead of =
which assigns in-place (you can think of an elementwise assignment). This gives
julia> @btime f($z);
372.284 ns (2 allocations: 48 bytes)
Note that you could write this much shorter as well
f(z::MyType) = (z.x .+= 1; z)
I know about that - this was just example code to show that I was making an update (the operation I am doing is much more complicated). But the issue is not that the RHS is not the correct expression, it's that it is not updating the object.
– nfernand
Nov 19 at 15:56
1
Your example is too minimal than because it does update the object (after you add the extra dot). I suggest you provide a minimal example that actually shows the "broken" behavior.
– crstnbr
Nov 19 at 17:01
I refactored my answer quite a bit. Maybe this helps. Nonetheless, both approaches updatez
. One is just more efficient in doing so.
– crstnbr
Nov 19 at 20:06
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
z.x
is an array so one must write z.x .+ 1
(note the extra dot) to indicate element-wise addition.
function f(z::MyType)
newx = z.x .+ 1
z.x = newx
return z
end
This function does update z
:
julia> z = MyType(rand(1:10, 4))
MyType([10.0, 7.0, 2.0, 2.0])
julia> f(z)
MyType([11.0, 8.0, 3.0, 3.0])
julia> z
MyType([11.0, 8.0, 3.0, 3.0])
julia> @btime f($z);
886.115 ns (4 allocations: 208 bytes)
The allocations are (at least) understood from the fact that it allocate a new array newx
(a copy of z.x
where every element is increased by one) which is then set to be the new array assigned to z.x
. The original array, which was assigned to z.x
before, is now lost (and will be gc'ed).
What you presumably want to do is modify the array that is assigned to z.x
in-place without creating an intermediate array. This can be achieved by writing
function f(z::MyType)
z.x .= z.x .+ 1 # or equivalently z.x .+= 1
return z
end
Note the .=
instead of =
which assigns in-place (you can think of an elementwise assignment). This gives
julia> @btime f($z);
372.284 ns (2 allocations: 48 bytes)
Note that you could write this much shorter as well
f(z::MyType) = (z.x .+= 1; z)
I know about that - this was just example code to show that I was making an update (the operation I am doing is much more complicated). But the issue is not that the RHS is not the correct expression, it's that it is not updating the object.
– nfernand
Nov 19 at 15:56
1
Your example is too minimal than because it does update the object (after you add the extra dot). I suggest you provide a minimal example that actually shows the "broken" behavior.
– crstnbr
Nov 19 at 17:01
I refactored my answer quite a bit. Maybe this helps. Nonetheless, both approaches updatez
. One is just more efficient in doing so.
– crstnbr
Nov 19 at 20:06
add a comment |
up vote
3
down vote
accepted
z.x
is an array so one must write z.x .+ 1
(note the extra dot) to indicate element-wise addition.
function f(z::MyType)
newx = z.x .+ 1
z.x = newx
return z
end
This function does update z
:
julia> z = MyType(rand(1:10, 4))
MyType([10.0, 7.0, 2.0, 2.0])
julia> f(z)
MyType([11.0, 8.0, 3.0, 3.0])
julia> z
MyType([11.0, 8.0, 3.0, 3.0])
julia> @btime f($z);
886.115 ns (4 allocations: 208 bytes)
The allocations are (at least) understood from the fact that it allocate a new array newx
(a copy of z.x
where every element is increased by one) which is then set to be the new array assigned to z.x
. The original array, which was assigned to z.x
before, is now lost (and will be gc'ed).
What you presumably want to do is modify the array that is assigned to z.x
in-place without creating an intermediate array. This can be achieved by writing
function f(z::MyType)
z.x .= z.x .+ 1 # or equivalently z.x .+= 1
return z
end
Note the .=
instead of =
which assigns in-place (you can think of an elementwise assignment). This gives
julia> @btime f($z);
372.284 ns (2 allocations: 48 bytes)
Note that you could write this much shorter as well
f(z::MyType) = (z.x .+= 1; z)
I know about that - this was just example code to show that I was making an update (the operation I am doing is much more complicated). But the issue is not that the RHS is not the correct expression, it's that it is not updating the object.
– nfernand
Nov 19 at 15:56
1
Your example is too minimal than because it does update the object (after you add the extra dot). I suggest you provide a minimal example that actually shows the "broken" behavior.
– crstnbr
Nov 19 at 17:01
I refactored my answer quite a bit. Maybe this helps. Nonetheless, both approaches updatez
. One is just more efficient in doing so.
– crstnbr
Nov 19 at 20:06
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
z.x
is an array so one must write z.x .+ 1
(note the extra dot) to indicate element-wise addition.
function f(z::MyType)
newx = z.x .+ 1
z.x = newx
return z
end
This function does update z
:
julia> z = MyType(rand(1:10, 4))
MyType([10.0, 7.0, 2.0, 2.0])
julia> f(z)
MyType([11.0, 8.0, 3.0, 3.0])
julia> z
MyType([11.0, 8.0, 3.0, 3.0])
julia> @btime f($z);
886.115 ns (4 allocations: 208 bytes)
The allocations are (at least) understood from the fact that it allocate a new array newx
(a copy of z.x
where every element is increased by one) which is then set to be the new array assigned to z.x
. The original array, which was assigned to z.x
before, is now lost (and will be gc'ed).
What you presumably want to do is modify the array that is assigned to z.x
in-place without creating an intermediate array. This can be achieved by writing
function f(z::MyType)
z.x .= z.x .+ 1 # or equivalently z.x .+= 1
return z
end
Note the .=
instead of =
which assigns in-place (you can think of an elementwise assignment). This gives
julia> @btime f($z);
372.284 ns (2 allocations: 48 bytes)
Note that you could write this much shorter as well
f(z::MyType) = (z.x .+= 1; z)
z.x
is an array so one must write z.x .+ 1
(note the extra dot) to indicate element-wise addition.
function f(z::MyType)
newx = z.x .+ 1
z.x = newx
return z
end
This function does update z
:
julia> z = MyType(rand(1:10, 4))
MyType([10.0, 7.0, 2.0, 2.0])
julia> f(z)
MyType([11.0, 8.0, 3.0, 3.0])
julia> z
MyType([11.0, 8.0, 3.0, 3.0])
julia> @btime f($z);
886.115 ns (4 allocations: 208 bytes)
The allocations are (at least) understood from the fact that it allocate a new array newx
(a copy of z.x
where every element is increased by one) which is then set to be the new array assigned to z.x
. The original array, which was assigned to z.x
before, is now lost (and will be gc'ed).
What you presumably want to do is modify the array that is assigned to z.x
in-place without creating an intermediate array. This can be achieved by writing
function f(z::MyType)
z.x .= z.x .+ 1 # or equivalently z.x .+= 1
return z
end
Note the .=
instead of =
which assigns in-place (you can think of an elementwise assignment). This gives
julia> @btime f($z);
372.284 ns (2 allocations: 48 bytes)
Note that you could write this much shorter as well
f(z::MyType) = (z.x .+= 1; z)
edited Nov 19 at 20:23
answered Nov 19 at 15:46
crstnbr
3,4191022
3,4191022
I know about that - this was just example code to show that I was making an update (the operation I am doing is much more complicated). But the issue is not that the RHS is not the correct expression, it's that it is not updating the object.
– nfernand
Nov 19 at 15:56
1
Your example is too minimal than because it does update the object (after you add the extra dot). I suggest you provide a minimal example that actually shows the "broken" behavior.
– crstnbr
Nov 19 at 17:01
I refactored my answer quite a bit. Maybe this helps. Nonetheless, both approaches updatez
. One is just more efficient in doing so.
– crstnbr
Nov 19 at 20:06
add a comment |
I know about that - this was just example code to show that I was making an update (the operation I am doing is much more complicated). But the issue is not that the RHS is not the correct expression, it's that it is not updating the object.
– nfernand
Nov 19 at 15:56
1
Your example is too minimal than because it does update the object (after you add the extra dot). I suggest you provide a minimal example that actually shows the "broken" behavior.
– crstnbr
Nov 19 at 17:01
I refactored my answer quite a bit. Maybe this helps. Nonetheless, both approaches updatez
. One is just more efficient in doing so.
– crstnbr
Nov 19 at 20:06
I know about that - this was just example code to show that I was making an update (the operation I am doing is much more complicated). But the issue is not that the RHS is not the correct expression, it's that it is not updating the object.
– nfernand
Nov 19 at 15:56
I know about that - this was just example code to show that I was making an update (the operation I am doing is much more complicated). But the issue is not that the RHS is not the correct expression, it's that it is not updating the object.
– nfernand
Nov 19 at 15:56
1
1
Your example is too minimal than because it does update the object (after you add the extra dot). I suggest you provide a minimal example that actually shows the "broken" behavior.
– crstnbr
Nov 19 at 17:01
Your example is too minimal than because it does update the object (after you add the extra dot). I suggest you provide a minimal example that actually shows the "broken" behavior.
– crstnbr
Nov 19 at 17:01
I refactored my answer quite a bit. Maybe this helps. Nonetheless, both approaches update
z
. One is just more efficient in doing so.– crstnbr
Nov 19 at 20:06
I refactored my answer quite a bit. Maybe this helps. Nonetheless, both approaches update
z
. One is just more efficient in doing so.– crstnbr
Nov 19 at 20:06
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53377438%2ffunction-modifying-argument-julia%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown