请选择 进入手机版 | 继续访问电脑版

网络科技

    今日:101| 主题:285206
收藏本版
互联网、科技极客的综合动态。

[其他] [MATLAB R2016b 抢鲜报道] : Implicit expansion(2) : 由来,举例和语法糖 ...

[复制链接]
死挣扎! 发表于 2016-10-4 11:53:36
161 2

[MATLAB R2016b 抢鲜报道] : Implicit expansion(2) : 由来,举例和语法糖 ...

[MATLAB R2016b 抢鲜报道] : Implicit expansion(2) : 由来,举例和语法糖 ...-1-网络科技-Matrix,平均值,历史,用户,元素

  Implicit Expansion的历史

  Implicit Expansion最初是Cleve Moler在2002年提出的设想,当二元矩阵运算的两个矩阵维度不同的时候,并且维度关系满足一定条件的情况下, MATLAB可以把参与运算的矩阵自动扩展到适合的维度来进行运算。考虑如下运算,我们想对矩阵中的每一个元素减去它的列平均值
  1. >> A = [1,2,3; 4,5,6;7,8,9]
  2. A =
  3.      1     2     3
  4.      4     5     6
  5.      7     8     9
  6. >> ma = mean(A,1)
  7. ma =
  8.      4     5     6
复制代码
在R2016b之前,如下的操作会报错
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.
复制代码
  在1997到2006b的MATLAB,我们可以通过 repmat 这个函数来完成上述操作
  1. >> A = A - repmat(ma,size(A,1),1)
  2. A =
  3.     -3    -3    -3
  4.      0     0     0
  5.      3     3     3
复制代码
其中repmat对ma矩阵在行的维度上进行了扩展,ma从 1 X3
  1. >> ma
  2. ma =
  3.      4     5     6
复制代码
变成 3 X 3
  1. >> repmat(ma,size(A,1),1)
  2. ans =
  3.      4     5     6
  4.      4     5     6
  5.      4     5     6
复制代码
repmat有如下缺点:
  
       
  • 用户需要知道和掌握repmat函数的使用   
  • A = A - repmat(ma,size(A,1),1) ,有很多函数调用,看上去是一段代码,而不是数学表达式   
  • 这段代码很冗长,要敲很多下键盘   
  • 最大的缺点:repmat构造出了新的临时矩阵,然后该临时矩阵才参与实际运算,在实际计算中,A通常是很大的矩阵,构造出临时的拷贝是对资源的浪费  
   针对这个问题,在2007a中,MATLAB引入了bsxfun来完成这个操作,bsx的代表 Binary Singleton Expansion 的缩写。可以叫做二元Singletion Dimension展开,这个Singleton Dimension我们可以理解成矩阵中维度为1的那个矩阵,该展开做同squeeze函数相反的操作,即在这个维度上对已有的数据进行扩充,展开。于是从2007a到2016a中,对矩阵做列均值的减法可以这样完成:
  1. >> A = bsxfun(@minus,A,ma)
  2. A =
  3.     -3    -3    -3
  4.      0     0     0
  5.      3     3     3
复制代码
bsxfun函数相对于repmat的优点是
  
       
  • 不需要构造临时矩阵,速度和内存性能有大的提升   
  • 要敲的键盘数有减少,表达式相对的简洁  
  但是它仍然存在缺点
  
       
  • bsxfun仍然是一个函数调用,代码看上去不是数学表达式   
  • 用户需要提供函数句柄,[email protected],所以这要求用户理解什么是句柄   
  • 这个用法还涉及算符,即减号的重载,用户的接受未必那么高  
   这里,重载是一个比较偏计算机的名词,简而言之,重载就是重新定义算符,实际计算过程中,视参与计算的元素来决定采用什么具体的算法。有兴趣的读者可以参考专栏里面的这篇文章: MATLAB算符重载和量纲分析 MATLAB算符重载和量纲分析 - MATLAB - 知乎专栏
  需要使用者懂得函数句柄和重载,这个足以让大多数工程背景的,或者年轻的提前学习编程的孩子望而却步。一个工程计算语言除了服务千百万工作岗位上的工程师,还要不停的改进,对更多的新用户提供更加的友好体验,于是,终于在2016b,MATLAB终于实现了Cleve Moler最初在2002年的一个提议,带给广大的工程师们这个新的语言改进
  1. >> A = A - ma
  2. A =
  3.     -3    -3    -3
  4.      0     0     0
  5.      3     3     3
