Inplace modification of Float64

Hi, I know that things like Float64 are immutable, so I can’t do inplace modification (in my specific situation: I can’t call clamp! on them).

I’m writing some code in which I either want to apply a routine on an entire vector simultaneously (in which case clamp! works fine) or by looping over Float64’s (in which case clamp! doesn’t work).

I can do two things: either forgo inplace modification in the Float64 case, or “make” the Float64 mutable: see the lines for u and w in my example. Which approach would typically be preferred performance-wise? Intuitively I’d think that not doing inplace modification is probably quicker here than all the extra referencing that you’d need to do by using Ref? I’m curious to hear your thoughts!

function my_clamp!(x, a, b)
    if x < a
        x = a
    elseif x > b
        x = b
    end
    return x
end

function my_clamp_ref!(x, a, b)
    if x[] < a
        x[] = a
    elseif x[] > b
        x[] = b
    end
    return x
end

a = -1.0
b = 1.0

u = 2.0
display("works") # prints 2.0, then 1.0 
display(u)
u = my_clamp!(u, a, b)
display(u)

v = 2.0
display("doesn't work") # prints 2.0, then 2.0
display(v)
my_clamp!(v, a, b)
display(v)

w = Ref(2.0)
display("works") # prints Base.RefValue{Float64}(2.0) then Base.RefValue{Float64}(1.0)
display(w)
my_clamp_ref!(w, a, b)
display(w)

Could you give a more complete example of what you want?

There could be a third option (inspired by MutableArithmetics.jl), design an optionally mutating API.

2 Likes

clamp! is something of an outlier in being defined to work on arrays. If you replace it with

u .= clamp.(u, a, b)

you have the usual duality between broadcasting and looping:

x .= f.(x)

vs

for i in eachindex(x)
    x[i] = f(x[i])
end

(This observation may or may not be helpful. It’s difficult to guess how your real problem generalizes outside of clamping.)

3 Likes

I’m somehow failing to reproduce this in my original setting at present, so I’ll close this question for now, returning to it if the issue resurfaces.

Thank you for your help nonetheless!

1 Like