Program Listing for File gate.hpp

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

#pragma once

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

#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(){};

    // jupiro変更: setのためにconstを消す
    std::vector<TargetQubitInfo>&
        target_qubit_list;
    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; };

    // ここから勝手にjupiroがつくったやつ
    void set_target_index_list(const std::vector<UINT>& target_index_list) {
        if (target_qubit_list.size() < target_index_list.size()) {
            target_qubit_list.resize(target_index_list.size());
        }
        for (UINT i = 0; i < target_qubit_list.size(); ++i) {
            target_qubit_list[i].set_index(target_index_list[i]);
        }
        if (target_qubit_list.size() < target_index_list.size()) {
            _target_qubit_list.resize(target_index_list.size());
        }
        for (UINT i = 0; i < target_qubit_list.size(); ++i) {
            _target_qubit_list[i].set_index(target_index_list[i]);
        }
    }

    void set_control_index_list(const std::vector<UINT>& control_index_list) {
        if (control_qubit_list.size() < control_index_list.size()) {
            control_qubit_list.resize(control_index_list.size());
        }
        for (UINT i = 0; i < control_qubit_list.size(); ++i) {
            control_qubit_list[i].set_index(control_index_list[i]);
        }
        if (control_qubit_list.size() < control_index_list.size()) {
            _control_qubit_list.resize(control_index_list.size());
        }
        for (UINT i = 0; i < control_qubit_list.size(); ++i) {
            _control_qubit_list[i].set_index(control_index_list[i]);
        }
    }

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