Skip to content

Commit

Permalink
Merge pull request #165 from qulacs/constant
Browse files Browse the repository at this point in the history
定数をinternalにする
  • Loading branch information
gandalfr-KY authored Sep 3, 2024
2 parents a24aac3 + 5904fa2 commit 1600c52
Show file tree
Hide file tree
Showing 30 changed files with 244 additions and 248 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ int main() {
circuit.add_gate(scaluq::gate::X(0));
circuit.add_gate(scaluq::gate::CNot(0, 1));
circuit.add_gate(scaluq::gate::Y(1));
circuit.add_gate(scaluq::gate::RX(1, M_PI / 2));
circuit.add_gate(scaluq::gate::RX(1, std::numbers::pi / 2));
circuit.update_quantum_state(state);

scaluq::Operator observable(n_qubits);
Expand Down
56 changes: 27 additions & 29 deletions scaluq/constant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
#include "types.hpp"

namespace scaluq {
//! PI value
KOKKOS_INLINE_FUNCTION
double PI() { return 3.141592653589793; }

//! square root of 2
KOKKOS_INLINE_FUNCTION
double SQRT2() { return 1.4142135623730950; }
namespace internal {

#define DEF_MATH_CONSTANT(TRAIT, VALUE) \
template <class T> \
inline constexpr auto TRAIT##_v = std::enable_if_t<std::is_floating_point_v<T>, T>(VALUE); \
inline constexpr auto TRAIT = TRAIT##_v<double>

//! inverse square root of 2
KOKKOS_INLINE_FUNCTION
double INVERSE_SQRT2() { return 0.707106781186547; }
double INVERSE_SQRT2() { return Kokkos::numbers::sqrt2 / 2; }

//! cosine pi/8
KOKKOS_INLINE_FUNCTION
Expand All @@ -28,71 +28,69 @@ double SINPI8() { return 0.382683432365090; }

//! identity matrix
KOKKOS_INLINE_FUNCTION
matrix_2_2 I_GATE() { return {1, 0, 0, 1}; }
Matrix2x2 I_GATE() { return {1, 0, 0, 1}; }
//! Pauli matrix X
KOKKOS_INLINE_FUNCTION
matrix_2_2 X_GATE() { return {0, 1, 1, 0}; }
Matrix2x2 X_GATE() { return {0, 1, 1, 0}; }
//! Pauli matrix Y
KOKKOS_INLINE_FUNCTION
matrix_2_2 Y_GATE() { return {0, Complex(0, -1), Complex(0, 1), 0}; }
Matrix2x2 Y_GATE() { return {0, Complex(0, -1), Complex(0, 1), 0}; }
//! Pauli matrix Z
KOKKOS_INLINE_FUNCTION
matrix_2_2 Z_GATE() { return {1, 0, 0, -1}; }
Matrix2x2 Z_GATE() { return {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};
// std::array<Matrix2x2, 4> PAULI_MATRIX = {I_GATE, X_GATE,
// Y_GATE, Z_GATE};

//! S-gate
KOKKOS_INLINE_FUNCTION
matrix_2_2 S_GATE_MATRIX() { return {1, 0, 0, Complex(0, 1)}; }
Matrix2x2 S_GATE_MATRIX() { return {1, 0, 0, Complex(0, 1)}; }
//! Sdag-gate
KOKKOS_INLINE_FUNCTION
matrix_2_2 S_DAG_GATE_MATRIX() { return {1, 0, 0, Complex(0, -1)}; }
Matrix2x2 S_DAG_GATE_MATRIX() { return {1, 0, 0, Complex(0, -1)}; }
//! T-gate
KOKKOS_INLINE_FUNCTION
matrix_2_2 T_GATE_MATRIX() {
return {COSPI8() - Complex(0, SINPI8()), 0., 0., COSPI8() + Complex(0, SINPI8()) * SINPI8()};
}
Matrix2x2 T_GATE_MATRIX() { return {1, 0, 0, Complex(INVERSE_SQRT2(), INVERSE_SQRT2())}; }
//! Tdag-gate
KOKKOS_INLINE_FUNCTION
matrix_2_2 T_DAG_GATE_MATRIX() {
return {COSPI8() + Complex(0, SINPI8()), 0., 0., COSPI8() - Complex(0, SINPI8())};
}
Matrix2x2 T_DAG_GATE_MATRIX() { return {1, 0, 0, Complex(INVERSE_SQRT2(), -INVERSE_SQRT2())}; }
//! Hadamard gate
KOKKOS_INLINE_FUNCTION
matrix_2_2 HADAMARD_MATRIX() {
Matrix2x2 HADAMARD_MATRIX() {
return {INVERSE_SQRT2(), INVERSE_SQRT2(), INVERSE_SQRT2(), -INVERSE_SQRT2()};
}
//! square root of X gate
KOKKOS_INLINE_FUNCTION
matrix_2_2 SQRT_X_GATE_MATRIX() {
Matrix2x2 SQRT_X_GATE_MATRIX() {
return {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
KOKKOS_INLINE_FUNCTION
matrix_2_2 SQRT_Y_GATE_MATRIX() {
Matrix2x2 SQRT_Y_GATE_MATRIX() {
return {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
KOKKOS_INLINE_FUNCTION
matrix_2_2 SQRT_X_DAG_GATE_MATRIX() {
Matrix2x2 SQRT_X_DAG_GATE_MATRIX() {
return {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
KOKKOS_INLINE_FUNCTION
matrix_2_2 SQRT_Y_DAG_GATE_MATRIX() {
Matrix2x2 SQRT_Y_DAG_GATE_MATRIX() {
return {Complex(0.5, -0.5), Complex(0.5, -0.5), Complex(-0.5, 0.5), Complex(0.5, -0.5)};
}
//! Projection to 0
KOKKOS_INLINE_FUNCTION
matrix_2_2 PROJ_0_MATRIX() { return {1, 0, 0, 0}; }
Matrix2x2 PROJ_0_MATRIX() { return {1, 0, 0, 0}; }
//! Projection to 1
KOKKOS_INLINE_FUNCTION
matrix_2_2 PROJ_1_MATRIX() { return {0, 0, 0, 1}; }
Matrix2x2 PROJ_1_MATRIX() { return {0, 0, 0, 1}; }
//! complex values for exp(j * i*pi/4 )
KOKKOS_INLINE_FUNCTION
array_4 PHASE_90ROT() { return {1., Complex(0, 1), -1, Complex(0, -1)}; }
Kokkos::Array<Complex, 4> PHASE_90ROT() { return {1., Complex(0, 1), -1, Complex(0, -1)}; }
//! complex values for exp(-j * i*pi/4 )
KOKKOS_INLINE_FUNCTION
array_4 PHASE_M90ROT() { return {1., Complex(0, -1), -1, Complex(0, 1)}; }
Kokkos::Array<Complex, 4> PHASE_M90ROT() { return {1., Complex(0, -1), -1, Complex(0, 1)}; }
} // namespace internal
} // namespace scaluq
2 changes: 1 addition & 1 deletion scaluq/gate/gate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class GateBase : public std::enable_shared_from_this<GateBase> {
}

[[nodiscard]] virtual Gate get_inverse() const = 0;
[[nodiscard]] virtual ComplexMatrix get_matrix() const = 0;
[[nodiscard]] virtual internal::ComplexMatrix get_matrix() const = 0;

virtual void update_quantum_state(StateVector& state_vector) const = 0;
};
Expand Down
11 changes: 5 additions & 6 deletions scaluq/gate/gate_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,15 @@ inline Gate PauliRotation(const PauliOperator& pauli,
internal::vector_to_mask(controls), pauli, angle);
}
inline Gate DenseMatrix(const std::vector<std::uint64_t>& targets,
const ComplexMatrix& matrix,
const internal::ComplexMatrix& matrix,
const std::vector<std::uint64_t>& controls = {}) {
std::uint64_t nqubits = targets.size();
std::uint64_t dim = 1ULL << nqubits;
if (static_cast<std::uint64_t>(matrix.rows()) != dim ||
static_cast<std::uint64_t>(matrix.cols()) != dim) {
throw std::runtime_error(
"gate::DenseMatrix(const std::vector<std::uint64_t>&, const ComplexMatrix&): matrix "
"size "
"must "
"be 2^{n_qubits} x 2^{n_qubits}.");
"gate::DenseMatrix(const std::vector<std::uint64_t>&, const internal::ComplexMatrix&): "
"matrix size must be 2^{n_qubits} x 2^{n_qubits}.");
}
if (targets.size() == 0) return I();
if (targets.size() == 1) {
Expand Down Expand Up @@ -204,7 +202,8 @@ inline Gate DenseMatrix(const std::vector<std::uint64_t>& targets,
controls);
}
throw std::runtime_error(
"gate::DenseMatrix(const std::vector<std::uint64_t>&, const ComplexMatrix&): DenseMatrix "
"gate::DenseMatrix(const std::vector<std::uint64_t>&, const internal::ComplexMatrix&): "
"DenseMatrix "
"gate "
"more "
"than two qubits is not implemented yet.");
Expand Down
49 changes: 23 additions & 26 deletions scaluq/gate/gate_matrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,35 @@
namespace scaluq {
namespace internal {
class OneTargetMatrixGateImpl : public GateBase {
matrix_2_2 _matrix;
Matrix2x2 _matrix;

public:
OneTargetMatrixGateImpl(std::uint64_t target_mask,
std::uint64_t control_mask,
const std::array<std::array<Complex, 2>, 2>& matrix)
: GateBase(target_mask, control_mask) {
_matrix.val[0][0] = matrix[0][0];
_matrix.val[0][1] = matrix[0][1];
_matrix.val[1][0] = matrix[1][0];
_matrix.val[1][1] = matrix[1][1];
_matrix[0][0] = matrix[0][0];
_matrix[0][1] = matrix[0][1];
_matrix[1][0] = matrix[1][0];
_matrix[1][1] = matrix[1][1];
}

std::array<std::array<Complex, 2>, 2> matrix() const {
return {_matrix.val[0][0], _matrix.val[0][1], _matrix.val[1][0], _matrix.val[1][1]};
return {_matrix[0][0], _matrix[0][1], _matrix[1][0], _matrix[1][1]};
}

Gate get_inverse() const override {
return std::make_shared<const OneTargetMatrixGateImpl>(
_target_mask,
_control_mask,
std::array<std::array<Complex, 2>, 2>{Kokkos::conj(_matrix.val[0][0]),
Kokkos::conj(_matrix.val[1][0]),
Kokkos::conj(_matrix.val[0][1]),
Kokkos::conj(_matrix.val[1][1])});
std::array<std::array<Complex, 2>, 2>{Kokkos::conj(_matrix[0][0]),
Kokkos::conj(_matrix[1][0]),
Kokkos::conj(_matrix[0][1]),
Kokkos::conj(_matrix[1][1])});
}
ComplexMatrix get_matrix() const override {
ComplexMatrix mat(2, 2);
mat << this->_matrix.val[0][0], this->_matrix.val[0][1], this->_matrix.val[1][0],
this->_matrix.val[1][1];
internal::ComplexMatrix get_matrix() const override {
internal::ComplexMatrix mat(2, 2);
mat << this->_matrix[0][0], this->_matrix[0][1], this->_matrix[1][0], this->_matrix[1][1];
return mat;
}

Expand All @@ -51,7 +50,7 @@ class OneTargetMatrixGateImpl : public GateBase {
};

class TwoTargetMatrixGateImpl : public GateBase {
matrix_4_4 _matrix;
Matrix4x4 _matrix;

public:
TwoTargetMatrixGateImpl(std::uint64_t target_mask,
Expand All @@ -60,7 +59,7 @@ class TwoTargetMatrixGateImpl : public GateBase {
: GateBase(target_mask, control_mask) {
for (std::uint64_t i : std::views::iota(0, 4)) {
for (std::uint64_t j : std::views::iota(0, 4)) {
_matrix.val[i][j] = matrix[i][j];
_matrix[i][j] = matrix[i][j];
}
}
}
Expand All @@ -69,7 +68,7 @@ class TwoTargetMatrixGateImpl : public GateBase {
std::array<std::array<Complex, 4>, 4> matrix;
for (std::uint64_t i : std::views::iota(0, 4)) {
for (std::uint64_t j : std::views::iota(0, 4)) {
matrix[i][j] = _matrix.val[i][j];
matrix[i][j] = _matrix[i][j];
}
}
return matrix;
Expand All @@ -79,20 +78,18 @@ class TwoTargetMatrixGateImpl : public GateBase {
std::array<std::array<Complex, 4>, 4> matrix_dag;
for (std::uint64_t i : std::views::iota(0, 4)) {
for (std::uint64_t j : std::views::iota(0, 4)) {
matrix_dag[i][j] = Kokkos::conj(_matrix.val[j][i]);
matrix_dag[i][j] = Kokkos::conj(_matrix[j][i]);
}
}
return std::make_shared<const TwoTargetMatrixGateImpl>(
_target_mask, _control_mask, matrix_dag);
}
ComplexMatrix get_matrix() const override {
ComplexMatrix mat(4, 4);
mat << this->_matrix.val[0][0], this->_matrix.val[0][1], this->_matrix.val[0][2],
this->_matrix.val[0][3], this->_matrix.val[1][0], this->_matrix.val[1][1],
this->_matrix.val[1][2], this->_matrix.val[1][3], this->_matrix.val[2][0],
this->_matrix.val[2][1], this->_matrix.val[2][2], this->_matrix.val[2][3],
this->_matrix.val[3][0], this->_matrix.val[3][1], this->_matrix.val[3][2],
this->_matrix.val[3][3];
internal::ComplexMatrix get_matrix() const override {
internal::ComplexMatrix mat(4, 4);
mat << this->_matrix[0][0], this->_matrix[0][1], this->_matrix[0][2], this->_matrix[0][3],
this->_matrix[1][0], this->_matrix[1][1], this->_matrix[1][2], this->_matrix[1][3],
this->_matrix[2][0], this->_matrix[2][1], this->_matrix[2][2], this->_matrix[2][3],
this->_matrix[3][0], this->_matrix[3][1], this->_matrix[3][2], this->_matrix[3][3];
return mat;
}

Expand Down
8 changes: 4 additions & 4 deletions scaluq/gate/gate_pauli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PauliGateImpl : public GateBase {
std::vector<std::uint64_t> pauli_id_list() const { return _pauli.pauli_id_list(); }

Gate get_inverse() const override { return shared_from_this(); }
ComplexMatrix get_matrix() const override { return this->_pauli.get_matrix(); }
internal::ComplexMatrix get_matrix() const override { return this->_pauli.get_matrix(); }

void update_quantum_state(StateVector& state_vector) const override {
pauli_gate(_control_mask, _pauli, state_vector);
Expand All @@ -44,12 +44,12 @@ class PauliRotationGateImpl : public GateBase {
return std::make_shared<const PauliRotationGateImpl>(_control_mask, _pauli, -_angle);
}

ComplexMatrix get_matrix() const override {
ComplexMatrix mat = this->_pauli.get_matrix_ignoring_coef();
internal::ComplexMatrix get_matrix() const override {
internal::ComplexMatrix mat = this->_pauli.get_matrix_ignoring_coef();
Complex true_angle = _angle * _pauli.coef();
StdComplex imag_unit(0, 1);
mat = (StdComplex)Kokkos::cos(-true_angle / 2) *
ComplexMatrix::Identity(mat.rows(), mat.cols()) +
internal::ComplexMatrix::Identity(mat.rows(), mat.cols()) +
imag_unit * (StdComplex)Kokkos::sin(-true_angle / 2) * mat;
return mat;
}
Expand Down
2 changes: 1 addition & 1 deletion scaluq/gate/gate_probablistic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class ProbablisticGateImpl : public GateBase {
});
return std::make_shared<const ProbablisticGateImpl>(_distribution, inv_gate_list);
}
ComplexMatrix get_matrix() const override {
internal::ComplexMatrix get_matrix() const override {
throw std::runtime_error(
"ProbablisticGateImpl::get_matrix(): This function must not be used in "
"ProbablisticGateImpl.");
Expand Down
Loading

0 comments on commit 1600c52

Please sign in to comment.