Skip to content

Commit

Permalink
tests clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Harsha Nagarajan committed Dec 4, 2024
1 parent 3549139 commit a7e3b38
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 63 deletions.
4 changes: 2 additions & 2 deletions examples/2qubit_gates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ function revcnot()
"num_qubits" => 2,
"maximum_depth" => 5,
"elementary_gates" => ["H_1", "H_2", "CNot_1_2", "Identity"],
"target_gate" => QCOpt.CNotRevGate(),
"target_gate" => -QCOpt.CNotRevGate(),
"objective" => "minimize_depth",
"decomposition_type" => "exact_optimal"
"decomposition_type" => "optimal_global_phase"
)
end

Expand Down
4 changes: 2 additions & 2 deletions examples/run_examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ include("optimizers.jl")
include("parametrized_gates.jl")
include("decompose_all_gates.jl")

# decompose_gates = ["iSwap"]
decompose_gates = ["revcnot"]

#----------------------------------------------#
# Quantum Circuit Optimization model #
Expand All @@ -29,7 +29,7 @@ for gates = 1:length(decompose_gates)
:convex_hull_gate_constraints => false,
:idempotent_gate_constraints => false,
:fix_unitary_variables => false,
:unitary_complex_conjugate => true,
:unitary_complex_conjugate => 1,
)

global result = QCOpt.run_QCModel(params, qcopt_optimizer; options = model_options)
Expand Down
8 changes: 3 additions & 5 deletions src/constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,6 @@ function constraint_unitary_property(qcm::QuantumCircuitModel)
end

function constraint_unitary_complex_conjugate(qcm::QuantumCircuitModel;
quadratic_constraint = true,
num_gates_bnd = 50)

