Векторизация с использованием accumarray

Я хочу спроектировать текстуру 3D поверхности (CylCoors 300000x3) в 2D плоскость (Image 380x360). Для этого я беру каждое уникальное значение в Z (UniqueZ=unique(CylCoors(:,3))а и тета (UniqueTheta=unique(CylCoors(:,1))) и спроецировать все значения текстуры (PointValues 300000x1) где оба встречаются так:

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

Есть ли способ векторизации for петли с помощью accumarray? Что-то подсказывает мне, что это так, но я нахожу многомерное субиндексирование для этой функции довольно запутанным.

Любые другие решения векторизации (используя умные комбинации reshape,bsxfun, а также sum Я предполагаю) также приветствуются, но я действительно хотел бы понять это использование 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)
Другие вопросы по тегам