QuantumBFS / Yao.jl

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

Bug in Yao.plot() when visualising identity rotations #528

Open dgrinko opened 4 days ago

dgrinko commented 4 days ago

I am trying to visualise a circuit involving some rotation gates, which happen to be identity gates with some phase factors. For example, if I run

using Yao
Yao.plot(rot(igate(1), 1.))

then I get the following error:

MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer

Stacktrace:
  [1] mapreduce_empty(::typeof(identity), op::Function, T::Type)
    @ Base ./reduce.jl:372
  [2] reduce_empty(op::Base.MappingRF{typeof(identity), typeof(max)}, ::Type{Float64})
    @ Base ./reduce.jl:361
  [3] reduce_empty_iter
    @ ./reduce.jl:384 [inlined]
  [4] mapreduce_empty_iter(f::Function, op::Function, itr::Vector{Float64}, ItrEltype::Base.HasEltype)
    @ Base ./reduce.jl:380
  [5] _mapreduce(f::typeof(identity), op::typeof(max), ::IndexLinear, A::Vector{Float64})
    @ Base ./reduce.jl:432
  [6] _mapreduce_dim
    @ ./reducedim.jl:365 [inlined]
  [7] mapreduce
    @ ./reducedim.jl:357 [inlined]
  [8] _maximum
    @ ./reducedim.jl:1015 [inlined]
  [9] _maximum
    @ ./reducedim.jl:1014 [inlined]
 [10] maximum
    @ ./reducedim.jl:1010 [inlined]
 [11] _draw!(c::YaoPlots.CircuitGrid, loc_brush_texts::Vector{Tuple{Tuple{}, YaoPlots.CircuitStyles.Box{Float64}, String}})
    @ YaoPlots ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:209
 [12] draw!(c::YaoPlots.CircuitGrid, p::RotationGate{2, Float64, IdentityGate{2}}, address::Vector{Int64}, controls::Vector{Any})
    @ YaoPlots ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:275
 [13] addblock!(c::YaoPlots.CircuitGrid, blk::RotationGate{2, Float64, IdentityGate{2}})
    @ YaoPlots ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:499
 [14] (::YaoPlots.var"#38#39"{RotationGate{2, Float64, IdentityGate{2}}})(c::YaoPlots.CircuitGrid)
    @ YaoPlots ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:494
 [15] circuit_canvas(f::YaoPlots.var"#38#39"{RotationGate{2, Float64, IdentityGate{2}}}, nline::Int64; format::Symbol, filename::Nothing, w_depth::Float64, w_line::Float64, show_ending_bar::Bool, starting_texts::Nothing, starting_offset::Float64, ending_texts::Nothing, ending_offset::Float64, gatestyles::YaoPlots.CircuitStyles.GateStyles)
    @ YaoPlots ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:509
 [16] circuit_canvas
    @ ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:502 [inlined]
 [17] #vizcircuit#37
    @ ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:492 [inlined]
 [18] vizcircuit
    @ ~/.julia/packages/YaoPlots/9BZIs/src/vizcircuit.jl:489 [inlined]
 [19] plot(blk::RotationGate{2, Float64, IdentityGate{2}})
    @ YaoPlots ~/.julia/packages/YaoPlots/9BZIs/src/YaoPlots.jl:18
 [20] top-level scope
    @ In[1]:2

This is clearly a bug since plotting an identity gate with a constant phase factor should not be a problem :)

GiggleLiu commented 4 days ago

Yeah, this is because occupied_locs for rot is not implemented correctly, or rotating over igate is not a local gate at all. I made an atempt to fix this issue in the above PR.

For creating a phase shift, you can use the phase gate as a more reliable solution:

julia> phase(0.3) |> mat
2×2 Diagonal{ComplexF64, Vector{ComplexF64}}:
 0.955336+0.29552im           ⋅    
          ⋅          0.955336+0.29552im