Download julia/yao_types.jl from Snapkitty/quantum-kernel: direct link, hf CLI and curl.
- Browser
- Download file 11.2 kB
-
https://huggingface.co/Snapkitty/quantum-kernel/resolve/main/julia/yao_types.jl
- Command line
-
hf download hf://Snapkitty/quantum-kernel/julia/yao_types.jl
-
curl -L -o yao_types.jl https://huggingface.co/Snapkitty/quantum-kernel/resolve/main/julia/yao_types.jl
11.2 kB
| # yao_types.jl β Core Yao.jl block hierarchy + Topological types | |
| module YaoTypes | |
| using LinearAlgebra | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Abstract Block Hierarchy | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| abstract type AbstractBlock end | |
| abstract type CompositeBlock <: AbstractBlock end | |
| struct PrimitiveGate <: AbstractBlock | |
| name::String | |
| params::Vector{Float64} | |
| nqubits::Int | |
| mat::Matrix{ComplexF64} | |
| end | |
| struct ChainBlock <: CompositeBlock | |
| nqubits::Int | |
| blocks::Vector{AbstractBlock} | |
| end | |
| struct KronBlock <: CompositeBlock | |
| nqubits::Int | |
| locs::Vector{Int} | |
| blocks::Vector{AbstractBlock} | |
| end | |
| struct PutBlock <: CompositeBlock | |
| nqubits::Int | |
| locs::Vector{Int} | |
| block::AbstractBlock | |
| end | |
| struct ControlBlock <: CompositeBlock | |
| nqubits::Int | |
| ctrl_locs::Vector{Int} | |
| ctrl_bits::Vector{Int} | |
| block::AbstractBlock | |
| end | |
| struct MeasureBlock <: AbstractBlock | |
| nqubits::Int | |
| locs::Vector{Int} | |
| end | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # TOPOLOGICAL TYPES: Braids, Defects, Anyons | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| struct BraidWord | |
| generators::Vector{Int} | |
| edge_indices::Vector{Int} | |
| n_strands::Int | |
| function BraidWord(gens::Vector{Int}, edges::Vector{Int}, n_strands::Int) | |
| length(gens) == length(edges) | |
| new(gens, edges, n_strands) | |
| end | |
| end | |
| BraidWord(n_strands::Int) = BraidWord(Int[], Int[], n_strands) | |
| struct DefectPair | |
| id::String | |
| anyon_type::Symbol | |
| smooth_defect::Tuple{Int,Int} | |
| rough_defect::Tuple{Int,Int} | |
| braid_trajectory::Vector{Tuple{Int,Int}} | |
| end | |
| mutable struct DefectTracker | |
| defects::Dict{String, DefectPair} | |
| fusion_rules::Dict{Tuple{Symbol,Symbol}, Vector{Symbol}} | |
| lattice_size::Tuple{Int,Int} | |
| time_step::Int | |
| function DefectTracker(lattice_size::Tuple{Int,Int}=(20,20)) | |
| rules = Dict( | |
| (:fibonacci, :fibonacci) => [:vacuum, :fibonacci], | |
| (:ising, :ising) => [:vacuum, :fermion], | |
| (:toric, :toric) => [:vacuum], | |
| ) | |
| new(Dict{String, DefectPair}(), rules, lattice_size, 0) | |
| end | |
| end | |
| struct LatticeSurgeryOp | |
| op_type::Symbol | |
| defect_ids::Vector{String} | |
| basis::Symbol | |
| ancilla_id::Union{String, Nothing} | |
| end | |
| function allocate_defect_pair!(tracker::DefectTracker, id::String, anyon_type::Symbol, | |
| smooth_pos::Tuple{Int,Int}, rough_pos::Tuple{Int,Int}) | |
| pair = DefectPair(id, anyon_type, smooth_pos, rough_pos, [smooth_pos, rough_pos]) | |
| tracker.defects[id] = pair | |
| return pair | |
| end | |
| function braid_defects!(tracker::DefectTracker, id1::String, id2::String, direction::Int) | |
| d1 = tracker.defects[id1] | |
| d2 = tracker.defects[id2] | |
| new_traj1 = vcat(d1.braid_trajectory, [d2.rough_defect]) | |
| new_traj2 = vcat(d2.braid_trajectory, [d1.rough_defect]) | |
| tracker.defects[id1] = DefectPair(d1.id, d1.anyon_type, d1.smooth_defect, | |
| d2.rough_defect, new_traj1) | |
| tracker.defects[id2] = DefectPair(d2.id, d2.anyon_type, d2.smooth_defect, | |
| d1.rough_defect, new_traj2) | |
| tracker.time_step += 1 | |
| end | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Accessors & Constructors | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| nqubits(b::AbstractBlock) = b.nqubits | |
| nqubits(b::PrimitiveGate) = b.nqubits | |
| const SQRT2 = sqrt(2.0) | |
| const IM = ComplexF64(0, 1) | |
| H() = PrimitiveGate("H", Float64[], 1, ComplexF64[1 1; 1 -1] / SQRT2) | |
| X() = PrimitiveGate("X", Float64[], 1, ComplexF64[0 1; 1 0]) | |
| Y() = PrimitiveGate("Y", Float64[], 1, ComplexF64[0 -IM; IM 0]) | |
| Z() = PrimitiveGate("Z", Float64[], 1, ComplexF64[1 0; 0 -1]) | |
| S() = PrimitiveGate("S", Float64[], 1, ComplexF64[1 0; 0 IM]) | |
| Sdg() = PrimitiveGate("Sdg", Float64[], 1, ComplexF64[1 0; 0 -IM]) | |
| T() = PrimitiveGate("T", Float64[], 1, ComplexF64[1 0; 0 exp(IM*Ο/4)]) | |
| Tdg() = PrimitiveGate("Tdg", Float64[], 1, ComplexF64[1 0; 0 exp(-IM*Ο/4)]) | |
| SX() = PrimitiveGate("SX", Float64[], 1, ComplexF64[(1+IM)/2 (1-IM)/2; (1-IM)/2 (1+IM)/2]) | |
| Rx(ΞΈ) = PrimitiveGate("Rx", [ΞΈ], 1, ComplexF64[cos(ΞΈ/2) -IM*sin(ΞΈ/2); -IM*sin(ΞΈ/2) cos(ΞΈ/2)]) | |
| Ry(ΞΈ) = PrimitiveGate("Ry", [ΞΈ], 1, ComplexF64[cos(ΞΈ/2) -sin(ΞΈ/2); sin(ΞΈ/2) cos(ΞΈ/2)]) | |
| Rz(ΞΈ) = PrimitiveGate("Rz", [ΞΈ], 1, ComplexF64[exp(-IM*ΞΈ/2) 0; 0 exp(IM*ΞΈ/2)]) | |
| CNOT() = PrimitiveGate("CX", Float64[], 2, ComplexF64[1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0]) | |
| CZ() = PrimitiveGate("CZ", Float64[], 2, ComplexF64[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 -1]) | |
| function chain(nq::Int, blocks::AbstractBlock...) | |
| ChainBlock(nq, collect(blocks)) | |
| end | |
| chain(nq::Int, blocks::Vector{<:AbstractBlock}) = ChainBlock(nq, blocks) | |
| function kron(nq::Int, pairs::Pair{Int,<:AbstractBlock}...) | |
| locs = [p.first for p in pairs] | |
| blks = [p.second for p in pairs] | |
| KronBlock(nq, locs, blks) | |
| end | |
| put(nq::Int, locs::Vector{Int}, block::AbstractBlock) = PutBlock(nq, locs, block) | |
| function control(nq::Int, ctrl_locs::Vector{Int}, target::Pair{Int,<:AbstractBlock}) | |
| ControlBlock(nq, ctrl_locs, ones(Int, length(ctrl_locs)), PutBlock(nq, [target.first], target.second)) | |
| end | |
| control(nq::Int, ctrl_locs::Vector{Int}, block::AbstractBlock) = ControlBlock(nq, ctrl_locs, ones(Int, length(ctrl_locs)), block) | |
| measure(nq::Int, locs::Vector{Int}) = MeasureBlock(nq, locs) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Heron-Native Decomposition | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| function decompose_to_heron(block::AbstractBlock)::AbstractBlock | |
| if block isa PrimitiveGate | |
| return _decompose_primitive(block) | |
| elseif block isa ChainBlock | |
| return ChainBlock(block.nqubits, decompose_to_heron.(block.blocks)) | |
| elseif block isa KronBlock | |
| return KronBlock(block.nqubits, block.locs, decompose_to_heron.(block.blocks)) | |
| elseif block isa PutBlock | |
| return PutBlock(block.nqubits, block.locs, decompose_to_heron(block.block)) | |
| elseif block isa ControlBlock | |
| return ControlBlock(block.nqubits, block.ctrl_locs, block.ctrl_bits, decompose_to_heron(block.block)) | |
| elseif block isa MeasureBlock | |
| return block | |
| else | |
| error("Unknown block type: $(typeof(block))") | |
| end | |
| end | |
| function _decompose_primitive(g::PrimitiveGate)::AbstractBlock | |
| name = g.name | |
| params = g.params | |
| if name in ("Rz", "SX", "CX", "CNOT") | |
| return g | |
| elseif name == "Ry" | |
| ΞΈ = params[1] | |
| return chain(1, Rz(Ο/2), SX(), Rz(ΞΈ), SX(), Rz(-Ο/2)) | |
| elseif name == "Rx" | |
| ΞΈ = params[1] | |
| return chain(1, Rz(-Ο/2), SX(), Rz(ΞΈ), SX(), Rz(Ο/2)) | |
| elseif name == "H" | |
| return chain(1, Rz(Ο/2), SX(), Rz(Ο/2), SX(), Rz(Ο/2)) | |
| elseif name == "X" | |
| return chain(1, SX(), SX()) | |
| elseif name == "Y" | |
| return chain(1, SX(), Rz(Ο), SX()) | |
| elseif name == "Z" | |
| return Rz(Ο) | |
| elseif name == "S" | |
| return Rz(Ο/2) | |
| elseif name == "Sdg" | |
| return Rz(-Ο/2) | |
| elseif name == "T" | |
| return Rz(Ο/4) | |
| elseif name == "Tdg" | |
| return Rz(-Ο/4) | |
| elseif name == "CZ" | |
| return g | |
| else | |
| return g | |
| end | |
| end | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Feature Map Parameters | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| struct FeatureMapParams | |
| data::Array{Float64,3} | |
| n_layers::Int | |
| n_qubits::Int | |
| end | |
| function FeatureMapParams(n_layers::Int, n_qubits::Int; init_scale::Float64=0.1) | |
| data = randn(n_layers, n_qubits, 3) * init_scale .+ 1.0 | |
| FeatureMapParams(data, n_layers, n_qubits) | |
| end | |
| Base.getindex(p::FeatureMapParams, i...) = p.data[i...] | |
| Base.setindex!(p::FeatureMapParams, v, i...) = (p.data[i...] = v) | |
| Base.size(p::FeatureMapParams) = size(p.data) | |
| Base.length(p::FeatureMapParams) = length(p.data) | |
| Base.eachindex(p::FeatureMapParams) = eachindex(p.data) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Pauli String & Heavy-Hex Topology | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| struct PauliString | |
| paulis::Vector{Char} | |
| end | |
| PauliString(n::Int) = PauliString(rand(['I','X','Y','Z'], n)) | |
| const HERON_EDGES_0 = [ | |
| (0, 1), (1, 2), | |
| (0, 3), (1, 3), (1, 4), (2, 4), (2, 5), | |
| (3, 4), (4, 5), (5, 6), | |
| (3, 7), (4, 7), (4, 8), (5, 8), (5, 9), (6, 9), | |
| (7, 8), (8, 9) | |
| ] | |
| const HERON_EDGE_INDEX = Dict(edge => i for (i, edge) in enumerate(HERON_EDGES_0)) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Exports | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export AbstractBlock, PrimitiveGate, ChainBlock, KronBlock, PutBlock, ControlBlock, MeasureBlock | |
| export nqubits | |
| export H, X, Y, Z, S, Sdg, T, Tdg, SX, Rx, Ry, Rz, CNOT, CZ | |
| export chain, kron, put, control, measure | |
| export decompose_to_heron | |
| export FeatureMapParams, PauliString | |
| export HERON_EDGES_0, HERON_EDGE_INDEX | |
| export BraidWord, DefectPair, DefectTracker, LatticeSurgeryOp | |
| export allocate_defect_pair!, braid_defects! | |
| end # module YaoTypes | |