MATLAB 백 슬래시 연산자 는 제곱 행렬의 를 어떻게 해결 합니까?


36

내 코드 중 일부를 "스톡"MATLAB 코드와 비교했습니다. 나는 결과에 놀랐다.

샘플 코드를 실행했습니다 (Sparse Matrix)

n = 5000;
a = diag(rand(n,1));
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('Inv(A)*B');
tic;inv(a)*b;toc;

결과 :

    For a\b
    Elapsed time is 0.052838 seconds.

    For LU
    Elapsed time is 7.441331 seconds.

    For Conj Grad
    Elapsed time is 3.819182 seconds.

    Inv(A)*B
    Elapsed time is 38.511110 seconds.

고밀도 매트릭스의 경우 :

n = 2000;
a = rand(n,n);
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('For INV(A)*B');
tic;inv(a)*b;toc;

결과 :

For a\b
Elapsed time is 0.575926 seconds.

For LU
Elapsed time is 0.654287 seconds.

For Conj Grad
Elapsed time is 9.875896 seconds.

Inv(A)*B
Elapsed time is 1.648074 seconds.

도대체 어떻게 대단해?


1
MATLAB의 내장 백 슬래시, 즉 선형 방정식 시스템을위한 직접 솔버는 희소 행렬에 대해 다중 전법을 사용하므로 A \ B가 대단합니다.
Shuhao Cao

1
cise.ufl.edu/research/sparse에 있는 Tim Davis의 코드를 사용 합니다. 또한 사소한 문제가 발생하면 놀라움이 사라집니다
stali

1
"LULU"란 무엇입니까? LU 인수 분해 및 후속 직접 해결이 잘 구현 된 이유는 무엇입니까?
Jed Brown

3
@Nunoxic 어떤 구현입니까? 직접 작성 했습니까? 일반적으로 알고리즘 적으로 잘 이해되는 고성능 고밀도 선형 대수학은 최신 하드웨어에서 효율적으로 구현하기가 쉽지 않습니다. 최고의 BLAS / Lapack 구현은 해당 크기의 매트릭스에 가장 근접해야합니다. 또한 귀하의 의견으로는 LU와 가우시안 제거가 다른 알고리즘이라고 생각합니다.
Jed Brown

1
Intel MKL을 사용하여 작성된 포트란 코드를 호출합니다.
Inquest

답변:


37

Matlab에서 '\'명령은 행렬 A의 구조에 의존하고 A의 속성에 대한 검사 (작은 오버 헤드)를 포함하는 알고리즘을 호출합니다.

  1. A가 희소하고 밴딩 된 경우 밴딩 솔버를 사용하십시오.
  2. A가 상위 삼각 행렬 또는 하위 삼각 행렬 인 경우 역 치환 알고리즘을 사용하십시오.
  3. A가 대칭이고 실제 양의 대각선 요소가있는 경우 Cholesky 인수 분해를 시도하십시오. A가 희소 한 경우 먼저 재주문을 사용하여 채우기를 최소화하십시오.
  4. 위의 기준 중 어느 것도 충족되지 않으면 부분 피벗과 함께 가우시안 제거를 사용하여 일반 삼각 분해를 수행하십시오.
  5. A가 드문 경우 UMFPACK 라이브러리를 사용하십시오.
  6. A가 제곱이 아닌 경우 결정되지 않은 시스템에 대해 QR 분해를 기반으로 알고리즘을 사용하십시오.

오버 헤드를 줄이려면 Matlab에서 linsolve 명령을 사용하여 이러한 옵션 중에서 적절한 솔버를 직접 선택할 수 있습니다.


모든 요소가 0이 아닌 (높은 수준의 밀도) 10000x10000 구조화되지 않은 고밀도 매트릭스를 처리한다고 가정하면 가장 좋은 방법은 무엇입니까? 밀도가 높은 행렬에 작동하는 알고리즘 1 개를 분리하고 싶습니다. LU, QR 또는 가우시안 제거입니까?
Inquest

