QuantumBFS / Yao.jl

Extensible, Efficient Quantum Algorithm Design for Humans.
https://yaoquantum.org
Other
928 stars 123 forks source link

Undesired handling of complex values when the expectation of an observable has zero real part #508

Closed wilf-phasecraft closed 4 months ago

wilf-phasecraft commented 4 months ago

There are valid cases where the expectation value of some observable gives a real part that is zero. When this is the case, and there is some vanishingly small, but not exactly zero imaginary component the safe_real function applied within expect returns an undesirable error.

To any sensible user, the value of safe_real(0 + 1e-323im) when interpreted as an expectation value should evaluate to 0.0. I'm not sure what the fix for this would be, but perhaps a more intelligent way of detecting values that are safe to convert to real needs to be considered.

To reproduce

julia> using YaoBlocks
julia> YaoBlocks.safe_real(0 + 1e-323im)
ERROR: Can not convert number 0.0 + 1.0e-323im to real due to its large imaginary part.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] safe_real(x::ComplexF64)
   @ YaoBlocks ~/.julia/packages/YaoBlocks/BlXhZ/src/utils.jl:319
 [3] top-level scope
   @ REPL[4]:1
wilf-phasecraft commented 4 months ago

To elaborate, this is a direct result of the method used to check whether the imaginary component is negligible compared to the real component, namely the expression isapprox(x - im*img, x) evaluates to false when the real part is exactly zero

function safe_real(x)
    img = imag(x)
    if !(iszero(img) || isapprox(x - im*img, x))
        error("Can not convert number $x to real due to its large imaginary part.")
    end
    return real(x)
end
Roger-luo commented 4 months ago

A possible solution is to give expect a throw option, whereas for expect(...; nothrow=True), it will just use real to obtain the real part when the user is sure about the result. I don't know what was the original motivation for adding this, in what case @GiggleLiu is expecting expect to throw an error and terminate the program?

GiggleLiu commented 4 months ago

Thanks for the issue, just submitted a PR to fix the issue.