mirror of https://github.com/Qiskit/qiskit-aer.git
241 lines
7.9 KiB
C++
241 lines
7.9 KiB
C++
/**
|
||
* This code is part of Qiskit.
|
||
*
|
||
* (C) Copyright IBM 2022.
|
||
*
|
||
* This code is licensed under the Apache License, Version 2.0. You may
|
||
* obtain a copy of this license in the LICENSE.txt file in the root directory
|
||
* of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
||
*
|
||
* Any modifications or derivative works of this code must retain this
|
||
* copyright notice, and modified files need to carry a notice indicating
|
||
* that they have been altered from the originals.
|
||
*/
|
||
#include "controllers/state_controller.hpp"
|
||
#include <cmath>
|
||
#include <stdio.h>
|
||
|
||
// initialize and return state
|
||
extern "C" {
|
||
|
||
void *aer_state() {
|
||
AER::AerState *handler = new AER::AerState();
|
||
return handler;
|
||
};
|
||
|
||
void aer_state_initialize(void *handler) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->initialize();
|
||
};
|
||
|
||
// finalize state
|
||
void aer_state_finalize(void *handler) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
delete (state);
|
||
};
|
||
|
||
// configure state
|
||
void aer_state_configure(void *handler, char *key, char *value) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->configure(key, value);
|
||
};
|
||
|
||
// allocate qubits and return the first qubit index.
|
||
// following qubits are indexed with incremented indices.
|
||
uint_t aer_allocate_qubits(void *handler, uint_t num_qubits) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
auto qubit_ids = state->allocate_qubits(num_qubits);
|
||
return qubit_ids[0];
|
||
};
|
||
|
||
// measure qubits
|
||
uint_t aer_apply_measure(void *handler, uint_t *qubits_, size_t num_qubits) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
std::vector<uint_t> qubits(qubits_, qubits_ + num_qubits);
|
||
return state->apply_measure(qubits);
|
||
};
|
||
|
||
// return probability of a specific bitstring
|
||
double aer_probability(void *handler, uint_t outcome) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
return state->probability(outcome);
|
||
};
|
||
|
||
// return probability amplitude of a specific bitstring
|
||
complex_t aer_amplitude(void *handler, uint_t outcome) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
return state->amplitude(outcome);
|
||
};
|
||
|
||
// return probability amplitudes
|
||
// returned pointer must be freed in the caller
|
||
complex_t *aer_release_statevector(void *handler) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
AER::Vector<complex_t> sv = state->move_to_vector();
|
||
return sv.move_to_buffer();
|
||
};
|
||
|
||
// u3 gate
|
||
void aer_apply_u3(void *handler, uint_t qubit, double theta, double phi,
|
||
double lambda) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_u(qubit, theta, phi, lambda);
|
||
}
|
||
|
||
// phase gate
|
||
void aer_apply_p(void *handler, uint_t qubit, double lambda) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcphase({qubit}, lambda);
|
||
};
|
||
|
||
// Pauli gate: bit-flip or NOT gate
|
||
void aer_apply_x(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcx({qubit});
|
||
};
|
||
|
||
// Pauli gate: bit and phase flip
|
||
void aer_apply_y(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcy({qubit});
|
||
};
|
||
|
||
// Pauli gate: phase flip
|
||
void aer_apply_z(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcz({qubit});
|
||
};
|
||
|
||
// Clifford gate: Hadamard
|
||
void aer_apply_h(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_h(qubit);
|
||
};
|
||
|
||
// Clifford gate: sqrt(Z) or S gate
|
||
void aer_apply_s(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_u(qubit, 0, 0, M_PI / 2.0);
|
||
};
|
||
|
||
// Clifford gate: inverse of sqrt(Z)
|
||
void aer_apply_sdg(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_u(qubit, 0, 0, -M_PI / 2.0);
|
||
};
|
||
|
||
// // sqrt(S) or T gate
|
||
void aer_apply_t(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_u(qubit, 0, 0, M_PI / 4.0);
|
||
};
|
||
|
||
// inverse of sqrt(S)
|
||
void aer_apply_tdg(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_u({qubit}, 0, 0, -M_PI / 4.0);
|
||
};
|
||
|
||
// sqrt(NOT) gate
|
||
void aer_apply_sx(void *handler, uint_t qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcsx({qubit});
|
||
};
|
||
|
||
// Rotation around X-axis
|
||
void aer_apply_rx(void *handler, uint_t qubit, double theta) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcrx({qubit}, theta);
|
||
};
|
||
|
||
// rotation around Y-axis
|
||
void aer_apply_ry(void *handler, uint_t qubit, double theta) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcry({qubit}, theta);
|
||
};
|
||
|
||
// rotation around Z axis
|
||
void aer_apply_rz(void *handler, uint_t qubit, double theta) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcrz({qubit}, theta);
|
||
};
|
||
|
||
// controlled-NOT
|
||
void aer_apply_cx(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcx({ctrl_qubit, tgt_qubit});
|
||
};
|
||
|
||
// controlled-Y
|
||
void aer_apply_cy(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcy({ctrl_qubit, tgt_qubit});
|
||
};
|
||
|
||
// controlled-Z
|
||
void aer_apply_cz(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcz({ctrl_qubit, tgt_qubit});
|
||
};
|
||
|
||
// controlled-phase
|
||
void aer_apply_cp(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit,
|
||
double lambda) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcphase({ctrl_qubit, tgt_qubit}, lambda);
|
||
};
|
||
|
||
// controlled-rx
|
||
void aer_apply_crx(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit,
|
||
double theta) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcrx({ctrl_qubit, tgt_qubit}, theta);
|
||
};
|
||
|
||
// controlled-ry
|
||
void aer_apply_cry(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit,
|
||
double theta) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcry({ctrl_qubit, tgt_qubit}, theta);
|
||
};
|
||
|
||
// controlled-rz
|
||
void aer_apply_crz(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit,
|
||
double theta) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcrz({ctrl_qubit, tgt_qubit}, theta);
|
||
};
|
||
|
||
// controlled-H
|
||
void aer_apply_ch(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcu({ctrl_qubit, tgt_qubit}, M_PI / 2.0, 0, M_PI, 0);
|
||
};
|
||
|
||
// swap
|
||
void aer_apply_swap(void *handler, uint_t qubit0, uint_t qubit1) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcswap({qubit0, qubit1});
|
||
};
|
||
|
||
// Toffoli
|
||
void aer_apply_ccx(void *handler, uint_t qubit0, uint_t qubit1, uint_t qubit2) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcx({qubit0, qubit1, qubit2});
|
||
};
|
||
|
||
// // controlled-swap
|
||
void aer_apply_cswap(void *handler, uint_t ctrl_qubit, uint_t qubit0,
|
||
uint_t qubit1) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcswap({ctrl_qubit, qubit0, qubit1});
|
||
};
|
||
|
||
// four parameter controlled-U gate with relative phase γ
|
||
void aer_apply_cu(void *handler, uint_t ctrl_qubit, uint_t tgt_qubit,
|
||
double theta, double phi, double lambda, double gamma) {
|
||
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
|
||
state->apply_mcu({ctrl_qubit, tgt_qubit}, theta, phi, lambda, gamma);
|
||
};
|
||
}
|