quantum-kernel / julia /yao_circuit.jl
SNAPKITTYWEST's picture
push from SNAPKITTYWEST/quantum-kernel
5c61046 verified
Raw History Blame Contribute Delete
3.49 kB
# yao_circuit.jl
#
# Circuit simulation utilities for standalone Yao-compatible execution.
# Statevector simulation without external dependencies.
include("yao_types.jl")
using LinearAlgebra
# -----------------------------------------------------------------------
# Statevector Simulation
# -----------------------------------------------------------------------
struct StateVector
n_qubits::Int
amplitudes::Vector{ComplexF64}
end
function StateVector(n_qubits::Int)
amps = zeros(ComplexF64, 2^n_qubits)
amps[1] = 1.0 + 0.0im
return StateVector(n_qubits, amps)
end
function apply_gate!(sv::StateVector, gate::AbstractBlock, target::Int)
mat = gate_matrix(gate)
n = sv.n_qubits
dim = 2^n
for i in 0:dim-1
if (i >> target) & 1 == 0
j = i | (1 << target)
a0 = sv.amplitudes[i+1]
a1 = sv.amplitudes[j+1]
sv.amplitudes[i+1] = mat[1,1] * a0 + mat[1,2] * a1
sv.amplitudes[j+1] = mat[2,1] * a0 + mat[2,2] * a1
end
end
end
function apply_controlled!(sv::StateVector, gate::AbstractBlock, control::Int, target::Int)
mat = gate_matrix(gate)
n = sv.n_qubits
dim = 2^n
for i in 0:dim-1
if ((i >> control) & 1 == 1) && ((i >> target) & 1 == 0)
j = i | (1 << target)
a0 = sv.amplitudes[i+1]
a1 = sv.amplitudes[j+1]
sv.amplitudes[i+1] = mat[1,1] * a0 + mat[1,2] * a1
sv.amplitudes[j+1] = mat[2,1] * a0 + mat[2,2] * a1
end
end
end
# -----------------------------------------------------------------------
# Gate Matrices
# -----------------------------------------------------------------------
function gate_matrix(::H)
s = 1.0/sqrt(2.0)
ComplexF64[s s; s -s]
end
function gate_matrix(::X)
ComplexF64[0 1; 1 0]
end
function gate_matrix(::Y)
ComplexF64[0 -im; im 0]
end
function gate_matrix(::Z)
ComplexF64[1 0; 0 -1]
end
function gate_matrix(::S)
ComplexF64[1 0; 0 im]
end
function gate_matrix(::Sdg)
ComplexF64[1 0; 0 -im]
end
function gate_matrix(::T)
ComplexF64[1 0; 0 exp(im*π/4)]
end
function gate_matrix(::Tdg)
ComplexF64[1 0; 0 exp(-im*π/4)]
end
function gate_matrix(::SX)
ComplexF64[(1+im)/2 (1-im)/2; (1-im)/2 (1+im)/2]
end
function gate_matrix(g::Rz)
θ = g.theta
ComplexF64[exp(-im*θ/2) 0; 0 exp(im*θ/2)]
end
function gate_matrix(g::Ry)
θ = g.theta
c = cos(θ/2)
s = sin(θ/2)
ComplexF64[c -s; s c]
end
function gate_matrix(g::Rx)
θ = g.theta
c = cos(θ/2)
s = sin(θ/2)
ComplexF64[c -im*s; -im*s c]
end
# -----------------------------------------------------------------------
# Measurement
# -----------------------------------------------------------------------
function measure_qubit!(sv::StateVector, target::Int)::Int
n = sv.n_qubits
dim = 2^n
prob_0 = 0.0
for i in 0:dim-1
if (i >> target) & 1 == 0
prob_0 += abs2(sv.amplitudes[i+1])
end
end
outcome = rand() < prob_0 ? 0 : 1
# Collapse
norm_factor = outcome == 0 ? sqrt(prob_0) : sqrt(1.0 - prob_0)
for i in 0:dim-1
bit = (i >> target) & 1
if bit == outcome
sv.amplitudes[i+1] /= norm_factor
else
sv.amplitudes[i+1] = 0.0 + 0.0im
end
end
return outcome
end
function fidelity(sv1::StateVector, sv2::StateVector)::Float64
return abs2(dot(sv1.amplitudes, sv2.amplitudes))
end