Quantum Computation 量子计算 API代码-立哥开发

#include <cstring>

#include "type.hpp"
#include "utility.hpp"
#include <fstream>

#ifndef _MSC_VER
extern "C"{
#include <csim/stat_ops.h>
}
#else
#include <csim/stat_ops.h>
#endif
#include "general_quantum_operator.hpp"
#include "pauli_operator.hpp"
#include "state.hpp"

GeneralQuantumOperator::GeneralQuantumOperator(UINT qubit_count){
    _qubit_count = qubit_count;
    _is_hermitian = true;
}

GeneralQuantumOperator::~GeneralQuantumOperator(){
    for(auto& term : this->_operator_list){
        delete term;
    }
}

void GeneralQuantumOperator::add_operator(const PauliOperator* mpt){
    PauliOperator* _mpt = mpt->copy();
    if (!check_Pauli_operator(this, _mpt)) {
        std::cerr << "Error: GeneralQuantumOperator::add_operator(const PauliOperator*): pauli_operator applies target qubit of which the index is larger than qubit_count" << std::endl;
        return;
    }
    if (this->_is_hermitian && std::abs(_mpt->get_coef().imag()) > 0){
        this->_is_hermitian = false;
    }
    this->_operator_list.push_back(_mpt);
}

void GeneralQuantumOperator::add_operator(CPPCTYPE coef, std::string pauli_string) {
    PauliOperator* _mpt = new PauliOperator(pauli_string, coef);
    if (!check_Pauli_operator(this, _mpt)) {
        std::cerr << "Error: GeneralQuantumOperator::add_operator(double,std::string): pauli_operator applies target qubit of which the index is larger than qubit_count" << std::endl;
        return;
    }
    if (this->_is_hermitian && std::abs(coef.imag()) > 0){
        this->_is_hermitian = false;
    }
    this->add_operator(_mpt);
    delete _mpt;
}

CPPCTYPE GeneralQuantumOperator::get_expectation_value(const QuantumStateBase* state) const {
    if (this->_qubit_count != state->qubit_count) {
        std::cerr << "Error: GeneralQuantumOperator::get_expectation_value(const QuantumStateBase*): invalid qubit count" << std::endl;
        return 0.;
    }
    CPPCTYPE sum = 0;
    for (auto pauli : this->_operator_list) {
        sum += pauli->get_expectation_value(state);
    }
    return sum;
}

CPPCTYPE GeneralQuantumOperator::get_transition_amplitude(const QuantumStateBase* state_bra, const QuantumStateBase* state_ket) const {
    if (this->_qubit_count != state_bra->qubit_count || this->_qubit_count != state_ket->qubit_count) {
        std::cerr << "Error: GeneralQuantumOperator::get_transition_amplitude(const QuantumStateBase*, const QuantumStateBase*): invalid qubit count" << std::endl;
        return 0.;
    }

    CPPCTYPE sum = 0;
    for (auto pauli : this->_operator_list) {
        sum += pauli->get_transition_amplitude(state_bra, state_ket);
    }
    return sum;
}

namespace quantum_operator{
    GeneralQuantumOperator* create_general_quantum_operator_from_openfermion_file(std::string file_path){
        UINT qubit_count = 0;
        std::vector<CPPCTYPE> coefs;
        std::vector<std::string> ops;

        
        double coef_real, coef_imag;
        std::string str_buf;
        std::vector<std::string> index_list;

        std::ifstream ifs;
        std::string line;
        ifs.open(file_path);

        while (getline(ifs, line)) {

            std::tuple<double, double, std::string> parsed_items = parse_openfermion_line(line);
            coef_real = std::get<0>(parsed_items);
            coef_imag = std::get<1>(parsed_items);
            str_buf = std::get<2>(parsed_items);

            CPPCTYPE coef(coef_real, coef_imag);
            coefs.push_back(coef);
            ops.push_back(str_buf);
            index_list = split(str_buf, "IXYZ ");

            for (UINT i = 0; i < index_list.size(); ++i){
                UINT n = std::stoi(index_list[i]) + 1;
                if (qubit_count < n)
                    qubit_count = n;
            }
        }
        if (!ifs.eof()){
            std::cerr << "ERROR: Invalid format" << std::endl;
            return (GeneralQuantumOperator*)NULL;
        }
        ifs.close();

        GeneralQuantumOperator* general_quantum_operator = new GeneralQuantumOperator(qubit_count);

        for (UINT i = 0; i < ops.size(); ++i){
            general_quantum_operator->add_operator(new PauliOperator(ops[i].c_str(), coefs[i]));
        }

        return general_quantum_operator;
    }

