Skip to content

Commit

Permalink
Gateのポインタ実装を隠蔽
Browse files Browse the repository at this point in the history
  • Loading branch information
KowerKoint committed Jan 18, 2024
1 parent 6738069 commit 51877d8
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 177 deletions.
35 changes: 18 additions & 17 deletions qulacs/gate/constant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,47 +27,48 @@ KOKKOS_INLINE_FUNCTION
double SINPI8() { return 0.382683432365090; }

//! identity matrix
matrix_2_2 I_GATE = {1, 0, 0, 1};
inline matrix_2_2 I_GATE = {1, 0, 0, 1};
//! Pauli matrix X
matrix_2_2 X_GATE = {0, 1, 1, 0};
inline matrix_2_2 X_GATE = {0, 1, 1, 0};
//! Pauli matrix Y
matrix_2_2 Y_GATE = {0, Complex(0, -1), Complex(0, 1), 0};
inline matrix_2_2 Y_GATE = {0, Complex(0, -1), Complex(0, 1), 0};
//! Pauli matrix Z
matrix_2_2 Z_GATE = {1, 0, 0, -1};
inline matrix_2_2 Z_GATE = {1, 0, 0, -1};

//! list of Pauli matrix I,X,Y,Z
// std::array<matrix_2_2, 4> PAULI_MATRIX = {I_GATE, X_GATE, Y_GATE, Z_GATE};

