2015-12-09 2 views
1

У меня есть огромная 3D-матрица и есть петля. На каждой итерации я хотел бы извлечь из нее несколько разных частей (например, 10000), затем рассчитывается свертка между этой частью и патчем.Извлеките несколько частей матрицы без использования петель

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

+0

Если вы знаете индексы элементов, которые вы хотите извлечь, например, 'idx = [1 5 21 10000]', то вы можете использовать этот вектор 'idx' для индексации исходной трехмерной матрицы для извлечения необходимых частей. –

+3

Вы используете Matlab правильно, а не C? – agold

+0

Я хотел бы извлечь некоторые патчи, и я просто знаю индексы верхнего левого угла патчей, поэтому есть матрица размером 10000, в которой содержатся индексы верхнего левого угла патчей! считая A исходной матрицей, я хотел бы извлечь 10000 патчей из A. – benyamin

ответ

1

Давайте предположим, что у вас есть:

1) Вектор строки idx, содержащие строки индексов левого верхнего угла ваших частей.

2) Вектор строки idy, содержащий индексы столбцов в верхних левых углах ваших частей.

3) Вектор строки idz, содержащий индексы вдоль третьей координаты левых углов ваших частей.

Мы должны сначала создать из idx, idy и idz 3 вектора, содержащего все индексы элементов, которые необходимо извлечь из вашей матрицы. Затем мы разделим выделенную матрицу на блоки того же размера вашего патча, используя mat2cell, а затем мы применим функцию convn к каждому блоку с помощью cellfun.

Totidx=bsxfun(@plus,idx,[0:(size(patch,1)-1)]'); \\i-th column of this is the column vector idx(i):(idx(i)+size(patch,1)-1) 

Totidx=reshape(Totidx,1,numel(Totidx)); \\ Creates the vector needed containing all indexes along first dimension. 

Проделав то же самое для idy и idz, получает 3 векторов Totidx, Totidy, Totidz, содержащие все необходимые индексы.

Теперь мы можем извлечь значения из вашей исходной матрицы, скажем A:

ExtractedA=A(Totidx,Totidy,Totidz); 

Применить mat2cell: NPatch обозначает ваше число извлекаемых пластырей

B=mat2cell(ExtractedA,size(patch,1)*ones(1,NPatch),size(patch,2)*ones(1,NPatch),size(patch,3)*ones(1,NPatch)); 

Затем вы можете применить convn функцию каждая ячейка массива ячеек B: patch обозначает патч, который вы хотите сверлить ваши извлеченные части с помощью

[email protected](M) convn(M,patch,'valid'); 
out=cellfun(fun,B,'uniformoutput',false); 

Каждая ячейка массива ячеек out теперь один на выходе вы хотели

+0

Большое спасибо. Это было очень полезно. С наилучшими пожеланиями :) – benyamin

+0

Если бы этот ответ был полезен для вас, пожалуйста, рассмотрите его как принятое, чтобы другие люди, имеющие один и тот же вопрос, знали, что это работает. Мне было бы интересно иметь некоторые сравнения с точки зрения скорости вычисления между вашим старым кодом и этим, а также – BillBokeey

+0

Здравствуйте, Извините, я студент, и в эти дни я очень занят! я сравню их и отправлю вам результат. – benyamin

Смежные вопросы