max_depth = qcm.data["maximum_depth"]
Expand All @@ -571,7 +570,7 @@ function constraint_unitary_complex_conjugate(qcm::QuantumCircuitModel;

num_gates = size(gates_real)[3]

if max_depth >= 2
if (max_depth >= 2) && (qcm.options.unitary_complex_conjugate in [1,2])
JuMP.@constraint(qcm.model, U_var[:, :, (max_depth-1)] .==
qcm.data["target_gate"] *
sum(z_bin_var[i, (max_depth)] *
Expand All @@ -580,7 +579,7 @@ function constraint_unitary_complex_conjugate(qcm::QuantumCircuitModel;
end

# Quadratic constraint
if (max_depth >= 3) && (num_gates <= num_gates_bnd) && (quadratic_constraint)
if (max_depth >= 3) && (num_gates <= num_gates_bnd) && (qcm.options.unitary_complex_conjugate in [2])
Memento.info(_LOGGER, "Applying quadratic unitary complex-congugate constraints")

JuMP.@constraint(qcm.model, U_var[:, :, (max_depth-2)] .==
Expand All @@ -589,8 +588,7 @@ function constraint_unitary_complex_conjugate(qcm::QuantumCircuitModel;
(gates_real[:,:,i]') for i=1:num_gates) *
sum(z_bin_var[i, (max_depth-1)] *
(gates_real[:,:,i]') for i=1:num_gates)
)

)
end

return
Expand Down
6 changes: 2 additions & 4 deletions src/qc_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,9 @@ function variable_QCModel_valid(qcm::QuantumCircuitModel)

if qcm.options.all_valid_constraints == 1
QCO.variable_binary_products(qcm)
qcm.options.unitary_complex_conjugate && QCO.variable_tight_unitary_linearization(qcm) # keeping this optional due to quadratic constraints while testing

elseif qcm.options.all_valid_constraints == 0
qcm.options.unitary_constraints && QCO.variable_binary_products(qcm)
qcm.options.unitary_complex_conjugate && QCO.variable_tight_unitary_linearization(qcm)
end

end
Expand Down Expand Up @@ -135,7 +133,7 @@ function constraint_QCModel_valid(qcm::QuantumCircuitModel)
QCO.constraint_identity_gate_symmetry(qcm)
QCO.constraint_convex_hull_complex_gates(qcm)
QCO.constraint_unitary_property(qcm)
qcm.options.unitary_complex_conjugate && QCO.constraint_unitary_complex_conjugate(qcm)
QCO.constraint_unitary_complex_conjugate(qcm)

elseif qcm.options.all_valid_constraints == 0
qcm.options.commute_gate_constraints && QCO.constraint_commutative_gate_pairs(qcm)
Expand All @@ -145,7 +143,7 @@ function constraint_QCModel_valid(qcm::QuantumCircuitModel)
qcm.options.identity_gate_symmetry_constraints && QCO.constraint_identity_gate_symmetry(qcm)
qcm.options.convex_hull_gate_constraints && QCO.constraint_convex_hull_complex_gates(qcm)
qcm.options.unitary_constraints && QCO.constraint_unitary_property(qcm)
qcm.options.unitary_complex_conjugate && QCO.constraint_unitary_complex_conjugate(qcm)
(qcm.options.unitary_complex_conjugate > 0) && QCO.constraint_unitary_complex_conjugate(qcm)
end

end
Expand Down
4 changes: 2 additions & 2 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mutable struct QCModelOptions
idempotent_gate_constraints :: Bool
convex_hull_gate_constraints :: Bool
unitary_constraints :: Bool
unitary_complex_conjugate :: Bool
unitary_complex_conjugate :: Int64

time_limit :: Float64
relax_integrality :: Bool
Expand All @@ -44,7 +44,7 @@ function get_default_options()
idempotent_gate_constraints = false # true, false
convex_hull_gate_constraints = false # true, false
unitary_constraints = false # true, false
unitary_complex_conjugate = true # true, false
unitary_complex_conjugate = 2 # 0, 1 (linear), 2 (linear + quadratic)

time_limit = 10800 # float value
relax_integrality = false # true, false
Expand Down
66 changes: 40 additions & 26 deletions src/variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,36 +114,57 @@ function variable_gate_products_copy(qcm::QuantumCircuitModel)
return
end

# function variable_gate_products_linearization(qcm::QuantumCircuitModel)
# n_r = size(qcm.data["gates_real"])[1]
# n_c = size(qcm.data["gates_real"])[2]
# max_depth = qcm.data["maximum_depth"]
# num_gates = size(qcm.data["gates_real"])[3]

# if !qcm.options.fix_unitary_variables
# qcm.variables[:zU_var] = JuMP.@variable(qcm.model, -1 <= zU_var[1:n_r, 1:n_c, 1:num_gates, 1:(max_depth-1)] <= 1)
# return
# end

# U_var = qcm.variables[:U_var]
# qcm.variables[:zU_var] = JuMP.@variable(qcm.model, zU_var[1:n_r, 1:n_c, 1:num_gates, 1:(max_depth-1)])

# for d = 1:(max_depth-1), i = 1:n_r, j = 1:n_c, k = 1:num_gates
# U_var_l = JuMP.lower_bound(U_var[i,j,d])
# U_var_u = JuMP.upper_bound(U_var[i,j,d])

# if QCO.is_zero(U_var_l) && QCO.is_zero(U_var_u)
# JuMP.set_lower_bound(zU_var[i,j,k,d], 0)
# JuMP.set_upper_bound(zU_var[i,j,k,d], 0)
# else
# JuMP.set_lower_bound(zU_var[i,j,k,d], -1)
# JuMP.set_upper_bound(zU_var[i,j,k,d], 1)
# end
# end

# return
# end

function variable_gate_products_linearization(qcm::QuantumCircuitModel)
n_r = size(qcm.data["gates_real"])[1]
n_c = size(qcm.data["gates_real"])[2]
max_depth = qcm.data["maximum_depth"]
num_gates = size(qcm.data["gates_real"])[3]
n_r, n_c, num_gates = size(qcm.data["gates_real"])[1:3]
max_depth = qcm.data["maximum_depth"]

if !qcm.options.fix_unitary_variables
qcm.variables[:zU_var] = JuMP.@variable(qcm.model, -1 <= zU_var[1:n_r, 1:n_c, 1:num_gates, 1:(max_depth-1)] <= 1)
return
return
end

U_var = qcm.variables[:U_var]
qcm.variables[:zU_var] = JuMP.@variable(qcm.model, zU_var[1:n_r, 1:n_c, 1:num_gates, 1:(max_depth-1)])

for d = 1:(max_depth-1), i = 1:n_r, j = 1:n_c, k = 1:num_gates
U_var_l = JuMP.lower_bound(U_var[i,j,d])
U_var_u = JuMP.upper_bound(U_var[i,j,d])

if QCO.is_zero(U_var_l) && QCO.is_zero(U_var_u)
JuMP.set_lower_bound(zU_var[i,j,k,d], 0)
JuMP.set_upper_bound(zU_var[i,j,k,d], 0)
else
JuMP.set_lower_bound(zU_var[i,j,k,d], -1)
JuMP.set_upper_bound(zU_var[i,j,k,d], 1)
end
end

return
for d in 1:(max_depth-1), i in 1:n_r, j in 1:n_c, k in 1:num_gates
lb, ub = JuMP.lower_bound(U_var[i, j, d]), JuMP.upper_bound(U_var[i, j, d])
bounds = (QCO.is_zero(lb) && QCO.is_zero(ub)) ? (0, 0) : (-1, 1)
JuMP.set_lower_bound(qcm.variables[:zU_var][i, j, k, d], bounds[1])
JuMP.set_upper_bound(qcm.variables[:zU_var][i, j, k, d], bounds[2])
end
end


# function variable_slack_for_feasibility(qcm::QuantumCircuitModel)
# n_r = size(qcm.data["gates_real"])[1]
# n_c = size(qcm.data["gates_real"])[2]
Expand Down Expand Up @@ -197,11 +218,4 @@ function variable_binary_products(qcm::QuantumCircuitModel)

qcm.variables[:Z_var] = JuMP.@variable(qcm.model, 0 <= Z[1:num_gates, 1:num_gates, 1:max_depth] <= 1)
return
end

function variable_tight_unitary_linearization(qcm::QuantumCircuitModel)
num_gates = size(qcm.data["gates_real"])[3]

qcm.variables[:Z_lin_var] = JuMP.@variable(qcm.model, 0 <= Z_lin_var[1:num_gates, 1:num_gates] <= 1)
return
end
Loading

0 comments on commit a7e3b38

Please sign in to comment.