Program Listing for File gate.hpp

↰ Return to documentation for file (/home/docs/checkouts/readthedocs.org/user_builds/qulacs-rtd-ja/checkouts/latest/src/cppsim/gate.hpp)

#pragma once

#include <iostream>
#include <ostream>
#include <string>
#include <vector>

#include "exception.hpp"
#include "qubit_info.hpp"
#include "type.hpp"
#include "utility.hpp"

#define FLAG_PAULI 0x01
#define FLAG_CLIFFORD 0x02
#define FLAG_GAUSSIAN 0x04
#define FLAG_PARAMETRIC 0x08

class QuantumGateMatrix;
class QuantumStateBase;

class DllExport QuantumGateBase {
protected:
    std::vector<TargetQubitInfo> _target_qubit_list;
    std::vector<ControlQubitInfo> _control_qubit_list;
    UINT _gate_property =
        0;
    std::string _name = "Generic gate";

    // prohibit constructor, destructor, copy constructor, and insertion
    QuantumGateBase()
        : target_qubit_list(_target_qubit_list),
          control_qubit_list(_control_qubit_list){};
    QuantumGateBase(const QuantumGateBase& obj)
        : target_qubit_list(_target_qubit_list),
          control_qubit_list(_control_qubit_list) {
        _gate_property = obj._gate_property;
        _name = obj._name;
        _target_qubit_list = obj.target_qubit_list;
        _control_qubit_list = obj.control_qubit_list;
    };
    QuantumGateBase& operator=(const QuantumGateBase& rhs) = delete;

public:
    virtual ~QuantumGateBase(){};

    const std::vector<TargetQubitInfo>&
        target_qubit_list;
    const std::vector<ControlQubitInfo>&
        control_qubit_list;
    std::vector<UINT> get_target_index_list() const {
        std::vector<UINT> res(target_qubit_list.size());
        for (UINT i = 0; i < target_qubit_list.size(); ++i)
            res[i] = target_qubit_list[i].index();
        return res;
    }
    std::vector<UINT> get_control_index_list() const {
        std::vector<UINT> res(control_qubit_list.size());
        for (UINT i = 0; i < control_qubit_list.size(); ++i)
            res[i] = control_qubit_list[i].index();
        return res;
    }

    std::vector<UINT> get_control_value_list() const {
        std::vector<UINT> res(control_qubit_list.size());
        for (UINT i = 0; i < control_qubit_list.size(); ++i)
            res[i] = control_qubit_list[i].control_value();
        return res;
    }

    std::vector<std::pair<UINT, UINT>> get_control_index_value_list() const {
        std::vector<std::pair<UINT, UINT>> res(control_qubit_list.size());
        for (UINT i = 0; i < control_qubit_list.size(); ++i)
            res[i] = std::make_pair(control_qubit_list[i].index(),
                control_qubit_list[i].control_value());
        return res;
    }

    virtual void update_quantum_state(QuantumStateBase* state) = 0;
    virtual QuantumGateBase* copy() const = 0;
    virtual void set_matrix(ComplexMatrix& matrix) const = 0;

    bool is_commute(const QuantumGateBase* gate) const;
    bool is_Pauli() const;
    bool is_Clifford() const;
    bool is_Gaussian() const;
    bool is_parametric() const;
    bool is_diagonal() const;

    UINT get_property_value() const;

    bool commute_Pauli_at(UINT qubit_index, UINT pauli_type) const;

    virtual std::string get_name() const;

    virtual std::string to_string() const;

    friend DllExport std::ostream& operator<<(
        std::ostream& os, const QuantumGateBase&);
    friend DllExport std::ostream& operator<<(
        std::ostream& os, const QuantumGateBase* gate);

    [[noreturn]] virtual boost::property_tree::ptree to_ptree() const;

    virtual bool is_noise() { return false; }
    virtual void set_seed(int) { return; };

    [[nodiscard]] virtual QuantumGateBase*
    create_gate_whose_qubit_indices_are_replaced(
        const std::vector<UINT>& target_index_list,
        const std::vector<UINT>& control_index_list) const {
        if (_target_qubit_list.size() != target_index_list.size()) {
            throw InvalidQubitCountException(
                "Error: "
                "QuantumGateBase::create_gate_whose_qubit_indices_is_"
                "replaced\n qubit count of target_index_list does not match.");
        }
        if (_control_qubit_list.size() != control_index_list.size()) {
            throw InvalidQubitCountException(
                "Error: "
                "QuantumGateBase::create_gate_whose_qubit_indices_is_"
                "replaced\n qubit count of control_index_list does not match.");
        }
        QuantumGateBase* ret = copy();
        for (UINT i = 0; i < target_index_list.size(); i++) {
            ret->_target_qubit_list[i].set_index(target_index_list[i]);
        }
        for (UINT i = 0; i < control_index_list.size(); i++) {
            ret->_control_qubit_list[i].set_index(control_index_list[i]);
        }
        return ret;
    }

    [[noreturn]] virtual QuantumGateBase* get_inverse(void) const;
};