👏

Quantics Tensor Trainを用いた不連続面のある関数の圧縮

に公開

前回の記事で、不連続面のある関数の圧縮を例に、QuanticsTensorCrossInterpolation(QTCI)のデモを行った。QTCIは、圧縮対象の全ての要素を保持する必要がない代わりに、ヒューリスティックなエラーが入る。

なので、ここでは、圧縮対象の全ての要素を事前に保持しておいて、SVDによって、どれくらい低ランク構造があるのかを確認する(というかまずこれは先にやるべきだったかもしれないが)

using Plots
using LinearAlgebra
using LaTeXStrings
using ITensors
using ITensorMPS
ITensors.disable_warn_order()
R = 10
N = 2^R
function f(x)
    if x < -1
        return x^2
    elseif x < 0
        return -1.0
    elseif x < 2
        return sin(x)
    elseif x < 3
        return 1.0
    else
        return x
    end
end

X = range(-3, 5, length = N)
fdata = [f(x) for x in X]
fdata_plot = [f(x) for x in X]

plot(X, fdata, label = L"f(x)", xlabel = L"x", ylabel = L"f(x, \gamma)", title = L"f(x)", legend = :topleft, size = (800, 400))

QTTによる圧縮

ここでは、足をスケールごとに並べたものとランダムに配置したもの二つの方法で、MPSを構築する。

sitesx = [Index(2, "Qubit,x=$i") for i in 1:R]
Tensor = ITensor(fdata, vcat(reverse(sitesx)))
#足の並べ方をランダムに配置してMPSを構成
using Random
cutoff = 1e-20
sitesx_ = [Index(2, "Qubit,x=$i") for i in 1:R]
shuffle!(sitesx_)
@show sitesx_
Tensor_ = ITensor(fdata, vcat(reverse(sitesx_)))
;

M = MPS(Tensor_, vcat(sitesx_))
M1 = MPS(Tensor_, vcat(sitesx_); cutoff=cutoff)

#スケール分離してMPSを構成
sites = Index{Int64}[]
for i in 1:R
    push!(sites, sitesx[i])
end

M2 = MPS(Tensor, sites; cutoff=cutoff)

#ボンド次元をプロットする

BondDim = plot(#yscale = :log,
                title = L"\mathrm{Bond~Dimension},~~ (R = 12, ~~\mathrm{cutoff}={cutoff})",
                xlabel = L"\mathrm{auxiliary~index}",
                ylabel = L"\mathrm{Bond~Dimension}")

plot!(BondDim, linkdims(M),
        linestyle = :dash,
        label = L"\mathrm{No~Compression}")

plot!(BondDim, linkdims(M1),
        markershape = :circle,
        label = L"\mathrm{QTT}")

plot!(BondDim, linkdims(M2),
        markershape = :circle,
        label = L"\mathrm{QTT~&~Scale~Separation}")
savefig("BondDim_spectol.pdf")
@show BondDim

ボンド次元は5である。

再構築

M2_reconst = Array(reduce(*, M2), vcat(reverse(sitesx)));
M2_reconst = reshape(M2_reconst, 2^R);
p = plot()
plot!(p, X, fdata, label = L"f(x, \gamma)", xlabel = L"x", ylabel = L"f(x, \gamma)", title = L"f(x, \gamma) = e^{-x + \gamma}", legend = :topleft, size = (800, 400))
plot!(p, X, M2_reconst , label = L"f(x)", xlabel = L"x", ylabel = L"f(x)", title = L"f(x)", legend = :topleft, size = (800, 400))

エラー

M2_reconst #
abs.( M2_reconst .- fdata ) |> maximum |> println

誤差は、1.0835776720341528e-13とかなり小さい。
今回はQTCIと比べて、SVDは前要素を読み出した上で圧縮をするので、誤差は小さいことを確かめられた。ただし、この誤差は、SVD/TCIの設定したtoleranceによって変わることに注意が必要だ。

Discussion