Skip to content

Commit

Permalink
Merge pull request #67 from harshangrjn/log_updates
Browse files Browse the repository at this point in the history
Log updates
  • Loading branch information
harshangrjn authored Aug 7, 2023
2 parents c23a46d + 08def47 commit 0fbdc0b
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 19 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
QuantumCircuitOpt.jl Change Log
===============================

### v0.5.7
- Clean up in log.jl to validate circuit decomposition upto global phase
- Added `parametrized_hermitian_gates` in examples

### v0.5.6
- Video link to SC22 presentation added

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "QuantumCircuitOpt"
uuid = "88128e30-b60a-4e54-ab02-1050a5f92a36"
authors = ["Harsha Nagarajan"]
version = "0.5.6"
version = "0.5.7"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
9 changes: 5 additions & 4 deletions examples/2qubit_gates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ function hadamard_coin()
return Dict{String, Any}(

"num_qubits" => 2,
"maximum_depth" => 14,
"maximum_depth" => 12,
"elementary_gates" => ["Y_1", "Y_2", "Z_1", "Z_2", "T_2", "Tdagger_1", "Sdagger_1", "SX_1", "SXdagger_2", "CNot_2_1", "CNot_1_2", "Identity"],
"target_gate" => QCOpt.HCoinGate(),
"objective" => "minimize_depth",
Expand All @@ -286,9 +286,10 @@ function GroverDiffusion_using_HX()
"num_qubits" => 2,
"maximum_depth" => 10,
"elementary_gates" => ["X_1", "X_1xX_2", "H_1xH_2", "X_2", "H_1", "H_2", "CNot_1_2", "Identity"],
# "elementary_gates" => ["X_1", "X_2", "H_1", "H_2", "CNot_1_2", "Identity"],
"target_gate" => QCOpt.GroverDiffusionGate(),
"objective" => "minimize_depth",
"decomposition_type" => "exact_optimal",
"decomposition_type" => "optimal_global_phase",
)
end

Expand All @@ -303,7 +304,7 @@ function GroverDiffusion_using_Clifford()
"elementary_gates" => ["X_1", "X_2", "H_1", "H_2", "S_1", "S_2", "T_1", "T_2", "Y_1", "Y_2", "CNot_1_2", "Identity"],
"target_gate" => QCOpt.GroverDiffusionGate(),
"objective" => "minimize_depth",
"decomposition_type" => "exact_optimal",
"decomposition_type" => "optimal_global_phase",
)
end

Expand Down Expand Up @@ -424,7 +425,7 @@ function CNOT_using_GR()
"elementary_gates" => ["GR", "R_1", "R_2", "CZ_1_2", "Identity"],
"target_gate" => QCOpt.CNotGate(),
"objective" => "minimize_depth",
"decomposition_type" => "exact_optimal",
"decomposition_type" => "optimal_global_phase",
"GR_θ_discretization" => -2π/2:2π,
"GR_ϕ_discretization" => [0],
"R_θ_discretization" => 0:π/4:π,
Expand Down
3 changes: 2 additions & 1 deletion examples/3qubit_gates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ function toffoli_left()
"maximum_depth" => 7,
"elementary_gates" => ["H_3", "T_1", "T_2", "T_3", "Tdagger_1", "Tdagger_2", "Tdagger_3", "CNot_1_2", "CNot_2_3", "CNot_1_3", "Identity"],
"target_gate" => target_gate(),
"objective" => "minimize_depth"
"objective" => "minimize_depth",
"decomposition_type" => "exact_optimal"
)
end

Expand Down
4 changes: 3 additions & 1 deletion examples/decompose_all_gates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@ decompose_gates = [
"quantum_fulladder",
"double_toffoli",
#-- 5-qubit gates --#
"RX_on_5qubits"
"RX_on_5qubits",
#-- paramterized gates --#
"parametrized_hermitian_gates"
]
2 changes: 1 addition & 1 deletion examples/optimizers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
function get_gurobi()
return JuMP.optimizer_with_attributes(Gurobi.Optimizer,
MOI.Silent() => false,
# "MIPFocus" => 3, # Focus on optimality over feasibility
# "MIPFocus" => 3, # Focus on optimality over feasibility
"Presolve" => 1)
end

Expand Down
29 changes: 29 additions & 0 deletions examples/parametrized_gates.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function parametrized_hermitian_gates()

function target_gate(num_qubits, i, j, t)
A = Array{Complex{Float64},2}(zeros(2^num_qubits, 2^num_qubits))

A[i,j] = 1.0 + 0.0im
A[j,i] = 1.0 + 0.0im

return exp(im*A*t)
end

num_qubits = 2
A_i = 1 # 1 <= i,j <= num_qubits
A_j = 4 # 1 <= i,j <= num_qubits
t = 2.5

