matlab 3 维数组_MATLAB 中 ipermute 广义反转置函数的实现分析

d2eca0313c61a51bb62b7bafdbfc5221.png

知道 permute 函数的请直接跳到第二节

转置函数介绍

MATLAB 中,转置符号大家应该都非常熟悉,不加点是共轭转置,加点是直接转置。

>> a = rand(2,4) + rand(2,4)*1i

a =

   0.9575 + 0.4218i   0.1576 + 0.7922i   0.9572 + 0.6557i   0.8003 + 0.8491i
   0.9649 + 0.9157i   0.9706 + 0.9595i   0.4854 + 0.0357i   0.1419 + 0.9340i

>> a'

ans =

   0.9575 - 0.4218i   0.9649 - 0.9157i
   0.1576 - 0.7922i   0.9706 - 0.9595i
   0.9572 - 0.6557i   0.4854 - 0.0357i
   0.8003 - 0.8491i   0.1419 - 0.9340i

>> a.'

ans =

   0.9575 + 0.4218i   0.9649 + 0.9157i
   0.1576 + 0.7922i   0.9706 + 0.9595i
   0.9572 + 0.6557i   0.4854 + 0.0357i
   0.8003 + 0.8491i   0.1419 + 0.9340i

但是对于高维数组,如果想更改维度,就需要广义转置函数 permute。

首先创建一个四维数组:

>> a = rand(3,4,1,2)

a(:,:,1,1) =

    0.4018    0.1233    0.4173    0.9448
    0.0760    0.1839    0.0497    0.4909
    0.2399    0.2400    0.9027    0.4893


a(:,:,1,2) =

    0.3377    0.1112    0.2417    0.1320
    0.9001    0.7803    0.4039    0.9421
    0.3692    0.3897    0.0965    0.9561

然后利用 permute 函数可以切换它的维度,函数的第一个参数是待切换维度的数组,第二个参数是一个向量,其长度与数组维度相同,向量每个位置的数值代表这个位置应该放置原来数组的哪个维度。比如下面的 4 1 2 3,就代表将原来数组的第 4 维转到第 1 维上,第 1 维转到 第 2 维上,第 2 维转到第 3 维上,第 3 维转到第 4 维上。观察新矩阵每一片的列,以第一个数 0.4018 为例,它的下一个数是 0.3377,正是原数组在第 4 维上移动一个到达的数,这就是原来的第 4 维到了第 1 维上的体现。因为第 3 维转到了第 4 维,而且第 3 维的长度为 1,所以新数组在最高的维度,第 4 维,长度为 1,实际上是一个 3 维数组。所以原数组显示的时候每一片的提示 a(:,:,1,2) 而新数组每一片的提示是 a(:,:,1)。

>> permute(a,[4 1 2 3])

ans(:,:,1) =

    0.4018    0.0760    0.2399
    0.3377    0.9001    0.3692


ans(:,:,2) =

    0.1233    0.1839    0.2400
    0.1112    0.7803    0.3897


ans(:,:,3) =

    0.4173    0.0497    0.9027
    0.2417    0.4039    0.0965


ans(:,:,4) =

    0.9448    0.4909    0.4893
    0.1320    0.9421    0.9561

利用 size 函数也可以看出 permute 对于维度的操作:

>> size(a)

ans =

     3     4     1     2

>> size(permute(a,[4 1 2 3]))

ans =

     2     3     4

ipermute 函数分析

首先说明 ipermute 函数的作用

>> permute(a,[4 1 2 3]);
>> ipermute(ans,[4 1 2 3])

ans(:,:,1,1) =

    0.4018    0.1233    0.4173    0.9448
    0.0760    0.1839    0.0497    0.4909
    0.2399    0.2400    0.9027    0.4893


ans(:,:,1,2) =

    0.3377    0.1112    0.2417    0.1320
    0.9001    0.7803    0.4039    0.9421
    0.3692    0.3897    0.0965    0.9561

可以看到,在对 a 进行广义转置后,如果想复原 a,可以直接对结果调用 ipermute 函数,第二个参数与之前输入给 permute 函数的完全一样,然后输出就是原来的 a 了。但是,这个函数是如何实现的?

MATLAB 中一些函数可以使用 edit 命令直接查看它们的源码(如果全是注释的说明是二进制形式的底层函数,如果是 p 函数会提醒无法查看),比如这个 ipermute 函数。

edit ipermute.m

之后可以看到除了注释和定义外,这个函数正文就两行

inverseorder(order) = 1:numel(order);   % Inverse permutation order
a = permute(b,inverseorder);

第二行还就是个 permute,这就非常有意思了,怎么一行就把寻找还原需要的顺序这事给干了,我们要看看第一行到底干了啥。

于是我们单独执行这个第一行,其中 order 还是使用刚才用过的 [4 1 2 3]

>> order = [4 1 2 3]

order =

     4     1     2     3

>> 1:numel(order)

ans =

     1     2     3     4

>> inverseorder(order) = 1:numel(order)

inverseorder =

     2     3     4     1

也就是说,首先创建一个自然数序列,然后把这个自然数序列按照之前指定的位置给放过去就行了?这是为什么?

让我们先分析一个。以原数组的第 4 个维度为例,一开始,第 4 个维度被挪到了第 1 个维度上,那么之后,自然是应该把第 1 个维度挪到第 4 个维度上,如果需要再次用 permute 来完成这种转换,那么需要的就是将第二个输入参数的第 4 个设置成 1。

对于 order 来说,一开始,我们是把 order 看成名单,permute 的操作是“根据名单把对应的维度找来”,比如第 1 项,就是

“根据第 1 项的 4,把第 4 个维度找来,放到第 1 项这里,也就是新的第 1 维变成了原来的第 4 维。”

但是在构造 inverseorder 这个向量时,这个 order 就变成了路标,具体的操作可以理解为“根据这个路标送去指定的位置”,比如第 1 项,就是

“根据第 1 项的 4,把这个第 1 项,也就是当前状态下的第 1 维,送回到第 4 个维度去,即放到 inverseorder 的第 4 项”;

这样,再次调用 permute 时,函数遇到了第 4 项的 1,就会把新数组的第 1 维找来,放在第 4 维的位置,还原了原来数组的维度排列。

或者可以理解成 1:numel(order) 记录了原来每个维度的“名字”或“位置”,第 1 维就叫“1”,或者说就在第“1”个,之后将这个队伍按照 order 来排列,那么新排列的队伍,它们的名字并没有改变,于是将这个新队伍作为排列的依据,自然会找回自己“名字”对应的位置。

明白了这点后,permute 与 ipermute 的作用就明白了,输入数组后,一个是根据数组“找回”,一个是根据数组“送去”,一开始根据一个 order 来“找来”,那么之后按照原来的名单再“送去”,自然是会消除“找来”的影响的。演示一下 ipermute 的“送去”

>> size(a)

ans =

     3     4     1     2

>> size(ipermute(a,[4 1 2 3]))

ans =

     4     1     2     3

可以看到,第 3 个维度被送到了第 4 个维度上,第 2 个维度被送到了第 1 个维度上,第 3 个维度被送到了第 2 个维度上,第 4 个维度被送到了第 3 个维度上。

permute 与 ipermute 就是这样一对强大的广义转置(维度转换)函数。

关于封面:封面是莎缇拉,因为她有“回溯”的能力,也就是“复原一切”的能力,这个和 ipermute 的原理很相似,虽然干过回档这活的人一大把,但是最近正在看 re0 所以还是放莎缇拉吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值