行列の低ランク近似がSVDによって実現されるように,テンソルの低(タッカー)ランク近似がHOSVDで実現できます.
なお,Eckart Youngの定理より,SVDがフロベニウスノルムの意味で最良低ランク近似を実現しますが,テンソルの場合はそのような保証はないと思います.
テンソルにおいては,タッカーランクとCPランクという異なるランクの定義が存在します.(以下,研究室のセミナーで用いた資料.間違ってたらゴメン)
記号×_nはモードn積です.モード積の定義はこちらを参考にすると良いと思います.
juliaでHOSVDがさくっとできないかいろいろ試してましたが,TensorToolbox
を使うのが手っ取り早そうですね.例として3×3×3テンソルTをHOSVDによってタッカーランク(2,2,2)で近似するJuliaコードは以下.
using TensorToolbox function HOSVD(T, reqrank) X = hosvd(T, reqrank=reqrank) g = X.cten Us = X.fmat #X = ttm(g, [Us[1],Us[2],Us[3]],[1,2,3]) X = ttm(g, [Us...]) return X end T = rand(3,3,3) println("input tensor") display(T) X = HOSVD(T, [2,2,2]) println("\n\noutput tensor") display(X) println("\n\nerror") println(norm(X-T))
タッカーランクを[3,3,3]にすると,エラーが0になります.
X.cten
でコアテンソルが取り出せて,X.fmat
でスライドでいうところのU_1,U_2,…を取り出しています.
ttm
の使い方はgithubに丁寧に載ってます.ttm(X, A, 2)
がXとAのモード2積 X ×_2 A です.
ところで,この実装って Truncated HOSVD になっているのだろうか...