return Dict{String, Any}(
"num_qubits" => num_qubits,
"maximum_depth" => 10,
"elementary_gates" => ["RX_1", "RX_2", "CRX_1_2", "CRX_2_1", "CNot_1_2", "CNot_2_1", "Identity"],
# "elementary_gates" => ["RX_1", "RX_2", "RX_3", "CRX_1_2", "CRX_2_1", "CRX_2_3", "CRX_3_2", "CNot_1_2", "CNot_2_1", "CNot_2_3", "CNot_3_2", "Identity"],
"target_gate" => target_gate(num_qubits, A_i, A_j, t),
"objective" => "minimize_depth",
"decomposition_type" => "exact_optimal",

"RX_discretization" => [t*2,-t*2],
"CRX_discretization" => [t*2,-t*2],
)
end
2 changes: 2 additions & 0 deletions examples/run_examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ include("2qubit_gates.jl")
include("3qubit_gates.jl")
include("4qubit_gates.jl")
include("5qubit_gates.jl")
include("parametrized_gates.jl")
include("decompose_all_gates.jl")

# decompose_gates = ["iSwap"]
Expand All @@ -26,6 +27,7 @@ for gates = 1:length(decompose_gates)
params = getfield(Main, Symbol(decompose_gates[gates]))()

model_options = Dict{Symbol, Any}(
:model_type => "compact_formulation",
:convex_hull_gate_constraints => false,
:idempotent_gate_constraints => false,
:unitary_constraints => false,
Expand Down
38 changes: 27 additions & 11 deletions src/log.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,12 @@ end
function get_postprocessed_circuit(results::Dict{String, Any}, data::Dict{String, Any})

gates_sol = Array{String,1}()
id_sequence = Array{Int64,1}()
id_sequence = QCO._gate_id_sequence(results["solution"]["z_bin_var"], data["maximum_depth"])
(data["decomposition_type"] in ["exact_optimal", "exact_feasible", "optimal_global_phase"]) && QCO.validate_circuit_decomposition(data, id_sequence)

for d = 1:data["maximum_depth"]
id = findall(isone.(round.(abs.(results["solution"]["z_bin_var"][:,d]), digits=3)))[1]
push!(id_sequence, id)

gate_id = data["gates_dict"]["$id"]

gate_id = data["gates_dict"]["$(id_sequence[d])"]

if !("Identity" in gate_id["type"])

Expand Down Expand Up @@ -165,8 +164,6 @@ function get_postprocessed_circuit(results::Dict{String, Any}, data::Dict{String
end
end
end

(data["decomposition_type"] in ["exact_optimal", "exact_feasible", "optimal_global_phase"]) && QCO.validate_circuit_decomposition(data, id_sequence)

gates_sol_compressed = QCO.get_depth_compressed_circuit(data["num_qubits"], gates_sol)

Expand All @@ -178,8 +175,9 @@ end
This function validates the circuit decomposition if it is indeed exact with respect to the specified target gate.
"""
function validate_circuit_decomposition(data::Dict{String, Any}, id_sequence::Array{Int64,1})

function validate_circuit_decomposition(data::Dict{String, Any}, id_sequence::Array{Int64,1}; error_message = true)
valid_status = false

M_sol = Array{Complex{Float64},2}(Matrix(LA.I, 2^(data["num_qubits"]), 2^(data["num_qubits"])))

for i in id_sequence
Expand All @@ -193,8 +191,15 @@ function validate_circuit_decomposition(data::Dict{String, Any}, id_sequence::Ar
target_gate = QCO.real_to_complex_gate(data["target_gate"])
end

(!QCO.isapprox_global_phase(M_sol, convert(Array{Complex{Float64},2}, target_gate))) &&
Memento.error(_LOGGER, "Decomposition is not valid: Problem may be infeasible")
if data["decomposition_type"] in ["exact_optimal", "exact_feasible"]
(QCO.isapprox(M_sol, convert(Array{Complex{Float64},2}, target_gate), atol = 1E-4)) && (valid_status = true)
elseif data["decomposition_type"] in ["optimal_global_phase"]
(QCO.isapprox_global_phase(M_sol, convert(Array{Complex{Float64},2}, target_gate))) && (valid_status = true)
end

(!(valid_status) && error_message) && Memento.error(_LOGGER, "Decomposition is not valid: Problem may be infeasible")

return valid_status
end

"""
Expand Down Expand Up @@ -279,3 +284,14 @@ function get_depth_compressed_circuit(num_qubits::Int64, gates_sol::Array{String

return gates_sol_compressed
end

function _gate_id_sequence(z_val::Matrix{<:Number}, maximum_depth::Int64)
id_sequence = Array{Int64,1}()

for d = 1:maximum_depth
id = findall(isone.(round.(abs.(z_val[:,d]), digits=3)))[1]
push!(id_sequence, id)
end

return id_sequence
end

0 comments on commit 0fbdc0b

Please sign in to comment.