read_jw

概要

この関数は正方行列のパウリ行列積の線型結合による表現を入力情報とし、係数部分と行列積部分に分解し出力するものである

引数一覧

argument name

type

role

jw_inf

list(elements:str)

正方行列のパウリ行列の線形結合による表現

戻り値

num_list(list):線型結合で用いる係数を格納したlist
各要素はfloat型をとる
ope_list(list):線型結合で用いるパウリ行列積を格納したlist
各要素はstr型をとる

Python code

def read_jw(jw_inf):
    """
    This function reads out the coefficients and Pauli matrix product information from the results of the Jordan–Wigner transformations performed using OpenFermion.

    Parameters:
        jw_inf: the results of the Jordan–Wigner and Bravyi–Kitaev transformations performed using OpenFermion

    Returns:
        (list, list): The coefficients information and Pauli matrix product information.
    """
    # Local Values
    read_counter = 0 # A switch to initiate reading
    minus_counter = 0 # A switch to treat reading result of coefficient as less than 0
    plus_counter = 0 # A switch to read imaginary part of coefficient
    num_list = [] # A list to store the results of the reading process for coefficients
    sub_num_list = "" # A temporary list to store the results of the reading process for coefficients
    ope_list = [] # A list to store the results of the reading process for Pauli matrix product
    sub_ope_list = "" # A temporary list to store the results of the reading process for Pauli matrix product
    e_sub = "" # A temporary list to store the part of the coefficient expressed using e (exponential notation)
    for i in range(len(jw_inf)):
        # Determine whether to interpret each item as a real part of coefficient, an imaginally part of coefficient, part of the coefficient expressed using e (exponential notation), a Pauli matrix product, or to ignore it.
        # 1: real part of coefficient, 2: Pauli matrix product, 3: imaginally part of coefficient, 4: ignore, 5: part of coefficient expressed using e (exponential notation)
        if jw_inf[i] == "(":
            read_counter = 1
        elif jw_inf[i] == "[":
            read_counter = 2
        elif jw_inf[i] == "+":
            read_counter = 3
            plus_counter += 1
        elif jw_inf[i] == "]":
            read_counter = 4
        elif jw_inf[i] == "e":
            read_counter = 5
        # Read the real part of coefficient as type str (ex: 0.2450065090650131)
        if read_counter == 1:
            one_counter = 0
            if jw_inf[i+1] == "+":
                one_counter += 1
            if jw_inf[i+1] == "e":
                one_counter += 1
            if jw_inf[i+1] == ".":
                one_counter += 2
            if jw_inf[i+1] == "-":
                one_counter += 3
            if one_counter == 0:
                sub_num_list += jw_inf[i+1]
            if one_counter == 2:
                true_add_num = int(sub_num_list)
                sub_num_list = ""
            if one_counter == 3:
                minus_counter = 1
        # Read the Pauli matrix product as type str (ex: 'X0X1Y2Y3')
        elif read_counter == 2:
            sub_switch = 0
            if jw_inf[i+1] == "]":
                sub_switch = 1
            if jw_inf[i+1] == " ":
                sub_switch = 1
            if sub_switch < 1:
                sub_ope_list += jw_inf[i+1]
        # Store the reading result for coefficient as type float
        elif read_counter == 3 and plus_counter % 2 == 1:
            len_snl = len(sub_num_list)
            add_ele = true_add_num + float(int(sub_num_list))/10**(len_snl)
            if e_sub != "":
                add_ele *= (10**int(e_sub))
            num_list.append(add_ele*(-1)**minus_counter)
            e_sub = ""
            sub_num_list = ""
            read_counter = 0
            minus_counter = 0
        # Store the reading result for Pauli matrix product
        elif read_counter == 4:
            ope_list.append(sub_ope_list)
            sub_ope_list = ""
            read_counter = 0
        # Read the part of the coefficient expressed using e (exponential notation) as type str (ex: -5)
        elif read_counter == 5:
            e_switch = 0
            if jw_inf[i+1] == "0":
                e_switch = 1
            if jw_inf[i+1] == "+":
                e_switch = 1
            if e_switch < 1:
                e_sub += jw_inf[i+1]
    return num_list, ope_list

実行例

[1]:
import numpy as np
import pitbe
[2]:
jw_hamiltonian = '(-0.2300259962688794+0j) [] + (-0.04711430043380896+0j) [X0 X1 Y2 Y3] + (0.04711430043380896+0j) [X0 Y1 Y2 X3] + (0.04711430043380896+0j) [Y0 X1 X2 Y3] + (-0.04711430043380896+0j) [Y0 Y1 X2 X3] + (0.153592312841566+0j) [Z0] + (0.16276753098254843+0j) [Z0 Z1] + (0.1135597567900135+0j) [Z0 Z2] + (0.16067405722382247+0j) [Z0 Z3] + (0.153592312841566+0j) [Z1] + (0.16067405722382247+0j) [Z1 Z2] + (0.1135597567900135+0j) [Z1 Z3] + (-0.17274355195698893+0j) [Z2] + (0.16885887724673027+0j) [Z2 Z3] + (-0.17274355195698887+0j) [Z3]'
# 今回は簡単のために'openfermion'の関数'jordan_wigner'の結果を代入する形をとっている

re_num, re_ope = pitbe.read_jw(str(jw_hamiltonian))
print(re_num)
print(re_ope)
[-0.2300259962688794, -0.04711430043380896, 0.04711430043380896, 0.04711430043380896, -0.04711430043380896, 0.153592312841566, 0.16276753098254845, 0.1135597567900135, 0.16067405722382247, 0.153592312841566, 0.16067405722382247, 0.1135597567900135, -0.17274355195698893, 0.1688588772467303, -0.17274355195698887]
['', 'X0X1Y2Y3', 'X0Y1Y2X3', 'Y0X1X2Y3', 'Y0Y1X2X3', 'Z0', 'Z0Z1', 'Z0Z2', 'Z0Z3', 'Z1', 'Z1Z2', 'Z1Z3', 'Z2', 'Z2Z3', 'Z3']

注意点

前述の通り入力するデータはライブラリ「openfermion」の関数「jordan_wigner」による出力結果を想定している
この手法の出力結果以外を代入した場合、正しく実行されないこともあることに注意されたし