复制代码
Implicit Expansion举例

  首先矩阵的Singleton Dimension就是 size(A,dim) = 1的那个dim。 下面是两个比较简单的例子,下例B的Col是singleton维度
  rowcolA55B51Result 55
  A和B之间的二元运算得到的维度是5 X 5
  下例其中B的row是singleton维度
  rowcolA43B13Result 43
  A和B之间的二元运算得到的维度是4 X 3
  Implicit Expansion也适用于两个操作矩阵都包含Singleton维度的例子,比如
  rowcolA 13B 41Result 43
  1. >> A = [1,2,3]
  2. A =
  3.      1     2     3
  4. >> B = [1;2;3;4]
  5. B =
  6.      1
  7.      2
  8.      3
  9.      4
  10. >> A - B
  11. ans =
  12.      0     1     2
  13.     -1     0     1
  14.     -2    -1     0
  15.     -3    -2    -1
复制代码
读者可以自己尝试一下更高维的情况。
  再举一个实际的例子,比如我们要给一张图像上施加一个mask.
  1. >> size(rgb)
  2. ans =
  3.    500   500     3
  4. >> size(mask)    % 500 x 500 of logical
  5. ans =
  6.    500   500
复制代码
这个mask中含有Singleton Dimension,在Implicit Expansion之前,我们需要
  1. >> img = bsxfun(@times,rgb,mask);
复制代码
有了Implicit Expansion之后,我们可以把它表达的更加易读易懂
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.0
复制代码
再比如我们要把矩阵的按列向量归一化,没有Implicit Expansion我们必须调用两次bsxfun
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.1
复制代码
有了Implicit Conversion之后,我们可以把它表达的更加易读易懂
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.2
复制代码
两种写法孰优孰劣立现。
  Implicit Expansion和语法糖

  Implicit Expansion利用重载让你减少敲键盘的次数,给我们书写代码带来便利,从功能上来说这其实就是一种语法糖(Syntactic Sugar)。即语言添加一种语法(Implicit Expansion),该语法对语言功能(bsxfun的功能)没有影响,但是更方便用户使用,增加可读性。
  比如
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.3
复制代码
在很多语言中可以简写成
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.4
复制代码
这就是一种语法糖。
  MATLAB语言中有很多这样的语法糖,比如获取一个对象的meta class的信息我们调用函数
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.5
复制代码
也可以直接使用?号
  1. >> A - ma
  2. Error using  -
  3. Matrix dimensions must agree.6
复制代码
  后者更加简练,可读性更高但是两者本质上没有区别 ,MATLAB分派调度器(Dispatcher)都会把两者的导向到实际的获取超类对象的函数上去。
  工程计算语言中,让语言更加简练贴近数学语言,并减少不必要的拷贝是每个计算语言的设计重要方面之一,所以不奇怪类似Implicit Expansion的操作几乎存在于大部分的主流计算语言中,在Python的NumPy中,这叫做Broadcasting,Octave和Julia也照搬了NumPy的规则,也叫做Boardcasting; Mathematica也会在二元运算时在一定条件的前提下做自动的扩充;在R中,类似的规则叫做Recylcing.
香莲 发表于 2016-10-5 02:13:40
报告!我就是路过来看看的。。。
回复 支持 反对

使用道具 举报

niamdaxue 发表于 2016-10-7 23:26:09
搬个小板凳 ,楼猪,go。
回复 支持 反对

使用道具 举报

我要投稿

回页顶回复上一篇下一篇回列表
手机版/c.CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 | 粤公网安备 44010402000842号 )

© 2001-2017 Comsenz Inc.

返回顶部 返回列表