Skip to content

Commit

Permalink
minor
Browse files Browse the repository at this point in the history
  • Loading branch information
harshangrjn committed Oct 9, 2022
1 parent 73c8b5c commit 25873fd
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 32 deletions.
7 changes: 3 additions & 4 deletions src/chull.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
Utility function for `convex_hull`. Given an ordered triplet, this function returns if three
points are collinear, oriented in clock-wise or anticlock-wise direction.
"""
function _orientation(x::Tuple{<:Number, <:Number}, y::Tuple{<:Number, <:Number}, z::Tuple{<:Number, <:Number})

function _orientation(x::Tuple{<:Number, <:Number},
y::Tuple{<:Number, <:Number},
z::Tuple{<:Number, <:Number})
a = ((y[2] - x[2]) * (z[1] - y[1]) - (y[1] - x[1]) * (z[2] - y[2]))

if isapprox(a, 0, atol=1e-6)
Expand All @@ -15,7 +16,6 @@ function _orientation(x::Tuple{<:Number, <:Number}, y::Tuple{<:Number, <:Number}
else
return 2 # counterclock-wise
end

end

"""
Expand All @@ -38,7 +38,6 @@ function _lt_filter(a::Tuple{<:Number, <:Number}, b::Tuple{<:Number, <:Number})
else
return false
end

end

