using LinearAlgebra "Sum over array while minimizing catastrophic cancellation as much as possible" function better_sum(arr::Array{Float64}) pos_arr = arr[arr .> 0] neg_arr = arr[arr .< 0] sort!(pos_arr) sort!(neg_arr, rev=true) return sum(pos_arr) + sum(neg_arr) end better_sum(arr::Array{ComplexF64}) = better_sum(real.(arr)) + 1im * better_sum(imag.(arr)) "The triangle inequality for angular momenta" triangle_ineq(l1, l2, L) = abs(l1 - l2) ≤ L && L ≤ (l1 + l2) "Index of the nearest value in a list to a given reference point" nearestIndex(list::Array, ref) = argmin(norm.(list .- ref)) "Nearest value in a list to a given reference point" nearest(list::Array, ref) = list[nearestIndex(list, ref)] "Simple implementation of the Kronecker sum" function kron_sum(A::AbstractMatrix, B::AbstractMatrix) @assert size(A, 1) == size(A, 2) && size(B, 1) == size(B, 2) "Matrices should be square" return kron(A, I(size(B, 1))) + kron(I(size(A, 1)), B) end "Flattened vector version of Iterators.product(...) with index hierachy reversed -- leftmost index has the highest hierachy" iter_prod(args...) = reverse.(collect(Iterators.product(reverse(args)...))[:])