2016-10-25 2 views
0

에서 "매트릭스 목록"I는 동일 다음 행렬효율적인 매트릭스 곱셈 MATLAB

N의 처음 두 인덱스가 행과 열의 수있다

M(i,j)=sum_(k,l) c(k,l) kron(N(:,:,k),N(:,:,l))

을 (계산하고자 이 경우) 마지막 인덱스는 행렬이 N이고 행렬 c이 계수의 행렬임을 나타냅니다. 인덱스 kl은 1에서 50까지 실행됩니다 (필자의 경우).

내가에 합을 절단한다는 말 : 그런 일이 왜 알아낼 수 없습니다이 코드 몇 가지 재미있는 것은이 있습니다

c=randn(50,50); 
N=randn(26,26,50); 
M=zeros(size(N,1)^2); 
for k=1:size(N,3) 
for l=1:size(N,3) 
M=M+c(k,l).*kron(N(:,:,k),N(:,:,l)); 
end 
end 

:

이렇게하려면, 나는 다음과 같은 알고리즘을 구현 한 예를 들어, 유한 번호 n까지 k. k이 1에서 n으로 바뀌고 1에서 n+1으로 갈 때 계산 사이의 시간차는 k=n+1으로 색인 된 행렬을 계산하는 데 걸리는 시간보다 훨씬 높습니다 (약 정도). 총 행렬은 k=n까지 계산됩니다.

제 질문은 : 제가 찾고있는 매트릭스를보다 효율적으로 계산할 수있는 방법이 있습니까? 그리고이 알고리즘에 어떤 문제가 있습니까?

대단히 감사합니다.

+0

'제로 (n)'차원 nxn의 2D 정사각형 행렬을 만듭니다. 따라서 예제에서 M, 2D 행렬을 만들지 만'M (:, :, k)'를 사용하여 세 번째 차원에 액세스하려고 시도하십시오 – obchardon

+1

@ obchardon 그 코드에 오타가 있었는지 확실히 알았습니다. Alex - 내 편집을 확인하십시오. – Brick

+0

@Alex 귀하의 수식이 귀하의 코드와 정확하게 일치하지 않습니다. 먼저, 위의 코드가 올바른 예상 출력을 생성하는지 확인할 수 있습니까? 그런 다음에야 그 루프를 최적화/벡터화하는 것에 대해 생각해야합니다. – Amro

답변

2

TL; DR : 난 그냥 어쨌든 시도 것을 공유하고 싶어이 아래


내가 언급 아이디어의 구현입니다 ... 코드보다 느린 것으로 밝혀졌다

function [t,v] = testKron() 
    s1 = 26; 
    s3 = 50; 
    c = randn(s3,s3); 
    N = randn(s1,s1,s3); 

    funcs = { 
     @() funcAlex(N,c) 
     @() funcAmro(N,c) 
    }; 
    t = cellfun(@timeit, funcs); 
    v = cellfun(@feval, funcs, 'Uniform',false); 
    norm(v{1}-v{2}) 
end 

function M = funcAlex(N,c) 
    [s1,~,s3] = size(N); 
    M = zeros(s1*s1); 
    for i=1:s3 
     for j=1:s3 
      M = M + c(i,j) .* kron(N(:,:,i), N(:,:,j)); 
     end 
    end 
end 

function M = funcAmro(N,c) 
    [s1,~,s3] = size(N); 
    % tall matrix, NN = cat(1, N(:,:,1), ..., N(:,:,s3)) 
    NN = reshape(permute(N, [1 3 2]), s1*s3, s1); 
    % accumulate kron results 
    M = zeros(s1*s1*s3, s1*s1); 
    for i=1:s3 
     M = M + bsxfun(@times, repelem(c(:,i), s1*s1), kron(NN, N(:,:,i))); 
    end 
    % split M back into s3 slices each of size s1^2-by-s1^2 
    M = permute(reshape(M.', s1*s1, s1*s1, s3), [2 1 3]); 
    % sum along slices 
    M = sum(M,3); 
end 

당신이 언급 한 크기를 사용하여, 나는 내 m에서 다음 타이밍을 얻을 (N는 26로-26에 의해-50 배열 인) : 원래 코드 (funcAlex)에 비해 의견 (funcAmro) achine running R2016b :

>> t = testKron 
t = 
    3.2770 % funcAlex 
    5.5119 % funcAmro 

그래서 내 방법은 느립니다 (읽기 쉽지 않음). 나는 모든 치환/변형이 무시할 수없는 오버 헤드를 가지고 있다고 생각한다.

물론 결과 행렬 M은 동일하다 (차이는 4.5801e-12 기계 엡실론에 가깝다).

+0

's1'이 작 으면 내 방법 시간이 더 빨리 걸린다는 것을 언급해야합니다 (예 : s1 = 5, s3 = 50; 또는 s1 = 5; s3 = 100;) – Amro

+0

코드를 공유해 주셔서 감사합니다. 나는 두 가지 코드로 조금씩 놀았으며, 문제는 크로네 커 제품과 다르다는 것을 알았지 만, 그것은 영원히 받아 들여지는 요약입니다. 이것은 계수 중 일부가 내가 사용하고있는 YALMIP 패키지를 해결하는 Semidefinite 프로그램의 변수라는 사실과 관련이 있다고 생각합니다. – Alex

+1

저는이 패키지에 익숙하지 않지만, 솔버가 반환하는 coefficients 변수가 일반 "double matrix"가 아닌 경우 루프 외부에서 변환해야합니다. MATLAB에서의 객체 인덱싱은 네이티브 배열 인덱싱보다 훨씬 느립니다. – Amro