问题描述
我无权使用matlab,因此我正在尝试使用 octave 做一些事情.您将如何有效地实现以下公式中描述的张量积?
I dont have access to matlab, so I am trying some things with octave. How would you efficiently implement the tensor product described in the following formula?
我对任意阶张量a
和b
的处理方法如下
My approach for arbitrary order tensors a
and b
is the following
% Tensor product
function out = tp(a,b)
if isvector(a)
da = prod(size(a));
else
da = size(a);
endif
if isvector(b)
db = prod(size(b));
else
db = size(b);
endif
out = reshape(a(:)*(b(:)'),[da,db]);
endfunction
仅出现if
语句是为了捕捉a
或b
为向量的情况.我不知道这是否是一种有效的方法,因为我通常不编程,而我是八度的新手.你会怎么做?
The if
statements are only there in order to catch the case for a
or b
to be vectors. I dont know if this is an efficient approach since I dont usually program and I am new to octave. What would be your approach?
我将使用Frobenius范数(见下图)来查看显式计算是否存在差异.
I will use the Frobenius norm, see picture below, to see if there is a difference with the explicit computation.
下面是一些用于检查实现的显式计算.它工作正常,但我想问一问,对于任意阶数张量,是否有更好的方法可以做到这一点.谢谢!
Below are some explicit computations for checking the implementation. It works fine, but I wanted to ask, if there is a better way to do this for arbitrary order tensors. Thanks!
% Frobenius norm
function out = nf(a)
out = sqrt(a(:)'*a(:));
endfunction
% Tests for (m,n)
% (1,1)
disp("(1,1)")
a = rand(4,1);
b = rand(7,1);
c1 = tp(a,b);
c2 = zeros(4,7);
for i1=1:4 for i2=1:7
c2(i1,i2) = a(i1)*b(i2);
endfor endfor
size(c1)
size(c2)
nf(c1-c2)
%(1,2)
disp("(1,2)")
a = rand(4,1);
b = rand(7,3);
c1 = tp(a,b);
c2 = zeros(4,7,3);
for i1=1:4 for i2=1:7 for i3=1:3
c2(i1,i2,i3) = a(i1)*b(i2,i3);
endfor endfor endfor
size(c1)
size(c2)
nf(c1-c2)
%(2,1)
disp("(2,1)")
a = rand(4,2);
b = rand(1,3);
c1 = tp(a,b);
c2 = zeros(4,2,3);
for i1=1:4 for i2=1:2 for i3=1:3
c2(i1,i2,i3) = a(i1,i2)*b(i3);
endfor endfor endfor
size(c1)
size(c2)
nf(c1-c2)
%(3,2)
disp("(3,2)")
a = rand(4,2,5);
b = rand(7,3);
c1 = tp(a,b);
c2 = zeros(4,2,5,7,3);
for i1=1:4 for i2=1:2 for i3=1:5 for i4=1:7 for i5=1:3
c2(i1,i2,i3,i4,i5) = a(i1,i2,i3)*b(i4,i5);
endfor endfor endfor endfor endfor
size(c1)
size(c2)
nf(c1-c2)
编辑
我看了一下tensorlab软件包,请参阅下面的Metahominid回答,这太棒了.出于好奇,我想检查一下我的实现,Andras Deak的实现(请参见下面的答案)和tensorlab软件包之间的时间性能.
I took a look at the tensorlab package, see Metahominid's answer below, and it is fantastic. Just for curiosity, I wanted to check the time performance between my implementation, Andras Deak's implementation (see his answer below) and the tensorlab package.
% See Andras Deak answer
function c=tensorprod(a, b)
b_inj = reshape(b, [ones(1,ndims(a)), size(b)]);
c = a.*b_inj;
end
% Tests
a = rand(10,11,12);
b = rand(9,8,7);
tic; c1=outprod(a,b); t1=toc % tensorlab, see Metahominid's answer
tic; c2=tp(a,b); t2=toc % my approach
tic; c3=tensorprod(a,b); t3=toc % Andras Deak's approach
disp("Check size")
size(c1)
size(c2)
size(c3)
disp("Check Frobenius norm")
frob(c1) % from tensorlab
nf(c2)
disp("Check equality of elements")
nf(c1-c2)
nf(c1-c3)
disp("Compare time performance relative to tp(a,b)")
t1/t2
t3/t2
对于超过2-4的考虑尺寸(至少在我的计算机上),张量产品outprod的tensorlab实现的计算时间t1(与我的tp对应)与t2的比率为tp.肯定是这种情况,因为在我的实现中,我不检查输入中是否有任何错误,也不捕获任何未定义的情况.与Andras Deak的采矿方法相比,t3/t2的情况几乎相同.拜托,请不要误会我的意思,我不是在吹牛,而是对可能对此感兴趣的人做最后的评论.结论:如果您只是想使用小型张量,我的简单实现可能对您有用,如果您需要更多内容,则绝对应该看一下tensorlab(请参阅下面的Metahominid回答).感谢您的回答和参考!
The ratio of the computation time t1 of the tensorlab implementation of outprod (corresponding to my tp) and t2 for tp is for the considered dimensions around 2-4 (at least on my computer). This is surely the case, since in my implementation I dont check for any errors in the input and dont catch any undefined cases. Almost the same is observed for t3/t2 comparing Andras Deak's approach to mine. Please, don't get me wrong, I am not trying to brag, but to give some final remarks for people who might be interested in this. Conclusion: if you need something for small sized tensors just to-go, my simple implementation might be useful for you, if you need more stuff, you should definitely take a look at tensorlab (see Metahominid's answer below). Thanks for the answers and references!
推荐答案
有些东西叫做 Tensorlab ,据我所知,它可以与八音度一起使用..您只需下载链接即可下载它.
There is a something called Tensorlab, which for all I can tell is usable with Octave.. You simply have to download it by getting a link.
它兼有这两种功能,并且速度将大大提高.
It has both of these and will be vastly faster.
[H,Heff] = hankelize(linspace(0,1,1000),'order',3);
tic; disp(frob(H)); toc; % Using the dense tensor H
tic; disp(frob(Heff)); toc; % Using the efficient representation of H
3.2181e+03
Elapsed time is 0.026401 seconds.
3.2181e+03
Elapsed time is 0.000832 seconds.
outprod(T1,T2)
是您想要的另一个命令.
is the other command you want.
这篇关于如何在八度中实现任意阶张量的张量积?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!