diff options
Diffstat (limited to 'src/core/quantum_components.c')
| -rw-r--r-- | src/core/quantum_components.c | 318 |
1 files changed, 159 insertions, 159 deletions
diff --git a/src/core/quantum_components.c b/src/core/quantum_components.c index a62a911..5870906 100644 --- a/src/core/quantum_components.c +++ b/src/core/quantum_components.c @@ -6,262 +6,262 @@ struct PsiVector psi_new_state_0(void) { - return psi_column_vector(psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0)); + return psi_column_vector(psi_new_complex(1.0, 0.0), psi_new_complex(0.0, 0.0)); } 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)); + 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) { - size_t expected_dim = (size_t)1 << num_qubits; - assert(matrix.rows == expected_dim); - assert(matrix.cols == expected_dim); + size_t expected_dim = (size_t)1 << num_qubits; + assert(matrix.rows == expected_dim); + assert(matrix.cols == expected_dim); - return (struct PsiQuantumGate){ - name, - matrix, - num_qubits, - }; + return (struct PsiQuantumGate){ + name, + matrix, + num_qubits, + }; } struct PsiQuantumGate psi_new_quantum_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++; - return (struct PsiQuantumGate){ - name, - matrix, - num_qubits, - }; + return (struct PsiQuantumGate){ + name, + matrix, + num_qubits, + }; } void psi_free_quantum_gate(struct PsiQuantumGate* gate) { - psi_free_matrix(&gate->matrix); + psi_free_matrix(&gate->matrix); } struct PsiQuantumBit psi_new_quantum_bit(const char* name, struct PsiVector state) { - return (struct PsiQuantumBit){ - name, - state, - }; + return (struct PsiQuantumBit){ + name, + state, + }; } void psi_free_quantum_bit(struct PsiQuantumBit* bit) { - psi_free_vector(&bit->state); + psi_free_vector(&bit->state); } static void update_register(struct PsiQuantumRegister* reg) { - psi_free_vector(®->state_vector); + psi_free_vector(®->state_vector); - if (reg->num_qubits == 0) - { - reg->state_vector = psi_new_vector(0, PSI_COLUMN_VECTOR); - return; - } + if (reg->num_qubits == 0) + { + reg->state_vector = psi_new_vector(0, PSI_COLUMN_VECTOR); + return; + } - struct PsiMatrix result = psi_matrix_from_vector(reg->qubits[0].state); - for (size_t i = 1; i < reg->num_qubits; i++) - { - struct PsiMatrix part = psi_matrix_from_vector(reg->qubits[i].state); - struct PsiMatrix next = psi_kronecker_matrix(result, part); - psi_free_matrix(&result); - psi_free_matrix(&part); - result = next; - } + struct PsiMatrix result = psi_matrix_from_vector(reg->qubits[0].state); + for (size_t i = 1; i < reg->num_qubits; i++) + { + struct PsiMatrix part = psi_matrix_from_vector(reg->qubits[i].state); + struct PsiMatrix next = psi_kronecker_matrix(result, part); + psi_free_matrix(&result); + psi_free_matrix(&part); + result = next; + } - reg->state_vector = psi_vector_from_matrix(result, PSI_COLUMN_VECTOR); - psi_free_matrix(&result); + reg->state_vector = psi_vector_from_matrix(result, PSI_COLUMN_VECTOR); + psi_free_matrix(&result); } struct PsiQuantumRegister psi_new_quantum_register(const char* name, const char** names, size_t count) { - struct PsiQuantumBit* qubits = malloc(count * sizeof(struct PsiQuantumBit)); - assert(qubits != NULL || count == 0); + 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()); + for (size_t i = 0; i < count; i++) + qubits[i] = psi_new_quantum_bit(names[i], psi_new_state_0()); - struct PsiQuantumRegister reg = { - name, - psi_new_vector(0, PSI_COLUMN_VECTOR), - qubits, - count, - }; + struct PsiQuantumRegister reg = { + name, + psi_new_vector(0, PSI_COLUMN_VECTOR), + qubits, + count, + }; - update_register(®); - return reg; + update_register(®); + return reg; } 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)); - assert(qubits != NULL || count == 0); + 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)); + 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 = { - name, - psi_new_vector(0, PSI_COLUMN_VECTOR), - qubits, - count, - }; + struct PsiQuantumRegister reg = { + name, + psi_new_vector(0, PSI_COLUMN_VECTOR), + qubits, + count, + }; - update_register(®); - return reg; + update_register(®); + return reg; } void psi_free_quantum_register(struct PsiQuantumRegister* reg) { - for (size_t i = 0; i < reg->num_qubits; i++) - psi_free_quantum_bit(®->qubits[i]); + for (size_t i = 0; i < reg->num_qubits; i++) + psi_free_quantum_bit(®->qubits[i]); - free(reg->qubits); - reg->qubits = NULL; - reg->num_qubits = 0; - psi_free_vector(®->state_vector); + free(reg->qubits); + reg->qubits = NULL; + reg->num_qubits = 0; + psi_free_vector(®->state_vector); } 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) - return true; + for (size_t i = 0; i < count; i++) + if (targets[i] == value) + return true; - return false; + return false; } 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; + size_t n = reg.num_qubits; + size_t g = gate.num_qubits; - bool has_result = false; - struct PsiMatrix result = { 0 }; + bool has_result = false; + struct PsiMatrix result = { 0 }; - for (size_t i = 0; i < n; i++) - { - if (i > start_idx && i < start_idx + g) - continue; + for (size_t i = 0; i < n; i++) + { + 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) - { - result = part; - has_result = true; - continue; - } + if (!has_result) + { + result = part; + has_result = true; + continue; + } - struct PsiMatrix next = psi_kronecker_matrix(result, part); - psi_free_matrix(&result); - psi_free_matrix(&part); - result = next; - } + struct PsiMatrix next = psi_kronecker_matrix(result, part); + psi_free_matrix(&result); + psi_free_matrix(&part); + result = next; + } - if (!has_result) - return psi_identity_matrix((size_t)1 << n); + if (!has_result) + return psi_identity_matrix((size_t)1 << n); - return result; + return result; } 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; - size_t dim = (size_t)1 << n; + size_t n = reg.num_qubits; + size_t g = gate.num_qubits; + size_t dim = (size_t)1 << n; - bool contiguous = true; - for (size_t i = 1; i < target_count; i++) - if (targets[i] != targets[i - 1] + 1) - { - contiguous = false; - break; - } + bool contiguous = true; + for (size_t i = 1; i < target_count; i++) + if (targets[i] != targets[i - 1] + 1) + { + contiguous = false; + break; + } - if (contiguous && g == n) - return psi_clone_matrix(gate.matrix); + if (contiguous && g == n) + return psi_clone_matrix(gate.matrix); - if (contiguous) - return build_contiguous_operator(reg, gate, targets[0]); + if (contiguous) + return build_contiguous_operator(reg, gate, targets[0]); - struct PsiMatrix result = psi_new_matrix(dim, dim); + struct PsiMatrix result = psi_new_matrix(dim, dim); - for (size_t col = 0; col < dim; col++) - for (size_t row = 0; row < dim; row++) - { - size_t target_row_bits = 0; - size_t target_col_bits = 0; + for (size_t col = 0; col < dim; col++) + for (size_t row = 0; row < dim; row++) + { + size_t target_row_bits = 0; + size_t target_col_bits = 0; - for (size_t i = 0; i < target_count; i++) - { - size_t qubit_pos = n - 1 - targets[i]; - if ((row >> qubit_pos) & 1) - target_row_bits |= (size_t)1 << (g - 1 - i); - if ((col >> qubit_pos) & 1) - target_col_bits |= (size_t)1 << (g - 1 - i); - } + for (size_t i = 0; i < target_count; i++) + { + size_t qubit_pos = n - 1 - targets[i]; + if ((row >> qubit_pos) & 1) + target_row_bits |= (size_t)1 << (g - 1 - i); + if ((col >> qubit_pos) & 1) + target_col_bits |= (size_t)1 << (g - 1 - i); + } - bool non_target_match = true; - for (size_t q = 0; q < n; q++) - { - if (targets_contain(targets, target_count, q)) - continue; + bool non_target_match = true; + for (size_t q = 0; q < n; q++) + { + if (targets_contain(targets, target_count, q)) + continue; - size_t qubit_pos = n - 1 - q; - if (((row >> qubit_pos) & 1) != ((col >> qubit_pos) & 1)) - { - non_target_match = false; - break; - } - } + size_t qubit_pos = n - 1 - q; + if (((row >> qubit_pos) & 1) != ((col >> qubit_pos) & 1)) + { + non_target_match = false; + break; + } + } - if (non_target_match) - result.data[row * result.cols + col] = - psi_get_matrix(gate.matrix, target_row_bits, target_col_bits); - } + if (non_target_match) + result.data[row * result.cols + col] = + psi_get_matrix(gate.matrix, target_row_bits, target_col_bits); + } - return result; + return result; } void psi_apply_gate(struct PsiQuantumRegister* reg, struct PsiQuantumGate gate, const size_t* targets, size_t target_count) { - size_t n = reg->num_qubits; + size_t n = reg->num_qubits; - assert(gate.num_qubits == target_count); - for (size_t i = 0; i < target_count; i++) - assert(targets[i] < n); + assert(gate.num_qubits == target_count); + for (size_t i = 0; i < target_count; i++) + assert(targets[i] < n); - for (size_t i = 0; i < target_count; i++) - for (size_t j = i + 1; j < target_count; j++) - assert(targets[i] != targets[j]); + for (size_t i = 0; i < target_count; i++) + for (size_t j = i + 1; j < target_count; j++) + assert(targets[i] != targets[j]); - struct PsiMatrix full_operator = build_full_operator(*reg, gate, targets, target_count); - struct PsiVector new_state = psi_mul_vector_matrix(reg->state_vector, full_operator); + struct PsiMatrix full_operator = build_full_operator(*reg, gate, targets, target_count); + struct PsiVector new_state = psi_mul_vector_matrix(reg->state_vector, full_operator); - psi_free_vector(®->state_vector); - psi_free_matrix(&full_operator); - reg->state_vector = new_state; + psi_free_vector(®->state_vector); + psi_free_matrix(&full_operator); + reg->state_vector = new_state; } |
