【问题标题】:Vectorization using accumarray使用 accumarray 进行矢量化
【发布时间】:2015-08-25 10:00:59
【问题描述】:

我想将 3D 表面的纹理 (CylCoors 300000x3) 投影到 2D 平面 (Image 380x360)。为此,我采用 Z (UniqueZ=unique(CylCoors(:,3))) 和 Theta (UniqueTheta=unique(CylCoors(:,1))) 中的每个唯一值,并投影所有纹理值 (PointValues300000x1),它们都像这样相遇:

Image=zeros(max(UniqueH),max(UniqueTheta)); %380x360

tic

HMat=bsxfun(@eq,CylCoors(:,3),UniqueH');  % 300000x380
ThetaMat=bsxfun(@eq,CylCoors(:,1),UniqueTheta'); %300000x360


for ii=1:length(UniqueH)          % Sloooow and not nice :(
    for jj=1:length(UniqueTheta)

        Image(ii,jj)=sum(PointValues.*...
            HMat(:,ii).*ThetaMat(:,jj))/...
            sum(HMat(:,ii).*ThetaMat(:,jj));

    end
end

toc

这是一个修剪变量的示例:

CylCoorsSample = [263.0000  184.2586   10.0000    
                  264.0000  183.0417   10.0000    
                  264.0000  182.1572   10.0000    
                  82.0000   157.4746   11.0000    
                  80.0000   158.2348   11.0000    
                  86.0000   157.3507   11.0000    
                  84.0000   157.7633   11.0000]   

PointValuesSample = [0.4745
                     0.5098
                     0.5020
                     0.4784
                     0.4510
                     0.4431
                     0.5804]


UniqueTheta = [80              
               82              
               84
               86
               263
               264]

UniqueH =[10
          11]

ThetaMat =                             HMat =   

 0     0     0     0     1     0       1   0
 0     0     0     0     0     1       1   0
 0     0     0     0     0     1       1   0
 0     1     0     0     0     0       0   1
 1     0     0     0     0     0       0   1
 0     0     0     1     0     0       0   1
 0     0     1     0     0     0       0   1 

Image =        % size: length(UniqueH)xlength(UniqueTheta)

   NaN       NaN       NaN       NaN    0.4745    0.5059
0.4510    0.4784    0.5804    0.4431       NaN       NaN

有没有办法使用accumarray 向量化for 循环?有些事情告诉我情况就是这样,但我发现这个函数的多维子索引非常混乱。

也欢迎任何其他矢量化解决方案(我假设使用 reshapebsxfunsum 的智能组合),但我真的很想更好地理解 accumarray 的这种用法。

【问题讨论】:

  • 可以加个小样本输入输出吗?
  • 不,我的意思是用简化数字的输入矩阵制作一个 small 样本,以及如何更改数字只是为了演示您的过程
  • 现在知道了!我想知道我的最后一次编辑会有多大帮助:D
  • UniqueThetaUniqueH 应该是 PointValuesSample 中每个点的元素坐标(或者如果索引多个点的平均值)应该位于最终输出上Image?
  • 是的,这正是它的作用。理想情况下,表面只有一个值,但分割和舍入有时会产生许多具有相同坐标 Theta 和 Z 的点,它们仅在半径坐标上有所不同。

标签: matlab vectorization accumulate accumarray


【解决方案1】:

给定:

CylCoorsSample = [263.0000  184.2586   10.0000    
                  264.0000  183.0417   10.0000    
                  264.0000  182.1572   10.0000    
                  82.0000   157.4746   11.0000    
                  80.0000   158.2348   11.0000    
                  86.0000   157.3507   11.0000    
                  84.0000   157.7633   11.0000]   

PointValuesSample = [0.4745
                     0.5098
                     0.5020
                     0.4784
                     0.4510
                     0.4431
                     0.5804]

您可以使用accumarray如下(使用unique的第三个输出来生成所需的subs输入):

[UniqueTheta, ~, subsTheta]=unique(CylCoorsSample(:,1))
[UniqueH,~,subsH]=unique(CylCoorsSample(:,3))
sz = [numel(UniqueH), numel(UniqueTheta)]

Image = accumarray([subsH, subsTheta], PointValuesSample, sz, @mean, NaN)

【讨论】:

  • 完美运行,但我将不得不坐下来剖析 accumarray() 及其所有参数才能真正理解它谢谢!
  • subs 是输出矩阵中位置的行向量列表。因此,如果 subs 的第一行是[1 1],则意味着将val 的第一行放在输出的[1 1] 位置。但是,如果有许多具有相同值的 subs 行(即在我的示例中为 [1 1]),则将所有相应的 val 值放在该位置,但使用 fun 函数句柄聚合它们(在我的情况下为 @mean所以平均它们)。
  • 这正是我还没有理解的!现在一切都清楚了,再次感谢您的出色回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多