Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change: Move Braket-specific pragma, instruction, and result logic out of parser #53

Merged
merged 11 commits into from
Sep 27, 2024
2 changes: 1 addition & 1 deletion docs/src/gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ BraketSimulator.Si
BraketSimulator.U
BraketSimulator.Unitary
BraketSimulator.PhaseShift
BraketSimulator.MultiQubitPhaseShift
BraketSimulator.GPhase
BraketSimulator.PRx
BraketSimulator.GPi
BraketSimulator.GPi2
Expand Down
15 changes: 8 additions & 7 deletions src/BraketSimulator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,21 @@ complex_matrix_to_ir(m) = m
include("raw_schema.jl")
include("qubit_set.jl")
include("operators.jl")
include("gates.jl")
include("noises.jl")
include("schemas.jl")
include("observables.jl")
using .Observables
include("results.jl")
include("Quasar.jl")
using .Quasar
include("pragmas.jl")
include("gates.jl")
include("noises.jl")
include("schemas.jl")
include("circuit.jl")
include("validation.jl")
include("custom_gates.jl")
include("pow_gates.jl")
include("gate_kernels.jl")
include("noise_kernels.jl")
include("Quasar.jl")
using .Quasar

const LOG2_CHUNK_SIZE = 10
const CHUNK_SIZE = 2^LOG2_CHUNK_SIZE
Expand Down Expand Up @@ -201,7 +202,7 @@ function _prepare_program(circuit_ir::OpenQasmProgram, inputs::Dict{String, <:An
ir_inputs = isnothing(circuit_ir.inputs) ? Dict{String, Float64}() : circuit_ir.inputs
merged_inputs = merge(ir_inputs, inputs)
src = circuit_ir.source::String
circuit = Quasar.to_circuit(src, merged_inputs)
circuit = to_circuit(src, merged_inputs)
n_qubits = qubit_count(circuit)
if shots > 0
_verify_openqasm_shots_observables(circuit, n_qubits)
Expand Down Expand Up @@ -820,8 +821,8 @@ include("dm_simulator.jl")
sv_oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), sv_exact_results_qasm, nothing)
dm_oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), dm_exact_results_qasm, nothing)
simulate(sv_simulator, sv_oq3_program, 0)
simulate("braket_sv_v2", sv_exact_results_qasm, "{}", 0)
simulate(dm_simulator, dm_oq3_program, 0)
simulate("braket_sv_v2", sv_exact_results_qasm, "{}", 0)
simulate("braket_dm_v2", dm_exact_results_qasm, "{}", 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), shots_results_qasm, nothing)
simulate(sv_simulator, oq3_program, 10)
Expand Down
812 changes: 297 additions & 515 deletions src/Quasar.jl

Large diffs are not rendered by default.

