Matlab:我可以通过唯一名称引用数组索引吗?

时间:2012-04-19 15:26:29

标签: matlab matrix data-structures matlab-struct

假设我有一个包含[theta,rho,z]向量的列矩阵pols。 这意味着,如果我有9个这样的向量,它将是一个9x3矩阵。 将它们安排得如此安排是非常方便的,因为我可以将它们中的任何一个馈送到像pol2cart这样的函数中:

cart3 = pol2cart(pols(3,:));

对于某个向量,我可以通过索引1,2,3找到它的组件:

rho5 = pols(5,2);

但有时矩阵实际上在另一个更宽的矩阵内,并且可能在中间而不是在开头,这样以上可能会变成:

rho5 = pols(5,6);

为了使代码更具可读性以防其他人必须维护它,无论如何通过唯一名称引用索引?像

rho5 = pols(5).rho;

可以在之前定义.rho映射到具有rho值的列。

我冒险尝试使用mat2cellcell2struct将矩阵转换为单元格然后转换为数组,但这似乎并不实用。或者,我可以制作一系列结构,但后来我失去了pol2cart(pols)的能力,而是必须做

pol2cart(pols.theta, pols.rho, pols.z);

所以重复一下这个问题:我可以将索引映射到唯一名称吗?

3 个答案:

答案 0 :(得分:3)

对于默认的MATLAB数据类型,不,你不能真的这样做。但是,您可以create your own new data type (i.e. class object)来存储数据。在类定义中,您将重载subsref方法,以定义下标引用(即使用(){}.)对新对象的行为方式。对于处理对象数组而言,这可能会变得相当棘手,但这是可能的。

请注意,您还必须为要在新数据类型上使用的所有现有函数创建重载方法。具体来说,您必须为对象创建一个pol2cart方法,该方法可以在内部调用内置pol2cart函数,并将来自对象的相应数据作为参数传递。

......这让我想出了一个更简单的解决方案,适合您目前的情况。您可以创建一个结构数组(或数组的标量结构)来存储数据,而只需创建一个专门用于struct data types的新的重载pol2cart函数,而不是创建一个全新类的类对象,这将简化调用语法。

我在另外两个答案herehere中讨论了内置数据类型的重载函数的更多细节。简而言之,您将创建一个名为@struct的文件夹,并将其放在MATLAB path上的文件夹中。在这个@struct文件夹中,您将放置此重载函数:

function varargout = pol2cart(polarCoordinates)
  [varargout{1:nargout}] = pol2cart(polarCoordinates.theta, ...
                                    polarCoordinates.rho, ...
                                    polarCoordinates.z);
end

请注意,这是函数的流线型版本,没有对输入进行错误检查等。现在,让我们制作一些示例数据:

pols = rand(9, 3);  %# A 2-D array of data
polStruct = struct('theta', pols(:, 1), ...  %# Convert it to a scalar
                   'rho', pols(:, 2), ...    %#   structure of arrays
                   'z', pols(:, 3));

您可以按如下方式访问第五行的rho值:

rho5 = pols(5,2);
rho5 = polStruct.rho(5);

如果您想从极坐标转换为笛卡尔坐标,以下是对每种数据类型的处理方式:

[X,Y,Z] = pol2cart(pols(:,1), pols(:,2), pols(:,3));  %# Calls the built-in one
[X2,Y2,Z2] = pol2cart(polStruct);  %# Calls the overloaded one

你可以检查他们每个人给出的结果如下:

>> isequal([X Y Z],[X2 Y2 Z2])

ans =

     1   %# True!

答案 1 :(得分:1)

好吧,正式答案可能是上面木片所给出的“不”。但是,如果你真的想做类似的事情,你可以使用半黑客。具体来说,您可以定义一个类并重载运算符以实现(几乎)您想要的。 不幸的是,我发现Matlab不允许重载.,所以你必须使用其他运算符。(见下面的编辑)

只是为了给你一个想法,这是一个通过M返回矩阵M^i的第i行的类。

classdef Test
  properties
    M;
  end

  methods
    function this = Test(M)
      this.M = M;
    end

    function res = mpower(this, i)
      res = this.M(i, :);
    end
  end
end

它可以像这样运行:

>> tmp = Test([1 2; 3 4]);
>> tmp^1

ans =

     1     2

>> tmp^2

ans =

     3     4

使用风险自负! :)

修改

上面我错了。正如gnovice的回答中提到的,您实际上可以使用方法.为自定义类定义subsref运算符。

答案 2 :(得分:0)

没有。你不能这样做。就这么简单。