2017-04-26 9 views
0

상수는 2D 행렬 mat1입니다. 2D 셀 배열 mat2 모든 셀에는 2D 또는 3D 이중 행렬이 들어 있습니다. 이 두 행렬의 행 및 열 수는 mat1입니다. 나는 mat2 내의 각 더블 매트릭스의 모든 슬라이스에 (. *) mat1을 곱해야합니다. 그 결과는 mat2과 같은 크기의 다른 셀 배열 results 일 필요가 있습니다. 따라서 contatining double 행렬은 크기면에서 mat2의 double 행렬과 같아야합니다.MATLAB : 셀 배열 내의 3D 행렬에 2D 행렬을 곱합니다.

설명을 위해 mat1mat2을 생성하는 코드는 다음과 같습니다. 나는 곱셈이 일어나야하는 시점에서 어려움을 겪고있다.

rowCells = 5; 
colCells = 3; 
rowTimeSeries = 300; 
colTimeSeries = 5; 
slices = [1;10]; 

% Create 2D double matrix 
mat1 = rand(rowTimeSeries, colTimeSeries); 

% Create 2D cell matrix comprisiong 2D and/or 3D double matrices 
mat2 = cell(rowCells,colCells); 

for c = 1:colCells 
    for r = 1:rowCells 
     slice = randsample(slices, 1, true); 
     mat2{r,c} = rand(rowTimeSeries, colTimeSeries, slice); 
    end 
end 

% Multiply (.*) mat1 with mat2 (every slice) 

results = cell(rowCells,colCells); 

for c = 1:colCells 
    for r = 1:rowCells 
     results{r,c} = ... % I am struggling here!!! 
    end 
end 

답변

1

당신은 사용자 정의 기능 multiply2D3D의 필요성을 제거 bsxfun를 사용할 수 있습니다, 그것은 비슷한 방식으로 작동합니다! 업데이트 된 코드 :

results = cell(rowCells,colCells); 
for c = 1:colCells 
    for r = 1:rowCells 
     results{r,c} = bsxfun(@times, mat1, mat2{r,c}); 
    end 
end 

이 행과 COLS의 번호가 "조각"각각 동일 2D 및 3D 행렬을 위해 작동합니다, 그래서 귀하의 경우에 작동합니다.


또한 셀 배열의 행과 열을 별도로 루프 할 필요가 없습니다. 이 루프는 반복의 같은 번호를 가지고 있지만 하나 개의 루프하지 두, 그래서 코드는 좀 더 능률적이다 :

results = cell(size(mat2)); 
for n = 1:numel(mat2) % Loop over every element of mat2. numel(mat2) = rowCells*colCells 
    results{n} = bsxfun(@times, mat1, mat2{n}); 
end 
+0

코드가 완벽하게 작동합니다. 고마워. – Andi

+0

걱정, 건배 – Wolfie

0

내가 한 가지 해결책은 3D 매트릭스가있는 2D의 곱셈을 함수로 아웃소싱하는 것입니다. 그러나이 문제를 해결하는 가장 효율적인 방법인지 궁금합니다.

rowCells = 5; 
colCells = 3; 
rowTimeSeries = 300; 
colTimeSeries = 5; 
slices = [1;10]; 

% Create 2D double matrix 
mat1 = rand(rowTimeSeries, colTimeSeries); 

% Create 2D cell matrix comprisiong 2D and/or 3D double matrices 
mat2 = cell(rowCells,colCells); 

for c = 1:colCells 
    for r = 1:rowCells 
     slice = randsample(slices, 1, true); 
     mat2{r,c} = rand(rowTimeSeries, colTimeSeries, slice); 
    end 
end 

% Multiply (.*) mat1 with mat2 (every slice) 

results = cell(rowCells,colCells); 

for c = 1:colCells 
    for r = 1:rowCells 
     results{r,c} = multiply2D3D(mat1, mat2{r,c}); 
    end 
end 


function vout = multiply2D3D(mat2D, mat3D) 
%MULTIPLY2D3D multiplies a 2D double matrix with every slice of a 3D 
% double matrix. 
% 
% INPUTs: 
% mat2D: 
% 2D double matrix 
% 
% mat3D: 
% 3D double matrix where the third dimension is equal or greater than 1. 
% 
% OUTPUT: 
% vout: 
% 3D double matrix with the same size as mat3D. Every slice in vout 
% is the result of a multiplication of mat2D with every individual slice 
% of mat3D. 

[rows, cols, slices] = size(mat3D); 
vout = zeros(rows, cols, slices); 

for s = 1 : slices 
    vout(:,:,s) = mat2D .* mat3D(:,:,s); 
end 

end 
1

나는 늑대와 거의 똑같은 대답을했지만, 그는 그것에 나를 이길.

어쨌든, 여기에 내가 생각 하나 라이너가 약간 더 좋은입니다 :

nR = rowCells; % Number of Rows 
nC = colCells; % Number of Cols 
results = arrayfun(@(I) bsxfun(@times, mat1, mat2{I}), reshape(1:nR*nC,[],nC), 'un',0); 

이것은 곱셈에 대한 루프 인덱싱 및 bsxfun을 수행 할 수 arrayfun를 사용합니다. results 변수는 세포 배열하고 대조 (초기화 될 필요가없는, 그래서 'UniformOutput' ('un') arrayfun 수익률 세포 배열 지정


몇몇 장점

1) 루프 사용).

2) 인덱스의 크기는 출력시 results의 크기를 결정하므로 사용자가 원하는대로 지정할 수 있습니다.

3) 단일 행을 함수의 입력 인수로 직접 사용할 수 있습니다.

단점 늑대로 for 루프를 사용하는 것보다

1) Can run slower는 코멘트에 지적했다.

+1

좋은 답변/코드 Jacob, 나는'arrayfun'을 사용하지 않을 것입니다! 아마도 단점 *을 지적 할 가치가 있습니다. 방금 테스트를 해봤는데,'arrayfun'을 사용하면 입력을위한 다양한 크기의 루핑보다 속도가 느린 것으로 보입니다. 이 질문을 참조하십시오. 상위 응답은 오버 헤드와 'arrayfun'의 속도 문제에 대해 약간의 깊이있게 들어갑니다 : http://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than -an-explicit-loop-in-matlab-why – Wolfie

+0

@JacobD 코드도 완벽하게 작동하지만, 나는 Wolfie의 솔루션을 선호합니다. 필자의 주된 장점은 코드를 읽고 이해하기가 쉽다는 점입니다. 하지만 그건 내 개인 의견입니다. – Andi

+1

@Wolfie 좋은 점,'arrayfun'으로 속도/오버 헤드에 대해 뭔가를 추가하는 것을 잊어 버렸습니다. 작은 크기의 경우에는 문제가되지 않지만 크기가 커지면 시간을 낭비 할 수 있습니다. 이 시나리오에서'arrayfun' 또는'for' 루프를 사용하는 것의 속도 차이가 '내부'와 '외부'행렬 크기의 비율에 크게 의존한다고 생각합니다 (Cells와 TimeSeries가 OP로 넣을 때).). – JacobD