Bri*_*erg 17 matlab arithmetic-expressions operator-overloading cell
我正在使用单元格管理我正在处理的一些东西中的数据.我希望能够做到这样的事情:
A = cellfun( @(X)( randn( 5,5 ) ), cell( 5,1 ), 'UniformOutput', 0 );
B = cellfun( @(X)( randn( 5,5 ) ), cell( 5,1 ), 'UniformOutput', 0 );
%#
%# Each of the following would fail if cell member dimensions
%# don't match up
%#
%# matrix sums for each cell entry
%# C = A + B;
C = cellfun( @(X,Y)( X + Y ), A, B, 'UniformOutput', 0 );
%#
%# direct/hadamard product
%# D = A .* B;
D = cellfun( @(X,Y)( X .* Y ), A, B, 'UniformOutput', 0 );
%#
%# matrix-matrix products (not across all entries)
%# E = A * B;
E = cellfun( @(X,Y)( X * Y ), A, B, 'UniformOutput', 0 );
Run Code Online (Sandbox Code Playgroud)
但是,我不希望使用极其冗长的语法来执行此操作.当我想要做的就是为单元格上的数学运算符提供定义时,为此创建一个新类似乎有些过分.
问题:课程是唯一可行的方法吗?
如果我编写一个类来执行此操作,它肯定会使编写代码变得更容易.我看到的最大的负面影响与优化有关,尽管还有其他一些让我烦恼的事情.
在幕后进行的任何优化(例如,当Jacket编译在GPU上运行的东西时)可能会更难确定要进行哪些优化.例如,假设我有两个包含许多适当维度矩阵的单元格(A,B).如果我编写代码来生成一个新单元格:
Z = c1*A + c2*B
Run Code Online (Sandbox Code Playgroud)
...使用标量{c1,c2},我可以用Jacket(或其他)很容易确定应该进行以下计算的方式编写它:
Z{kk} = c1*A{kk} + c2*B{kk}
Run Code Online (Sandbox Code Playgroud)
或者甚至比这更好的优化.除此以外.它可能会以更慢的速度和/或更低的内存效率结束,例如:
temp1 = cellfun( @(X)( c1*X ), A );
temp2 = cellfun( @(X)( c2*X ), B );
Z = cellfun( @plus, temp1, temp2 );
Run Code Online (Sandbox Code Playgroud)
假设MATLAB或Jacket无法对其进行优化,最终会占用太多内存.
gno*_*ice 25
实际上,可以在MATLAB中为内置数据类型创建新操作符或重载现有操作符.我在另一个关于修改整数类型的默认溢出行为的 SO问题的答案中描述了这个例子.
首先,您可能想要了解单元阵列当前存在哪些方法.你可以使用函数METHODS来完成这个,这是我在MATLAB R2010b中得到的:
>> methods cell
Methods for class cell:
aa2nt issorted regexptranslate strfind
accumarray newdepfun reshape strjust
cell2struct nt2aa rna2dna strmatch
ctranspose nwalign seq2regexp strtok
display permute setdiff transpose
dna2rna regexp setxor union
intersect regexpi sort unique
ismember regexprep strcat
Run Code Online (Sandbox Code Playgroud)
算术运算符方法将上述列表作为他们的显示功能等价物,如plus对于+运营商或times为.*运营商.仅为单元阵列定义transpose方法(.'运算符).您必须自己创建其余的,定义给定运算符对单元数组参数的行为方式.
您可以通过首先调用一个新文件夹@cell并将其放在MATLAB路径上的现有文件夹中来完成此操作.然后,您可以将新方法放在该@cell文件夹中.例如,一个非常简单的plus单元格数组方法实现(没有任何输入检查,错误检查等)将是这样的:
function C = plus(A,B)
C = cellfun(@plus,A,B,'UniformOutput',false); %# Apply plus cell-wise
end
Run Code Online (Sandbox Code Playgroud)
在上面的代码,你可能首先要检查操作数A和B大小相同的单元阵列.但是,您可以创建所需的任何独特功能,例如允许B将标量值添加到每个单元格中A.完全取决于您定义+运算符对单元数组的行为方式.
这将允许您以更紧凑的方式编写代码,如下例所示:
>> A = {[1 2 3] [4 5] 6}; %# One 3-element cell array
>> B = {5 [4 5] 2}; %# Another 3-element cell array
>> C = A+B; %# Use the new plus operator
>> C{:} %# Display the cell contents
ans =
6 7 8
ans =
8 10
ans =
8
Run Code Online (Sandbox Code Playgroud)
我无法真正谈论幕后优化以及这可能会对它们产生什么影响.我知道文档"提高性能的技术"特别提到了有关重载内置函数的问题:
在任何标准MATLAB数据类上重载MATLAB内置函数都会对性能产生负面影响.例如,如果重载
plus函数以不同方式处理任何整数类,则可能会妨碍MATLAB内置函数代码中的某些优化plus,从而可能减慢使用此重载的任何程序的速度.
但是,在您的情况下,您不会重载类的现有函数.你只是创造了那个不存在的新类,所以很难说这最终会对性能产生什么影响.