罗兰在MATLAB的艺术

把想法变成MATLAB

请注意

罗兰在MATLAB的艺术已经存档,不会被更新。

在R2016b MATLAB算法扩展

快乐,我介绍今天的嘉宾博客,我的同事,史蒂夫·埃丁。他一直积极参与图像处理能力在我们的工具和最近也贡献了大幅增加和改善MATLAB语言设计。

今年夏天早些时候,我在写一些彩色空间转换代码。在代码中,我有一个叫Px3矩阵RGB,含有P颜色,每行一个。我也有一个1 x3向量,v。我需要把每一列的RGB通过相应的元素v像这样:

RGB_c = [RGB (: 1) * v (1) RGB (:, 2) * v (2) RGB (:, 3) * v (3)];

但自从我使用一个内部开发人员构建MATLAB R2016(9月14日发布),我没有上面的代码类型。相反,我输入:

RGB_c = RGB。* v;

R2016a以上MATLAB版本中,这行代码产生一个错误:

> > RGB_c = RGB。* v错误使用。*矩阵维度必须一致。

然而,在新版本中,MATLAB隐式地扩大向量v同样大小的矩阵RGB然后进行elementwise乘法。我说“隐式”,因为MATLAB并不实际内存扩展向量的副本。

今天我想解释这一新的隐式的扩张行为MATLAB算术运算符(和一些函数)。我将讨论它是如何工作的,以及为什么我们做到了。接下来的讨论的一部分,我将使用一个示例,几乎所有人都在MathWorks使用在谈到这个话题:减去列意味着从一个矩阵。

内容

减去列的意思是:十年十年

假设您有一个矩阵一个

兰德(3、3)=
一个= 0.48976 0.70936 0.6797 0.44559 0.75469 0.6551 0.64631 0.27603 0.16261

假设您想修改每一列的一个通过减去列的意思。的的意思是功能方便给你的每个列的意思是:

马=意味着(A)
0.58003 - 0.49914 = 0.52722

但自不一样的尺寸一个而不是一个标量,你不能只是减去一个直接。相反,您不得不扩大相同的大小一个然后做减法。

在MATLAB的头十年,专家用户通常使用一个索引技术托尼的技巧扩张。

马ma_expanded = ((3,1),:)
ma_expanded = 0.52722 0.58003 0.49914 0.52722 0.58003 0.49914 0.52722 0.58003 0.49914
A - ma_expanded
ans = -0.037457 0.12934 0.18057 -0.081635 0.17466 0.15596 0.11909 -0.304 -0.33653

在第二个十年(粗略地说)的MATLAB,大多数人开始使用一个函数调用repmat矩阵(简称“复制”)的扩张。

马ma_expansion = repmat (3 - 1)
ma_expansion = 0.52722 0.58003 0.49914 0.52722 0.58003 0.49914 0.52722 0.58003 0.49914

使用函数repmat比使用托尼的技巧更可读,但它仍然在内存中创建扩展矩阵。很大问题,额外的内存分配计算和内存复制可以明显减缓,甚至导致内存不足的错误。

所以,在MATLAB的第三个十年,我们引入了一个新的函数bsxfun直接可以做减法操作而无需扩大向量在内存中。你叫它是这样的:

bsxfun (@minus、马)
ans = -0.037457 0.12934 0.18057 -0.081635 0.17466 0.15596 0.11909 -0.304 -0.33653

函数名的“bsx”指“二进制单例扩张,”,“二进制”在这种情况下是指执行两个输入。(不,它不是任何人的喜欢的函数名)。

这个函数和已经使用很多工作。一年前,大约有1800的使用bsxfun740年的文件。

但也有抱怨bsxfun

bsxfun痛苦

除了尴尬的名字,还有其他相关的可用性和性能问题bsxfun

  • 没有多少人知道这个函数。一点都不明显,每个人都应该去找与减法时寻求帮助。
  • 使用bsxfun需要编程的抽象级别(调用一个函数将另一个函数应用到一组输入)这似乎不匹配与应用程序(基本的算术)。
  • 使用bsxfun需要相对先进的MATLAB编程的知识。你必须理解函数处理,你必须了解MATLAB算术运算符(如功能对等+,-,,rdivide)。
  • 它是比较困难的MATLAB执行引擎工程师来生成代码,为基本的算术一样高效的代码。
  • 代码使用bsxfun不出现数学。(有些甚至称之为丑陋。)

所以,十四年之后克里夫硅藻土最初提议这么做,我们已经改变了MATLAB两个输入算术运算符、逻辑运算符、关系运算符和几个两个输入功能bsxfun风格的隐式扩张时自动输入兼容的大小

兼容的大小