91 changes: 39 additions & 52 deletions src/builtin_gates.jl
Original file line number Diff line number Diff line change
@@ -1,92 +1,79 @@
# OpenQASM 3 Braket Standard Gates
builtin_gates() = Dict{String, GateDefinition}(
builtin_gates() = Dict{String, BuiltinGateDefinition}(
# identity gate
"i"=>GateDefinition("i", String[], ["a"], Instruction(BraketSimulator.I(), 0)),
"i"=>BuiltinGateDefinition("i", String[], ["a"], (type="i", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# phase gate
"phaseshift"=>GateDefinition("phaseshift", ["λ"], ["a"], Instruction(BraketSimulator.PhaseShift(BraketSimulator.FreeParameter(:λ)), 0)),
"phaseshift"=>BuiltinGateDefinition("phaseshift", ["λ"], ["a"], (type="phaseshift", arguments=InstructionArgument[:λ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# pauli X gate
"x"=>GateDefinition("x", String[], ["a"], Instruction(BraketSimulator.X(), 0)),
"x"=>BuiltinGateDefinition("x", String[], ["a"], (type="x", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# pauli Y gate
"y"=>GateDefinition("y", String[], ["a"], Instruction(BraketSimulator.Y(), 0)),
"y"=>BuiltinGateDefinition("y", String[], ["a"], (type="y", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# pauli Z gate
"z"=>GateDefinition("z", String[], ["a"], Instruction(BraketSimulator.Z(), 0)),
"z"=>BuiltinGateDefinition("z", String[], ["a"], (type="z", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Hadamard gate
"h"=>GateDefinition("h", String[], ["a"], Instruction(BraketSimulator.H(), 0)),
"h"=>BuiltinGateDefinition("h", String[], ["a"], (type="h", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# S gate
"s"=>GateDefinition("s", String[], ["a"], Instruction(BraketSimulator.S(), 0)),
"s"=>BuiltinGateDefinition("s", String[], ["a"], (type="s", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Si gate
"si"=>GateDefinition("si", String[], ["a"], Instruction(BraketSimulator.Si(), 0)),
"si"=>BuiltinGateDefinition("si", String[], ["a"], (type="si", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# T gate
"t"=>GateDefinition("t", String[], ["a"], Instruction(BraketSimulator.T(), 0)),
"t"=>BuiltinGateDefinition("t", String[], ["a"], (type="t", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Ti gate
"ti"=>GateDefinition("ti", String[], ["a"], Instruction(BraketSimulator.Ti(), 0)),
"ti"=>BuiltinGateDefinition("ti", String[], ["a"], (type="ti", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# V gate
"v"=>GateDefinition("v", String[], ["a"], Instruction(BraketSimulator.V(), 0)),
"v"=>BuiltinGateDefinition("v", String[], ["a"], (type="v", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Vi gate
"vi"=>GateDefinition("vi", String[], ["a"], Instruction(BraketSimulator.Vi(), 0)),
"vi"=>BuiltinGateDefinition("vi", String[], ["a"], (type="vi", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# RotX gate
"rx"=>GateDefinition("rx", ["θ"], ["a"], Instruction(BraketSimulator.Rx(BraketSimulator.FreeParameter(:θ)), 0)),
"rx"=>BuiltinGateDefinition("rx", ["θ"], ["a"], (type="rx", arguments=InstructionArgument[:θ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# RotY gate
"ry"=>GateDefinition("ry", ["θ"], ["a"], Instruction(BraketSimulator.Ry(BraketSimulator.FreeParameter(:θ)), 0)),
"ry"=>BuiltinGateDefinition("ry", ["θ"], ["a"], (type="ry", arguments=InstructionArgument[:θ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# RotZ gate
"rz"=>GateDefinition("rz", ["θ"], ["a"], Instruction(BraketSimulator.Rz(BraketSimulator.FreeParameter(:θ)), 0)),
"rz"=>BuiltinGateDefinition("rz", ["θ"], ["a"], (type="rz", arguments=InstructionArgument[:θ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# CNot gate
"cnot"=>GateDefinition("cnot", String[], ["a", "b"], Instruction(BraketSimulator.CNot(), BraketSimulator.QubitSet(0, 1))),
"cnot"=>BuiltinGateDefinition("cnot", String[], ["a", "b"], (type="cnot", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# CY gate
"cy"=>GateDefinition("cy", String[], ["a", "b"], Instruction(BraketSimulator.CY(), BraketSimulator.QubitSet(0, 1))),
"cy"=>BuiltinGateDefinition("cy", String[], ["a", "b"], (type="cy", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# CZ gate
"cz"=>GateDefinition("cz", String[], ["a", "b"], Instruction(BraketSimulator.CZ(), BraketSimulator.QubitSet(0, 1))),
"cz"=>BuiltinGateDefinition("cz", String[], ["a", "b"], (type="cz", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# CV gate
"cv"=>GateDefinition("cv", String[], ["a", "b"], Instruction(BraketSimulator.CV(), BraketSimulator.QubitSet(0, 1))),
"cv"=>BuiltinGateDefinition("cv", String[], ["a", "b"], (type="cv", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase
"cphaseshift"=>GateDefinition("cphaseshift", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift(BraketSimulator.FreeParameter(:λ)), BraketSimulator.QubitSet(0, 1))),
"cphaseshift"=>BuiltinGateDefinition("cphaseshift", ["λ"], ["a", "b"], (type="cphaseshift", arguments=InstructionArgument[:λ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase-00
"cphaseshift00"=>GateDefinition("cphaseshift00", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift00(BraketSimulator.FreeParameter(:λ)), BraketSimulator.QubitSet(0, 1))),
"cphaseshift00"=>BuiltinGateDefinition("cphaseshift00", ["λ"], ["a", "b"], (type="cphaseshift00", arguments=InstructionArgument[:λ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase-01
"cphaseshift01"=>GateDefinition("cphaseshift01", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift01(BraketSimulator.FreeParameter(:λ)), BraketSimulator.QubitSet(0, 1))),
"cphaseshift01"=>BuiltinGateDefinition("cphaseshift01", ["λ"], ["a", "b"], (type="cphaseshift01", arguments=InstructionArgument[:λ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase-10
"cphaseshift10"=>GateDefinition("cphaseshift10", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift10(BraketSimulator.FreeParameter(:λ)), BraketSimulator.QubitSet(0, 1))),
"cphaseshift10"=>BuiltinGateDefinition("cphaseshift10", ["λ"], ["a", "b"], (type="cphaseshift10", arguments=InstructionArgument[:λ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# Swap gate
"swap"=>GateDefinition("swap", String[], ["a", "b"], Instruction(BraketSimulator.Swap(), BraketSimulator.QubitSet(0, 1))),
"swap"=>BuiltinGateDefinition("swap", String[], ["a", "b"], (type="swap", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ISwap gate
"iswap"=>GateDefinition("iswap", String[], ["a", "b"], Instruction(BraketSimulator.ISwap(), BraketSimulator.QubitSet(0, 1))),
"iswap"=>BuiltinGateDefinition("iswap", String[], ["a", "b"], (type="iswap", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ISwap gate
"pswap"=>GateDefinition("pswap", ["θ"], ["a", "b"], Instruction(BraketSimulator.PSwap(BraketSimulator.FreeParameter(:θ)), BraketSimulator.QubitSet(0, 1))),
"pswap"=>BuiltinGateDefinition("pswap", ["θ"], ["a", "b"], (type="pswap", arguments=InstructionArgument[:θ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-swap gate
"cswap"=>GateDefinition("cswap", String[], ["a", "b", "c"], Instruction(BraketSimulator.CSwap(), BraketSimulator.QubitSet(0, 1, 2))),
"cswap"=>BuiltinGateDefinition("cswap", String[], ["a", "b", "c"], (type="cswap", arguments=InstructionArgument[], targets=[0, 1, 2], controls=Pair{Int,Int}[], exponent=1.0)),
# ccnot/Toffoli gate
"ccnot"=>GateDefinition("ccnot", String[], ["a", "b", "c"], Instruction(BraketSimulator.CCNot(), BraketSimulator.QubitSet(0, 1, 2))),
"ccnot"=>BuiltinGateDefinition("ccnot", String[], ["a", "b", "c"], (type="ccnot", arguments=InstructionArgument[], targets=[0, 1, 2], controls=Pair{Int,Int}[], exponent=1.0)),
# XX gate
"xx"=>GateDefinition("xx", ["θ"], ["a", "b"], Instruction(BraketSimulator.XX(BraketSimulator.FreeParameter(:θ)), BraketSimulator.QubitSet(0, 1))),
"xx"=>BuiltinGateDefinition("xx", ["θ"], ["a", "b"], (type="xx", arguments=InstructionArgument[:θ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# XY gate
"xy"=>GateDefinition("xy", ["θ"], ["a", "b"], Instruction(BraketSimulator.XY(BraketSimulator.FreeParameter(:θ)), BraketSimulator.QubitSet(0, 1))),
"xy"=>BuiltinGateDefinition("xy", ["θ"], ["a", "b"], (type="xy", arguments=InstructionArgument[:θ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# YY gate
"yy"=>GateDefinition("yy", ["θ"], ["a", "b"], Instruction(BraketSimulator.YY(BraketSimulator.FreeParameter(:θ)), BraketSimulator.QubitSet(0, 1))),
"yy"=>BuiltinGateDefinition("yy", ["θ"], ["a", "b"], (type="yy", arguments=InstructionArgument[:θ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ZZ gate
"zz"=>GateDefinition("zz", ["θ"], ["a", "b"], Instruction(BraketSimulator.ZZ(BraketSimulator.FreeParameter(:θ)), BraketSimulator.QubitSet(0, 1))),
"zz"=>BuiltinGateDefinition("zz", ["θ"], ["a", "b"], (type="zz", arguments=InstructionArgument[:θ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ECR gate
"ecr"=>GateDefinition("ecr", String[], ["a", "b"], Instruction(BraketSimulator.ECR(), BraketSimulator.QubitSet(0, 1))),
"ecr"=>BuiltinGateDefinition("ecr", String[], ["a", "b"], (type="ecr", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# MS gate
"ms"=>GateDefinition("ms", ["ϕ", "θ", "λ"], ["a", "b"], Instruction(BraketSimulator.MS(BraketSimulator.FreeParameter(:ϕ), BraketSimulator.FreeParameter(:θ), BraketSimulator.FreeParameter(:λ)), BraketSimulator.QubitSet(0, 1))),
"ms"=>BuiltinGateDefinition("ms", ["ϕ", "θ", "λ"], ["a", "b"], (type="ms", arguments=InstructionArgument[:ϕ, :θ, :λ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# GPi gate
"gpi"=>GateDefinition("gpi", ["θ"], ["a"], Instruction(BraketSimulator.GPi(BraketSimulator.FreeParameter(:θ)), 0)),
"gpi"=>BuiltinGateDefinition("gpi", ["θ"], ["a"], (type="gpi", arguments=InstructionArgument[:θ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# GPi2 gate
"gpi2"=>GateDefinition("gpi2", ["θ"], ["a"], Instruction(BraketSimulator.GPi2(BraketSimulator.FreeParameter(:θ)), 0)),
"gpi2"=>BuiltinGateDefinition("gpi2", ["θ"], ["a"], (type="gpi2", arguments=InstructionArgument[:θ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# PRx gate
"prx"=>GateDefinition("prx", ["θ", "ϕ"], ["a"], Instruction(BraketSimulator.PRx(BraketSimulator.FreeParameter(:θ), BraketSimulator.FreeParameter(:ϕ)), 0)),
"prx"=>BuiltinGateDefinition("prx", ["θ", "ϕ"], ["a"], (type="prx", arguments=InstructionArgument[:θ, :ϕ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# 3-angle U gate
"U"=>GateDefinition("U", ["θ", "ϕ", "λ"], ["a"], Instruction(BraketSimulator.U(BraketSimulator.FreeParameter(:θ), BraketSimulator.FreeParameter(:ϕ), BraketSimulator.FreeParameter(:λ)), 0)),
"U"=>BuiltinGateDefinition("U", ["θ", "ϕ", "λ"], ["a"], (type="u", arguments=InstructionArgument[:θ, :ϕ, :λ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
)

const noise_types = Dict{String, Type}(
"bit_flip"=>BraketSimulator.BitFlip,
"phase_flip"=>BraketSimulator.PhaseFlip,
"pauli_channel"=>BraketSimulator.PauliChannel,
"depolarizing"=>BraketSimulator.Depolarizing,
"two_qubit_depolarizing"=>BraketSimulator.TwoQubitDepolarizing,
"two_qubit_dephasing"=>BraketSimulator.TwoQubitDephasing,
"amplitude_damping"=>BraketSimulator.AmplitudeDamping,
"generalized_amplitude_damping"=>BraketSimulator.GeneralizedAmplitudeDamping,
"phase_damping"=>BraketSimulator.PhaseDamping,
"kraus"=>BraketSimulator.Kraus,
)
35 changes: 35 additions & 0 deletions src/circuit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,38 @@ function add_instruction!(c::Circuit, ix::Instruction{O}) where {O<:Operator}
push!(c.instructions, ix)
return c
end

function to_circuit(v::Quasar.QasmProgramVisitor)
c = Circuit()
foreach(v.instructions) do ix
sim_op = StructTypes.constructfrom(QuantumOperator, ix)
op = isempty(ix.controls) ? sim_op : Control(sim_op, tuple(map(c->getindex(c, 2), ix.controls)...))
sim_ix = Instruction(op, ix.targets)
add_instruction!(c, sim_ix)
end
for rt in v.results
sim_rt = StructTypes.constructfrom(Result, rt)
obs = extract_observable(sim_rt)
if !isnothing(obs) && c.observables_simultaneously_measureable && !(rt isa AdjointGradient)
add_to_qubit_observable_mapping!(c, obs, sim_rt.targets)
end
add_to_qubit_observable_set!(c, sim_rt)
push!(c.result_types, sim_rt)
end
return c
end

# semgrep rules can't handle this macro properly yet
function to_circuit(qasm_source::String, inputs)
input_qasm = if endswith(qasm_source, ".qasm") && isfile(qasm_source)
read(qasm_source, String)
else
qasm_source
end
endswith(input_qasm, "\n") || (input_qasm *= "\n")
parsed = parse_qasm(input_qasm)
visitor = QasmProgramVisitor(inputs)
visitor(parsed)
return to_circuit(visitor)
end
to_circuit(qasm_source::String) = to_circuit(qasm_source, Dict{String, Float64}())
19 changes: 10 additions & 9 deletions src/custom_gates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,22 @@ end
qubit_count(g::MultiRZ) = 1

"""
MultiQubitPhaseShift{N}(angle)
GPhase{N}(angle)

Global phase shift on `N` qubits. Equivalent to
the OpenQASM3 built-in [`gphase` gate](https://openqasm.com/language/gates.html#gphase).
Controls/negative controls applied to this gate control
which states are rotated, so that `Control(g::MultiQubitPhaseShift{2})` will apply the rotation
which states are rotated, so that `Control(g::GPhase{2})` will apply the rotation
to the `|11>` state.
"""
mutable struct MultiQubitPhaseShift{N} <: AngledGate{1}
mutable struct GPhase{N} <: AngledGate{1}
angle::NTuple{1,Union{Real,FreeParameter}}
pow_exponent::Float64
MultiQubitPhaseShift{N}(angle::T, pow_exponent::Float64=1.0) where {N, T<:NTuple{1,Union{Real,FreeParameter}}} = new(angle, pow_exponent)
GPhase{N}(angle::T, pow_exponent::Float64=1.0) where {N, T<:NTuple{1,Union{Real,FreeParameter}}} = new(angle, pow_exponent)
end
matrix_rep_raw(g::MultiQubitPhaseShift{N}) where {N} = Diagonal(SVector{2^N, ComplexF64}(exp(im*g.angle[1]) for _ in 1:2^N))
qubit_count(g::MultiQubitPhaseShift{N}) where {N} = N
matrix_rep_raw(g::GPhase{N}) where {N} = Diagonal(SVector{2^N, ComplexF64}(exp(im*g.angle[1]) for _ in 1:2^N))
qubit_count(g::GPhase{N}) where {N} = N
StructTypes.constructfrom(::Type{GPhase}, nt::Quasar.CircuitInstruction) = GPhase{length(nt.targets)}(only(nt.arguments), nt.exponent)

function apply_gate!(
factor::ComplexF64,
Expand All @@ -75,7 +76,7 @@ for (V, f) in ((true, :conj), (false, :identity))
apply_gate!(::Val{$V}, g::MultiRZ, state_vec::AbstractStateVector{T}, t::Int) where {T<:Complex} = apply_gate!(Val($V), Rz(g.angle, g.pow_exponent), state_vec, t)
apply_gate!(::Val{$V}, g::MultiRZ, state_vec::AbstractStateVector{T}, t1::Int,t2::Int,) where {T<:Complex} = apply_gate!(Val($V), ZZ(g.angle, g.pow_exponent), state_vec, t1, t2)
apply_gate!(::Val{$V}, g::MultiRZ, state_vec::AbstractStateVector{T}, ts::Vararg{Int,N}) where {T<:Complex,N} = apply_gate!($f(-im * g.angle[1] / 2.0), PauliEigenvalues(Val(N)), state_vec, ts...)
apply_gate!(::Val{$V}, g::MultiQubitPhaseShift{N}, state_vec::AbstractStateVector{T}, ts::Vararg{Int,N}) where {T<:Complex, N} = apply_gate!($f(exp(im*g.angle[1]*g.pow_exponent)), state_vec, ts...)
apply_gate!(::Val{$V}, g::GPhase{N}, state_vec::AbstractStateVector{T}, ts::Vararg{Int,N}) where {T<:Complex, N} = apply_gate!($f(exp(im*g.angle[1]*g.pow_exponent)), state_vec, ts...)
end
end

Expand Down Expand Up @@ -119,7 +120,7 @@ Control(g::Control{G, BC}, bitvals::NTuple{0, Int}, pow_exponent::Float64=1.0) w
Control(g::G, bitvals::NTuple{0, Int}, pow_exponent::Float64=1.0) where {G<:Gate} = g
Base.copy(c::Control{G, B}) where {G<:Gate, B} = Control(copy(c.g), c.bitvals, c.pow_exponent)
qubit_count(c::Control{G, B}) where {G<:Gate, B} = qubit_count(c.g) + B
qubit_count(c::Control{MultiQubitPhaseShift{N}, B}) where {N, B} = N
qubit_count(c::Control{GPhase{N}, B}) where {N, B} = N
function matrix_rep_raw(c::Control{G, B}) where {G<:Gate, B}
inner_mat = matrix_rep(c.g)
inner_qc = qubit_count(c.g)
Expand All @@ -134,7 +135,7 @@ function matrix_rep_raw(c::Control{G, B}) where {G<:Gate, B}
end
return full_mat
end
function matrix_rep_raw(c::Control{MultiQubitPhaseShift{N}, B}) where {N, B}
function matrix_rep_raw(c::Control{GPhase{N}, B}) where {N, B}
g_mat = matrix_rep(c.g)
qc = N
ctrl_ix = 0
Expand Down
Loading
Loading