👏
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