MATLAB:是否可以在本机构造(单元格、结构等)上重载运算符?

发布于 2024-10-24 20:28:24 字数 1313 浏览 2 评论 0 原文

我正在使用单元格来管理我正在处理的一些内容中的数据。我希望能够执行以下操作:

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放我走吧 2024-10-31 20:28:24

事实上,可以为 MATLAB 中的内置数据类型创建新运算符或重载现有运算符。我在我对另一个关于中描述了一个例子/q/2425251/52738">修改整数类型的默认溢出行为

首先,您可能想了解当前元胞数组有哪些方法。您可以使用函数方法来完成此操作,这就是我得到的在 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           

算术运算符方法将在上面的列表中显示为其 函数等效,例如 + 运算符的 plus 运算符的 times。* 运算符。仅为元胞数组定义了 transpose 方法(.' 运算符)。您必须自己创建其余部分,定义给定运算符对元胞数组参数的行为方式。

您可以通过首先创建一个名为 @cell 的新文件夹并将其放置在 MATLAB 路径。然后,您可以将新方法放入 @cell 文件夹中。例如,元胞数组的 plus 方法的非常简单实现(没有任何输入检查、错误检查等)将是这样的:

function C = plus(A,B)
  C = cellfun(@plus,A,B,'UniformOutput',false);  %# Apply plus cell-wise
end

在上面的代码中,您可能首先要检查操作数 AB 是否是相同大小的元胞数组。但是,您可以创建所需的任何独特功能,例如允许 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

我无法真正谈论幕后优化以及这可能如何影响它们。我知道文档“提高性能的技术”专门提到这个关于重载内置函数

重载 MATLAB 内置函数
任何标准 MATLAB 数据
课程可能会产生负面影响
表现。例如,如果您
重载 plus 函数来处理
任何整数类
不同的是,你可能会阻碍某些
MATLAB 内置优化
plus 的函数代码,因此可以
减慢任何使用的程序
这种超载。

但是,在您的情况下,您没有重载类的现有函数。您只是创建了该类中不存在的新类,因此很难说这最终会对性能产生什么影响。

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:

>> 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           

The arithmetic operator methods would show up in the above list as their function equivalents, like plus for the + operator or times for the .* operator. Only the transpose 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 a plus method for cell arrays (without any input-checking, error-checking, etc.) would be this:

function C = plus(A,B)
  C = cellfun(@plus,A,B,'UniformOutput',false);  %# Apply plus cell-wise
end

In the above code, you would probably first want to check that the operands A and B are cell arrays of the same size. However, you could create whatever unique functionality you want, such as allowing B to be a scalar value which would get added to every cell of A. 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:

>> 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

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:

Overloading MATLAB built-in functions
on any of the standard MATLAB data
classes can negatively affect
performance. For example, if you
overload the plus function to handle
any of the integer classes
differently, you may hinder certain
optimizations in the MATLAB built-in
function code for plus, and thus may
slow down any programs that make use
of this overload.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文