🚀

MPSの定数倍

2023/09/17に公開

あるMPSの定数倍をしたいとする。

C_{\mathrm{MPS}} = A_{\mathrm{MPS}} \cdot \mathrm{const}

Aの一つのコアに定数がかかる。この時、ボンド次元(=ランク)は変わらない

注意点

  • 定数aをあるmpsにかける場合、ブロードキャスト(mps .* a)と通常の掛け算(mps * a)で結果が異なることに注意する。

  • ブロードキャストでは、全てのコアに対してaがかかる。縮約の結果は、a^{bit}に比例する。

  • 後者では、あるコアにaがかかった値が出力される。縮約の結果h、MPSの定数倍の結果と一致する。

具体例

実際に、以下のコードで確かめてみる。

using ITensors
ITensors.disable_warn_order()
#Create a MPS filled with one
function onemps(::Type{T}, sites) where {T<:Number}
    M = MPS(T, sites; linkdims=1)
    l = linkinds(M)
    for n in eachindex(M)
        if n == 1
            M[n] = ITensor(T, sites[n], l[n])
        elseif n == length(M)
            M[n] = ITensor(T, l[n - 1], sites[n])
        else
            M[n] = ITensor(T, l[n - 1], sites[n], l[n])
        end
        M[n] .= one(T)
    end
    #M[1] .= zero(T)
    return M
end

テスト

nbit = 3 
sites = siteinds("Qubit", nbit) 
M =  onemps(Float64, sites)
@show vec(Array(reduce(*, M), sites))
@assert vec(Array(reduce(*, M), sites)) ≈ ones(2^nbit)

ブロードキャスト

nbit = 3
sites = siteinds("Qubit", nbit)
a = 2.0
M =  a .* onemps(Float64, sites)
@show M[1] #
@show M[2] # 
@show M[3]
@show vec(Array(reduce(*, M), sites))
8-element Vector{Float64}:
 8.0
 8.0
 8.0
 8.0
 8.0
 8.0
 8.0
 8.0

通常の掛け算

nbit = 3  
sites = siteinds("Qubit", nbit)
M =  2.0 * onemps(Float64, sites)
@show M[1]
@show M[2]
@show M[3]
@show vec(Array(reduce(*, M), sites))
8-element Vector{Float64}:
 2.0
 2.0
 2.0
 2.0
 2.0
 2.0
 2.0
 2.0

まとめ

  • ブロードキャスト(onemps .* a)と単なる掛け算(onemps * a)でmpsの縮約の結果が異なる。

  • 全ての要素が1のMPSの例では、前者では、a^{bit}が出力値となるが、後者では、単に定数aがかかった値(望ましい結果)となる。

Discussion