动态创建d维张量

时间:2018-01-14 15:35:02

标签: matlab tensor

我想使用d作为输入创建一个d维张量,而不使用if语句,如下所示:

if d == 2
   B = zeros(r,r);
   for i = 1:r
       B(i,i) = 1;
   end                
elseif d == 3
   B = zeros(r,r,r);
   for i = 1:r
       B(i,i,i) = 1;
   end
end

有更有效的方法吗?

2 个答案:

答案 0 :(得分:4)

您可以使用accumarray

f = @(d,r)accumarray(repmat((1:r).',1 , d), 1);

> f(2,5)
=
1   0   0   0   0
0   1   0   0   0
0   0   1   0   0
0   0   0   1   0
0   0   0   0   1

这是accumarray的基本签名:

accumarray( subs , val )

使用accumarray我们可以创建一个n维数组,其中subs表示将在数组中填充的点的位置,val表示它们的值。

如果subs作为矩阵提供,其列数决定了结果数组的维数,每行代表每个点的位置。

例如,对于d = 2r = 5,我们要创建一个(5 x 5)数组,其中包含以下位置的1:[1 1],[2 2],[3 3],[4 4],[5 5]

使用repmat我们可以创建subs

subs = repmat ((1:5).' , 1, 2)

=
1 1
2 2
3 3
4 4
5 5

val设置为1,因此所有指定的位置都将由1填充。

.

答案 1 :(得分:3)

这适用于任意rd

B = zeros(repmat(r,1,d)); % initiallize as d×d×···×d array filled with 0
B(linspace(1,end,r)) = 1; % write 1 in the "diagonal". end can be replaced by r^d

关于它是如何工作的一些注释:

等效地,您可以先以线性形式构建数组,然后重新整形:

B = reshape(mod(1:r^d, (r^d-1)/(r-1))==1, repmat(r,1,d));

注意:

  • 线性索引中包含1的条目之间的步骤为(r^d-1)/(r-1)
  • reshape允许向量作为输入来指定维度,类似于zeros