找到矩阵的大小,而不使用MATLAB中的`size`

时间:2013-10-09 18:43:49

标签: matlab matrix size

假设我想查找矩阵的大小,但不能使用sizenumellength等任何函数。有没有任何巧妙的方法来做到这一点?我可以想到使用循环的几个版本,例如下面的循环,但是没有循环可以做到这一点吗?

function sz = find_size(m)
sz = [0, 0]
   for ii = m'    %' or m(1,:) (probably faster)
      sz(1) = sz(1) + 1;
   end

   for ii = m     %' or m(:,1)'
      sz(2) = sz(2) + 1;
   end    
end

并且记录:这不是作业,而是出于好奇。虽然这个问题的解决方案在这种情况下永远不会有用,但它们有可能提供关于如何使用某些功能/技术的新知识。

5 个答案:

答案 0 :(得分:8)

这是一个更通用的解决方案

function sz = find_size(m)
sz = [];
m(f(end), f(end));
    function r = f(e)
        r=[];
        sz=[sz e];
    end
end

哪些

  1. 适用于数组单元格数组对象数组
  2. 其时间复杂度是恒定的,与矩阵大小无关
  3. 不使用任何MATLAB函数
  4. 易于适应更高的尺寸

答案 1 :(得分:3)

对于非空矩阵,您可以使用:

sz = [sum(m(:,1)|1) sum(m(1,:)|1)];

但要涵盖空矩阵,我们需要更多函数调用

sz = sqrt([sum(sum(m*m'|1)) sum(sum(m'*m|1))]);

或更多行

n=m&0;
n(end+1,end+1)=1;
[I,J]=find(n);
sz=[I,J]-1;

哪个适用于m=zeros(0,0)m=zeros(0,10)m=zeros(10,0)

答案 2 :(得分:2)

增量索引和try-catch语句有效:

function sz = find_size(m)

  sz = [0 0];

  isError = false;
  while ~isError
    try
      b = m(sz(1) + 1, :);
      sz(1) = sz(1) + 1;
    catch
      isError = true;
    end
  end

  isError = false;
  while ~isError
    try
      b = m(:, sz(2) + 1);
      sz(2) = sz(2) + 1;
    catch
      isError = true;
    end
  end

end

答案 3 :(得分:2)

一个非常通用的解决方案是:

[ sum(~sum(m(:,[]),2)) sum(~sum(m([],:),1)) ]

它接受矩阵(包含0列,0行或两者),以及复杂 NaN inf 值。

它还非常快:对于1000×1000矩阵,我的旧笔记本电脑需要大约22微秒(重复1e5的for循环需要2.2秒,用{{测量1}},tic)。


如何运作

统一处理空矩阵的关键是:

  • 空索引(即使用toc编制索引);
  • 沿着空维度求和的事实给出了零。

r c 成为[]的行数和列数(可能为零)。 m r ×0空向量。即使 r c 为零,这也成立。此外,此空索引会自动对m(:,[])中的NaNinf或复杂值提供不敏感性(并且可能也会占用较小的计算时间)。

r ×0向量沿其第二维(m)求和,得到 r ×1个零的向量。否定和求和此向量会给出 r

对于列数 c 应用相同的过程,通过第一维中的空索引并沿该维进行求和。

答案 4 :(得分:1)

find命令有一个简洁的选项来获取最后K个元素:

  

I = find(X,K,'last')最多返回K indices corresponding to the nonzero entries of the array X`。

要获取大小,请询问最后k=1个元素。例如,

>> x=zeros(256,4);
>> [numRows,numCols] = find(x|x==0, 1, 'last')
numRows =
   256
numCols =
     4
>> numRows0 = size(x,1), numCols0 = size(x,2)
numRows0 =
   256
numCols0 =
     4

您可以将find与单输出参数语法结合使用,这将为您提供numel

>> numEl = find(x|x==0, 1, 'last')
numEl =
        1024
>> numEl0 = numel(x)
numEl0 =
        1024

另一个简单但不太有趣的解决方案是使用whos(感谢提醒Navan):

s=whos('x'); s.size

最后,有format debug