найти среднеквадратичную ошибку двух массивов ячеек разного размера

У меня есть два массива ячеек. Один из них — «trans_blk» размером ‹232324x1> состоит из ячеек размером ‹8x8>, а другой «ca» имеет размер ‹1024x1> и состоит из ячеек размером ‹8x8>. Я хочу вычислить среднеквадратичную ошибку (MSE) для каждой ячейки «ca» по отношению к каждой ячейке «trans_blk».

Я использовал следующий код для вычисления:

m=0;
for ii=0:7
    for jj=0:7

        m=m+((trans_blk{:,1}(ii,jj)-ca{:,1}(ii,jj))^2);

    end
end

m=m/(size of cell);    //size of cell=8*8
disp('MSE=',m);

Это дает ошибку. Неверная операция ссылки на ячейку в MATLAB.


person Indu Aggarwal    schedule 15.05.2015    source источник
comment
Я думаю, что ошибка связана с индексацией ячейки. {:,1}‹- не уверен, что это правильно...   -  person Ander Biguri    schedule 15.05.2015
comment
Другая проблема заключается в том, что индексы Matlab начинаются с 1, а не с 0. Ваш цикл повторяется с 0:7, а не с 1:8.   -  person hiandbaii    schedule 15.05.2015
comment
Не могли бы вы сказать, что он говорит, когда вы набираете class(trans_blk{1}) в консоли? также для class(ca{1})?   -  person    schedule 15.05.2015


Ответы (1)


Несколько способов, которыми, как я понял, вы могли бы пойти:

% First define the MSE function
mse = @(x,y) sum(sum((x-y).^2))./numel(x);

Я большой поклонник использования bsxfun для подобных вещей, но, к сожалению, он не работает с массивами ячеек. Итак, я позаимствовал форму одноэлементного расширения ответа из здесь.

% Singleton expansion way:
mask = bsxfun(@or, true(size(A)), true(size(B))');
idx_A = bsxfun(@times, mask, reshape(1:numel(A), size(A)));
idx_B = bsxfun(@times, mask, reshape(1:numel(B), size(B))');

func = @(x,y) cellfun(@(a,b) mse(a,b),x,y);

C = func(A(idx_A), B(idx_B));

Теперь, если это слишком безумно (или если явное создание массивов с помощью A(idx_A) слишком велико), вы всегда можете попробовать циклический подход, подобный приведенному ниже.

% Or a quick loop:
results = zeros(length(A),length(B));
y = B{1};
for iter = 1:length(B)
  y = B{iter};
  results(:,iter) = cellfun(@(x) mse(x,y) ,A);  
end

Если у вас закончилась память: подумайте о том, что вы выделяете: матрица двойников, состоящая из (232324 x 1024) элементов. (Это приличный объем памяти. В зависимости от вашей системы это может быть около 2 ГБ памяти...)

Если вы не можете хранить все это в памяти, вам, возможно, придется решить, что вы собираетесь делать со всеми MSE, и либо делать это в пакетном режиме, либо найти машину, на которой вы можете запустить полная симуляция/код включена.

EDIT Если вы хотите сохранить только сумму всех MSE (как указано в комментариях ниже), вы можете сэкономить память,

% Sum it as you go along:
results = zeros(length(A),1);
y = B{1};
for iter = 1:length(B)
  y = B{iter};
  results = results + cellfun(@(x) mse(x,y) ,A);  
end
results =sum (results);
person aepound    schedule 15.05.2015
comment
Я бы, вероятно, заменил A на ca, а B на trans_blk, хотя я не думаю, что это имеет значение, как вы это сделаете. Может быть, вы могли бы проверить, чтобы увидеть, что будет быстрее? - person aepound; 16.05.2015
comment
Прежде всего, ответы дают ошибку «недостаточно памяти». Пожалуйста, дайте мне знать любой другой метод для решения моей проблемы. - person Indu Aggarwal; 16.05.2015
comment
Что вы хотите делать с MSE после их вычисления? Вы хотите сложить все MSE? Вы хотите построить гистограмму? - person aepound; 16.05.2015
comment
Да, мне придется добавить все из них. - person Indu Aggarwal; 16.05.2015
comment
Большое спасибо за вашу помощь и руководство. Это было действительно очень полезно для меня. - person Indu Aggarwal; 17.05.2015
comment
Если бы мой ответ помог ответить на ваш вопрос, вы могли бы замаскировать его как принятый ответ. - person aepound; 18.05.2015