1
가우시안 제거가 호출되는 4 단계처럼 들립니다. 이는 성능을 향상시키기 위해 A의 구조를 이용할 수없는 가장 일반적인 경우에 해당합니다. 따라서 기본적으로 이것은 LU 인수 분해와 그 다음의 포워드 이후에 역 치환 단계입니다.
Allan P. Engsig-Karup

감사! 나는 그것이 생각할 방향을 제시한다고 생각합니다. 현재 가우시안 제거는 이러한 구조화되지 않은 문제를 해결하는 데 가장 적합합니다. 맞습니까?
Inquest

37

a\b특정 매트릭스의 기능 을보고 싶다면 spparms('spumoni',1)어떤 알고리즘에 영향을 받았는지 정확하게 설정 하고 파악할 수 있습니다 . 예를 들면 다음과 같습니다.

spparms('spumoni',1);
A = delsq(numgrid('B',256));
b = rand(size(A,2),1);
mldivide(A,b);  % another way to write A\b

출력합니다

sp\: bandwidth = 254+1+254.
sp\: is A diagonal? no.
sp\: is band density (0.01) > bandden (0.50) to try banded solver? no.
sp\: is A triangular? no.
sp\: is A morally triangular? no.
sp\: is A a candidate for Cholesky (symmetric, real positive diagonal)? yes.
sp\: is CHOLMOD's symbolic Cholesky factorization (with automatic reordering) successful? yes.
sp\: is CHOLMOD's numeric Cholesky factorization successful? yes.
sp\: is CHOLMOD's triangular solve successful? yes.

이 경우 "\"가 "CHOLMOD"를 사용하여 종료 된 것을 볼 수 있습니다.


3
내가 들어 본 적이없는 새로운 MATLAB 설정의 경우 +1 잘 연주했습니다.
제프 옥스 베리

2
고마워! 에 help mldivide있습니다.
dranxo

16

희소 행렬의 경우 Matlab은 " \"연산에 UMFPACK을 사용 합니다.이 예에서는 기본적으로 값을 통해 실행 a하고 반전 한 다음 값을 곱합니다 b. 그러나이 예제에서는을 사용 b./diag(a)하는 것이 훨씬 빠릅니다.

고밀도 시스템의 경우 백 슬래시 연산자는 조금 더 복잡합니다. 언제 수행 될지에 대한 간단한 설명이 여기에 있습니다 . 그 설명에 따르면, 귀하의 예에서 Matlab은 a\b역 치환을 사용하여 해결할 것 입니다. 일반적인 정사각 행렬의 경우 LU 분해가 사용됩니다.


등록 희소성, diag 행렬의 inv는 단순히 대각선 요소의 역수이므로 b./diag(a)는 작동하지만 a \ b는 일반적인 희소 행렬에도 훌륭하게 작동합니다. linsolve 또는 LULU (최적화 된 LU 버전)가 밀도가 높은 매트릭스의 경우 a보다 빠르지 않은 이유는 무엇입니까?
Inquest

@Nunoxic LULU는 밀도 매트릭스의 대각선 또는 삼각을 감지하기 위해 어떤 작업을 수행합니까? 그렇지 않으면 내용이나 구조에 관계없이 모든 행렬에 시간이 오래 걸립니다.
Pedro

약간. 그러나 linsolve OPT 플래그를 사용하여 구조에 대해 정의해야 할 모든 것을 정의했습니다. 그러나 a \ b가 더 빠릅니다.
Inquest

@Nunoxic, 사용자 함수를 호출 할 때마다 오버 헤드가 발생합니다. Matlab은 내부에서 백 슬래시를 위해 모든 작업을 수행합니다. 예를 들어 오버 헤드가 거의없이 분해 및 이후의 오른쪽 적용은 오버 헤드가 거의 없으므로 더 빠릅니다. 또한 테스트에서 신뢰할 수있는 타이밍을 얻으려면 하나 이상의 호출을 사용해야합니다 (예 :) tic; for k=1:100, a\b; end; toc.
Pedro