//! S-gate
matrix_2_2 S_GATE_MATRIX = {1, 0, 0, Complex(0, 1)};
inline matrix_2_2 S_GATE_MATRIX = {1, 0, 0, Complex(0, 1)};
//! Sdag-gate
matrix_2_2 S_DAG_GATE_MATRIX = {1, 0, 0, Complex(0, -1)};
inline matrix_2_2 S_DAG_GATE_MATRIX = {1, 0, 0, Complex(0, -1)};
//! T-gate
matrix_2_2 T_GATE_MATRIX = {
inline matrix_2_2 T_GATE_MATRIX = {
COSPI8() - Complex(0, SINPI8()), 0., 0., COSPI8() + Complex(0, SINPI8()) * SINPI8()};
//! Tdag-gate
matrix_2_2 T_DAG_GATE_MATRIX = {
inline matrix_2_2 T_DAG_GATE_MATRIX = {
COSPI8() + Complex(0, SINPI8()), 0., 0., COSPI8() - Complex(0, SINPI8())};
//! Hadamard gate
matrix_2_2 HADAMARD_MATRIX = {INVERSE_SQRT2(), INVERSE_SQRT2(), INVERSE_SQRT2(), -INVERSE_SQRT2()};
inline matrix_2_2 HADAMARD_MATRIX = {
INVERSE_SQRT2(), INVERSE_SQRT2(), INVERSE_SQRT2(), -INVERSE_SQRT2()};
//! square root of X gate
matrix_2_2 SQRT_X_GATE_MATRIX = {
inline matrix_2_2 SQRT_X_GATE_MATRIX = {
Complex(0.5, 0.5), Complex(0.5, -0.5), Complex(0.5, -0.5), Complex(0.5, 0.5)};
//! square root of Y gate
matrix_2_2 SQRT_Y_GATE_MATRIX = {
inline matrix_2_2 SQRT_Y_GATE_MATRIX = {
Complex(0.5, 0.5), Complex(-0.5, -0.5), Complex(0.5, 0.5), Complex(0.5, 0.5)};
//! square root dagger of X gate
matrix_2_2 SQRT_X_DAG_GATE_MATRIX = {
inline matrix_2_2 SQRT_X_DAG_GATE_MATRIX = {
Complex(0.5, -0.5), Complex(0.5, 0.5), Complex(0.5, 0.5), Complex(0.5, -0.5)};
//! square root dagger of Y gate
matrix_2_2 SQRT_Y_DAG_GATE_MATRIX = {
inline matrix_2_2 SQRT_Y_DAG_GATE_MATRIX = {
Complex(0.5, -0.5), Complex(0.5, -0.5), Complex(-0.5, 0.5), Complex(0.5, -0.5)};
//! Projection to 0
matrix_2_2 PROJ_0_MATRIX = {1, 0, 0, 0};
inline matrix_2_2 PROJ_0_MATRIX = {1, 0, 0, 0};
//! Projection to 1
matrix_2_2 PROJ_1_MATRIX = {0, 0, 0, 1};
inline matrix_2_2 PROJ_1_MATRIX = {0, 0, 0, 1};
//! complex values for exp(j * i*pi/4 )
matrix_2_2 PHASE_90ROT = {1., Complex(0, 1), -1, Complex(0, -1)};
inline matrix_2_2 PHASE_90ROT = {1., Complex(0, 1), -1, Complex(0, -1)};
//! complex values for exp(-j * i*pi/4 )
matrix_2_2 PHASE_M90ROT = {1., Complex(0, -1), -1, Complex(0, 1)};
inline matrix_2_2 PHASE_M90ROT = {1., Complex(0, -1), -1, Complex(0, 1)};
} // namespace qulacs
34 changes: 31 additions & 3 deletions qulacs/gate/gate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
#include "../types.hpp"

namespace qulacs {
using GatePtr = std::unique_ptr<class QuantumGate>;
namespace internal {
using GatePtr = std::unique_ptr<class GateBase>;
}

class QuantumGate {
namespace internal {
class GateBase {
public:
virtual ~QuantumGate() = default;
virtual ~GateBase() = default;

[[nodiscard]] virtual std::vector<UINT> get_target_qubit_list() const = 0;
[[nodiscard]] virtual std::vector<UINT> get_control_qubit_list() const = 0;
Expand All @@ -26,4 +29,29 @@ class QuantumGate {

virtual void update_quantum_state(StateVector& state_vector) const = 0;
};

template <typename T>
concept GateImpl = std::derived_from<T, GateBase>;

class GateFactory;
} // namespace internal

class Gate {
friend class internal::GateFactory;

private:
internal::GatePtr _gate_ptr;
Gate(internal::GatePtr&& gate_ptr) : _gate_ptr(std::move(gate_ptr)) {}

public:
std::vector<UINT> get_control_qubit_list() const { return _gate_ptr->get_control_qubit_list(); }
std::vector<UINT> get_target_qubit_list() const { return _gate_ptr->get_target_qubit_list(); }
UINT n_qubits() const { return _gate_ptr->n_qubits(); }
Gate copy() const { return _gate_ptr->copy(); }
Gate get_inverse() const { return _gate_ptr->get_inverse(); }
void update_quantum_state(StateVector& state_vector) const {
_gate_ptr->update_quantum_state(state_vector);
}
};

} // namespace qulacs
82 changes: 53 additions & 29 deletions qulacs/gate/gate_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,57 @@
#include "gate/gate_quantum_matrix.hpp"

namespace qulacs {
namespace gate {
GatePtr I(UINT target) { return std::make_unique<qulacs::I>(target); }
GatePtr X(UINT target) { return std::make_unique<qulacs::X>(target); }
GatePtr Y(UINT target) { return std::make_unique<qulacs::Y>(target); }
GatePtr Z(UINT target) { return std::make_unique<qulacs::Z>(target); }
GatePtr H(UINT target) { return std::make_unique<qulacs::H>(target); }
GatePtr S(UINT target) { return std::make_unique<qulacs::S>(target); }
GatePtr Sdag(UINT target) { return std::make_unique<qulacs::Sdag>(target); }
GatePtr T(UINT target) { return std::make_unique<qulacs::T>(target); }
GatePtr Tdag(UINT target) { return std::make_unique<qulacs::Tdag>(target); }
GatePtr sqrtX(UINT target) { return std::make_unique<qulacs::sqrtX>(target); }
GatePtr sqrtXdag(UINT target) { return std::make_unique<qulacs::sqrtXdag>(target); }
GatePtr sqrtY(UINT target) { return std::make_unique<qulacs::sqrtY>(target); }
GatePtr sqrtYdag(UINT target) { return std::make_unique<qulacs::sqrtYdag>(target); }
GatePtr P0(UINT target) { return std::make_unique<qulacs::P0>(target); }
GatePtr P1(UINT target) { return std::make_unique<qulacs::P1>(target); }
GatePtr RX(UINT target, double angle) { return std::make_unique<qulacs::RX>(target, angle); }
GatePtr RY(UINT target, double angle) { return std::make_unique<qulacs::RY>(target, angle); }
GatePtr RZ(UINT target, double angle) { return std::make_unique<qulacs::RZ>(target, angle); }
GatePtr U1(UINT target, double lambda) { return std::make_unique<qulacs::U1>(target, lambda); }
GatePtr U2(UINT target, double phi, double lambda) {
return std::make_unique<qulacs::U2>(target, phi, lambda);
}
GatePtr U3(UINT target, double theta, double phi, double lambda) {
return std::make_unique<qulacs::U3>(target, theta, phi, lambda);
}
GatePtr CNOT(UINT control, UINT target) { return std::make_unique<qulacs::CNOT>(control, target); }
GatePtr CZ(UINT control, UINT target) { return std::make_unique<qulacs::CZ>(control, target); }
} // namespace gate
namespace internal {
class GateFactory {
public:
template <GateImpl T, typename... Args>
static Gate create_gate(Args... args) {
return {std::make_unique<T>(args...)};
}
};
} // namespace internal

Gate I(UINT target) { return internal::GateFactory::create_gate<internal::IGate>(target); }
Gate X(UINT target) { return internal::GateFactory::create_gate<internal::XGate>(target); }
Gate Y(UINT target) { return internal::GateFactory::create_gate<internal::YGate>(target); }
Gate Z(UINT target) { return internal::GateFactory::create_gate<internal::ZGate>(target); }
Gate H(UINT target) { return internal::GateFactory::create_gate<internal::HGate>(target); }
Gate S(UINT target) { return internal::GateFactory::create_gate<internal::SGate>(target); }
Gate Sdag(UINT target) { return internal::GateFactory::create_gate<internal::SdagGate>(target); }
Gate T(UINT target) { return internal::GateFactory::create_gate<internal::TGate>(target); }
Gate Tdag(UINT target) { return internal::GateFactory::create_gate<internal::TdagGate>(target); }
Gate sqrtX(UINT target) { return internal::GateFactory::create_gate<internal::sqrtXGate>(target); }
Gate sqrtXdag(UINT target) {
return internal::GateFactory::create_gate<internal::sqrtXdagGate>(target);
}
Gate sqrtY(UINT target) { return internal::GateFactory::create_gate<internal::sqrtYGate>(target); }
Gate sqrtYdag(UINT target) {
return internal::GateFactory::create_gate<internal::sqrtYdagGate>(target);
}
Gate P0(UINT target) { return internal::GateFactory::create_gate<internal::P0Gate>(target); }
Gate P1(UINT target) { return internal::GateFactory::create_gate<internal::P1Gate>(target); }
Gate RX(UINT target, double angle) {
return internal::GateFactory::create_gate<internal::RXGate>(target, angle);
}
Gate RY(UINT target, double angle) {
return internal::GateFactory::create_gate<internal::RYGate>(target, angle);
}
Gate RZ(UINT target, double angle) {
return internal::GateFactory::create_gate<internal::RZGate>(target, angle);
}
Gate U1(UINT target, double lambda) {
return internal::GateFactory::create_gate<internal::U1Gate>(target, lambda);
}
Gate U2(UINT target, double phi, double lambda) {
return internal::GateFactory::create_gate<internal::U2Gate>(target, phi, lambda);
}
Gate U3(UINT target, double theta, double phi, double lambda) {
return internal::GateFactory::create_gate<internal::U3Gate>(target, theta, phi, lambda);
}
Gate CNOT(UINT control, UINT target) {
return internal::GateFactory::create_gate<internal::CNOTGate>(control, target);
}
Gate CZ(UINT control, UINT target) {
return internal::GateFactory::create_gate<internal::CZGate>(control, target);
}
} // namespace qulacs
6 changes: 4 additions & 2 deletions qulacs/gate/gate_one_control_one_target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
#include "update_ops.hpp"

namespace qulacs {
void CNOT::update_quantum_state(StateVector& state_vector) const {
namespace internal {
void CNOTGate::update_quantum_state(StateVector& state_vector) const {
cnot_gate(this->_control, this->_target, state_vector);
}

void CZ::update_quantum_state(StateVector& state_vector) const {
void CZGate::update_quantum_state(StateVector& state_vector) const {
cz_gate(this->_control, this->_target, state_vector);
}
} // namespace internal
} // namespace qulacs
23 changes: 12 additions & 11 deletions qulacs/gate/gate_one_control_one_target.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
#include "gate.hpp"

namespace qulacs {
class QuantumGateOneControlOneTarget : public QuantumGate {
namespace internal {
class OneControlOneTargetGateBase : public GateBase {
protected:
UINT _control, _target;

public:
QuantumGateOneControlOneTarget(UINT control, UINT target)
: _control(control), _target(target){};
OneControlOneTargetGateBase(UINT control, UINT target) : _control(control), _target(target){};

UINT control() const { return _control; }
UINT target() const { return _target; }
Expand All @@ -20,23 +20,24 @@ class QuantumGateOneControlOneTarget : public QuantumGate {
std::vector<UINT> get_control_qubit_list() const override { return {_control}; };
};

class CNOT : public QuantumGateOneControlOneTarget {
class CNOTGate : public OneControlOneTargetGateBase {
public:
CNOT(UINT control, UINT target) : QuantumGateOneControlOneTarget(control, target) {}
CNOTGate(UINT control, UINT target) : OneControlOneTargetGateBase(control, target) {}

GatePtr copy() const override { return std::make_unique<CNOT>(*this); }
GatePtr get_inverse() const override { return std::make_unique<CNOT>(*this); }
GatePtr copy() const override { return std::make_unique<CNOTGate>(*this); }
GatePtr get_inverse() const override { return std::make_unique<CNOTGate>(*this); }

void update_quantum_state(StateVector& state_vector) const override;
};

class CZ : public QuantumGateOneControlOneTarget {
class CZGate : public OneControlOneTargetGateBase {
public:
CZ(UINT control, UINT target) : QuantumGateOneControlOneTarget(control, target) {}
CZGate(UINT control, UINT target) : OneControlOneTargetGateBase(control, target) {}

GatePtr copy() const override { return std::make_unique<CZ>(*this); }
GatePtr get_inverse() const override { return std::make_unique<CZ>(*this); }
GatePtr copy() const override { return std::make_unique<CZGate>(*this); }
GatePtr get_inverse() const override { return std::make_unique<CZGate>(*this); }

void update_quantum_state(StateVector& state_vector) const override;
};
} // namespace internal
} // namespace qulacs
46 changes: 24 additions & 22 deletions qulacs/gate/gate_one_qubit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,80 +3,82 @@
#include "update_ops.hpp"

namespace qulacs {
GatePtr S::get_inverse() const { return std::make_unique<Sdag>(_target); }
GatePtr T::get_inverse() const { return std::make_unique<Tdag>(_target); }
GatePtr sqrtX::get_inverse() const { return std::make_unique<sqrtXdag>(_target); }
GatePtr sqrtY::get_inverse() const { return std::make_unique<sqrtYdag>(_target); }
namespace internal {
GatePtr SGate::get_inverse() const { return std::make_unique<SdagGate>(_target); }
GatePtr TGate::get_inverse() const { return std::make_unique<TdagGate>(_target); }
GatePtr sqrtXGate::get_inverse() const { return std::make_unique<sqrtXdagGate>(_target); }
GatePtr sqrtYGate::get_inverse() const { return std::make_unique<sqrtYdagGate>(_target); }

void I::update_quantum_state(StateVector& state_vector) const {
void IGate::update_quantum_state(StateVector& state_vector) const {
i_gate(this->_target, state_vector);
}

void X::update_quantum_state(StateVector& state_vector) const {
void XGate::update_quantum_state(StateVector& state_vector) const {
x_gate(this->_target, state_vector);
}

void Y::update_quantum_state(StateVector& state_vector) const {
void YGate::update_quantum_state(StateVector& state_vector) const {
y_gate(this->_target, state_vector);
}

void Z::update_quantum_state(StateVector& state_vector) const {
void ZGate::update_quantum_state(StateVector& state_vector) const {
z_gate(this->_target, state_vector);
}

void H::update_quantum_state(StateVector& state_vector) const {
void HGate::update_quantum_state(StateVector& state_vector) const {
h_gate(this->_target, state_vector);
}

void S::update_quantum_state(StateVector& state_vector) const {
void SGate::update_quantum_state(StateVector& state_vector) const {
s_gate(this->_target, state_vector);
}

void Sdag::update_quantum_state(StateVector& state_vector) const {
void SdagGate::update_quantum_state(StateVector& state_vector) const {
sdag_gate(this->_target, state_vector);
}

void T::update_quantum_state(StateVector& state_vector) const {
void TGate::update_quantum_state(StateVector& state_vector) const {
t_gate(this->_target, state_vector);
}

void Tdag::update_quantum_state(StateVector& state_vector) const {
void TdagGate::update_quantum_state(StateVector& state_vector) const {
tdag_gate(this->_target, state_vector);
}

void sqrtX::update_quantum_state(StateVector& state_vector) const {
void sqrtXGate::update_quantum_state(StateVector& state_vector) const {
sqrtx_gate(this->_target, state_vector);
}

void sqrtXdag::update_quantum_state(StateVector& state_vector) const {
void sqrtXdagGate::update_quantum_state(StateVector& state_vector) const {
sqrtxdag_gate(this->_target, state_vector);
}

void sqrtY::update_quantum_state(StateVector& state_vector) const {
void sqrtYGate::update_quantum_state(StateVector& state_vector) const {
sqrty_gate(this->_target, state_vector);
}

void sqrtYdag::update_quantum_state(StateVector& state_vector) const {
void sqrtYdagGate::update_quantum_state(StateVector& state_vector) const {
sqrtydag_gate(this->_target, state_vector);
}

void P0::update_quantum_state(StateVector& state_vector) const {
void P0Gate::update_quantum_state(StateVector& state_vector) const {
p0_gate(this->_target, state_vector);
}

void P1::update_quantum_state(StateVector& state_vector) const {
void P1Gate::update_quantum_state(StateVector& state_vector) const {
p1_gate(this->_target, state_vector);
}

void RX::update_quantum_state(StateVector& state_vector) const {
void RXGate::update_quantum_state(StateVector& state_vector) const {
rx_gate(this->_target, this->_angle, state_vector);
}

void RY::update_quantum_state(StateVector& state_vector) const {
void RYGate::update_quantum_state(StateVector& state_vector) const {
ry_gate(this->_target, this->_angle, state_vector);
}

void RZ::update_quantum_state(StateVector& state_vector) const {
void RZGate::update_quantum_state(StateVector& state_vector) const {
rz_gate(this->_target, this->_angle, state_vector);
}
} // namespace internal
} // namespace qulacs
Loading

0 comments on commit 51877d8

Please sign in to comment.