2012-09-13 8 views
2

큰 m * n 희박한 행렬 Y가 있습니다. 각 행의 평균이 0이되도록 Y의 각 행을 정규화하고 싶습니다.Matlab에서 희소 행렬을 제로 평균으로 행 정규화

나는 이것을 처음 시도했다. 그러나 각 행의 평균도 0 항목에서 뺍니다. 이는 내가 원하는 것이 아닙니다.

Ynorm = bsxfun(@minus, Y, Ymean); 

그런 다음 시도해 보았습니다.

[m, n] = size(Y); 
nonZeroNum = nnz(Y); 
Ynorm = spalloc(m,n,nonZeroNum); 
for i = 1:m 
    Ynorm(i, :) = spfun(@(x)(x - Ymean(i)), Y(i, :)); 
end 

그러나이 벡터화되지 않은 솔루션은 너무 느립니다.

나는 또한 bsxfun과 spfun을 결합하려고 생각했지만 작성하지 않았다.

누구에게 벡터화 된 솔루션이 있습니까?

답변

3

쉽고 간단합니다.

임의의 희소 행렬입니다.

A = sprand(100,100,.05); 

행 의미를 얻으십시오. 행에 0이 아닌 요소가없는 경우 0/0 = NaN이 올 것으로 예상되지만 그 행에는 결코 다음 단계가 적용되지 않습니다.

rowmeans = sum(A,2)./sum(A~=0,2); 

비 - 제로를 추출하십시오.

[i,j.a] = find(A); 

그리고 평균을 빼서 배열을 복원하십시오.

[n,m] = size(A); 
B = sparse(i,j,a - rowmeans(i),n,m); 

이제 테스트 해보십시오. 부동 소수점 연산이 여기에 적용된다는 것을 잊지 마십시오. 따라서 행의 평균은 정확히 0이 아니며 eps의 순서로만 나타납니다.

min(mean(B,2)) 
ans = 
    (1,1)  -1.5543e-17 

max(mean(B,2)) 
ans = 
    (1,1)  1.1657e-17 

약 오른쪽 및 완전히 벡터화 된 것 같습니다. 그 결과가 정말로 희박하고 제로 요소가 손상되지 않았다는 것을 당신을 납득시키기 위해 여기 스파이의 결과가 있습니다.

spy(B) 

spyplot.jpg

+0

[I, j.a = 찾기 (A); [i, j, a] = find (A) 여야합니다. 내가 맞습니까? – Eugenio

관련 문제