I don’t want to actively enter (even if I follow you with interest) in the “high” part of the discussion.
Nor, even less, to suggest what might be a “right” solution that satisfies the different needs.
I just want to report some reflections that may be useful to those who, like me, are not very familiar with the internal aspects of Julia.
And take comfort from the experts that I’m not completely off track.
I tried to find a form of the problem that was easy to follow on numbers even “by hand”
At first I thought the problematic expression was equivalent to this, which, in fact, gives no problems.
x=[1 2; 3 4]
x = x .* mean.(eachrow(x))
I then realized that instead it is equivalent to this
x=[1 3; 2 4]
x .= x .* mean.(eachrow(x))
which, put this way, actually has several problems.
the first, from what I understand, is that it can’t put real numbers into an array of integers
julia> x .= x .* mean.(eachrow(x))
ERROR: InexactError: Int64(7.5)
the second, actually related to the first, is the unexpected result reported by the OP.
julia> x=[1. 3; 2 4]
2×2 Matrix{Float64}:
1.0 3.0
2.0 4.0
julia> x .= x .* mean.(eachrow(x))
2×2 Matrix{Float64}:
2.0 7.5
6.0 20.0
Where in the second column one would expect what is obtained from the following expression
Which simultaneously solves the problem of putting real numbers into an matrix of integers.
julia> x=[1. 3; 2 4]
2×2 Matrix{Float64}:
1.0 3.0
2.0 4.0
julia> x = x .* mean.(eachrow(x))
2×2 Matrix{Float64}:
2.0 6.0
6.0 12.0
The fact is that in this expression the x on the left side (x= …) is not the same as the x on the right side.
While in the previous expression (x.=…) the two x’s are the same memory area.
I’m not sure if that’s completely correct and relevant, but I’d like to show that…
julia> x=[1. 3; 2 4]
2×2 Matrix{Float64}:
1.0 3.0
2.0 4.0
julia> pointer(x)
Ptr{Float64} @0x000001e021f2d840
julia> x .= x .* mean.(eachrow(x))
2×2 Matrix{Float64}:
2.0 7.5
6.0 20.0
julia> pointer(x)
Ptr{Float64} @0x000001e021f2d840 # same pointer as above
#--------------
julia> x=[1. 2; 3 4]
2×2 Matrix{Float64}:
1.0 2.0
3.0 4.0
julia> pointer(x)
Ptr{Float64} @0x000001e05c1d27a0
julia> x = x .* mean.(eachrow(x))
2×2 Matrix{Float64}:
1.5 3.0
10.5 14.0
julia> pointer(x)
Ptr{Float64} @0x000001e05c369e40