动态创建一个 d 维张量
Create a d-dimensional tensor dynamically
我想使用 d
作为输入并且不使用 if
语句创建一个 d 维张量,如下所示:
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
有没有更高效的方法?
您可以使用 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 = 2
和 r = 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
.
填充
这可以满足您对任意 r
和 d
:
的要求
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
关于其工作原理的一些说明:
zeros
可以将向量作为输入,这样可以动态指定维数。
- Linear indexing 用于指定包含
1
的位置。
end
is being used within a function call. This is a not very well known feature.
等价地,你可以先以线性形式构建数组,然后再整形:
B = reshape(mod(1:r^d, (r^d-1)/(r-1))==1, repmat(r,1,d));
备注:
- 在线性索引中,包含
1
的条目之间的步长为 (r^d-1)/(r-1)
。
reshape
允许一个向量作为输入来指定维度,类似于 zeros
.
我想使用 d
作为输入并且不使用 if
语句创建一个 d 维张量,如下所示:
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
有没有更高效的方法?
您可以使用 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 = 2
和 r = 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
.
这可以满足您对任意 r
和 d
:
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
关于其工作原理的一些说明:
zeros
可以将向量作为输入,这样可以动态指定维数。- Linear indexing 用于指定包含
1
的位置。 end
is being used within a function call. This is a not very well known feature.
等价地,你可以先以线性形式构建数组,然后再整形:
B = reshape(mod(1:r^d, (r^d-1)/(r-1))==1, repmat(r,1,d));
备注:
- 在线性索引中,包含
1
的条目之间的步长为(r^d-1)/(r-1)
。 reshape
允许一个向量作为输入来指定维度,类似于zeros
.