I have in some weird side effect with structs of sparse vectors of BigFloats, where operating on a copy of the sum seems to change the struct itself.
In spirit, the structure of the code looks like below. After a copying step from y
to x
, the value of active_set
itself.
** NoTe ** this example sadly does not reproduce the bug (yet), I haven’t managed to extract what is going on.
using SparseArrays
using LinearAlgebra
n = 10_000
a1_indices = Int[]
a2_indices = [160, 162, 166, 264, 381, 594, 629, 640, 646, 651, 656, 696, 804, 851, 1021, 1040, 1091, 1176, 1185, 1210, 1377, 1424, 1603, 1607, 1770, 1826, 2087, 2156, 2292, 2371, 2465, 2484, 2521, 2556, 2605, 2658, 2741, 2743, 3204, 3216, 3423, 3478, 3666, 3740, 3748, 3758, 3770, 3815, 4032, 4177, 4206, 4225, 4559, 4564, 4597, 4723, 4816, 4840, 4848, 5221, 5530, 5561, 5573, 5877, 6046, 6066, 6241, 6243, 6246, 6255, 6378, 6468, 6595, 6679, 6761, 6955, 6979, 7006, 7029, 7302, 7373, 7522, 7562, 7591, 7890, 7940, 8009, 8025, 8037, 8249, 8716, 8778, 8943, 9077, 9221, 9685, 9721, 9813, 9835, 9857]
a1_vals = BigFloat[]
a2_vals = BigFloat[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
active_set = (
weights = [0.999755859375, 0.000244140625],
atoms = [
SparseVector(n, a1_indices, a1_vals),
SparseVector(n, a2_indices, a2_vals),
]
)
function compute_active_set_iterate(active_set)
return sum(λi * ai for (λi, ai) in zip(active_set.weights, active_set.atoms))
end
@show norm(compute_active_set_iterate(active_set))
x = spzeros(BigFloat, length(active_set.atoms[1]))
function do_stuff!(x, active_set)
x .= 0
SparseArrays.dropzeros!(x)
y = compute_active_set_iterate(active_set)
@info "$(norm(compute_active_set_iterate(active_set)))"
@info "$(norm(y))"
# HERE, the two values above are identical
x .= y
# NOW, the result below is different
@info "$(norm(compute_active_set_iterate(active_set)))"
# the two displayed norms diverge
return x
end
x = compute_active_set_iterate(active_set)
for _ in 1:5
x = if rand(Bool)
do_stuff!(x, active_set)
else
compute_active_set_iterate(active_set)
end
@info "$(norm(compute_active_set_iterate(active_set)))"
@info "$(norm(x))"
end