Reputation: 877
In the following function
function foo(g)
a = [g * sqrt(i) for i in 1:4]
b = [g * i ^ 2 for i in 1:4]
for j in [a, b]
j /= sum(j)
println(j)
end
return a, b
end
foo(2)
I expect the printed values to agree with the returned values. Instead, the returned values do not reflect the division performed in line 5. The result is
[0.16270045344786252, 0.2300931878702196, 0.2818054517861928, 0.32540090689572504]
[0.03333333333333333, 0.13333333333333333, 0.3, 0.5333333333333333]
([2.0, 2.8284271247461903, 3.4641016151377544, 4.0], [2, 8, 18, 32])
I saw a discussion on the Julia forum where a user was having similar issues in a REPL session. But the suggested solution was to either wrap the for loop in a function, which I have already done, or to write the equivalent of global j \= sum(j)
in place of line 5, which doesn't change the result.
Similar suggestions appear in this SE question: Changing variable in loop [Julia]
How can I batch modify a
and b
before returning them?
Upvotes: 2
Views: 83
Reputation: 42254
You need to vectorize the division and use a Float64
arg:
function foo(g)
a = [g * sqrt(i) for i in 1:4]
b = [g * i ^ 2 for i in 1:4]
for j in [a, b]
j ./= sum(j)
println(j)
end
return a, b
end
And now:
julia> foo(2.0)
[0.16270045344786252, 0.2300931878702196, 0.2818054517861928, 0.32540090689572504]
[0.03333333333333333, 0.13333333333333333, 0.3, 0.5333333333333333]
([0.16270045344786252, 0.2300931878702196, 0.2818054517861928, 0.32540090689572504], [0.03333333333333333, 0.13333333333333333, 0.3, 0.5333333333333333])
Now the tricky explanation
Int
argument than in your code a
is a Vector
of Float64
s and b
is a Vector
of Int
s. Look what happens when you combine them:
julia> [[1.0,2.0],[1,2]]
2-element Array{Array{Float64,1},1}:
[1.0, 2.0]
[1.0, 2.0]
Julia brings all data to common Float64 and in your case you loose the reference information!j =/ sum(j)
is a linear algebra division and it allocates a new object. You want to have an element wise operation so you needed to vectorize.Upvotes: 1