2012-09-15 5 views
1

기본적으로 상관 관계 또는 공분산 계산을위한 모든 기본 제공 함수는 행렬을 반환합니다. 시드 영역과 다른 여러 영역 간의 상관 관계를 계산하는 효율적인 함수를 작성하려고하지만 다른 영역 간의 상관 관계는 필요하지 않습니다. 따라서 전체 상관 행렬을 계산하는 것이 비효율적이라고 가정합니다.MATLAB : 시드 영역과의 상관 관계

대신에 각 영역과 시드 영역 사이의 상관 행렬을 계산할 수 있습니다. 대각선을 벗어난 점 중 하나를 선택하여 저장하십시오. 그러나이 상황에서 루핑하는 것이 비효율적이라고 생각합니다.

더 구체적으로 말하면, 내 3 차원 공간의 각 점에는 시간 차원이 있습니다. 주어진 반경 내에서 주어진 점과 공간상의 모든 점 사이의 평균 상관 관계를 계산하려고합니다. 나는이 과정을 수십만 번, 많은 다른 반지름 길이에 대해 반복하고 싶습니다. 그래서 이것을 가능한 한 효율적으로하고 싶습니다.

그럼 내가 무시할 상관 관계 계산없이 단일 벡터와 다른 여러 벡터 간의 상관 관계를 계산하는 가장 좋은 방법은 무엇일까요?

는 크리스에게,

편집을 주셔서 감사합니다 : 여기 내 코드는 지금 ...

function [corrMap] = TIME_meanCorrMap(A,radius) 
% Even though the variable is "radius", we work with cubes for simplicity... 
% So, the radius is the distance (in voxels) from the center of the cube an edge. 
denom = ((radius*2)^3)-1; 
dim = size(A); 
corrMap = zeros(dim(1:3)); 
for x = radius+1:dim(1)-radius 
    rx = [x-radius : x+radius]; 
    for y = radius+1:dim(2)-radius 
     ry = [y-radius : y+radius]; 
     for z = radius+1:dim(3)-radius 
      rz = [z-radius : z+radius]; 
      corrCoefs = zeros(1,denom); 
      seed = A(x,y,z,:); 
      i=0; 
      for xx = rx 
       for yy = ry 
        for zz = rz 
         if ~all([x y z] == [xx yy zz]) 
          i = i + 1; 
          temp = corrcoef(seed,A(xx,yy,zz,:)); 
          corrCoeffs(i) = temp(1,2); 
         end 
        end 
       end 
      end 
      corrMap = mean(corrCoeffs); 
     end 
    end 
end 

편집 : 여기 허용 대답을 보완하기 위해 좀 더 시간이 있습니다. 상관 계산하도록 정규화 할 bsxfun()을 사용하고, 행렬 곱셈 :

tic; for i=1:10000                 
    x=rand(100); 
    xz = bsxfun(@rdivide,bsxfun(@minus,x,mean(x)),std(x)); 
    cc = xz(:,2:end)' * xz(:,1) ./ 99; 
end; toc 
Elapsed time is 6.928251 seconds. 

zscore 사용()를 정상화, 행렬 곱셈은 상관 관계를 계산하기 :

tic; for i=1:10000          
    x=rand(100);           
    xz = zscore(x);          
    cc = xz(:,2:end)' * xz(:,1) ./ 99; 
end; toc 
Elapsed time is 7.040677 seconds. 

정상화 bsxfun()을 사용하여, 와 corr()을 사용하여 상관 관계를 계산합니다.

tic; for i=1:10000          
    x=rand(100); 
    xz = bsxfun(@rdivide,bsxfun(@minus,x,mean(x)),std(x)); 
    cc = corr(x(:,1),x(:,2:end)); 
end; toc 
Elapsed time is 11.385707 seconds. 

답변

4

현재 사용중인 루프를 향상시킬 수 있습니다. for 상관 관계 계산은 충분한 RAM이있는 경우 행렬 곱셈을 사용하여 병렬 처리 할 수 ​​있습니다. 그러나 4 차원 데이터 행렬 A를 다른 모양으로 풀어야합니다. 가장 가능성이 큰 것은 3 차원 voxelwise fMRI 데이터를 다루는 것입니다.이 경우 [x y z time] 행렬에서 [index time] 행렬로 바꿔야합니다. 나는 그 형체를 다룰 수 있다고 생각할 것이다. seed의 시간 계획 [Time by 1]과 target [NumTargets by Time] 시간 준비가 완료되면 훨씬 더 효율적인 계산을 수행 할 수 있습니다.

원하는 상관 관계를 효율적으로 계산하는 가장 빠른 방법은 MATLAB에서 corr 함수를 사용하는 것입니다. 이 함수는 2 개의 행렬 인수를 받아들이며, 인수 1의 열과 인수 2의 열 사이의 모든 쌍으로의 상관 관계를 매우 효율적으로 계산합니다. 내 컴퓨터에서

T = 200; %time samples 
N = 20; %number of other voxels 

seed = randn(T,1);  %data from seed voxel 
targets = randn(T,N); %data from target voxels 

%here is the for loop method 
tic 
for n = 1:N 
    tmp = corrcoef(seed, targets(:,n)); 
    tmpcc = tmp(1,2); 
end 
looptime = toc; 

%here is the parallel method 
tic 
cc = corr(seed, targets); 
matrixtime = toc; 

corr 병렬 동작의 T * N에 비례하는 인자에 의해 루프 방법보다 빠르다.

기본 매트릭스 작업을 직접 수행 할 수 있고 어떤 경우이든 알 수있는 가치가있는 경우 corr 기능보다 약간 빠르게 진행할 수 있습니다.두 벡터 사이의 상관 관계는 그래서 많이 왜 corr 기능이있는 무엇을 할 것 기본적으로 다음과 같은 방법으로

zseed = zscore(seed); %normalize the seed timecourse by z-scoring 
ztargets= zscore(targets); %normalize the target timecourses by z-scoring 
ztargets = ztargets';  %flip columns and rows for convenience 
cc2 = ztargets*zseed./(T-1); %compute many dot products with one matrix multiplication 

위의 코드에서 상관 관계를 계산할 수 위의 규칙을한다하여, 기본적으로 정규화 된 내적이다 루프보다 빠릅니다. 대부분의 작업 시간은작업에 있으며 bsxfun 명령을 사용하여 을 효율적으로 계산하면 corr 기능의 성능을 향상시킬 수 있습니다. 지금 당장은 시드 시간대와 많은 타겟 시간대 사이의 상관 관계를 계산하는 방법에 대한 지침을 제공하여 각각을 따로 따로 계산하고 계산할 필요가 없기를 바랍니다.

+0

이것은 매우 도움이되었습니다. 감사합니다! 그리고 당신이 내 설명과 코드에서 내 데이터의 본질을 추론했다는 사실은 좋은 추가 터치였습니다. –

+0

글쎄, 나는 과거에 비슷한 문제에 대해 연구 해왔다. 그래서 추측하기는 쉽지 않았다. 도와 줘서 기뻐요! – cjh