aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-14 12:20:52 +0200
committerhachem <im@hachem.wtf>2026-09-14 12:20:52 +0200
commitee14ad272e68d9363202d7f668e0b20302827209 (patch)
tree88dd1012ad7f9d6ac7abeb7562dac2194794b823 /src/core
parentae07aab1442a45bbddb79e066f15eaf252a4254a (diff)
feat: simd + testing + formatting
Diffstat (limited to 'src/core')
-rw-r--r--src/core/circuit.c194
-rw-r--r--src/core/classical_components.c15
-rw-r--r--src/core/custom_gate.c21
-rw-r--r--src/core/gates.c92
-rw-r--r--src/core/kernel.c116
-rw-r--r--src/core/noise.c201
-rw-r--r--src/core/quantum_components.c60
-rw-r--r--src/core/runtime.c186
8 files changed, 539 insertions, 346 deletions
diff --git a/src/core/circuit.c b/src/core/circuit.c
index 1869ee6..8009db5 100644
--- a/src/core/circuit.c
+++ b/src/core/circuit.c
@@ -4,7 +4,7 @@
#include <stdlib.h>
#include <string.h>
-const char *psi_gate_op_name(struct PsiGateOp op)
+const char* psi_gate_op_name(struct PsiGateOp op)
{
switch (op.kind)
{
@@ -41,7 +41,7 @@ const char *psi_gate_op_name(struct PsiGateOp op)
return "?";
}
-const size_t *psi_gate_op_quantum_targets(const struct PsiGateOp *op, size_t *out_count)
+const size_t* psi_gate_op_quantum_targets(const struct PsiGateOp* op, size_t* out_count)
{
if (op->kind == PSI_GATE_CUSTOM)
{
@@ -53,7 +53,7 @@ const size_t *psi_gate_op_quantum_targets(const struct PsiGateOp *op, size_t *ou
return op->qubits;
}
-const size_t *psi_gate_op_classical_targets(const struct PsiGateOp *op, size_t *out_count)
+const size_t* psi_gate_op_classical_targets(const struct PsiGateOp* op, size_t* out_count)
{
if (op->kind == PSI_GATE_MEASURE)
{
@@ -93,10 +93,8 @@ bool psi_gate_op_is_non_clifford(struct PsiGateOp op)
case PSI_GATE_CRX:
case PSI_GATE_CRY:
case PSI_GATE_CRZ:
- case PSI_GATE_CP:
- return true;
- default:
- return false;
+ case PSI_GATE_CP: return true;
+ default: return false;
}
}
@@ -105,7 +103,8 @@ struct PsiQuantumCircuit psi_new_quantum_circuit(size_t num_qubits)
return psi_new_quantum_circuit_with_classical(num_qubits, 0);
}
-struct PsiQuantumCircuit psi_new_quantum_circuit_with_classical(size_t num_qubits, size_t num_classical)
+struct PsiQuantumCircuit psi_new_quantum_circuit_with_classical(size_t num_qubits,
+ size_t num_classical)
{
struct PsiQuantumCircuit c;
c.num_qubits = num_qubits;
@@ -119,11 +118,11 @@ struct PsiQuantumCircuit psi_new_quantum_circuit_with_classical(size_t num_qubit
return c;
}
-static void free_operations(struct PsiQuantumCircuit *c)
+static void free_operations(struct PsiQuantumCircuit* c)
{
for (size_t i = 0; i < c->operation_count; i++)
{
- struct PsiGateOp *op = &c->operations[i];
+ struct PsiGateOp* op = &c->operations[i];
if (op->kind != PSI_GATE_CUSTOM)
continue;
@@ -133,7 +132,7 @@ static void free_operations(struct PsiQuantumCircuit *c)
}
}
-void psi_free_quantum_circuit(struct PsiQuantumCircuit *c)
+void psi_free_quantum_circuit(struct PsiQuantumCircuit* c)
{
free_operations(c);
free(c->operations);
@@ -144,7 +143,7 @@ void psi_free_quantum_circuit(struct PsiQuantumCircuit *c)
c->is_computed = false;
}
-void psi_reset_circuit(struct PsiQuantumCircuit *c)
+void psi_reset_circuit(struct PsiQuantumCircuit* c)
{
free_operations(c);
c->operation_count = 0;
@@ -153,7 +152,7 @@ void psi_reset_circuit(struct PsiQuantumCircuit *c)
c->is_computed = false;
}
-static struct PsiGateOp *append_op(struct PsiQuantumCircuit *c)
+static struct PsiGateOp* append_op(struct PsiQuantumCircuit* c)
{
if (c->operation_count == c->operation_capacity)
{
@@ -163,24 +162,25 @@ static struct PsiGateOp *append_op(struct PsiQuantumCircuit *c)
c->operation_capacity = new_capacity;
}
- struct PsiGateOp *op = &c->operations[c->operation_count++];
+ struct PsiGateOp* op = &c->operations[c->operation_count++];
memset(op, 0, sizeof(*op));
c->is_computed = false;
return op;
}
-static void push_1q(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_t target)
+static void push_1q(struct PsiQuantumCircuit* c, enum PsiGateKind kind, size_t target)
{
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = kind;
op->qubits[0] = target;
op->qubit_count = 1;
}
-static void push_1q_1p(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_t target, double theta)
+static void push_1q_1p(struct PsiQuantumCircuit* c, enum PsiGateKind kind, size_t target,
+ double theta)
{
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = kind;
op->qubits[0] = target;
op->qubit_count = 1;
@@ -188,18 +188,19 @@ static void push_1q_1p(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_
op->param_count = 1;
}
-static void push_2q(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_t a, size_t b)
+static void push_2q(struct PsiQuantumCircuit* c, enum PsiGateKind kind, size_t a, size_t b)
{
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = kind;
op->qubits[0] = a;
op->qubits[1] = b;
op->qubit_count = 2;
}
-static void push_2q_1p(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_t control, size_t target, double theta)
+static void push_2q_1p(struct PsiQuantumCircuit* c, enum PsiGateKind kind, size_t control,
+ size_t target, double theta)
{
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = kind;
op->qubits[0] = control;
op->qubits[1] = target;
@@ -208,9 +209,10 @@ static void push_2q_1p(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_
op->param_count = 1;
}
-static void push_3q(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_t a, size_t b, size_t d)
+static void push_3q(struct PsiQuantumCircuit* c, enum PsiGateKind kind, size_t a, size_t b,
+ size_t d)
{
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = kind;
op->qubits[0] = a;
op->qubits[1] = b;
@@ -218,26 +220,71 @@ static void push_3q(struct PsiQuantumCircuit *c, enum PsiGateKind kind, size_t a
op->qubit_count = 3;
}
-void psi_apply_h(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_H, target); }
-void psi_apply_x(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_X, target); }
-void psi_apply_y(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_Y, target); }
-void psi_apply_z(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_Z, target); }
-void psi_apply_s(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_S, target); }
-void psi_apply_t(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_T, target); }
-void psi_apply_sdg(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_SDG, target); }
-void psi_apply_tdg(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_TDG, target); }
-void psi_apply_sx(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_SX, target); }
-void psi_apply_sxdg(struct PsiQuantumCircuit *c, size_t target) { push_1q(c, PSI_GATE_SXDG, target); }
+void psi_apply_h(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_H, target);
+}
+void psi_apply_x(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_X, target);
+}
+void psi_apply_y(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_Y, target);
+}
+void psi_apply_z(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_Z, target);
+}
+void psi_apply_s(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_S, target);
+}
+void psi_apply_t(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_T, target);
+}
+void psi_apply_sdg(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_SDG, target);
+}
+void psi_apply_tdg(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_TDG, target);
+}
+void psi_apply_sx(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_SX, target);
+}
+void psi_apply_sxdg(struct PsiQuantumCircuit* c, size_t target)
+{
+ push_1q(c, PSI_GATE_SXDG, target);
+}
-void psi_apply_rx(struct PsiQuantumCircuit *c, size_t target, double theta) { push_1q_1p(c, PSI_GATE_RX, target, theta); }
-void psi_apply_ry(struct PsiQuantumCircuit *c, size_t target, double theta) { push_1q_1p(c, PSI_GATE_RY, target, theta); }
-void psi_apply_rz(struct PsiQuantumCircuit *c, size_t target, double theta) { push_1q_1p(c, PSI_GATE_RZ, target, theta); }
-void psi_apply_p(struct PsiQuantumCircuit *c, size_t target, double theta) { push_1q_1p(c, PSI_GATE_P, target, theta); }
-void psi_apply_u1(struct PsiQuantumCircuit *c, size_t target, double lambda) { push_1q_1p(c, PSI_GATE_U1, target, lambda); }
+void psi_apply_rx(struct PsiQuantumCircuit* c, size_t target, double theta)
+{
+ push_1q_1p(c, PSI_GATE_RX, target, theta);
+}
+void psi_apply_ry(struct PsiQuantumCircuit* c, size_t target, double theta)
+{
+ push_1q_1p(c, PSI_GATE_RY, target, theta);
+}
+void psi_apply_rz(struct PsiQuantumCircuit* c, size_t target, double theta)
+{
+ push_1q_1p(c, PSI_GATE_RZ, target, theta);
+}
+void psi_apply_p(struct PsiQuantumCircuit* c, size_t target, double theta)
+{
+ push_1q_1p(c, PSI_GATE_P, target, theta);
+}
+void psi_apply_u1(struct PsiQuantumCircuit* c, size_t target, double lambda)
+{
+ push_1q_1p(c, PSI_GATE_U1, target, lambda);
+}
-void psi_apply_u2(struct PsiQuantumCircuit *c, size_t target, double phi, double lambda)
+void psi_apply_u2(struct PsiQuantumCircuit* c, size_t target, double phi, double lambda)
{
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = PSI_GATE_U2;
op->qubits[0] = target;
op->qubit_count = 1;
@@ -246,9 +293,10 @@ void psi_apply_u2(struct PsiQuantumCircuit *c, size_t target, double phi, double
op->param_count = 2;
}
-void psi_apply_u3(struct PsiQuantumCircuit *c, size_t target, double theta, double phi, double lambda)
+void psi_apply_u3(struct PsiQuantumCircuit* c, size_t target, double theta, double phi,
+ double lambda)
{
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = PSI_GATE_U3;
op->qubits[0] = target;
op->qubit_count = 1;
@@ -258,47 +306,75 @@ void psi_apply_u3(struct PsiQuantumCircuit *c, size_t target, double theta, doub
op->param_count = 3;
}
-void psi_apply_cnot(struct PsiQuantumCircuit *c, size_t control, size_t target) { push_2q(c, PSI_GATE_CNOT, control, target); }
-void psi_apply_cz(struct PsiQuantumCircuit *c, size_t control, size_t target) { push_2q(c, PSI_GATE_CZ, control, target); }
-void psi_apply_swap(struct PsiQuantumCircuit *c, size_t qubit1, size_t qubit2) { push_2q(c, PSI_GATE_SWAP, qubit1, qubit2); }
-void psi_apply_crx(struct PsiQuantumCircuit *c, size_t control, size_t target, double theta) { push_2q_1p(c, PSI_GATE_CRX, control, target, theta); }
-void psi_apply_cry(struct PsiQuantumCircuit *c, size_t control, size_t target, double theta) { push_2q_1p(c, PSI_GATE_CRY, control, target, theta); }
-void psi_apply_crz(struct PsiQuantumCircuit *c, size_t control, size_t target, double theta) { push_2q_1p(c, PSI_GATE_CRZ, control, target, theta); }
-void psi_apply_cp(struct PsiQuantumCircuit *c, size_t control, size_t target, double theta) { push_2q_1p(c, PSI_GATE_CP, control, target, theta); }
+void psi_apply_cnot(struct PsiQuantumCircuit* c, size_t control, size_t target)
+{
+ push_2q(c, PSI_GATE_CNOT, control, target);
+}
+void psi_apply_cz(struct PsiQuantumCircuit* c, size_t control, size_t target)
+{
+ push_2q(c, PSI_GATE_CZ, control, target);
+}
+void psi_apply_swap(struct PsiQuantumCircuit* c, size_t qubit1, size_t qubit2)
+{
+ push_2q(c, PSI_GATE_SWAP, qubit1, qubit2);
+}
+void psi_apply_crx(struct PsiQuantumCircuit* c, size_t control, size_t target, double theta)
+{
+ push_2q_1p(c, PSI_GATE_CRX, control, target, theta);
+}
+void psi_apply_cry(struct PsiQuantumCircuit* c, size_t control, size_t target, double theta)
+{
+ push_2q_1p(c, PSI_GATE_CRY, control, target, theta);
+}
+void psi_apply_crz(struct PsiQuantumCircuit* c, size_t control, size_t target, double theta)
+{
+ push_2q_1p(c, PSI_GATE_CRZ, control, target, theta);
+}
+void psi_apply_cp(struct PsiQuantumCircuit* c, size_t control, size_t target, double theta)
+{
+ push_2q_1p(c, PSI_GATE_CP, control, target, theta);
+}
-void psi_apply_ccnot(struct PsiQuantumCircuit *c, size_t control1, size_t control2, size_t target) { push_3q(c, PSI_GATE_CCNOT, control1, control2, target); }
-void psi_apply_cswap(struct PsiQuantumCircuit *c, size_t control, size_t target1, size_t target2) { push_3q(c, PSI_GATE_CSWAP, control, target1, target2); }
+void psi_apply_ccnot(struct PsiQuantumCircuit* c, size_t control1, size_t control2, size_t target)
+{
+ push_3q(c, PSI_GATE_CCNOT, control1, control2, target);
+}
+void psi_apply_cswap(struct PsiQuantumCircuit* c, size_t control, size_t target1, size_t target2)
+{
+ push_3q(c, PSI_GATE_CSWAP, control, target1, target2);
+}
-void psi_measure(struct PsiQuantumCircuit *c, size_t qubit, size_t classical)
+void psi_measure(struct PsiQuantumCircuit* c, size_t qubit, size_t classical)
{
if (classical >= c->num_classical)
c->num_classical = classical + 1;
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = PSI_GATE_MEASURE;
op->qubits[0] = qubit;
op->qubit_count = 1;
op->classical = classical;
}
-void psi_measure_all(struct PsiQuantumCircuit *c)
+void psi_measure_all(struct PsiQuantumCircuit* c)
{
for (size_t i = 0; i < c->num_qubits; i++)
psi_measure(c, i, i);
}
-void psi_apply_custom(struct PsiQuantumCircuit *c, struct PsiCustomGate gate, const size_t *targets, size_t count)
+void psi_apply_custom(struct PsiQuantumCircuit* c, struct PsiCustomGate gate, const size_t* targets,
+ size_t count)
{
- struct PsiCustomGate *owned = malloc(sizeof(struct PsiCustomGate));
+ struct PsiCustomGate* owned = malloc(sizeof(struct PsiCustomGate));
assert(owned != NULL);
*owned = gate;
- size_t *owned_targets = malloc(count * sizeof(size_t));
+ size_t* owned_targets = malloc(count * sizeof(size_t));
assert(owned_targets != NULL || count == 0);
if (count > 0)
memcpy(owned_targets, targets, count * sizeof(size_t));
- struct PsiGateOp *op = append_op(c);
+ struct PsiGateOp* op = append_op(c);
op->kind = PSI_GATE_CUSTOM;
op->custom = owned;
op->custom_targets = owned_targets;
diff --git a/src/core/classical_components.c b/src/core/classical_components.c
index 836784c..3ffeb88 100644
--- a/src/core/classical_components.c
+++ b/src/core/classical_components.c
@@ -3,32 +3,31 @@
#include <assert.h>
#include <stdlib.h>
-struct PsiClassicalBit psi_new_classical_bit(const char *name, bool state)
+struct PsiClassicalBit psi_new_classical_bit(const char* name, bool state)
{
- return (struct PsiClassicalBit)
- {
+ return (struct PsiClassicalBit){
name,
state,
};
}
-struct PsiClassicalRegister psi_new_classical_register(const char *name, const char **names, size_t count)
+struct PsiClassicalRegister psi_new_classical_register(const char* name, const char** names,
+ size_t count)
{
- struct PsiClassicalBit *bits = malloc(count * sizeof(struct PsiClassicalBit));
+ struct PsiClassicalBit* bits = malloc(count * sizeof(struct PsiClassicalBit));
assert(bits != NULL || count == 0);
for (size_t i = 0; i < count; i++)
bits[i] = psi_new_classical_bit(names[i], false);
- return (struct PsiClassicalRegister)
- {
+ return (struct PsiClassicalRegister){
name,
bits,
count,
};
}
-void psi_free_classical_register(struct PsiClassicalRegister *reg)
+void psi_free_classical_register(struct PsiClassicalRegister* reg)
{
free(reg->bits);
reg->bits = NULL;
diff --git a/src/core/custom_gate.c b/src/core/custom_gate.c
index 3b3a7e2..dd41635 100644
--- a/src/core/custom_gate.c
+++ b/src/core/custom_gate.c
@@ -7,7 +7,7 @@
#include "core/gates.h"
-struct PsiCustomGate psi_new_custom_gate_from_matrix(const char *name, struct PsiMatrix matrix)
+struct PsiCustomGate psi_new_custom_gate_from_matrix(const char* name, struct PsiMatrix matrix)
{
assert(matrix.rows == matrix.cols);
@@ -27,9 +27,11 @@ struct PsiCustomGate psi_new_custom_gate_from_matrix(const char *name, struct Ps
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 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));
+ struct PsiCompositeGateOp* owned = malloc(op_count * sizeof(struct PsiCompositeGateOp));
assert(owned != NULL || op_count == 0);
if (op_count > 0)
@@ -45,7 +47,7 @@ struct PsiCustomGate psi_new_custom_gate_from_composite(const char *name, size_t
return gate;
}
-void psi_free_custom_gate(struct PsiCustomGate *gate)
+void psi_free_custom_gate(struct PsiCustomGate* gate)
{
if (gate->kind == PSI_CUSTOM_GATE_MATRIX)
{
@@ -78,7 +80,7 @@ static struct PsiQuantumGate op_gate(enum PsiCompositeOp op)
return psi_identity_gate();
}
-static bool find_target(const size_t *targets, size_t count, size_t q, size_t *pos)
+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)
@@ -90,7 +92,8 @@ static bool find_target(const size_t *targets, size_t count, size_t q, size_t *p
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)
+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;
@@ -139,7 +142,8 @@ static struct PsiMatrix compute_composite_matrix(struct PsiCustomGate gate)
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 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);
@@ -154,7 +158,8 @@ static struct PsiMatrix compute_composite_matrix(struct PsiCustomGate gate)
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);
+ 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);
}
diff --git a/src/core/gates.c b/src/core/gates.c
index 0eb2997..51605c9 100644
--- a/src/core/gates.c
+++ b/src/core/gates.c
@@ -9,9 +9,8 @@ struct PsiMatrix psi_rx_matrix(double theta)
double cos_h = cos(theta / 2.0);
double sin_h = sin(theta / 2.0);
- return psi_matrix(2, 2,
- psi_new_complex(cos_h, 0.0), psi_new_complex(0.0, -sin_h),
- psi_new_complex(0.0, -sin_h), psi_new_complex(cos_h, 0.0));
+ return psi_matrix(2, 2, psi_new_complex(cos_h, 0.0), psi_new_complex(0.0, -sin_h),
+ psi_new_complex(0.0, -sin_h), psi_new_complex(cos_h, 0.0));
}
struct PsiMatrix psi_ry_matrix(double theta)
@@ -19,25 +18,22 @@ struct PsiMatrix psi_ry_matrix(double theta)
double cos_h = cos(theta / 2.0);
double sin_h = sin(theta / 2.0);
- return psi_matrix(2, 2,
- psi_new_complex(cos_h, 0.0), psi_new_complex(-sin_h, 0.0),
- psi_new_complex(sin_h, 0.0), psi_new_complex(cos_h, 0.0));
+ return psi_matrix(2, 2, psi_new_complex(cos_h, 0.0), psi_new_complex(-sin_h, 0.0),
+ psi_new_complex(sin_h, 0.0), psi_new_complex(cos_h, 0.0));
}
struct PsiMatrix psi_rz_matrix(double theta)
{
double half = theta / 2.0;
- return psi_matrix(2, 2,
- psi_new_complex(cos(half), -sin(half)), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(cos(half), sin(half)));
+ return psi_matrix(2, 2, psi_new_complex(cos(half), -sin(half)), psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(cos(half), sin(half)));
}
struct PsiMatrix psi_p_matrix(double theta)
{
- return psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(cos(theta), sin(theta)));
+ return psi_matrix(2, 2, psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(cos(theta), sin(theta)));
}
struct PsiMatrix psi_u1_matrix(double lambda)
@@ -47,11 +43,11 @@ struct PsiMatrix psi_u1_matrix(double lambda)
struct PsiMatrix psi_u2_matrix(double phi, double lambda)
{
- return psi_matrix(2, 2,
- psi_new_complex(INV_SQRT_2, 0.0),
- psi_new_complex(-INV_SQRT_2 * cos(lambda), -INV_SQRT_2 * sin(lambda)),
- psi_new_complex(INV_SQRT_2 * cos(phi), INV_SQRT_2 * sin(phi)),
- psi_new_complex(cos(phi + lambda) * INV_SQRT_2, sin(phi + lambda) * INV_SQRT_2));
+ return psi_matrix(
+ 2, 2, psi_new_complex(INV_SQRT_2, 0.0),
+ psi_new_complex(-INV_SQRT_2 * cos(lambda), -INV_SQRT_2 * sin(lambda)),
+ psi_new_complex(INV_SQRT_2 * cos(phi), INV_SQRT_2 * sin(phi)),
+ psi_new_complex(cos(phi + lambda) * INV_SQRT_2, sin(phi + lambda) * INV_SQRT_2));
}
struct PsiMatrix psi_u3_matrix(double theta, double phi, double lambda)
@@ -59,11 +55,10 @@ struct PsiMatrix psi_u3_matrix(double theta, double phi, double lambda)
double cos_h = cos(theta / 2.0);
double sin_h = sin(theta / 2.0);
- return psi_matrix(2, 2,
- psi_new_complex(cos_h, 0.0),
- psi_new_complex(-sin_h * cos(lambda), -sin_h * sin(lambda)),
- psi_new_complex(sin_h * cos(phi), sin_h * sin(phi)),
- psi_new_complex(cos_h * cos(phi + lambda), cos_h * sin(phi + lambda)));
+ return psi_matrix(2, 2, psi_new_complex(cos_h, 0.0),
+ psi_new_complex(-sin_h * cos(lambda), -sin_h * sin(lambda)),
+ psi_new_complex(sin_h * cos(phi), sin_h * sin(phi)),
+ psi_new_complex(cos_h * cos(phi + lambda), cos_h * sin(phi + lambda)));
}
struct PsiMatrix psi_crx_matrix(double theta)
@@ -115,90 +110,83 @@ struct PsiMatrix psi_cp_matrix(double theta)
struct PsiQuantumGate psi_hadamard_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(INV_SQRT_2, 0.0), psi_new_complex(INV_SQRT_2, 0.0),
- psi_new_complex(INV_SQRT_2, 0.0), psi_new_complex(-INV_SQRT_2, 0.0));
+ struct PsiMatrix m =
+ psi_matrix(2, 2, psi_new_complex(INV_SQRT_2, 0.0), psi_new_complex(INV_SQRT_2, 0.0),
+ psi_new_complex(INV_SQRT_2, 0.0), psi_new_complex(-INV_SQRT_2, 0.0));
return psi_new_quantum_gate_from_matrix("H", m);
}
struct PsiQuantumGate psi_pauli_x_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(1.0, 0.0),
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0));
+ struct PsiMatrix m = psi_matrix(2, 2, psi_new_complex(0.0, 0.0), psi_new_complex(1.0, 0.0),
+ psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0));
return psi_new_quantum_gate_from_matrix("X", m);
}
struct PsiQuantumGate psi_pauli_y_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, -1.0),
- psi_new_complex(0.0, 1.0), psi_new_complex(0.0, 0.0));
+ struct PsiMatrix m = psi_matrix(2, 2, psi_new_complex(0.0, 0.0), psi_new_complex(0.0, -1.0),
+ psi_new_complex(0.0, 1.0), psi_new_complex(0.0, 0.0));
return psi_new_quantum_gate_from_matrix("Y", m);
}
struct PsiQuantumGate psi_pauli_z_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(-1.0, 0.0));
+ struct PsiMatrix m = psi_matrix(2, 2, psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(-1.0, 0.0));
return psi_new_quantum_gate_from_matrix("Z", m);
}
struct PsiQuantumGate psi_s_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 1.0));
+ struct PsiMatrix m = psi_matrix(2, 2, psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 1.0));
return psi_new_quantum_gate_from_matrix("S", m);
}
struct PsiQuantumGate psi_t_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(INV_SQRT_2, INV_SQRT_2));
+ struct PsiMatrix m =
+ psi_matrix(2, 2, psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(INV_SQRT_2, INV_SQRT_2));
return psi_new_quantum_gate_from_matrix("T", m);
}
struct PsiQuantumGate psi_sdg_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, -1.0));
+ struct PsiMatrix m = psi_matrix(2, 2, psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, -1.0));
return psi_new_quantum_gate_from_matrix("S†", m);
}
struct PsiQuantumGate psi_tdg_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(INV_SQRT_2, -INV_SQRT_2));
+ struct PsiMatrix m =
+ psi_matrix(2, 2, psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(INV_SQRT_2, -INV_SQRT_2));
return psi_new_quantum_gate_from_matrix("T†", m);
}
struct PsiQuantumGate psi_sx_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(0.5, 0.5), psi_new_complex(0.5, -0.5),
- psi_new_complex(0.5, -0.5), psi_new_complex(0.5, 0.5));
+ struct PsiMatrix m = psi_matrix(2, 2, psi_new_complex(0.5, 0.5), psi_new_complex(0.5, -0.5),
+ psi_new_complex(0.5, -0.5), psi_new_complex(0.5, 0.5));
return psi_new_quantum_gate_from_matrix("√X", m);
}
struct PsiQuantumGate psi_sxdg_gate(void)
{
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(0.5, -0.5), psi_new_complex(0.5, 0.5),
- psi_new_complex(0.5, 0.5), psi_new_complex(0.5, -0.5));
+ struct PsiMatrix m = psi_matrix(2, 2, psi_new_complex(0.5, -0.5), psi_new_complex(0.5, 0.5),
+ psi_new_complex(0.5, 0.5), psi_new_complex(0.5, -0.5));
return psi_new_quantum_gate_from_matrix("√X†", m);
}
diff --git a/src/core/kernel.c b/src/core/kernel.c
index f8f7dfd..def0782 100644
--- a/src/core/kernel.c
+++ b/src/core/kernel.c
@@ -6,19 +6,19 @@
#include <stdlib.h>
#include <string.h>
-static char *dup_string(const char *s)
+static char* dup_string(const char* s)
{
size_t n = strlen(s) + 1;
- char *p = malloc(n);
+ char* p = malloc(n);
assert(p != NULL);
memcpy(p, s, n);
return p;
}
-static size_t *dup_targets(const size_t *targets, size_t count)
+static size_t* dup_targets(const size_t* targets, size_t count)
{
- size_t *p = malloc(count * sizeof(size_t));
+ size_t* p = malloc(count * sizeof(size_t));
assert(p != NULL || count == 0);
if (count > 0)
@@ -27,29 +27,30 @@ static size_t *dup_targets(const size_t *targets, size_t count)
return p;
}
-static bool starts_with(const char *s, const char *prefix)
+static bool starts_with(const char* s, const char* prefix)
{
return strncmp(s, prefix, strlen(prefix)) == 0;
}
-static enum PsiGateType detect_gate_type(const char *name, struct PsiMatrix matrix)
+static enum PsiGateType detect_gate_type(const char* name, struct PsiMatrix matrix)
{
- static const char *diagonal[] = { "Z", "S", "T", "Sdg", "Tdg", "Rz", "P", "U1", "CZ", "CP", "CRz" };
+ static const char* diagonal[] = { "Z", "S", "T", "Sdg", "Tdg", "Rz",
+ "P", "U1", "CZ", "CP", "CRz" };
for (size_t i = 0; i < sizeof(diagonal) / sizeof(diagonal[0]); i++)
if (starts_with(name, diagonal[i]))
return PSI_GATE_TYPE_DIAGONAL;
- static const char *controlled[] = { "CNOT", "CZ", "SWAP", "CRx", "CRy", "CRz", "CP", "CCNOT", "CSWAP" };
+ static const char* controlled[] = { "CNOT", "CZ", "SWAP", "CRx", "CRy",
+ "CRz", "CP", "CCNOT", "CSWAP" };
for (size_t i = 0; i < sizeof(controlled) / sizeof(controlled[0]); i++)
if (starts_with(name, controlled[i]))
return PSI_GATE_TYPE_CONTROLLED;
if (matrix.rows == 2 && matrix.cols == 2)
{
- bool is_diag = fabs(matrix.data[1].real) < 1e-10
- && fabs(matrix.data[1].imaginary) < 1e-10
- && fabs(matrix.data[2].real) < 1e-10
- && fabs(matrix.data[2].imaginary) < 1e-10;
+ bool is_diag = fabs(matrix.data[1].real) < 1e-10 &&
+ fabs(matrix.data[1].imaginary) < 1e-10 && fabs(matrix.data[2].real) < 1e-10 &&
+ fabs(matrix.data[2].imaginary) < 1e-10;
if (is_diag)
return PSI_GATE_TYPE_DIAGONAL;
}
@@ -57,7 +58,8 @@ static enum PsiGateType detect_gate_type(const char *name, struct PsiMatrix matr
return PSI_GATE_TYPE_NON_DIAGONAL;
}
-struct PsiKernel psi_new_kernel(const char *name, struct PsiMatrix matrix, const size_t *targets, size_t target_count)
+struct PsiKernel psi_new_kernel(const char* name, struct PsiMatrix matrix, const size_t* targets,
+ size_t target_count)
{
struct PsiKernel kernel;
kernel.matrix = matrix;
@@ -81,7 +83,7 @@ struct PsiKernel psi_clone_kernel(struct PsiKernel kernel)
return copy;
}
-void psi_free_kernel(struct PsiKernel *kernel)
+void psi_free_kernel(struct PsiKernel* kernel)
{
psi_free_matrix(&kernel->matrix);
free(kernel->targets);
@@ -118,7 +120,8 @@ bool psi_kernels_commute(struct PsiKernel a, struct PsiKernel b)
if (!psi_kernels_share_qubits(a, b))
return true;
- if (a.gate_type == PSI_GATE_TYPE_DIAGONAL && b.gate_type == PSI_GATE_TYPE_DIAGONAL && targets_equal(a, b))
+ if (a.gate_type == PSI_GATE_TYPE_DIAGONAL && b.gate_type == PSI_GATE_TYPE_DIAGONAL &&
+ targets_equal(a, b))
return true;
return false;
@@ -132,17 +135,18 @@ bool psi_kernels_can_fuse(struct PsiKernel a, struct PsiKernel b)
return a.targets[0] == b.targets[0];
}
-bool psi_fuse_kernels(struct PsiKernel a, struct PsiKernel b, struct PsiKernel *out)
+bool psi_fuse_kernels(struct PsiKernel a, struct PsiKernel b, struct PsiKernel* out)
{
if (!psi_kernels_can_fuse(a, b))
return false;
- enum PsiGateType new_type = a.gate_type == PSI_GATE_TYPE_DIAGONAL && b.gate_type == PSI_GATE_TYPE_DIAGONAL
- ? PSI_GATE_TYPE_DIAGONAL
- : PSI_GATE_TYPE_NON_DIAGONAL;
+ enum PsiGateType new_type =
+ a.gate_type == PSI_GATE_TYPE_DIAGONAL && b.gate_type == PSI_GATE_TYPE_DIAGONAL
+ ? PSI_GATE_TYPE_DIAGONAL
+ : PSI_GATE_TYPE_NON_DIAGONAL;
size_t name_len = strlen(a.name) + strlen(b.name) + 2;
- char *fused_name = malloc(name_len);
+ char* fused_name = malloc(name_len);
assert(fused_name != NULL);
snprintf(fused_name, name_len, "%s+%s", a.name, b.name);
@@ -155,13 +159,14 @@ bool psi_fuse_kernels(struct PsiKernel a, struct PsiKernel b, struct PsiKernel *
return true;
}
-static struct PsiComplex *apply_kernel(const struct PsiComplex *state, struct PsiKernel kernel, size_t num_qubits)
+static struct PsiComplex* apply_kernel(const struct PsiComplex* state, struct PsiKernel kernel,
+ size_t num_qubits)
{
size_t dim = (size_t)1 << num_qubits;
size_t g = kernel.target_count;
size_t gate_dim = (size_t)1 << g;
- size_t *target_bits = malloc(g * sizeof(size_t));
+ size_t* target_bits = malloc(g * sizeof(size_t));
assert(target_bits != NULL || g == 0);
for (size_t k = 0; k < g; k++)
target_bits[k] = num_qubits - 1 - kernel.targets[k];
@@ -170,7 +175,7 @@ static struct PsiComplex *apply_kernel(const struct PsiComplex *state, struct Ps
for (size_t k = 0; k < g; k++)
non_target_mask &= ~((size_t)1 << target_bits[k]);
- struct PsiComplex *new_state = malloc(dim * sizeof(struct PsiComplex));
+ struct PsiComplex* new_state = malloc(dim * sizeof(struct PsiComplex));
assert(new_state != NULL);
for (size_t i = 0; i < dim; i++)
@@ -213,7 +218,7 @@ struct PsiKernelBatch psi_new_kernel_batch(size_t num_qubits)
return batch;
}
-void psi_free_kernel_batch(struct PsiKernelBatch *batch)
+void psi_free_kernel_batch(struct PsiKernelBatch* batch)
{
for (size_t i = 0; i < batch->count; i++)
psi_free_kernel(&batch->kernels[i]);
@@ -224,7 +229,7 @@ void psi_free_kernel_batch(struct PsiKernelBatch *batch)
batch->capacity = 0;
}
-void psi_add_kernel(struct PsiKernelBatch *batch, struct PsiKernel kernel)
+void psi_add_kernel(struct PsiKernelBatch* batch, struct PsiKernel kernel)
{
if (batch->count == batch->capacity)
{
@@ -237,13 +242,13 @@ void psi_add_kernel(struct PsiKernelBatch *batch, struct PsiKernel kernel)
batch->kernels[batch->count++] = kernel;
}
-void psi_optimize_kernel_batch(struct PsiKernelBatch *batch)
+void psi_optimize_kernel_batch(struct PsiKernelBatch* batch)
{
if (batch->count < 2)
return;
size_t original = batch->count;
- struct PsiKernel *out = malloc(original * sizeof(struct PsiKernel));
+ struct PsiKernel* out = malloc(original * sizeof(struct PsiKernel));
assert(out != NULL);
size_t out_count = 0;
@@ -273,27 +278,28 @@ void psi_optimize_kernel_batch(struct PsiKernelBatch *batch)
batch->capacity = original;
}
-void psi_execute_kernel_batch(struct PsiKernelBatch batch, struct PsiVector *state)
+void psi_execute_kernel_batch(struct PsiKernelBatch batch, struct PsiVector* state)
{
size_t dim = (size_t)1 << batch.num_qubits;
assert(state->size == dim);
for (size_t i = 0; i < batch.count; i++)
{
- struct PsiComplex *next = apply_kernel(state->data, batch.kernels[i], batch.num_qubits);
+ struct PsiComplex* next = apply_kernel(state->data, batch.kernels[i], batch.num_qubits);
free(state->data);
state->data = next;
}
}
-void psi_apply_kernel(struct PsiVector *state, struct PsiKernel kernel, size_t num_qubits)
+void psi_apply_kernel(struct PsiVector* state, struct PsiKernel kernel, size_t num_qubits)
{
- struct PsiComplex *next = apply_kernel(state->data, kernel, num_qubits);
+ struct PsiComplex* next = apply_kernel(state->data, kernel, num_qubits);
free(state->data);
state->data = next;
}
-static void push_kernel(struct PsiKernel **kernels, size_t *count, size_t *capacity, struct PsiKernel kernel)
+static void push_kernel(struct PsiKernel** kernels, size_t* count, size_t* capacity,
+ struct PsiKernel kernel)
{
if (*count == *capacity)
{
@@ -315,7 +321,7 @@ static bool layer_can_add(struct PsiExecutionLayer layer, struct PsiKernel kerne
return true;
}
-static void free_layer(struct PsiExecutionLayer *layer)
+static void free_layer(struct PsiExecutionLayer* layer)
{
for (size_t i = 0; i < layer->count; i++)
psi_free_kernel(&layer->kernels[i]);
@@ -341,7 +347,7 @@ struct PsiStructureAwareBatch psi_new_structure_aware_batch(size_t num_qubits)
return batch;
}
-static void clear_layers(struct PsiStructureAwareBatch *batch)
+static void clear_layers(struct PsiStructureAwareBatch* batch)
{
for (size_t i = 0; i < batch->layer_count; i++)
free_layer(&batch->layers[i]);
@@ -352,7 +358,7 @@ static void clear_layers(struct PsiStructureAwareBatch *batch)
batch->layer_capacity = 0;
}
-void psi_free_structure_aware_batch(struct PsiStructureAwareBatch *batch)
+void psi_free_structure_aware_batch(struct PsiStructureAwareBatch* batch)
{
for (size_t i = 0; i < batch->count; i++)
psi_free_kernel(&batch->kernels[i]);
@@ -364,13 +370,13 @@ void psi_free_structure_aware_batch(struct PsiStructureAwareBatch *batch)
clear_layers(batch);
}
-void psi_add_structure_aware_kernel(struct PsiStructureAwareBatch *batch, struct PsiKernel kernel)
+void psi_add_structure_aware_kernel(struct PsiStructureAwareBatch* batch, struct PsiKernel kernel)
{
push_kernel(&batch->kernels, &batch->count, &batch->capacity, kernel);
batch->optimised = false;
}
-static struct PsiKernel remove_kernel_at(struct PsiStructureAwareBatch *batch, size_t index)
+static struct PsiKernel remove_kernel_at(struct PsiStructureAwareBatch* batch, size_t index)
{
struct PsiKernel removed = batch->kernels[index];
for (size_t i = index; i + 1 < batch->count; i++)
@@ -380,7 +386,8 @@ static struct PsiKernel remove_kernel_at(struct PsiStructureAwareBatch *batch, s
return removed;
}
-static void insert_kernel_at(struct PsiStructureAwareBatch *batch, size_t index, struct PsiKernel kernel)
+static void insert_kernel_at(struct PsiStructureAwareBatch* batch, size_t index,
+ struct PsiKernel kernel)
{
if (batch->count == batch->capacity)
{
@@ -397,7 +404,7 @@ static void insert_kernel_at(struct PsiStructureAwareBatch *batch, size_t index,
batch->count++;
}
-static void reorder_commuting_gates(struct PsiStructureAwareBatch *batch)
+static void reorder_commuting_gates(struct PsiStructureAwareBatch* batch)
{
bool changed = true;
size_t iterations = 0;
@@ -413,9 +420,8 @@ static void reorder_commuting_gates(struct PsiStructureAwareBatch *batch)
struct PsiKernel current = batch->kernels[i];
struct PsiKernel next = batch->kernels[i + 1];
- if (current.target_count != 1 || next.target_count != 1
- || current.targets[0] == next.targets[0]
- || !psi_kernels_commute(current, next))
+ if (current.target_count != 1 || next.target_count != 1 ||
+ current.targets[0] == next.targets[0] || !psi_kernels_commute(current, next))
continue;
for (size_t j = i + 2; j < batch->count; j++)
@@ -428,7 +434,8 @@ static void reorder_commuting_gates(struct PsiStructureAwareBatch *batch)
for (size_t k = i + 1; k < j; k++)
{
struct PsiKernel between = batch->kernels[k];
- if (psi_kernels_share_qubits(between, current) && !psi_kernels_commute(current, between))
+ if (psi_kernels_share_qubits(between, current) &&
+ !psi_kernels_commute(current, between))
{
can_move = false;
break;
@@ -447,7 +454,7 @@ static void reorder_commuting_gates(struct PsiStructureAwareBatch *batch)
}
}
-static void multi_pass_fusion(struct PsiStructureAwareBatch *batch)
+static void multi_pass_fusion(struct PsiStructureAwareBatch* batch)
{
bool changed = true;
size_t iterations = 0;
@@ -458,7 +465,7 @@ static void multi_pass_fusion(struct PsiStructureAwareBatch *batch)
changed = false;
iterations++;
- struct PsiKernel *new_kernels = NULL;
+ struct PsiKernel* new_kernels = NULL;
size_t new_count = 0;
size_t new_capacity = 0;
@@ -490,7 +497,7 @@ static void multi_pass_fusion(struct PsiStructureAwareBatch *batch)
}
}
-static void build_execution_layers(struct PsiStructureAwareBatch *batch)
+static void build_execution_layers(struct PsiStructureAwareBatch* batch)
{
clear_layers(batch);
@@ -502,8 +509,9 @@ static void build_execution_layers(struct PsiStructureAwareBatch *batch)
for (size_t l = 0; l < batch->layer_count; l++)
if (layer_can_add(batch->layers[l], kernel))
{
- struct PsiExecutionLayer *layer = &batch->layers[l];
- push_kernel(&layer->kernels, &layer->count, &layer->capacity, psi_clone_kernel(kernel));
+ struct PsiExecutionLayer* layer = &batch->layers[l];
+ push_kernel(&layer->kernels, &layer->count, &layer->capacity,
+ psi_clone_kernel(kernel));
placed = true;
break;
}
@@ -528,7 +536,7 @@ static void build_execution_layers(struct PsiStructureAwareBatch *batch)
}
}
-void psi_optimize_structure_aware_batch(struct PsiStructureAwareBatch *batch)
+void psi_optimize_structure_aware_batch(struct PsiStructureAwareBatch* batch)
{
if (batch->optimised || batch->count < 2)
return;
@@ -539,20 +547,21 @@ void psi_optimize_structure_aware_batch(struct PsiStructureAwareBatch *batch)
batch->optimised = true;
}
-void psi_execute_structure_aware_batch(struct PsiStructureAwareBatch batch, struct PsiVector *state)
+void psi_execute_structure_aware_batch(struct PsiStructureAwareBatch batch, struct PsiVector* state)
{
size_t dim = (size_t)1 << batch.num_qubits;
assert(state->size == dim);
for (size_t i = 0; i < batch.count; i++)
{
- struct PsiComplex *next = apply_kernel(state->data, batch.kernels[i], batch.num_qubits);
+ struct PsiComplex* next = apply_kernel(state->data, batch.kernels[i], batch.num_qubits);
free(state->data);
state->data = next;
}
}
-void psi_execute_structure_aware_batch_layered(struct PsiStructureAwareBatch batch, struct PsiVector *state)
+void psi_execute_structure_aware_batch_layered(struct PsiStructureAwareBatch batch,
+ struct PsiVector* state)
{
size_t dim = (size_t)1 << batch.num_qubits;
assert(state->size == dim);
@@ -560,7 +569,8 @@ void psi_execute_structure_aware_batch_layered(struct PsiStructureAwareBatch bat
for (size_t l = 0; l < batch.layer_count; l++)
for (size_t k = 0; k < batch.layers[l].count; k++)
{
- struct PsiComplex *next = apply_kernel(state->data, batch.layers[l].kernels[k], batch.num_qubits);
+ struct PsiComplex* next =
+ apply_kernel(state->data, batch.layers[l].kernels[k], batch.num_qubits);
free(state->data);
state->data = next;
}
diff --git a/src/core/noise.c b/src/core/noise.c
index 9aaf1d9..5f141c8 100644
--- a/src/core/noise.c
+++ b/src/core/noise.c
@@ -5,30 +5,30 @@
#include <stdlib.h>
#include <string.h>
-struct PsiKrausOperator psi_new_kraus_operator(const char *name, struct PsiMatrix matrix)
+struct PsiKrausOperator psi_new_kraus_operator(const char* name, struct PsiMatrix matrix)
{
- return (struct PsiKrausOperator)
- {
+ return (struct PsiKrausOperator){
matrix,
name,
};
}
-void psi_free_kraus_operator(struct PsiKrausOperator *op)
+void psi_free_kraus_operator(struct PsiKrausOperator* op)
{
psi_free_matrix(&op->matrix);
}
-struct PsiNoiseChannel psi_new_noise_channel(const char *name, const struct PsiKrausOperator *operators, size_t count, size_t num_qubits)
+struct PsiNoiseChannel psi_new_noise_channel(const char* name,
+ const struct PsiKrausOperator* operators, size_t count,
+ size_t num_qubits)
{
- struct PsiKrausOperator *owned = malloc(count * sizeof(struct PsiKrausOperator));
+ struct PsiKrausOperator* owned = malloc(count * sizeof(struct PsiKrausOperator));
assert(owned != NULL || count == 0);
if (count > 0)
memcpy(owned, operators, count * sizeof(struct PsiKrausOperator));
- return (struct PsiNoiseChannel)
- {
+ return (struct PsiNoiseChannel){
name,
owned,
count,
@@ -36,7 +36,7 @@ struct PsiNoiseChannel psi_new_noise_channel(const char *name, const struct PsiK
};
}
-void psi_free_noise_channel(struct PsiNoiseChannel *channel)
+void psi_free_noise_channel(struct PsiNoiseChannel* channel)
{
for (size_t i = 0; i < channel->operator_count; i++)
psi_free_matrix(&channel->operators[i].matrix);
@@ -52,18 +52,22 @@ struct PsiNoiseChannel psi_depolarising_channel(double p)
double sqrt_p3 = sqrt(p / 3.0);
struct PsiKrausOperator ops[] = {
- psi_new_kraus_operator("K0", psi_matrix(2, 2,
- psi_new_complex(sqrt_1_p, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_1_p, 0.0))),
- psi_new_kraus_operator("K1(X)", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_p3, 0.0),
- psi_new_complex(sqrt_p3, 0.0), psi_new_complex(0.0, 0.0))),
- psi_new_kraus_operator("K2(Y)", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, -sqrt_p3),
- psi_new_complex(0.0, sqrt_p3), psi_new_complex(0.0, 0.0))),
- psi_new_kraus_operator("K3(Z)", psi_matrix(2, 2,
- psi_new_complex(sqrt_p3, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(-sqrt_p3, 0.0))),
+ psi_new_kraus_operator("K0",
+ psi_matrix(2, 2, psi_new_complex(sqrt_1_p, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_p, 0.0))),
+ psi_new_kraus_operator(
+ "K1(X)",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_p3, 0.0),
+ psi_new_complex(sqrt_p3, 0.0), psi_new_complex(0.0, 0.0))),
+ psi_new_kraus_operator(
+ "K2(Y)",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0), psi_new_complex(0.0, -sqrt_p3),
+ psi_new_complex(0.0, sqrt_p3), psi_new_complex(0.0, 0.0))),
+ psi_new_kraus_operator("K3(Z)",
+ psi_matrix(2, 2, psi_new_complex(sqrt_p3, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(-sqrt_p3, 0.0))),
};
return psi_new_noise_channel("Depolarising", ops, 4, 1);
@@ -75,12 +79,14 @@ struct PsiNoiseChannel psi_amplitude_damping_channel(double gamma)
double sqrt_1_gamma = sqrt(1.0 - gamma);
struct PsiKrausOperator ops[] = {
- psi_new_kraus_operator("K0", psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_1_gamma, 0.0))),
- psi_new_kraus_operator("K1", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_gamma, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0))),
+ psi_new_kraus_operator("K0",
+ psi_matrix(2, 2, psi_new_complex(1.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_gamma, 0.0))),
+ psi_new_kraus_operator("K1",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_gamma, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0))),
};
return psi_new_noise_channel("AmplitudeDamping", ops, 2, 1);
@@ -92,12 +98,14 @@ struct PsiNoiseChannel psi_phase_damping_channel(double gamma)
double sqrt_1_gamma = sqrt(1.0 - gamma);
struct PsiKrausOperator ops[] = {
- psi_new_kraus_operator("K0", psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_1_gamma, 0.0))),
- psi_new_kraus_operator("K1", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_gamma, 0.0))),
+ psi_new_kraus_operator("K0",
+ psi_matrix(2, 2, psi_new_complex(1.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_gamma, 0.0))),
+ psi_new_kraus_operator("K1",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_gamma, 0.0))),
};
return psi_new_noise_channel("PhaseDamping", ops, 2, 1);
@@ -109,12 +117,14 @@ struct PsiNoiseChannel psi_bit_flip_channel(double p)
double sqrt_p = sqrt(p);
struct PsiKrausOperator ops[] = {
- psi_new_kraus_operator("K0(I)", psi_matrix(2, 2,
- psi_new_complex(sqrt_1_p, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_1_p, 0.0))),
- psi_new_kraus_operator("K1(X)", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_p, 0.0),
- psi_new_complex(sqrt_p, 0.0), psi_new_complex(0.0, 0.0))),
+ psi_new_kraus_operator("K0(I)",
+ psi_matrix(2, 2, psi_new_complex(sqrt_1_p, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_p, 0.0))),
+ psi_new_kraus_operator("K1(X)",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_p, 0.0),
+ psi_new_complex(sqrt_p, 0.0), psi_new_complex(0.0, 0.0))),
};
return psi_new_noise_channel("BitFlip", ops, 2, 1);
@@ -126,12 +136,14 @@ struct PsiNoiseChannel psi_phase_flip_channel(double p)
double sqrt_p = sqrt(p);
struct PsiKrausOperator ops[] = {
- psi_new_kraus_operator("K0(I)", psi_matrix(2, 2,
- psi_new_complex(sqrt_1_p, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_1_p, 0.0))),
- psi_new_kraus_operator("K1(Z)", psi_matrix(2, 2,
- psi_new_complex(sqrt_p, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(-sqrt_p, 0.0))),
+ psi_new_kraus_operator("K0(I)",
+ psi_matrix(2, 2, psi_new_complex(sqrt_1_p, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_p, 0.0))),
+ psi_new_kraus_operator("K1(Z)",
+ psi_matrix(2, 2, psi_new_complex(sqrt_p, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(-sqrt_p, 0.0))),
};
return psi_new_noise_channel("PhaseFlip", ops, 2, 1);
@@ -143,12 +155,14 @@ struct PsiNoiseChannel psi_bit_phase_flip_channel(double p)
double sqrt_p = sqrt(p);
struct PsiKrausOperator ops[] = {
- psi_new_kraus_operator("K0(I)", psi_matrix(2, 2,
- psi_new_complex(sqrt_1_p, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_1_p, 0.0))),
- psi_new_kraus_operator("K1(Y)", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, -sqrt_p),
- psi_new_complex(0.0, sqrt_p), psi_new_complex(0.0, 0.0))),
+ psi_new_kraus_operator("K0(I)",
+ psi_matrix(2, 2, psi_new_complex(sqrt_1_p, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_p, 0.0))),
+ psi_new_kraus_operator("K1(Y)",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0),
+ psi_new_complex(0.0, -sqrt_p),
+ psi_new_complex(0.0, sqrt_p), psi_new_complex(0.0, 0.0))),
};
return psi_new_noise_channel("BitPhaseFlip", ops, 2, 1);
@@ -162,18 +176,22 @@ struct PsiNoiseChannel psi_generalised_amplitude_damping_channel(double p, doubl
double sqrt_1_gamma = sqrt(1.0 - gamma);
struct PsiKrausOperator ops[] = {
- psi_new_kraus_operator("K0", psi_matrix(2, 2,
- psi_new_complex(sqrt_p, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_p * sqrt_1_gamma, 0.0))),
- psi_new_kraus_operator("K1", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_p * sqrt_gamma, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0))),
- psi_new_kraus_operator("K2", psi_matrix(2, 2,
- psi_new_complex(sqrt_1_p * sqrt_1_gamma, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(0.0, 0.0), psi_new_complex(sqrt_1_p, 0.0))),
- psi_new_kraus_operator("K3", psi_matrix(2, 2,
- psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
- psi_new_complex(sqrt_1_p * sqrt_gamma, 0.0), psi_new_complex(0.0, 0.0))),
+ psi_new_kraus_operator("K0",
+ psi_matrix(2, 2, psi_new_complex(sqrt_p, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_p * sqrt_1_gamma, 0.0))),
+ psi_new_kraus_operator("K1",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_p * sqrt_gamma, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0))),
+ psi_new_kraus_operator("K2",
+ psi_matrix(2, 2, psi_new_complex(sqrt_1_p * sqrt_1_gamma, 0.0),
+ psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_p, 0.0))),
+ psi_new_kraus_operator(
+ "K3",
+ psi_matrix(2, 2, psi_new_complex(0.0, 0.0), psi_new_complex(0.0, 0.0),
+ psi_new_complex(sqrt_1_p * sqrt_gamma, 0.0), psi_new_complex(0.0, 0.0))),
};
return psi_new_noise_channel("GeneralisedAmplitudeDamping", ops, 4, 1);
@@ -182,41 +200,40 @@ struct PsiNoiseChannel psi_generalised_amplitude_damping_channel(double p, doubl
struct PsiDensityMatrix psi_new_density_matrix(size_t num_qubits)
{
size_t dim = (size_t)1 << num_qubits;
- struct PsiComplex *data = calloc(dim * dim, sizeof(struct PsiComplex));
+ struct PsiComplex* data = calloc(dim * dim, sizeof(struct PsiComplex));
assert(data != NULL);
data[0] = psi_new_complex(1.0, 0.0);
- return (struct PsiDensityMatrix)
- {
+ return (struct PsiDensityMatrix){
data,
dim,
num_qubits,
};
}
-struct PsiDensityMatrix psi_new_density_matrix_from_state(const struct PsiComplex *state, size_t len)
+struct PsiDensityMatrix psi_new_density_matrix_from_state(const struct PsiComplex* state,
+ size_t len)
{
size_t dim = len;
size_t num_qubits = 0;
while (((size_t)1 << num_qubits) < dim)
num_qubits++;
- struct PsiComplex *data = malloc(dim * dim * sizeof(struct PsiComplex));
+ struct PsiComplex* data = malloc(dim * dim * sizeof(struct PsiComplex));
assert(data != NULL);
for (size_t i = 0; i < dim; i++)
for (size_t j = 0; j < dim; j++)
data[i * dim + j] = psi_mul_complex(state[i], psi_conjugate_complex(state[j]));
- return (struct PsiDensityMatrix)
- {
+ return (struct PsiDensityMatrix){
data,
dim,
num_qubits,
};
}
-void psi_free_density_matrix(struct PsiDensityMatrix *dm)
+void psi_free_density_matrix(struct PsiDensityMatrix* dm)
{
free(dm->data);
dm->data = NULL;
@@ -230,7 +247,8 @@ struct PsiComplex psi_get_density_matrix(struct PsiDensityMatrix dm, size_t row,
return dm.data[row * dm.dim + col];
}
-void psi_set_density_matrix(struct PsiDensityMatrix *dm, size_t row, size_t col, struct PsiComplex value)
+void psi_set_density_matrix(struct PsiDensityMatrix* dm, size_t row, size_t col,
+ struct PsiComplex value)
{
assert(row < dm->dim && col < dm->dim);
dm->data[row * dm->dim + col] = value;
@@ -250,7 +268,8 @@ double psi_purity_density_matrix(struct PsiDensityMatrix dm)
struct PsiComplex sum = psi_new_complex(0.0, 0.0);
for (size_t i = 0; i < dm.dim; i++)
for (size_t j = 0; j < dm.dim; j++)
- sum = psi_add_complex(sum, psi_mul_complex(dm.data[i * dm.dim + j], dm.data[j * dm.dim + i]));
+ sum = psi_add_complex(
+ sum, psi_mul_complex(dm.data[i * dm.dim + j], dm.data[j * dm.dim + i]));
return sum.real;
}
@@ -260,19 +279,20 @@ bool psi_is_pure_density_matrix(struct PsiDensityMatrix dm, double tolerance)
return fabs(psi_purity_density_matrix(dm) - 1.0) < tolerance;
}
-void psi_density_matrix_probabilities(struct PsiDensityMatrix dm, double *out)
+void psi_density_matrix_probabilities(struct PsiDensityMatrix dm, double* out)
{
for (size_t i = 0; i < dm.dim; i++)
out[i] = dm.data[i * dm.dim + i].real;
}
-void psi_apply_unitary_density_matrix(struct PsiDensityMatrix *dm, struct PsiMatrix gate, const size_t *targets, size_t target_count)
+void psi_apply_unitary_density_matrix(struct PsiDensityMatrix* dm, struct PsiMatrix gate,
+ const size_t* targets, size_t target_count)
{
size_t g = target_count;
size_t gate_dim = (size_t)1 << g;
size_t dim = dm->dim;
- size_t *target_bits = malloc(g * sizeof(size_t));
+ size_t* target_bits = malloc(g * sizeof(size_t));
assert(target_bits != NULL || g == 0);
for (size_t t = 0; t < g; t++)
target_bits[t] = dm->num_qubits - 1 - targets[t];
@@ -281,7 +301,7 @@ void psi_apply_unitary_density_matrix(struct PsiDensityMatrix *dm, struct PsiMat
for (size_t t = 0; t < g; t++)
non_target_mask &= ~((size_t)1 << target_bits[t]);
- struct PsiComplex *new_data = calloc(dim * dim, sizeof(struct PsiComplex));
+ struct PsiComplex* new_data = calloc(dim * dim, sizeof(struct PsiComplex));
assert(new_data != NULL);
for (size_t i = 0; i < dim; i++)
@@ -314,10 +334,12 @@ void psi_apply_unitary_density_matrix(struct PsiDensityMatrix *dm, struct PsiMat
}
struct PsiComplex u_ik = gate.data[tgt_i * gate_dim + k];
- struct PsiComplex u_jl_dag = psi_conjugate_complex(gate.data[tgt_j * gate_dim + l]);
+ struct PsiComplex u_jl_dag =
+ psi_conjugate_complex(gate.data[tgt_j * gate_dim + l]);
struct PsiComplex rho_kl = dm->data[src_i * dim + src_j];
- sum = psi_add_complex(sum, psi_mul_complex(psi_mul_complex(u_ik, rho_kl), u_jl_dag));
+ sum = psi_add_complex(sum,
+ psi_mul_complex(psi_mul_complex(u_ik, rho_kl), u_jl_dag));
}
new_data[i * dim + j] = sum;
@@ -328,14 +350,15 @@ void psi_apply_unitary_density_matrix(struct PsiDensityMatrix *dm, struct PsiMat
dm->data = new_data;
}
-void psi_apply_noise_channel(struct PsiDensityMatrix *dm, struct PsiNoiseChannel channel, size_t target)
+void psi_apply_noise_channel(struct PsiDensityMatrix* dm, struct PsiNoiseChannel channel,
+ size_t target)
{
assert(channel.num_qubits == 1);
size_t dim = dm->dim;
size_t target_bit = dm->num_qubits - 1 - target;
- struct PsiComplex *new_data = calloc(dim * dim, sizeof(struct PsiComplex));
+ struct PsiComplex* new_data = calloc(dim * dim, sizeof(struct PsiComplex));
assert(new_data != NULL);
for (size_t op = 0; op < channel.operator_count; op++)
@@ -355,10 +378,12 @@ void psi_apply_noise_channel(struct PsiDensityMatrix *dm, struct PsiNoiseChannel
size_t src_j = (j & ~((size_t)1 << target_bit)) | (kj << target_bit);
struct PsiComplex k_elem = k.data[i_target * 2 + ki];
- struct PsiComplex k_dag_elem = psi_conjugate_complex(k.data[j_target * 2 + kj]);
+ struct PsiComplex k_dag_elem =
+ psi_conjugate_complex(k.data[j_target * 2 + kj]);
struct PsiComplex rho_elem = dm->data[src_i * dim + src_j];
- struct PsiComplex term = psi_mul_complex(psi_mul_complex(k_elem, rho_elem), k_dag_elem);
+ struct PsiComplex term =
+ psi_mul_complex(psi_mul_complex(k_elem, rho_elem), k_dag_elem);
new_data[i * dim + j] = psi_add_complex(new_data[i * dim + j], term);
}
}
@@ -368,7 +393,8 @@ void psi_apply_noise_channel(struct PsiDensityMatrix *dm, struct PsiNoiseChannel
dm->data = new_data;
}
-double psi_measure_probability_density_matrix(struct PsiDensityMatrix dm, size_t qubit, size_t outcome)
+double psi_measure_probability_density_matrix(struct PsiDensityMatrix dm, size_t qubit,
+ size_t outcome)
{
size_t target_bit = dm.num_qubits - 1 - qubit;
double prob = 0.0;
@@ -380,13 +406,16 @@ double psi_measure_probability_density_matrix(struct PsiDensityMatrix dm, size_t
return prob;
}
-double psi_fidelity_density_matrix(struct PsiDensityMatrix dm, const struct PsiComplex *state)
+double psi_fidelity_density_matrix(struct PsiDensityMatrix dm, const struct PsiComplex* state)
{
struct PsiComplex sum = psi_new_complex(0.0, 0.0);
for (size_t i = 0; i < dm.dim; i++)
for (size_t j = 0; j < dm.dim; j++)
- sum = psi_add_complex(sum, psi_mul_complex(psi_mul_complex(psi_conjugate_complex(state[i]), dm.data[i * dm.dim + j]), state[j]));
+ sum = psi_add_complex(sum,
+ psi_mul_complex(psi_mul_complex(psi_conjugate_complex(state[i]),
+ dm.data[i * dm.dim + j]),
+ state[j]));
return sum.real;
}
diff --git a/src/core/quantum_components.c b/src/core/quantum_components.c
index 31d60dc..a62a911 100644
--- a/src/core/quantum_components.c
+++ b/src/core/quantum_components.c
@@ -14,21 +14,21 @@ struct PsiVector psi_new_state_1(void)
return psi_column_vector(psi_new_complex(0.0, 0.0), psi_new_complex(1.0, 0.0));
}
-struct PsiQuantumGate psi_new_quantum_gate(const char *name, struct PsiMatrix matrix, size_t num_qubits)
+struct PsiQuantumGate psi_new_quantum_gate(const char* name, struct PsiMatrix matrix,
+ size_t num_qubits)
{
size_t expected_dim = (size_t)1 << num_qubits;
assert(matrix.rows == expected_dim);
assert(matrix.cols == expected_dim);
- return (struct PsiQuantumGate)
- {
+ return (struct PsiQuantumGate){
name,
matrix,
num_qubits,
};
}
-struct PsiQuantumGate psi_new_quantum_gate_from_matrix(const char *name, struct PsiMatrix matrix)
+struct PsiQuantumGate psi_new_quantum_gate_from_matrix(const char* name, struct PsiMatrix matrix)
{
assert(matrix.rows == matrix.cols);
@@ -39,34 +39,32 @@ struct PsiQuantumGate psi_new_quantum_gate_from_matrix(const char *name, struct
while (((size_t)1 << num_qubits) < dim)
num_qubits++;
- return (struct PsiQuantumGate)
- {
+ return (struct PsiQuantumGate){
name,
matrix,
num_qubits,
};
}
-void psi_free_quantum_gate(struct PsiQuantumGate *gate)
+void psi_free_quantum_gate(struct PsiQuantumGate* gate)
{
psi_free_matrix(&gate->matrix);
}
-struct PsiQuantumBit psi_new_quantum_bit(const char *name, struct PsiVector state)
+struct PsiQuantumBit psi_new_quantum_bit(const char* name, struct PsiVector state)
{
- return (struct PsiQuantumBit)
- {
+ return (struct PsiQuantumBit){
name,
state,
};
}
-void psi_free_quantum_bit(struct PsiQuantumBit *bit)
+void psi_free_quantum_bit(struct PsiQuantumBit* bit)
{
psi_free_vector(&bit->state);
}
-static void update_register(struct PsiQuantumRegister *reg)
+static void update_register(struct PsiQuantumRegister* reg)
{
psi_free_vector(&reg->state_vector);
@@ -90,16 +88,16 @@ static void update_register(struct PsiQuantumRegister *reg)
psi_free_matrix(&result);
}
-struct PsiQuantumRegister psi_new_quantum_register(const char *name, const char **names, size_t count)
+struct PsiQuantumRegister psi_new_quantum_register(const char* name, const char** names,
+ size_t count)
{
- struct PsiQuantumBit *qubits = malloc(count * sizeof(struct PsiQuantumBit));
+ struct PsiQuantumBit* qubits = malloc(count * sizeof(struct PsiQuantumBit));
assert(qubits != NULL || count == 0);
for (size_t i = 0; i < count; i++)
qubits[i] = psi_new_quantum_bit(names[i], psi_new_state_0());
- struct PsiQuantumRegister reg =
- {
+ struct PsiQuantumRegister reg = {
name,
psi_new_vector(0, PSI_COLUMN_VECTOR),
qubits,
@@ -110,16 +108,16 @@ struct PsiQuantumRegister psi_new_quantum_register(const char *name, const char
return reg;
}
-struct PsiQuantumRegister psi_new_quantum_register_from(const char *name, const struct PsiQuantumBit *bits, size_t count)
+struct PsiQuantumRegister
+psi_new_quantum_register_from(const char* name, const struct PsiQuantumBit* bits, size_t count)
{
- struct PsiQuantumBit *qubits = malloc(count * sizeof(struct PsiQuantumBit));
+ struct PsiQuantumBit* qubits = malloc(count * sizeof(struct PsiQuantumBit));
assert(qubits != NULL || count == 0);
for (size_t i = 0; i < count; i++)
qubits[i] = psi_new_quantum_bit(bits[i].name, psi_clone_vector(bits[i].state));
- struct PsiQuantumRegister reg =
- {
+ struct PsiQuantumRegister reg = {
name,
psi_new_vector(0, PSI_COLUMN_VECTOR),
qubits,
@@ -130,7 +128,7 @@ struct PsiQuantumRegister psi_new_quantum_register_from(const char *name, const
return reg;
}
-void psi_free_quantum_register(struct PsiQuantumRegister *reg)
+void psi_free_quantum_register(struct PsiQuantumRegister* reg)
{
for (size_t i = 0; i < reg->num_qubits; i++)
psi_free_quantum_bit(&reg->qubits[i]);
@@ -141,7 +139,7 @@ void psi_free_quantum_register(struct PsiQuantumRegister *reg)
psi_free_vector(&reg->state_vector);
}
-static bool targets_contain(const size_t *targets, size_t count, size_t value)
+static bool targets_contain(const size_t* targets, size_t count, size_t value)
{
for (size_t i = 0; i < count; i++)
if (targets[i] == value)
@@ -150,7 +148,8 @@ static bool targets_contain(const size_t *targets, size_t count, size_t value)
return false;
}
-static struct PsiMatrix build_contiguous_operator(struct PsiQuantumRegister reg, struct PsiQuantumGate gate, size_t start_idx)
+static struct PsiMatrix build_contiguous_operator(struct PsiQuantumRegister reg,
+ struct PsiQuantumGate gate, size_t start_idx)
{
size_t n = reg.num_qubits;
size_t g = gate.num_qubits;
@@ -163,9 +162,8 @@ static struct PsiMatrix build_contiguous_operator(struct PsiQuantumRegister reg,
if (i > start_idx && i < start_idx + g)
continue;
- struct PsiMatrix part = i == start_idx
- ? psi_clone_matrix(gate.matrix)
- : psi_identity_matrix(2);
+ struct PsiMatrix part =
+ i == start_idx ? psi_clone_matrix(gate.matrix) : psi_identity_matrix(2);
if (!has_result)
{
@@ -186,7 +184,9 @@ static struct PsiMatrix build_contiguous_operator(struct PsiQuantumRegister reg,
return result;
}
-static struct PsiMatrix build_full_operator(struct PsiQuantumRegister reg, struct PsiQuantumGate gate, const size_t *targets, size_t target_count)
+static struct PsiMatrix build_full_operator(struct PsiQuantumRegister reg,
+ struct PsiQuantumGate gate, const size_t* targets,
+ size_t target_count)
{
size_t n = reg.num_qubits;
size_t g = gate.num_qubits;
@@ -238,13 +238,15 @@ static struct PsiMatrix build_full_operator(struct PsiQuantumRegister reg, struc
}
if (non_target_match)
- result.data[row * result.cols + col] = psi_get_matrix(gate.matrix, target_row_bits, target_col_bits);
+ result.data[row * result.cols + col] =
+ psi_get_matrix(gate.matrix, target_row_bits, target_col_bits);
}
return result;
}
-void psi_apply_gate(struct PsiQuantumRegister *reg, struct PsiQuantumGate gate, const size_t *targets, size_t target_count)
+void psi_apply_gate(struct PsiQuantumRegister* reg, struct PsiQuantumGate gate,
+ const size_t* targets, size_t target_count)
{
size_t n = reg->num_qubits;
diff --git a/src/core/runtime.c b/src/core/runtime.c
index 950ec7c..24cbe26 100644
--- a/src/core/runtime.c
+++ b/src/core/runtime.c
@@ -34,14 +34,9 @@ struct PsiRuntimeConfig psi_runtime_to_config(enum PsiRuntime runtime)
switch (runtime)
{
- case PSI_RUNTIME_BASIC:
- break;
- case PSI_RUNTIME_BASIC_MT:
- config.parallel = true;
- break;
- case PSI_RUNTIME_BATCHED:
- config.batched = true;
- break;
+ case PSI_RUNTIME_BASIC: break;
+ case PSI_RUNTIME_BASIC_MT: config.parallel = true; break;
+ case PSI_RUNTIME_BATCHED: config.batched = true; break;
case PSI_RUNTIME_BATCHED_MT:
config.batched = true;
config.parallel = true;
@@ -69,45 +64,126 @@ struct PsiRuntimeConfig psi_runtime_to_config(enum PsiRuntime runtime)
return config;
}
-static bool op_to_kernel(struct PsiGateOp op, struct PsiKernel *out)
+static bool op_to_kernel(struct PsiGateOp op, struct PsiKernel* out)
{
struct PsiMatrix matrix;
- const char *name;
+ const char* name;
switch (op.kind)
{
- case PSI_GATE_H: matrix = psi_hadamard_gate().matrix; name = "H"; break;
- case PSI_GATE_X: matrix = psi_pauli_x_gate().matrix; name = "X"; break;
- case PSI_GATE_Y: matrix = psi_pauli_y_gate().matrix; name = "Y"; break;
- case PSI_GATE_Z: matrix = psi_pauli_z_gate().matrix; name = "Z"; break;
- case PSI_GATE_S: matrix = psi_s_gate().matrix; name = "S"; break;
- case PSI_GATE_T: matrix = psi_t_gate().matrix; name = "T"; break;
- case PSI_GATE_SDG: matrix = psi_sdg_gate().matrix; name = "Sdg"; break;
- case PSI_GATE_TDG: matrix = psi_tdg_gate().matrix; name = "Tdg"; break;
- case PSI_GATE_SX: matrix = psi_sx_gate().matrix; name = "Sx"; break;
- case PSI_GATE_SXDG: matrix = psi_sxdg_gate().matrix; name = "Sxdg"; break;
- case PSI_GATE_RX: matrix = psi_rx_matrix(op.params[0]); name = "Rx"; break;
- case PSI_GATE_RY: matrix = psi_ry_matrix(op.params[0]); name = "Ry"; break;
- case PSI_GATE_RZ: matrix = psi_rz_matrix(op.params[0]); name = "Rz"; break;
- case PSI_GATE_P: matrix = psi_p_matrix(op.params[0]); name = "P"; break;
- case PSI_GATE_U1: matrix = psi_u1_matrix(op.params[0]); name = "U1"; break;
- case PSI_GATE_U2: matrix = psi_u2_matrix(op.params[0], op.params[1]); name = "U2"; break;
- case PSI_GATE_U3: matrix = psi_u3_matrix(op.params[0], op.params[1], op.params[2]); name = "U3"; break;
- case PSI_GATE_CNOT: matrix = psi_cnot_gate().matrix; name = "CNOT"; break;
- case PSI_GATE_CZ: matrix = psi_cz_gate().matrix; name = "CZ"; break;
- case PSI_GATE_SWAP: matrix = psi_swap_gate().matrix; name = "SWAP"; break;
- case PSI_GATE_CRX: matrix = psi_crx_matrix(op.params[0]); name = "CRx"; break;
- case PSI_GATE_CRY: matrix = psi_cry_matrix(op.params[0]); name = "CRy"; break;
- case PSI_GATE_CRZ: matrix = psi_crz_matrix(op.params[0]); name = "CRz"; break;
- case PSI_GATE_CP: matrix = psi_cp_matrix(op.params[0]); name = "CP"; break;
- case PSI_GATE_CCNOT: matrix = psi_toffoli_gate().matrix; name = "CCNOT"; break;
- case PSI_GATE_CSWAP: matrix = psi_fredkin_gate().matrix; name = "CSWAP"; break;
+ case PSI_GATE_H:
+ matrix = psi_hadamard_gate().matrix;
+ name = "H";
+ break;
+ case PSI_GATE_X:
+ matrix = psi_pauli_x_gate().matrix;
+ name = "X";
+ break;
+ case PSI_GATE_Y:
+ matrix = psi_pauli_y_gate().matrix;
+ name = "Y";
+ break;
+ case PSI_GATE_Z:
+ matrix = psi_pauli_z_gate().matrix;
+ name = "Z";
+ break;
+ case PSI_GATE_S:
+ matrix = psi_s_gate().matrix;
+ name = "S";
+ break;
+ case PSI_GATE_T:
+ matrix = psi_t_gate().matrix;
+ name = "T";
+ break;
+ case PSI_GATE_SDG:
+ matrix = psi_sdg_gate().matrix;
+ name = "Sdg";
+ break;
+ case PSI_GATE_TDG:
+ matrix = psi_tdg_gate().matrix;
+ name = "Tdg";
+ break;
+ case PSI_GATE_SX:
+ matrix = psi_sx_gate().matrix;
+ name = "Sx";
+ break;
+ case PSI_GATE_SXDG:
+ matrix = psi_sxdg_gate().matrix;
+ name = "Sxdg";
+ break;
+ case PSI_GATE_RX:
+ matrix = psi_rx_matrix(op.params[0]);
+ name = "Rx";
+ break;
+ case PSI_GATE_RY:
+ matrix = psi_ry_matrix(op.params[0]);
+ name = "Ry";
+ break;
+ case PSI_GATE_RZ:
+ matrix = psi_rz_matrix(op.params[0]);
+ name = "Rz";
+ break;
+ case PSI_GATE_P:
+ matrix = psi_p_matrix(op.params[0]);
+ name = "P";
+ break;
+ case PSI_GATE_U1:
+ matrix = psi_u1_matrix(op.params[0]);
+ name = "U1";
+ break;
+ case PSI_GATE_U2:
+ matrix = psi_u2_matrix(op.params[0], op.params[1]);
+ name = "U2";
+ break;
+ case PSI_GATE_U3:
+ matrix = psi_u3_matrix(op.params[0], op.params[1], op.params[2]);
+ name = "U3";
+ break;
+ case PSI_GATE_CNOT:
+ matrix = psi_cnot_gate().matrix;
+ name = "CNOT";
+ break;
+ case PSI_GATE_CZ:
+ matrix = psi_cz_gate().matrix;
+ name = "CZ";
+ break;
+ case PSI_GATE_SWAP:
+ matrix = psi_swap_gate().matrix;
+ name = "SWAP";
+ break;
+ case PSI_GATE_CRX:
+ matrix = psi_crx_matrix(op.params[0]);
+ name = "CRx";
+ break;
+ case PSI_GATE_CRY:
+ matrix = psi_cry_matrix(op.params[0]);
+ name = "CRy";
+ break;
+ case PSI_GATE_CRZ:
+ matrix = psi_crz_matrix(op.params[0]);
+ name = "CRz";
+ break;
+ case PSI_GATE_CP:
+ matrix = psi_cp_matrix(op.params[0]);
+ name = "CP";
+ break;
+ case PSI_GATE_CCNOT:
+ matrix = psi_toffoli_gate().matrix;
+ name = "CCNOT";
+ break;
+ case PSI_GATE_CSWAP:
+ matrix = psi_fredkin_gate().matrix;
+ name = "CSWAP";
+ break;
case PSI_GATE_MEASURE: return false;
- case PSI_GATE_CUSTOM: matrix = psi_to_quantum_gate(*op.custom).matrix; name = "Custom"; break;
+ case PSI_GATE_CUSTOM:
+ matrix = psi_to_quantum_gate(*op.custom).matrix;
+ name = "Custom";
+ break;
}
size_t target_count;
- const size_t *targets = psi_gate_op_quantum_targets(&op, &target_count);
+ const size_t* targets = psi_gate_op_quantum_targets(&op, &target_count);
*out = psi_new_kernel(name, matrix, targets, target_count);
return true;
@@ -122,7 +198,8 @@ static struct PsiVector new_zero_state(size_t num_qubits)
return state;
}
-static void execute_kernels(struct PsiVector *state, const struct PsiKernel *kernels, size_t count, size_t num_qubits, struct PsiRuntimeConfig config)
+static void execute_kernels(struct PsiVector* state, const struct PsiKernel* kernels, size_t count,
+ size_t num_qubits, struct PsiRuntimeConfig config)
{
bool use_parallel = config.parallel && num_qubits >= config.parallel_threshold;
@@ -138,7 +215,8 @@ static void execute_kernels(struct PsiVector *state, const struct PsiKernel *ker
};
if (use_parallel)
- psi_apply_single_qubit_gate_simd_parallel(state->data, gate, kernel.targets[0], num_qubits);
+ psi_apply_single_qubit_gate_simd_parallel(state->data, gate, kernel.targets[0],
+ num_qubits);
else
psi_apply_single_qubit_gate_simd(state->data, gate, kernel.targets[0], num_qubits);
}
@@ -147,7 +225,8 @@ static void execute_kernels(struct PsiVector *state, const struct PsiKernel *ker
}
}
-struct PsiVector psi_compute_runtime_config(struct PsiRuntimeConfig config, size_t num_qubits, const struct PsiGateOp *operations, size_t op_count)
+struct PsiVector psi_compute_runtime_config(struct PsiRuntimeConfig config, size_t num_qubits,
+ const struct PsiGateOp* operations, size_t op_count)
{
struct PsiVector state = new_zero_state(num_qubits);
@@ -185,42 +264,47 @@ struct PsiVector psi_compute_runtime_config(struct PsiRuntimeConfig config, size
return state;
}
-struct PsiVector psi_compute_runtime(enum PsiRuntime runtime, size_t num_qubits, const struct PsiGateOp *operations, size_t op_count)
+struct PsiVector psi_compute_runtime(enum PsiRuntime runtime, size_t num_qubits,
+ const struct PsiGateOp* operations, size_t op_count)
{
- return psi_compute_runtime_config(psi_runtime_to_config(runtime), num_qubits, operations, op_count);
+ return psi_compute_runtime_config(psi_runtime_to_config(runtime), num_qubits, operations,
+ op_count);
}
-const struct PsiVector *psi_compute_circuit_with_config(struct PsiQuantumCircuit *circuit, struct PsiRuntimeConfig config)
+const struct PsiVector* psi_compute_circuit_with_config(struct PsiQuantumCircuit* circuit,
+ struct PsiRuntimeConfig config)
{
if (!circuit->is_computed)
{
psi_free_vector(&circuit->computed_state);
- circuit->computed_state = psi_compute_runtime_config(config, circuit->num_qubits, circuit->operations, circuit->operation_count);
+ circuit->computed_state = psi_compute_runtime_config(
+ config, circuit->num_qubits, circuit->operations, circuit->operation_count);
circuit->is_computed = true;
}
return &circuit->computed_state;
}
-const struct PsiVector *psi_compute_circuit_with(struct PsiQuantumCircuit *circuit, enum PsiRuntime runtime)
+const struct PsiVector* psi_compute_circuit_with(struct PsiQuantumCircuit* circuit,
+ enum PsiRuntime runtime)
{
return psi_compute_circuit_with_config(circuit, psi_runtime_to_config(runtime));
}
-const struct PsiVector *psi_compute_circuit(struct PsiQuantumCircuit *circuit)
+const struct PsiVector* psi_compute_circuit(struct PsiQuantumCircuit* circuit)
{
return psi_compute_circuit_with(circuit, PSI_RUNTIME_BASIC);
}
-double psi_circuit_probability(struct PsiQuantumCircuit *circuit, size_t state_index)
+double psi_circuit_probability(struct PsiQuantumCircuit* circuit, size_t state_index)
{
- const struct PsiVector *state = psi_compute_circuit(circuit);
+ const struct PsiVector* state = psi_compute_circuit(circuit);
return psi_norm2_complex(state->data[state_index]);
}
-void psi_circuit_probabilities(struct PsiQuantumCircuit *circuit, double *out)
+void psi_circuit_probabilities(struct PsiQuantumCircuit* circuit, double* out)
{
- const struct PsiVector *state = psi_compute_circuit(circuit);
+ const struct PsiVector* state = psi_compute_circuit(circuit);
size_t dim = (size_t)1 << circuit->num_qubits;
for (size_t i = 0; i < dim; i++)
out[i] = psi_norm2_complex(state->data[i]);