이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

svds

일부 특이값과 특이 벡터

설명

예제

s = svds(A)는 행렬 A에서 가장 큰 특이값 여섯 개로 구성된 벡터를 반환합니다. svd를 사용하여 전체 특이값을 계산할 때 많은 계산량이 필요한 경우(예: 큰 희소 행렬) 이 함수를 사용하는 것이 유용합니다.

예제

s = svds(A,k)는 가장 큰 특이값 k개를 반환합니다.

예제

s = svds(A,k,sigma)sigma 값을 기반으로 하여 특이값 k개를 반환합니다. 예를 들어, svds(A,k,'smallest')는 가장 작은 특이값 k개를 반환합니다.

s = svds(A,k,sigma,Name,Value)는 하나 이상의 이름-값 쌍의 인수로 추가 옵션을 지정합니다. 예를 들어, svds(A,k,sigma,'Tolerance',1e-3)은 알고리즘에 대한 수렴 허용오차를 조정합니다.

예제

s = svds(A,k,sigma,opts)는 구조체를 사용하여 옵션을 지정합니다.

예제

s = svds(Afun,n,___)은 행렬 대신 함수 핸들 Afun을 지정합니다. 두 번째 입력 인수 nAfun에 사용된 행렬 A의 크기를 지정합니다. 선택적으로 k, sigma, opts 또는 이름-값 쌍을 추가 입력 인수로 지정할 수 있습니다.

예제

[U,S,V] = svds(___)는 좌측 특이 벡터 U, 특이값으로 구성된 대각 행렬 S, 우측 특이 벡터 V를 반환합니다. 위에 열거된 구문에 나와 있는 입력 인수를 원하는 대로 조합하여 사용할 수 있습니다.

예제

[U,S,V,flag] = svds(___)는 수렴 플래그도 반환합니다. flag0이면 모든 특이값이 수렴됩니다.

예제

모두 축소

행렬 A = delsq(numgrid('C',15))는 구간 (0 8)에 적절히 분산된 특이값을 갖는 양의 정부호 대칭 행렬입니다. 가장 큰 특이값 6개를 계산합니다.

A = delsq(numgrid('C',15));
s = svds(A)
s = 6×1

    7.8666
    7.7324
    7.6531
    7.5213
    7.4480
    7.3517

특정 개수의 가장 큰 특이값을 계산하려면 두 번째 입력값을 지정하십시오.

s = svds(A,3)
s = 3×1

    7.8666
    7.7324
    7.6531

행렬 A = delsq(numgrid('C',15))는 구간 (0 8)에 적절히 분산된 특이값을 갖는 양의 정부호 대칭 행렬입니다. 가장 작은 특이값 5개를 계산합니다.

A = delsq(numgrid('C',15));
s = svds(A,5,'smallest')
s = 5×1

    0.5520
    0.4787
    0.3469
    0.2676
    0.1334

희소 형식의 100x100 노이만 행렬을 만듭니다.

C = gallery('neumann',100);

가장 작은 특이값 10개를 계산합니다.

ss = svds(C,10,'smallest')
ss = 10×1

    0.9828
    0.9049
    0.5625
    0.5625
    0.4541
    0.4506
    0.2256
    0.1139
    0.1139
         0

0이 아닌 가장 작은 특이값 10개를 계산합니다. 행렬에 값이 0인 특이값이 1개 있기 때문에 'smallestnz' 옵션은 이 값을 생략합니다.

snz = svds(C,10,'smallestnz')
snz = 10×1

    0.9828
    0.9828
    0.9049
    0.5625
    0.5625
    0.4541
    0.4506
    0.2256
    0.1139
    0.1139

희소 행렬에서 오른쪽 위와 왼쪽 아래의 0이 아닌 블록을 나타내는 행렬 2개를 만듭니다.

n = 500;
B = rand(500);
C = rand(500);

svds와 함께 사용할 수 있도록 Afun을 현재 디렉터리에 저장합니다.

function y = Afun(x,tflag,B,C,n)
if strcmp(tflag,'notransp')
    y = [B*x(n+1:end); C*x(1:n)];
else
    y = [C'*x(n+1:end); B'*x(1:n)];
end

함수 Afun은 전체 희소 행렬 A = [zeros(n) B; C zeros(n)]을 실제로 구성하지 않고 BC를 사용하여 A*x 또는 A'*x를 계산합니다(지정된 플래그에 따라 달라짐). 이 방법은 행렬의 희소성 패턴을 활용하기 때문에 A*xA'*x 계산 시 메모리를 절약할 수 있습니다.