5

일반적으로 합리적인 복잡성의 희소 행렬이있는 경우 (즉, 5 포인트 스텐실 일 필요는 없지만 실제로 행당 0이 아닌 숫자의 수인 스토크 방정식의 이산화 일 수 있음) UMFPACK과 같은 희박한 직접 솔버는 일반적으로 문제가 10 만 명 이하인 경우 크롤 로프 솔버를 능가합니다.

다시 말해, 2 차원 이산화로 인한 대부분의 희소 행렬의 경우 직접 솔버가 가장 빠른 대안입니다. 알 수없는 100,000 개 이상을 빠르게 얻는 3D 문제에 대해서만 반복 솔버를 사용해야합니다.


3
이것이 어떻게 질문에 대답하는지 명확하지 않지만 전제에 문제가 있습니다. 다이렉트 솔버는 적당한 크기의 2D 문제에 대해 잘 작동하는 경향이 있지만, 다이렉트 솔버는 100k 미지수 (정점 분리기가 2D보다 훨씬 큼)가되기 전에 3D에서 어려움을 겪는 경향이 있습니다. 또한 대부분의 경우 (예 : 타원 연산자) 반복적 인 솔버가 중간 크기의 2D 문제인 경우에도 직접 솔버보다 빠를 수 있지만 그렇게하려면 상당한 노력이 필요할 수 있습니다 (예 : 올바른 재료를 사용하여 멀티 그리드 수행) .
Jed Brown

1
귀하의 문제가 합리적으로 작고 암시 적 해결사 설계에 대해 생각하고 싶지 않거나 문제가 매우 어려운 경우 (고주파 Maxwell과 같이) 귀하가 경력을 좋은 해결사 설계에 전념하고 싶지 않은 경우, 저는 희소 직접 솔버가 훌륭한 선택이라는 데 동의합니다.
Jed Brown

실제로 내 문제는 좋은 고밀도 솔버를 디자인하는 것입니다. 나는 특별한 응용 프로그램을 가지고 있지 않습니다 (따라서 구조가 없습니다). 내 코드 중 일부를 조정하여 현재 사용되는 코드와 경쟁적으로 만들고 싶었습니다. 나는 단지 a \ b에 대해 궁금했고 그것이 어떻게 내 코드에서 항상 쓰레기를 이길 수 있 었는가.
Inquest

@JedBrown : 예, 상당한 노력을 기울이면 작은 2D 문제에서도 반복 솔버가 직접 솔버를 이길 수 있습니다. 그러나 왜 그렇습니까? <100k 미지의 문제에 대해, 2D의 희소 직접 솔버는 충분히 빠릅니다. 내가 말하고 싶은 것은 : 작은 문제에 대해서는 시간을 낭비하지 말고 최상의 매개 변수 조합을 알아 내십시오. 블랙 박스를 가져 가십시오.
Wolfgang Bangerth

5 포인트 스텐실을 사용하여 100k dofs에서 "쉬운"2D 문제에 대한 희소 한 Cholesky와 (매트릭스 기반) 기하 멀티 그리드 사이에는 이미 상당한 정도의 런타임 차이가 있습니다 (~ 0.05 초와 비교하여 ~ 0.5 초). 스텐실에서 2 차 이웃 (예 : 4 차 이산화, 비선형 유 동학, 안정화 등의 선택을위한 뉴턴)을 사용하는 경우 정점 분리기의 크기가 약 두 배가되어 직접 해결 비용이 약 8 배 증가합니다 (비용은 더 많음) MG의 경우 문제에 따라 다름). 많은 시간 단계 또는 최적화 / UQ 루프에서 이러한 차이는 중요합니다.
Jed Brown
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.