我正在使用单元格来管理我正在处理的一些内容中的数据。我希望能够执行以下操作:
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 );
但是,我不希望使用极其冗长的语法来执行此操作。当我只想为单元格上的数学运算符提供定义时,为此创建一个新类似乎有点过分了。
问题是:上课是解决这个问题的唯一方法吗?
如果我编写一个类来执行此操作,那么编写代码肯定会更容易。我看到的最大的负面因素与优化有关,尽管还有其他一些事情让我烦恼。
任何在幕后进行的优化(例如,当 Jacket 编译某些东西以在 GPU 上运行时)可能会更难确定进行哪些优化。作为一个例子,假设我有两个单元格(A,B),其中包含许多适当维度的矩阵。如果我编写代码来生成一个新单元格:
Z = c1*A + c2*B
...使用标量 {c1,c2},我可以用 Jacket(或其他)轻松确定它应该进行计算的方式编写它:
Z{kk} = c1*A{kk} + c2*B{kk}
或者可能是偶数比这更好的优化。否则。它可能最终会导致速度较慢和/或内存效率较低,例如:
temp1 = cellfun( @(X)( c1*X ), A );
temp2 = cellfun( @(X)( c2*X ), B );
Z = cellfun( @plus, temp1, temp2 );
假设 MATLAB 或 Jacket 无法对其进行优化,这最终会使用过多的内存。
I'm using cells to manage data in some stuff I'm working on. I'd like to be able to do things like:
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 );
However, I don't want the extremely verbose syntax to do it. It seems a bit overboard to create a new class for this when all I want to do is provide a definition for math operators on cells.
The question: Is a class the only way to go about it?
If I write a class to do this, it certainly makes it easier to write the code. The biggest negatives I see are related to optimizations, though there's a few other things that bug me about it..
Any optimizations going on behind the scenes (eg, when Jacket compiles something to run on a GPU) would potentially have a harder time determining what optimizations to make. As an example, suppose I have two cells (A,B) containing a number of matrices of appropriate dimension. If I write code to produce a new cell:
Z = c1*A + c2*B
... with scalars {c1,c2}, I can write it in such a way that Jacket (or whatever) will easily determine that it should do the calculations as:
Z{kk} = c1*A{kk} + c2*B{kk}
or perhaps an even better optimization than that. Otherwise. it may end up with something slower and/or less memory efficient, eg:
temp1 = cellfun( @(X)( c1*X ), A );
temp2 = cellfun( @(X)( c2*X ), B );
Z = cellfun( @plus, temp1, temp2 );
Assuming MATLAB or Jacket are unable to optimize it, this would end up using too much memory.
发布评论
评论(1)
事实上,可以为 MATLAB 中的内置数据类型创建新运算符或重载现有运算符。我在我对另一个关于中描述了一个例子/q/2425251/52738">修改整数类型的默认溢出行为。
首先,您可能想了解当前元胞数组有哪些方法。您可以使用函数方法来完成此操作,这就是我得到的在 MATLAB R2010b 中:
算术运算符方法将在上面的列表中显示为其 函数等效,例如
+
运算符的plus
或运算符的
运算符。仅为元胞数组定义了times
。*transpose
方法(.'
运算符)。您必须自己创建其余部分,定义给定运算符对元胞数组参数的行为方式。您可以通过首先创建一个名为
@cell
的新文件夹并将其放置在 MATLAB 路径。然后,您可以将新方法放入@cell
文件夹中。例如,元胞数组的plus
方法的非常简单实现(没有任何输入检查、错误检查等)将是这样的:在上面的代码中,您可能首先要检查操作数
A
和B
是否是相同大小的元胞数组。但是,您可以创建所需的任何独特功能,例如允许B
为标量值,该值将添加到A
的每个单元格中。完全由您来定义+
运算符对元胞数组的行为方式。这将允许您以更紧凑的方式编写代码,如本例所示:
我无法真正谈论幕后优化以及这可能如何影响它们。我知道文档“提高性能的技术”专门提到这个关于重载内置函数:
但是,在您的情况下,您没有重载类的现有函数。您只是创建了该类中不存在的新类,因此很难说这最终会对性能产生什么影响。
It is in fact possible to create new operators or overload existing ones for built-in data types in MATLAB. I describe one example of this in my answer to another SO question about modifying the default overflow behavior of integer types.
First, you may want to look at what methods currently exist for cell arrays. You can do this using the function METHODS, and here's what I get in MATLAB R2010b:
The arithmetic operator methods would show up in the above list as their function equivalents, like
plus
for the+
operator ortimes
for the.*
operator. Only thetranspose
method (.'
operator) is defined for cell arrays. You would have to create the rest yourself, defining how a given operator will behave for cell arrays arguments.You can do this by first making a new folder called
@cell
and placing it in an existing folder on your MATLAB path. You would then place your new methods in the@cell
folder. For example, a very simple implementation of aplus
method for cell arrays (without any input-checking, error-checking, etc.) would be this:In the above code, you would probably first want to check that the operands
A
andB
are cell arrays of the same size. However, you could create whatever unique functionality you want, such as allowingB
to be a scalar value which would get added to every cell ofA
. It's totally up to you to define how the+
operator will behave for cell arrays.This would then allow you to write your code in a much more compact way, as in this example:
I can't really speak to the behind-the-scenes optimizations and how this might affect them. I know that the documentation "Techniques for Improving Performance" specifically mentions this about overloading built-in functions:
However, in your case you aren't overloading existing functions for a class. You're simply creating new ones that didn't exist for that class, so it's hard to say what effect this may ultimately have on performance.