Afun을 사용하여 A의 가장 큰 특이값 10개를 계산합니다. 추가 입력값으로 B, C, nAfun에 전달합니다.

s = svds(@(x,tflag) Afun(x,tflag,B,C,n),[1000 1000],10)
s =

  250.3248
  249.9914
   12.7627
   12.7232
   12.6988
   12.6608
   12.6166
   12.5643
   12.5419
   12.4512

직접 A의 가장 큰 특이값 10개를 계산하여 결과를 비교합니다.

A = [zeros(n) B; C zeros(n)];
s = svds(A,10)
s =

  250.3248
  249.9914
   12.7627
   12.7232
   12.6988
   12.6608
   12.6166
   12.5643
   12.5419
   12.4512

west0479는 실수 값의 479x479 희소 행렬입니다. 이 행렬에는 큰 특이값 몇 개와 작은 특이값 여러 개가 있습니다.

west0479를 불러와서 A로 저장합니다.

load west0479
A = west0479;

A의 특이값 분해를 계산하면 가장 큰 특이값 6개와 대응하는 특이 벡터가 반환됩니다. 네 번째 출력 인수를 지정하여 특이값의 수렴을 확인합니다.

[U,S,V,cflag] = svds(A);
cflag
cflag = 0

cflag는 모든 특이값이 수렴되었음을 나타냅니다. 특이값은 출력 행렬 S의 대각선에 있습니다.

s = diag(S)
s = 6×1
105 ×

    3.1895
    3.1725
    3.1695
    3.1685
    3.1669
    0.3038

A의 전체 특이값 분해를 계산하여 결과를 확인합니다. A를 비희소 행렬로 변환하고 svd를 사용합니다.

[U1,S1,V1] = svd(full(A));

svdsvds로 계산된 A의 가장 큰 특이값 6개를 로그 스케일을 사용하여 플로팅합니다.

s2 = diag(S1);
semilogy(s2(1:6),'r.')
hold on
semilogy(s,'ro','MarkerSize',10)
title('Singular Values of west0479')
legend('svd','svds')

희소 대각 행렬을 만들고 가장 큰 특이값 6개를 계산합니다.

A = diag(sparse([1e4*ones(1, 8) 1e4:-1:1]));
s = svds(A)
Warning: Only 2 of the 6 requested singular values converged. Singular values that did not converge are NaN.
s = 6×1
104 ×

    1.0000
    0.9999
       NaN
       NaN
       NaN
       NaN

최대 반복 횟수에 도달했지만 허용오차를 충족할 수 없기 때문에 svds 알고리즘은 경고를 발생시킵니다.

수렴 문제를 해결할 수 있는 가장 효과적인 방법은 계산에 사용되는 크릴로프 부분공간의 최대 크기를 더 큰 'SubspaceDimension' 값을 사용하여 늘리는 것입니다. 이름-값 쌍 'SubspaceDimension'을 값 60으로 전달하십시오.

s = svds(A,6,'largest','SubspaceDimension',60)
s = 6×1
104 ×

    1.0000
    1.0000
    1.0000
    1.0000
    1.0000
    1.0000

유사 특이 행렬의 가장 작은 특이값 10개를 계산합니다.

rng default
format shortg
B = spdiags([repelem([1; 1e-7], [198, 2]) ones(200, 1)], [0 1], 200, 200);
s1 = svds(B,10,'smallest')
Warning: Large residual norm detected. This is likely due to bad condition of the input matrix (condition number 1.0008e+16).
s1 = 10×1

       7.0945
       7.0945
       7.0945
       7.0945
       7.0945
       7.0945
       7.0945
       7.0945
      0.25927
   7.0888e-16

경고는 svds가 적합한 특이값 계산에 실패했음을 나타냅니다. svds가 실패한 이유는 가장 작은 특이값과 두 번째로 작은 특이값 사이의 간격 때문입니다. svds(...,'smallest')는 큰 수치 오차를 발생시키는 B의 역을 구해야 합니다.

비교를 위해 svd를 사용하여 정확한 특이값을 계산합니다.

s = svd(full(B));
s = s(end-9:end)
s = 10×1

      0.14196
      0.12621
      0.11045
     0.094686
     0.078914
     0.063137
     0.047356
     0.031572
     0.015787
   7.0888e-16

