aboutsummaryrefslogtreecommitdiff
path: root/src/core/custom_gate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/custom_gate.c')
-rw-r--r--src/core/custom_gate.c202
1 files changed, 101 insertions, 101 deletions
diff --git a/src/core/custom_gate.c b/src/core/custom_gate.c
index dd41635..2dce185 100644
--- a/src/core/custom_gate.c
+++ b/src/core/custom_gate.c
@@ -9,157 +9,157 @@
struct PsiCustomGate psi_new_custom_gate_from_matrix(const char* name, struct PsiMatrix matrix)
{
- assert(matrix.rows == matrix.cols);
+ assert(matrix.rows == matrix.cols);
- size_t dim = matrix.rows;
- assert(dim > 0 && (dim & (dim - 1)) == 0);
+ size_t dim = matrix.rows;
+ assert(dim > 0 && (dim & (dim - 1)) == 0);
- size_t num_qubits = 0;
- while (((size_t)1 << num_qubits) < dim)
- num_qubits++;
+ size_t num_qubits = 0;
+ while (((size_t)1 << num_qubits) < dim)
+ num_qubits++;
- struct PsiCustomGate gate;
- gate.name = name;
- gate.num_qubits = num_qubits;
- gate.kind = PSI_CUSTOM_GATE_MATRIX;
- gate.definition.matrix = matrix;
+ struct PsiCustomGate gate;
+ gate.name = name;
+ gate.num_qubits = num_qubits;
+ gate.kind = PSI_CUSTOM_GATE_MATRIX;
+ gate.definition.matrix = matrix;
- return gate;
+ return gate;
}
struct PsiCustomGate psi_new_custom_gate_from_composite(const char* name, size_t num_qubits,
const struct PsiCompositeGateOp* ops,
size_t op_count)
{
- struct PsiCompositeGateOp* owned = malloc(op_count * sizeof(struct PsiCompositeGateOp));
- assert(owned != NULL || op_count == 0);
+ struct PsiCompositeGateOp* owned = malloc(op_count * sizeof(struct PsiCompositeGateOp));
+ assert(owned != NULL || op_count == 0);
- if (op_count > 0)
- memcpy(owned, ops, op_count * sizeof(struct PsiCompositeGateOp));
+ if (op_count > 0)
+ memcpy(owned, ops, op_count * sizeof(struct PsiCompositeGateOp));
- struct PsiCustomGate gate;
- gate.name = name;
- gate.num_qubits = num_qubits;
- gate.kind = PSI_CUSTOM_GATE_COMPOSITE;
- gate.definition.composite.ops = owned;
- gate.definition.composite.count = op_count;
+ struct PsiCustomGate gate;
+ gate.name = name;
+ gate.num_qubits = num_qubits;
+ gate.kind = PSI_CUSTOM_GATE_COMPOSITE;
+ gate.definition.composite.ops = owned;
+ gate.definition.composite.count = op_count;
- return gate;
+ return gate;
}
void psi_free_custom_gate(struct PsiCustomGate* gate)
{
- if (gate->kind == PSI_CUSTOM_GATE_MATRIX)
- {
- psi_free_matrix(&gate->definition.matrix);
- return;
- }
+ if (gate->kind == PSI_CUSTOM_GATE_MATRIX)
+ {
+ psi_free_matrix(&gate->definition.matrix);
+ return;
+ }
- free(gate->definition.composite.ops);
- gate->definition.composite.ops = NULL;
- gate->definition.composite.count = 0;
+ free(gate->definition.composite.ops);
+ gate->definition.composite.ops = NULL;
+ gate->definition.composite.count = 0;
}
static struct PsiQuantumGate op_gate(enum PsiCompositeOp op)
{
- switch (op)
- {
- case PSI_OP_H: return psi_hadamard_gate();
- case PSI_OP_X: return psi_pauli_x_gate();
- case PSI_OP_Y: return psi_pauli_y_gate();
- case PSI_OP_Z: return psi_pauli_z_gate();
- case PSI_OP_S: return psi_s_gate();
- case PSI_OP_T: return psi_t_gate();
- case PSI_OP_CNOT: return psi_cnot_gate();
- case PSI_OP_CZ: return psi_cz_gate();
- case PSI_OP_SWAP: return psi_swap_gate();
- case PSI_OP_CCNOT: return psi_toffoli_gate();
- case PSI_OP_CSWAP: return psi_fredkin_gate();
- }
+ switch (op)
+ {
+ case PSI_OP_H: return psi_hadamard_gate();
+ case PSI_OP_X: return psi_pauli_x_gate();
+ case PSI_OP_Y: return psi_pauli_y_gate();
+ case PSI_OP_Z: return psi_pauli_z_gate();
+ case PSI_OP_S: return psi_s_gate();
+ case PSI_OP_T: return psi_t_gate();
+ case PSI_OP_CNOT: return psi_cnot_gate();
+ case PSI_OP_CZ: return psi_cz_gate();
+ case PSI_OP_SWAP: return psi_swap_gate();
+ case PSI_OP_CCNOT: return psi_toffoli_gate();
+ case PSI_OP_CSWAP: return psi_fredkin_gate();
+ }
- return psi_identity_gate();
+ return psi_identity_gate();
}
static bool find_target(const size_t* targets, size_t count, size_t q, size_t* pos)
{
- for (size_t i = 0; i < count; i++)
- if (targets[i] == q)
- {
- *pos = i;
- return true;
- }
+ for (size_t i = 0; i < count; i++)
+ if (targets[i] == q)
+ {
+ *pos = i;
+ return true;
+ }
- return false;
+ return false;
}
static struct PsiMatrix build_full_operator(struct PsiMatrix gate_matrix, const size_t* targets,
size_t num_gate_qubits, size_t total_qubits)
{
- size_t dim = (size_t)1 << total_qubits;
- size_t gate_dim = gate_matrix.rows;
+ size_t dim = (size_t)1 << total_qubits;
+ size_t gate_dim = gate_matrix.rows;
- struct PsiMatrix result = psi_new_matrix(dim, dim);
+ struct PsiMatrix result = psi_new_matrix(dim, dim);
- for (size_t i = 0; i < dim; i++)
- for (size_t j = 0; j < dim; j++)
- {
- size_t gate_i = 0;
- size_t gate_j = 0;
- bool match_non_targets = true;
+ for (size_t i = 0; i < dim; i++)
+ for (size_t j = 0; j < dim; j++)
+ {
+ size_t gate_i = 0;
+ size_t gate_j = 0;
+ bool match_non_targets = true;
- for (size_t q = 0; q < total_qubits; q++)
- {
- size_t bit_i = (i >> (total_qubits - 1 - q)) & 1;
- size_t bit_j = (j >> (total_qubits - 1 - q)) & 1;
+ for (size_t q = 0; q < total_qubits; q++)
+ {
+ size_t bit_i = (i >> (total_qubits - 1 - q)) & 1;
+ size_t bit_j = (j >> (total_qubits - 1 - q)) & 1;
- size_t pos;
- if (find_target(targets, num_gate_qubits, q, &pos))
- {
- gate_i |= bit_i << (num_gate_qubits - 1 - pos);
- gate_j |= bit_j << (num_gate_qubits - 1 - pos);
- }
- else if (bit_i != bit_j)
- {
- match_non_targets = false;
- break;
- }
- }
+ size_t pos;
+ if (find_target(targets, num_gate_qubits, q, &pos))
+ {
+ gate_i |= bit_i << (num_gate_qubits - 1 - pos);
+ gate_j |= bit_j << (num_gate_qubits - 1 - pos);
+ }
+ else if (bit_i != bit_j)
+ {
+ match_non_targets = false;
+ break;
+ }
+ }
- if (match_non_targets)
- result.data[i * dim + j] = gate_matrix.data[gate_i * gate_dim + gate_j];
- }
+ if (match_non_targets)
+ result.data[i * dim + j] = gate_matrix.data[gate_i * gate_dim + gate_j];
+ }
- return result;
+ return result;
}
static struct PsiMatrix compute_composite_matrix(struct PsiCustomGate gate)
{
- size_t dim = (size_t)1 << gate.num_qubits;
- struct PsiMatrix result = psi_identity_matrix(dim);
+ size_t dim = (size_t)1 << gate.num_qubits;
+ struct PsiMatrix result = psi_identity_matrix(dim);
- for (size_t i = 0; i < gate.definition.composite.count; i++)
- {
- struct PsiCompositeGateOp step = gate.definition.composite.ops[i];
- struct PsiQuantumGate g = op_gate(step.op);
+ for (size_t i = 0; i < gate.definition.composite.count; i++)
+ {
+ struct PsiCompositeGateOp step = gate.definition.composite.ops[i];
+ struct PsiQuantumGate g = op_gate(step.op);
- struct PsiMatrix full =
- build_full_operator(g.matrix, step.targets, step.target_count, gate.num_qubits);
- struct PsiMatrix next = psi_dot_matrix(full, result);
+ struct PsiMatrix full =
+ build_full_operator(g.matrix, step.targets, step.target_count, gate.num_qubits);
+ struct PsiMatrix next = psi_dot_matrix(full, result);
- psi_free_matrix(&full);
- psi_free_matrix(&result);
- psi_free_quantum_gate(&g);
- result = next;
- }
+ psi_free_matrix(&full);
+ psi_free_matrix(&result);
+ psi_free_quantum_gate(&g);
+ result = next;
+ }
- return result;
+ return result;
}
struct PsiQuantumGate psi_to_quantum_gate(struct PsiCustomGate gate)
{
- if (gate.kind == PSI_CUSTOM_GATE_MATRIX)
- return psi_new_quantum_gate(gate.name, psi_clone_matrix(gate.definition.matrix),
- gate.num_qubits);
+ if (gate.kind == PSI_CUSTOM_GATE_MATRIX)
+ return psi_new_quantum_gate(gate.name, psi_clone_matrix(gate.definition.matrix),
+ gate.num_qubits);
- return psi_new_quantum_gate(gate.name, compute_composite_matrix(gate), gate.num_qubits);
+ return psi_new_quantum_gate(gate.name, compute_composite_matrix(gate), gate.num_qubits);
}