表达式A - B只要工作一个B兼容的大小。两个数组有兼容的大小,如果每一个尺寸,尺寸大小的输入是相同的或其中之一是1。在最简单的情况下,两个数组大小是兼容的,如果他们是完全相同的或者是一个标量。

这里有一些插图的兼容的大小不同的情况下。

  • 两个输入是完全相同的大小。

  • 一个输入是一个标量。

  • 一个输入是一个矩阵,另一个是一个列向量具有相同的行数。

  • 一个输入是一个列向量,,另一个是一个行向量。注意,输入都是隐式地扩大在这种情况下,每个方向不同。

  • 一个输入是一个矩阵,另一个是一个三维数组相同的行和列的数量。注意,矩阵的大小一个在第三维度是隐式地认为是1,所以一个在第三维度可以扩展是一样的尺寸吗B

  • 一个输入是一个矩阵,另一个是一个三维数组。尺寸都是相同的或者其中一个是1。请注意,这是另一个例子输入都是隐式地扩大。

万博1manbetx支持运营商和功能

这是MATLAB操作符和函数的初始设置,现在有隐式扩张行为。

+ - * /。\。^ < < = > > = = = ~ = | & xor bitor bitand bitxor分钟马克斯mod rem函数量化

我预计,其他功能将被添加到这个集合。

反对

这种变化在MathWorks MATLAB算法并非没有争议。一些人担心,用户可以写代码,在某种程度上取决于这些运营商在某些情况下产生一个错误。但在检查自己的代码库,在预览的变化R2016a和R2016b预映,我们没有看到显著的兼容性问题在实践中出现。

其他人认为新的运营商行为不够是基于线性代数符号。然而,而不是想着MATLAB作为一个纯粹的线性代数符号,它是更准确的把MATLAB作为一个矩阵和数组运算符号。MATLAB有着悠久的历史,在这个意义上,成为被广泛接受的发明的符号,包括反斜杠、结肠癌、和各种形式的加下标。

最后,一些人担心会发生什么当用户试图添加两个向量而没有意识到,一个是,另一个是一行一列。在MATLAB的早期版本中,会产生一个错误。在R2016b,它产生一个矩阵。(我喜欢叫这个矩阵外和的两个向量)。但是我们相信这个问题会立即注意到,很容易纠正。事实上,我认为它更容易注意到这个问题,而不是当你错误地使用*操作符,而不是。*操作符。同时,相对较新的保护性限制数组大小在MATLAB (MATLAB - >工作区- >首选项- > MATLAB数组大小限制)防止MATLAB试图形成一个非常大的矩阵可能导致内存不足的情况。

隐式扩张在实践中

作为研究的一部分,我们之前做的决定做出这种改变,我们回顾了人们如何使用bsxfun。我完成后通过展示你的一些最常见的用途bsxfun看起来像当你重写他们在R2016b使用隐式扩张。

对真彩图像应用一个面具。

%面具:480 x640 % rgb: 480 x640x3
%老rgb2 = bsxfun (@times, rgb,面具);
%的新rgb2 = rgb。*面具;

规范化矩阵列(减去平均值和除以偏差)。

% X: 1000 x4μ=意味着(X);σ=性病(X);
%老Y = bsxfun (@rdivide bsxfun (@minus, X,μ)σ);
%的新Y = (X -μ)。/σ;

计算两两距离矩阵。

对两组向量,计算每一对向量之间的欧氏距离。

% X: 4 x2向量(4)% Y: 3 x2(3向量)X =重塑(X, [4 1 2]);Y =重塑(Y, [1 3 2]);
%老m = bsxfun (@minus, X, Y);D =函数(m (:,: 1), m (:,: 2));
%新的m = X - Y;D =函数(m (:,: 1), m (:,: 2));

计算外总和。

这个例子来自的实现托普利兹函数。看到我25 - 2008年2月——文章的邻居索引另一个应用程序。

cidx = (0: m - 1);ridx = p: 1:1;
%老ij = bsxfun (@plus、cidx ridx);
%的新ij = cidx + ridx;

找到彼此的整数倍数的。

这个例子是Redheffer矩阵的计算画廊函数。它说明了隐式扩张行为在一个函数而不是一个操作符。

我= 1:n;
%老= bsxfun (@rem,我,我”)= = 0;
%的新=快速眼动(我的)= = 0;

你自找的

我想完成所有MATLAB喊出用户要求这种行为。文件交换的贡献说了你们所有的人当他包括他的这个评论里实现提交:

%,我们需要完整的单例扩张无处不在。为什么它不是%,% % [1 - 2]+ [0 1]' = = (3 1 2;2)?% % bsxfun()是一个总攻击,和污染%每个人的代码。

尤,这个给你。

读者们,你们使用bsxfun过吗?你会利用新算法的行为吗?让我们知道在这里




发表与MATLAB®R2016b


评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。