svds를 사용하여 이 계산을 재현하려면 B의 QR 분해를 수행하십시오. 삼각 행렬 R의 특이값은 B의 경우와 동일합니다.

[Q,R,p] = qr(B,0);

R에 있는 각 행의 노름을 플로팅합니다.

rownormR = sqrt(diag(R*R'));
semilogy(rownormR)
hold on;
semilogy(size(R, 1), rownormR(end), 'ro')

R의 마지막 요소는 거의 0에 가깝기 때문에 해가 불안정하게 됩니다.

이러한 요소가 해의 안정성을 해치지 않도록 하려면 R의 마지막 행을 정확하게 0으로 설정하십시오.

R(end,:) = 0;

svds를 사용하여 R의 가장 작은 특이값 10개를 구합니다. 해당 결과는 svd로 구한 결과와 유사합니다.

sr = svds(R,10,'smallest')
sr = 10×1

      0.14196
      0.12621
      0.11045
     0.094686
     0.078914
     0.063137
     0.047356
     0.031572
     0.015787
            0

이 메서드를 사용하여 B의 특이 벡터를 계산하려면 Q와 치환 벡터 p를 사용하여 좌측 특이 벡터와 우측 특이 벡터를 변환하십시오.

[U,S,V] = svds(R,20,'s');
U = Q*U;
V(p,:) = V;

입력 인수

모두 축소

입력 행렬입니다. A는 항상 그렇지는 않지만 일반적으로 큰 희소 행렬입니다.

데이터형: double
복소수 지원 여부:

계산할 특이값의 개수로, 양의 정수 스칼라로 지정됩니다. 다음 조건 중 하나가 충족될 경우 svds는 요청된 개수보다 적은 특이값을 반환합니다.

  • kmin(size(A))보다 큽니다.

  • sigma = 'smallestnz'이고 kA의 0이 아닌 특이값의 개수보다 큽니다.

k가 너무 크면 svds는 이 값을 k의 유효한 최댓값으로 바꿉니다.

예: svds(A,2)A의 가장 큰 특이값 2개를 반환합니다.

특이값 유형으로, 다음 값 중 하나로 지정됩니다.

옵션설명

'largest'(디폴트 값)

가장 큰 특이값

'smallest'

가장 작은 특이값

'smallestnz'

0이 아닌 가장 작은 특이값

스칼라

스칼라에 가장 가까운 특이값

예: svds(A,k,'smallest')는 가장 작은 특이값 k개를 계산합니다.

예: svds(A,k,100)100에 가장 가까운 특이값 k개를 계산합니다.

데이터형: double | char | string

options 구조체로, 다음 표의 필드 중 하나 이상을 포함하는 구조체로 지정됩니다.

참고

옵션을 지정하는 데 options 구조체를 사용하는 것은 권장되지 않습니다. 대신 이름-값 쌍을 사용하십시오.

옵션 필드설명이름-값 쌍
tol

수렴 허용오차

'Tolerance'
maxit

최대 반복 횟수

'MaxIterations'
p

크릴로프 부분공간의 최대 크기

'SubspaceDimension'
u0

좌측 초기 시작 벡터

'LeftStartVector'
v0

우측 초기 시작 벡터

'RightStartVector'
disp

진단 정보 표시 수준

'Display'
fail출력값에서 수렴되지 않은 특이값의 처리'FailureTreatment'

참고

svds는 숫자형 스칼라 변위 sigma를 사용할 때 옵션 p를 무시합니다.

예: opts.tol = 1e-6, opts.maxit = 500은 필드 tolmaxit의 값이 설정된 구조체를 생성합니다.

데이터형: struct

행렬 함수로, 함수 핸들로 지정됩니다. 함수 Afun은 다음 조건을 충족해야 합니다.

  • Afun(x,'notransp')는 벡터 x를 받고 곱 A*x를 반환합니다.

  • Afun(x,'transp')는 벡터 x를 받고 곱 A'*x를 반환합니다.

참고

sigma = 'largest'(디폴트 값)인 경우에만 함수 핸들을 사용하십시오.

예: svds(Afun,[1000 1200])

Afun에서 사용되는 행렬 A의 크기로, 요소를 2개 가진 크기 벡터 [m n]으로 지정됩니다.

이름-값 쌍의 인수

선택적으로 Name,Value 인수가 쉼표로 구분되어 지정됩니다. 여기서 Name은 인수 이름이고 Value는 대응값입니다. Name은 따옴표 안에 표시해야 합니다. Name1,Value1,...,NameN,ValueN과 같이 여러 개의 이름-값 쌍의 인수를 어떤 순서로든 지정할 수 있습니다.

예: s = svds(A,k,sigma,'Tolerance',1e-10,'MaxIterations',100)은 수렴 허용오차를 완화하고 더 적은 반복 횟수를 사용합니다.

수렴 허용오차로, 'Tolerance'와 함께 음이 아닌 실수 숫자형 스칼라가 쉼표로 구분되어 지정됩니다.

예: s = svds(A,k,sigma,'Tolerance',1e-3)

최대 알고리즘 반복 횟수로, 'MaxIterations'와 함께 양의 정수가 쉼표로 구분되어 지정됩니다.

예: s = svds(A,k,sigma,'MaxIterations',350)

크릴로프 부분공간의 최대 크기로, 'SubspaceDimension'과 함께 음이 아닌 정수가 쉼표로 구분되어 지정됩니다. 'SubspaceDimension' 값은 k + 2보다 크거나 같아야 합니다. 여기서 k는 특이값의 개수입니다.

svds가 수렴에 실패하는 문제의 경우 'SubspaceDimension'의 값을 증가시키면 수렴 동작이 개선될 수 있습니다.

숫자형 값 sigma에 대해서는 이 옵션이 무시됩니다.

예: s = svds(A,k,sigma,'SubspaceDimension',25)

좌측 초기 시작 벡터로, 'LeftStartVector'와 함께 숫자형 벡터가 쉼표로 구분되어 지정됩니다.

'LeftStartVector''RightStartVector' 중 하나를 지정할 수 있으나, 둘 다 지정할 수는 없습니다. 어떤 옵션도 지정하지 않은 경우, mxn 행렬 A의 디폴트 값은 다음과 같습니다.

  • m < nrandn(m,1)로 설정된 좌측 초기 시작 벡터

  • m >= nrandn(n,1)로 설정된 우측 초기 시작 벡터

다른 난수 시작 벡터를 지정하는 1차적인 이유는 벡터를 생성하는 데 사용되는 난수 스트림을 제어하기 위해서입니다.

참고

svds는 프라이빗 난수 스트림을 사용하여 재현 가능한 방식으로 시작 벡터를 선택합니다. 난수 시드값을 변경해도 이러한 randn 사용에는 영향을 주지 않습니다.

예: s = svds(A,k,sigma,'LeftStartVector',randn(m,1))에서는 전역 난수 스트림에서 값을 도출하는 난수 시작 벡터를 사용합니다.

데이터형: double

우측 초기 시작 벡터로, 'RightStartVector'와 함께 숫자형 벡터가 쉼표로 구분되어 지정됩니다.

'LeftStartVector''RightStartVector' 중 하나를 지정할 수 있으나, 둘 다 지정할 수는 없습니다. 어떤 옵션도 지정하지 않은 경우, mxn 행렬 A의 디폴트 값은 다음과 같습니다.

  • m < nrandn(m,1)로 설정된 좌측 초기 시작 벡터

  • m >= nrandn(n,1)로 설정된 우측 초기 시작 벡터

다른 난수 시작 벡터를 지정하는 1차적인 이유는 벡터를 생성하는 데 사용되는 난수 스트림을 제어하기 위해서입니다.

참고

svds는 프라이빗 난수 스트림을 사용하여 재현 가능한 방식으로 시작 벡터를 선택합니다. 난수 시드값을 변경해도 이러한 randn 사용에는 영향을 주지 않습니다.

예: s = svds(A,k,sigma,'RightStartVector',randn(n,1))에서는 전역 난수 스트림에서 값을 도출하는 난수 시작 벡터를 사용합니다.

데이터형: double

수렴되지 않은 특이값의 처리로, 'FailureTreatment'와 함께 옵션 'replacenan', 'keep', 'drop' 중 하나가 쉼표로 구분되어 지정됩니다.

'FailureTreatment' 값에 따라, 수렴되지 않은 특이값이 출력값에 표시되는 방법이 결정됩니다.

옵션

출력값에 미치는 영향

'drop'

수렴되지 않은 특이값이 출력값에서 제거됩니다. 따라서 svds가 요청된 개수보다 적은 특이값을 반환할 수 있습니다. 숫자형 값 sigma에 대해서는 이 옵션이 디폴트 값입니다.

'replacenan'

수렴되지 않은 특이값이 NaN 값으로 대체됩니다. sigma가 숫자가 아닌 경우에는 언제나 이 옵션이 디폴트 값입니다.

'keep'

수렴되지 않은 특이값이 출력값에 포함됩니다.

예: s = svds(A,k,sigma,'FailureTreatment','drop')은 수렴되지 않은 특이값을 출력값에서 제거합니다.

데이터형: char | string

진단 정보 표시에 대한 토글로, false, true, 0 또는 1로 지정됩니다. 값이 false 또는 0이면 표시가 꺼지고, 값이 true 또는 1이면 표시가 켜집니다.

출력 인수

모두 축소

특이값으로, 열 벡터로 반환됩니다. 특이값은 음이 아닌 실수로, 내림차순으로 나열됩니다.

좌측 특이 벡터로, 행렬의 열로 반환됩니다. Amxn 행렬이고 사용자가 k개의 특이값을 요청한 경우, U는 정규 직교 열이 있는 mxk 행렬이 됩니다.

컴퓨터, MATLAB®의 릴리스 또는 파라미터(예: 시작 벡터 및 부분공간 차원)에 따라 각기 다른 특이 벡터가 생성될 수 있으나, 수치적으로는 다 정확합니다. UV에서 서로 대응하는 열은 부호를 뒤집을 수 있으며, 이렇게 해도 표현식 A = U*S*V'의 값에는 영향을 미치지 않습니다.

특이값으로, 대각 행렬로 반환됩니다. S의 대각선 요소는 음이 아닌 특이값입니다. Amxn 행렬이고 사용자가 k개의 특이값을 요청한 경우, Skxk가 됩니다.

우측 특이 벡터로, 행렬의 열로 반환됩니다. Amxn 행렬이고 사용자가 k개의 특이값을 요청한 경우, V는 정규 직교 열이 있는 nxk 행렬이 됩니다.

컴퓨터, MATLAB의 릴리스 또는 파라미터(예: 시작 벡터 및 부분공간 차원)에 따라 각기 다른 특이 벡터가 생성될 수 있으나, 수치적으로는 다 정확합니다. UV에서 서로 대응하는 열은 부호를 뒤집을 수 있으며, 이렇게 해도 표현식 A = U*S*V'의 값에는 영향을 미치지 않습니다.

수렴 플래그로, 스칼라로 반환됩니다. 값이 0이면 모든 특이값이 수렴되었음을 나타냅니다. 그렇지 않으면 일부 특이값이 수렴되지 않았음을 나타냅니다.

이 수렴 플래그 출력값을 사용하면 실패한 수렴에 대한 경고가 표시되지 않습니다.

  • svds는 실행 전체에 걸쳐 재현될 수 있도록 프라이빗 난수 스트림을 사용하여 디폴트 시작 벡터를 생성합니다. svds를 호출하기 전에 rng를 사용하여 난수 생성기 상태를 설정해도 출력값에는 영향을 주지 않습니다.

  • 작고 조밀한 행렬의 특이값 몇 개를 구하고자 한다면 svds를 사용하는 것이 그렇게 효율적인 방법은 아닙니다. 이러한 문제에는 svd(full(A))를 사용하는 편이 더 빠를 수도 있습니다. 예를 들어, 500x500 행렬에서 특이값 세 개를 구하는 것은 비교적 작은 문제이며 svd를 사용하여 손쉽게 처리할 수 있습니다.

  • svds가 주어진 행렬에 대해 수렴하지 못하면 'SubspaceDimension'의 값을 증가시켜 크릴로프 부분공간 크기를 늘려 보십시오. 부차적인 옵션으로 최대 반복 횟수('MaxIterations')와 수렴 허용오차('Tolerance')를 조정해도 수렴 동작에 도움이 될 수 있습니다.

  • 특히 행렬에서 특이값이 반복되는 경우에 k를 늘리면 성능이 개선될 수도 있습니다.

호환성 관련 고려 사항

모두 확장

R2016a에서 동작이 변경됨

참고 문헌

[1] Baglama, J. and L. Reichel, “Augmented Implicitly Restarted Lanczos Bidiagonalization Methods.” SIAM Journal on Scientific Computing. Vol. 27, 2005, pp. 19–42.

[2] Larsen, R. M. “Lanczos Bidiagonalization with partial reorthogonalization.” Dept. of Computer Science, Aarhus University. DAIMI PB-357, 1998.

확장 기능

참고 항목

|

도움말 항목

R2006a 이전에 개발됨