"""
Expand Down
17 changes: 7 additions & 10 deletions src/constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function constraint_gates_onoff_per_depth(qcm::QuantumCircuitModel)
return
end

function constraint_gate_initial_condition(qcm::QuantumCircuitModel)
function constraint_initial_gate_condition(qcm::QuantumCircuitModel)

num_gates = size(qcm.data["gates_real"])[3]

Expand All @@ -33,7 +33,7 @@ function constraint_gate_initial_condition(qcm::QuantumCircuitModel)
return
end

function constraint_gate_intermediate_products(qcm::QuantumCircuitModel)
function constraint_intermediate_products(qcm::QuantumCircuitModel)

num_gates = size(qcm.data["gates_real"])[3]
max_depth = qcm.data["maximum_depth"]
Expand All @@ -50,7 +50,7 @@ function constraint_gate_intermediate_products(qcm::QuantumCircuitModel)
return
end

function constraint_gate_target_condition(qcm::QuantumCircuitModel)
function constraint_target_gate_condition(qcm::QuantumCircuitModel)

max_depth = qcm.data["maximum_depth"]
num_gates = size(qcm.data["gates_real"])[3]
Expand All @@ -77,7 +77,6 @@ function constraint_complex_to_real_symmetry(qcm::QuantumCircuitModel)
JuMP.@constraint(qcm.model, qcm.variables[:U_var][i,j,d] == qcm.variables[:U_var][i+1,j+1,d])
JuMP.@constraint(qcm.model, qcm.variables[:U_var][i,j+1,d] == -qcm.variables[:U_var][i+1,j,d]) # This seems to slow down the solution search
end


return
end
Expand Down Expand Up @@ -116,7 +115,7 @@ function constraint_gate_product_linearization(qcm::QuantumCircuitModel)
return
end

function constraint_gate_initial_condition_compact(qcm::QuantumCircuitModel)
function constraint_initial_gate_condition_compact(qcm::QuantumCircuitModel)

num_gates = size(qcm.data["gates_real"])[3]

Expand All @@ -126,7 +125,7 @@ function constraint_gate_initial_condition_compact(qcm::QuantumCircuitModel)
return
end

function constraint_gate_intermediate_products_compact(qcm::QuantumCircuitModel)
function constraint_intermediate_products_compact(qcm::QuantumCircuitModel)

num_gates = size(qcm.data["gates_real"])[3]
max_depth = qcm.data["maximum_depth"]
Expand All @@ -137,14 +136,13 @@ function constraint_gate_intermediate_products_compact(qcm::QuantumCircuitModel)
return
end

function constraint_gate_target_condition_compact(qcm::QuantumCircuitModel)
function constraint_target_gate_condition_compact(qcm::QuantumCircuitModel)

max_depth = qcm.data["maximum_depth"]
decomposition_type = qcm.data["decomposition_type"]

U_var = qcm.variables[:U_var]

# For correct implementation of this, use MutableArithmetics.jl >= v0.2.11
if decomposition_type in ["exact_optimal", "exact_feasible"]
JuMP.@constraint(qcm.model, U_var[:,:,max_depth] .== qcm.data["target_gate"][:,:])

Expand All @@ -155,14 +153,13 @@ function constraint_gate_target_condition_compact(qcm::QuantumCircuitModel)
return
end

function constraint_gate_target_condition_glphase(qcm::QuantumCircuitModel)
function constraint_target_gate_condition_glphase(qcm::QuantumCircuitModel)

max_depth = qcm.data["maximum_depth"]
n_r = size(qcm.data["gates_real"])[1]
n_c = size(qcm.data["gates_real"])[2]

U_var = qcm.variables[:U_var]
# ref_nonzero_r, ref_nonzero_c = QCO._get_nonzero_idx_of_real_target(qcm.data::Dict{String,Any})

if qcm.data["are_gates_real"]
ref_nonzero_r, ref_nonzero_c = QCO._get_nonzero_idx_of_complex_matrix(Array{Complex{Float64},2}(qcm.data["target_gate"]))
Expand Down
5 changes: 2 additions & 3 deletions src/data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ function _populate_data_angle_discretization!(data::Dict{String, Any}, params::D

end
end

end

return data
Expand Down Expand Up @@ -529,7 +528,7 @@ end
Given an input string representing the gate and number of qubits of the circuit, this function returns a full-sized
gate with respect to the input number of qubits. For example, if `num_qubits = 3` and the input gate in `H_3`
(Hadamard on third qubit), then this function returns `IGate IGate HGate`, where IGate and HGate are single
(Hadamard on third qubit), then this function returns `IGate IGate HGate`, where IGate and HGate are single
qubit Identity and Hadamard gates, respectively. Note that `angle` vector is an optional input which is
necessary when the input gate is parametrized by Euler angles.
"""
Expand Down Expand Up @@ -638,7 +637,7 @@ end
Given an input string with kronecker symbols representing the gate and number of qubits of
the circuit, this function returns a full-sized gate with respect to the input number of qubits.
For example, if `num_qubits = 3` and the input gate in `I_1xT_2xH_3`, then this function returns
`IGateTGateHGate`, where IGate, TGate and HGate are single-qubit Identity, T and
`IGateTGateHGate`, where IGate, TGate and HGate are single-qubit Identity, T and
Hadamard gates, respectively. Two qubit gates can also be used as one of the input gates, for ex. `I_1xCV_2_3xH_4`.
Note that this function currently does not support an input gate parametrized with Euler angles.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/gates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2049,5 +2049,5 @@ GR(\theta, \phi) = \exp \left(-i \sum_{i=1}^{3} (\cos(\phi)X_i + \sin(\phi)Y_i)
"""
function GRGate(num_qubits::Int64, θ::Number, ϕ::Number)

return QCO.round_complex_values(QCO.kron_multi_qubit_gate(num_qubits, QCO.RGate(θ,ϕ)))
return QCO.round_complex_values(QCO.multi_qubit_global_gate(num_qubits, QCO.RGate(θ,ϕ)))
end
14 changes: 7 additions & 7 deletions src/qc_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ function constraint_QCModel_balas(qcm::QuantumCircuitModel)

QCO.constraint_single_gate_per_depth(qcm)
QCO.constraint_gates_onoff_per_depth(qcm)
QCO.constraint_gate_initial_condition(qcm)
QCO.constraint_gate_intermediate_products(qcm)
QCO.constraint_initial_gate_condition(qcm)
QCO.constraint_intermediate_products(qcm)
QCO.constraint_gate_product_linearization(qcm)
QCO.constraint_gate_target_condition(qcm)
QCO.constraint_target_gate_condition(qcm)
QCO.constraint_cnot_gate_bounds(qcm)
(qcm.data["decomposition_type"] == "approximate") && (QCO.constraint_slack_var_outer_approximation(qcm))
(!qcm.data["are_gates_real"]) && (QCO.constraint_complex_to_real_symmetry(qcm))
Expand Down Expand Up @@ -104,14 +104,14 @@ end
function constraint_QCModel_compact(qcm::QuantumCircuitModel)

QCO.constraint_single_gate_per_depth(qcm)
QCO.constraint_gate_initial_condition_compact(qcm)
QCO.constraint_gate_intermediate_products_compact(qcm)
QCO.constraint_initial_gate_condition_compact(qcm)
QCO.constraint_intermediate_products_compact(qcm)
QCO.constraint_gate_product_linearization(qcm)

if qcm.data["decomposition_type"] == "optimal_global_phase"
QCO.constraint_gate_target_condition_glphase(qcm)
QCO.constraint_target_gate_condition_glphase(qcm)
else
QCO.constraint_gate_target_condition_compact(qcm)
QCO.constraint_target_gate_condition_compact(qcm)
end

QCO.constraint_cnot_gate_bounds(qcm)
Expand Down
25 changes: 18 additions & 7 deletions src/utility.jl
Original file line number Diff line number Diff line change
Expand Up @@ -497,16 +497,15 @@ function kron_two_qubit_gate(num_qubits::Int64, M::Array{Complex{Float64},2}, c_
end

"""
kron_multi_qubit_gate(num_qubits::Int64, M::Array{Complex{Float64},2})
multi_qubit_global_gate(num_qubits::Int64, M::Array{Complex{Float64},2})
Given number of qubits of the circuit and any complex-valued one-qubit gate in it's matrix form,
this function returns a multi-qubit global gate, after applying it simultaneously on all the qubits.
This function supports any number of integer-valued qubits. For example, given `G` and `num_qubits = 3`,
this function returns `G ⨷ G ⨷ G`.
Given number of qubits of the circuit and any complex-valued one-qubit gate (`G``) in it's matrix form,
this function returns a multi-qubit global gate, by applying `G` simultaneously on all the qubits.
For example, given `G` and `num_qubits = 3`, this function returns `G⨂G⨂G`.
"""
function kron_multi_qubit_gate(num_qubits::Int64, M::Array{Complex{Float64},2})
function multi_qubit_global_gate(num_qubits::Int64, M::Array{Complex{Float64},2})
if size(M)[1] != 2
Memento.error(_LOGGER, "Input should be an one-qubit R gate")
Memento.error(_LOGGER, "Input should be an one-qubit gate")
end

M_kron = 1
Expand Down Expand Up @@ -714,6 +713,12 @@ function _determinant_test_for_infeasibility(data::Dict{String,Any})

end

"""
_get_nonzero_idx_of_complex_to_real_matrix(M::Array{Float64,2})
A helper function for global phase constraints: Given a complex to real reformulated matrix, `M`, using `QCO.complex_to_real_gate`, this function
returns the first non-zero index it locates within `M`.
"""
function _get_nonzero_idx_of_complex_to_real_matrix(M::Array{Float64,2})
for i=1:2:size(M)[1], j=1:2:size(M)[2]
if !isapprox(M[i,j], 0, atol=1E-6) || !isapprox(M[i,j+1], 0, atol=1E-6)
Expand All @@ -722,6 +727,12 @@ function _get_nonzero_idx_of_complex_to_real_matrix(M::Array{Float64,2})
end
end

"""
_get_nonzero_idx_of_complex_matrix(M::Array{Complex{Float64},2})
A helper function for global phase constraints: Given a complex matrix, `M`, this
function returns the first non-zero index it locates within `M`, either in real or the complex part.
"""
function _get_nonzero_idx_of_complex_matrix(M::Array{Complex{Float64},2})
for i=1:size(M)[1], j=1:size(M)[2]
if !isapprox(M[i,j], 0, atol=1E-6)
Expand Down

0 comments on commit 25873fd

Please sign in to comment.