1. 程式人生 > 實用技巧 >MATLAB 三階張量T-QR分解

MATLAB 三階張量T-QR分解

 這裡所謂的張量和黎曼那裡的張量是不一樣的,那個張量更多的用在物理上,這個張量就是矩陣的擴充套件。比如零階張量就是數,一階張量就是向量,二階張量就是矩陣,三階四階就是更高維的數的集合。這個領域現在在數學上還都是很新的東西,矩陣的秩我們都知道怎麼求,但是三維的張量或更高維的張量的秩現在在數學上也沒有結果。至於張量的奇異值分解也只是也只是用很早的如用HOSVD來處理,我感覺這並不完全合適,新的分解演算法就連老美也都沒研究出來,從二維到多維的確有很多基礎的理論都不適用了,像兩個張量相乘這樣基礎的演算法,現在雖然有,但我感覺也不是通用的,還要繼續改進。

  下面就是我看的一篇論文的張量相乘和分解方法,她的理論也可能不正確,不過這種新領域,大家都是在探索。

  論文在這裡:http://www.cs.tufts.edu/tech_reports/reports/2010-5/report.pdf,他主要介紹的是T-svd,T-svd分解後合成的只是原張量的一個近似結果,而T-QR就能得到一個準確的結果,所以我這裡用了T-QR。以Matlab角度來看T-SVD和T-QR的程式碼其實是很類似的。

main.m

 1 clear all;
 2 close all;
 3 clc;
 4 n1=3;
 5 n2=3;
 6 n3=3;
 7 
 8 A(:,:,1)=[10 23 34;43 55 63;72 85 96];
 9 A(:,:,2)=[24 17 35
;52 36 55;81 94 75]; 10 A(:,:,3)=[65 16 52;21 47 78;92 33 43]; 11 %A=imread('s.jpg'); 12 13 D=fft(A,[],3); 14 15 for i=1:n3 16 [q r]=qr(D(:,:,i)); 17 %[u s v]=svd(D(:,:,i)); 18 Q(:,:,i)=q; 19 R(:,:,i)=r; 20 %S(:,:,i)=s; 21 end 22 Q=ifft(Q,[],3); 23 R=ifft(R,[],3); 24 %S=ifft(S,[],3
); 25 26 27 B(:,:,1)=eye(n1,n2); 28 B(:,:,2)=zeros(n1,n2); 29 B(:,:,3)=zeros(n1,n2); 30 31 32 %c=mul(mul(U,S),transpos(V)); 33 c=mul(Q,R);

mul.m  張量相乘,論文第七頁3.3的那個公式

 1 function c=mul(a,b)
 2 
 3     [a_n1 a_n2 a_n3]=size(a);
 4     [b_n1 b_n2 b_n3]=size(b);
 5     c=zeros(a_n1,b_n2,a_n3);
 6     A=cell(a_n3,1);
 7     B=cell(b_n3,1);
 8     
 9     for i=1:a_n3
10         A{i}=a(:,:,i);
11         B{i}=b(:,:,i);
12     end
13 
14     index_up=zeros(1,a_n3);
15     index_down=zeros(1,a_n3);
16     for i=1:a_n3    
17         index_up(i)=a_n3-i+1;
18         index_down(i)=i;
19     end
20     
21     s=cell(a_n3,a_n3);
22     for i=1:a_n3
23         for j=1:a_n3
24             if i==j
25                 s{i,j}=A{1};
26             end       
27             if j>i
28                 s{i,j}=A{index_up(j-i)};
29             end       
30             if j<i
31                 s{i,j}=A{index_down(i-j+1)};
32             end      
33         end   
34     end
35     
36     re=cell(a_n3,1);
37     for i=1:a_n3
38         re{i}=zeros(a_n1,b_n2);
39     end
40 
41     for i=1:a_n3
42         for j=1:a_n3
43             for k=1:1
44                 re{i,k}=re{i,k}+s{i,j}*B{j,k};
45             end
46         end    
47     end
48 
49     for i=1:a_n3
50         c(:,:,i)=re{i};        
51     end
52     
53 end

transpos.m 張量求轉置,論文第十頁example3.15的公式

1 function a=transpos(b)    
2     [n1 n2 n3]=size(b);
3     a=zeros(n2,n1,n3);
4     for i=1:n3
5         a(:,:,i)=b(:,:,i)';
6     end
7 end