    GeneralQuantumOperator* create_general_quantum_operator_from_openfermion_text(std::string text){
        UINT qubit_count = 0;
        std::vector<CPPCTYPE> coefs;
        std::vector<std::string> ops;

        double coef_real, coef_imag;
        std::string str_buf;
        std::vector<std::string> index_list;

        std::vector<std::string> lines;
        lines = split(text, "\n");
        for (std::string line: lines){

            std::tuple<double, double, std::string> parsed_items = parse_openfermion_line(line);
            coef_real = std::get<0>(parsed_items);
            coef_imag = std::get<1>(parsed_items);
            str_buf = std::get<2>(parsed_items);

            CPPCTYPE coef(coef_real, coef_imag);
            coefs.push_back(coef);
            ops.push_back(str_buf);
            index_list = split(str_buf, "IXYZ ");

            for (UINT i = 0; i < index_list.size(); ++i){
                UINT n = std::stoi(index_list[i]) + 1;
                if (qubit_count < n)
                    qubit_count = n;
            }
        }
        GeneralQuantumOperator* general_quantum_operator = new GeneralQuantumOperator(qubit_count);

        for (UINT i = 0; i < ops.size(); ++i){
            general_quantum_operator->add_operator(new PauliOperator(ops[i].c_str(), coefs[i]));
        }

        return general_quantum_operator;
    }

    std::pair<GeneralQuantumOperator*, GeneralQuantumOperator*> create_split_general_quantum_operator(std::string file_path){
        UINT qubit_count = 0;
        std::vector<CPPCTYPE> coefs;
        std::vector<std::string> ops;

        std::ifstream ifs;
        ifs.open(file_path);

        if (!ifs){
            std::cerr << "ERROR: Cannot open file" << std::endl;
            return std::make_pair((GeneralQuantumOperator*)NULL, (GeneralQuantumOperator*)NULL);
        }

        // loading lines and check qubit_count
        double coef_real, coef_imag;
        std::string str_buf;
        std::vector<std::string> index_list;

        std::string line;
        while (getline(ifs, line)) {

            std::tuple<double, double, std::string> parsed_items = parse_openfermion_line(line);
            coef_real = std::get<0>(parsed_items);
            coef_imag = std::get<1>(parsed_items);
            str_buf = std::get<2>(parsed_items);
            if (str_buf == (std::string) NULL){
                continue;
            }
            CPPCTYPE coef(coef_real, coef_imag);
            coefs.push_back(coef);
            ops.push_back(str_buf);
            index_list = split(str_buf, "IXYZ ");

            for (UINT i = 0; i < index_list.size(); ++i){
                UINT n = std::stoi(index_list[i]) + 1;
                if (qubit_count < n)
                    qubit_count = n;
            }
        }
        if (!ifs.eof()){
            std::cerr << "ERROR: Invalid format" << std::endl;
            return std::make_pair((GeneralQuantumOperator*)NULL, (GeneralQuantumOperator*)NULL);
        }
        ifs.close();

        GeneralQuantumOperator* general_quantum_operator_diag =  new GeneralQuantumOperator(qubit_count);
        GeneralQuantumOperator* general_quantum_operator_non_diag =  new GeneralQuantumOperator(qubit_count);

        for (UINT i = 0; i < ops.size(); ++i){
            if (ops[i].find("X") != std::string::npos || ops[i].find("Y") != std::string::npos){
                general_quantum_operator_non_diag->add_operator(new PauliOperator(ops[i].c_str(), coefs[i]));
            }else{
                general_quantum_operator_diag->add_operator(new PauliOperator(ops[i].c_str(), coefs[i]));
            }
        }

        return std::make_pair(general_quantum_operator_diag, general_quantum_operator_non_diag);
    }
}

bool check_Pauli_operator(const GeneralQuantumOperator* quantum_operator, const PauliOperator* pauli_operator) {
    auto vec = pauli_operator->get_index_list();
    UINT val = 0;
    if (vec.size() > 0) {
        val = std::max(val, *std::max_element(vec.begin(), vec.end()));
    }
    return val < (quantum_operator->get_qubit_count());
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值