빠른 명시 적 솔루션


9

3x3 선형 실제 문제인 빠른 (최적이라고 말합니까?) 명시 적 솔루션을 찾고 있습니다. Ax=b, AR3×3,bR3.

매트릭스 A 일반적이지만 조건 번호가 1에 가까운 항등 행렬에 가깝습니다. b 실제로 약 5 자리의 정밀도로 센서를 측정하는 경우 수치 문제로 인해 여러 자리를 잃어 버릴 염려가 없습니다.

물론, 여러 방법을 기반으로 명시 적 솔루션을 제시하는 것은 어렵지 않지만 FLOPS 수 측면에서 최적의 것으로 나타난 것이 이상적입니다 (결국 전체 문제). FP 레지스터에 적합 할 것입니다!).

(예,이 루틴은 종종 호출 됩니다 . 나는 이미 낮은 교수형 과일을 제거했으며 이것이 프로파일 링 목록의 다음입니다 ...)


각각 A한 번만 사용되거나 동일한 매트릭스를 가진 여러 선형 시스템이 있습니까? 이것은 비용을 변화시킬 것입니다.
Federico Poloni

이 경우 A는 한 번만 사용됩니다.
Damien

답변:


14

당신은 명백한 공식을 이길 수 없습니다. 솔루션의 공식을 적을 수 있습니다x=A1b한 장의 종이에. 컴파일러가 여러분을 위해 최적화하도록하십시오. 다른 방법은 거의 모든 직선 코드보다 코드를 느리게하는 if명령문 또는 for루프 (예 : 반복적 인 방법)가 불가피 합니다.


9

매트릭스는 동일성에 매우 가깝기 때문에 다음 Neumann 시리즈는 매우 빠르게 수렴됩니다.

A1=k=0(IA)k

필요한 정확도에 따라 2 개의 용어 후에 잘릴 수도 있습니다.

A1I+(IA)=2IA.

정확도는 떨어지지 만 직접 수식보다 약간 빠를 수 있습니다 (Wolfgang Bangerth의 답변에서 제안한대로).


세 가지 용어로 더 정확한 결과를 얻을 수 있습니다.

A1I+(IA)+(IA)2=3I3A+A2

그러나 당신이 항목 별 입력 공식을 작성하는 경우 (3I3A+A2)b, 당신은 직접 3x3 행렬 역 공식 으로 비교할만한 양의 부동 소수점 연산을보고 있습니다 (분할을 할 필요가 없으므로 조금 도움이됩니다).


다른 플롭보다 디비전이 여전히 더 비쌉니까? 나는 그것이 과거의 유물이라고 생각했다.
Federico Poloni

부서는 일부 아키텍처 중 하나를 잘 파이프 라인하지 않습니다 (ARM은 현대적인 예입니다)
Damien

@FedericoPoloni Cuda를 사용하면 여기 에서 명령어 처리량을 볼 수 있습니다 . 나누기 / 더하기의 경우 나누기보다 6 배 더 높습니다.
Kirill

@Damien과 Kirill은 포인터에 감사드립니다.
Federico Poloni 2013

5

FLOPS는 위의 제안에 따라 계산됩니다.

  • LU, 피벗 없음 :

    • Mul = 11, Div / Recip = 6, Add / Sub = 11, Total = 28; 또는
    • Mul = 16, Div / Recip = 3, 추가 / 하위 = 11, 총계 = 30
  • 역 치환이 가능한 가우시안 제거, 피벗 없음 :

    • Mul = 11, Div / Recip = 6, Add / Sub = 11, Total = 28; 또는
    • Mul = 16, Div / Recip = 3, 추가 / 하위 = 11, 총계 = 30
  • 보조 인자 확장을 통한 크 래머의 규칙

    • 뮬 = 24, Div = 3, 추가 / 구간 = 15, 총계 = 42; 또는
    • 뮬 = 27, Div = 1, 추가 / 하위 = 15, 총계 = 43
  • 그런 다음 명시 적 역수를 곱합니다.

    • 뮬 = 30, Div = 3, 추가 / 서브 = 17, 총계 = 50; 또는
    • 뮬 = 33, Div = 1, 추가 / 하위 = 17, 총계 = 51

MATLAB 개념 증명 :

보조 인자 확장을 통한 크 래머 규칙 :

function k = CramersRule(A, m)
%
% FLOPS:
%
% Multiplications:        24
% Subtractions/Additions: 15
% Divisions:               3
%
% Total:                  42

a = A(1,1);
b = A(1,2);
c = A(1,3);

d = A(2,1);
e = A(2,2);
f = A(2,3);

g = A(3,1);
h = A(3,2);
i = A(3,3);

x = m(1);
y = m(2);
z = m(3);

ei = e*i;
fh = f*h;

di = d*i;
fg = f*g;

dh = d*h;
eg = e*g;

ei_m_fh = ei - fh;
di_m_fg = di - fg;
dh_m_eg = dh - eg;

yi = y*i;
fz = f*z;

yh = y*h;
ez = e*z;

yi_m_fz = yi - fz;
yh_m_ez = yh - ez;

dz = d*z;
yg = y*g;

dz_m_yg = dz - yg;
ez_m_yh = ez - yh;


det_a = a*ei_m_fh - b*di_m_fg + c*dh_m_eg;
det_1 = x*ei_m_fh - b*yi_m_fz + c*yh_m_ez;
det_2 = a*yi_m_fz - x*di_m_fg + c*dz_m_yg;
det_3 = a*ez_m_yh - b*dz_m_yg + x*dh_m_eg;


p = det_1 / det_a;
q = det_2 / det_a;
r = det_3 / det_a;

k = [p;q;r];

LU (피벗 없음) 및 역 치환 :

function [x, y, L, U] = LUSolve(A, b)
% Total FLOPS count:     (w/ Mods)
%
% Multiplications:  11    16
% Divisions/Recip:   6     3
% Add/Subtractions: 11    11
% Total =           28    30
%

A11 = A(1,1);
A12 = A(1,2);
A13 = A(1,3);

A21 = A(2,1);
A22 = A(2,2);
A23 = A(2,3);

A31 = A(3,1);
A32 = A(3,2);
A33 = A(3,3);

b1 = b(1);
b2 = b(2);
b3 = b(3);

L11 = 1;
L22 = 1;
L33 = 1;

U11 = A11;
U12 = A12;
U13 = A13;

L21 = A21 / U11;
L31 = A31 / U11;

U22 = (A22 - L21*U12);
L32 = (A32 - L31*U12) / U22;

U23 = (A23 - L21*U13);

U33 = (A33 - L31*U13 - L32*U23);

y1 = b1;
y2 = b2 - L21*y1;
y3 = b3 - L31*y1 - L32*y2;

x3 = (y3                  ) / U33;
x2 = (y2 -          U23*x3) / U22;
x1 = (y1 - U12*x2 - U13*x3) / U11;

L = [ ...
    L11,   0,   0;
    L21, L22,   0;
    L31, L32, L33];

U = [ ...
    U11, U12, U13;
      0, U22, U23;
      0,   0, U33];

x = [x1;x2;x3];
y = [y1;y2;y3];

명시 적 역수 : 곱하기 :

function x = ExplicitInverseMultiply(A, m)
%
% FLOPS count:                  Alternative
%
% Multiplications:        30            33
% Divisions:               3             1
% Additions/Subtractions: 17            17
% Total:                  50            51


a = A(1,1);
b = A(1,2);
c = A(1,3);

d = A(2,1);
e = A(2,2);
f = A(2,3);

g = A(3,1);
h = A(3,2);
i = A(3,3);

ae = a*e;
af = a*f;
ah = a*h;
ai = a*i;

bd = b*d;
bf = b*f;
bg = b*g;
bi = b*i;

cd = c*d;
ce = c*e;
cg = c*g;
ch = c*h;

dh = d*h;
di = d*i;

eg = e*g;
ei = e*i;

fg = f*g;
fh = f*h;

dh_m_eg = (dh - eg);
ei_m_fh = (ei - fh);
fg_m_di = (fg - di);

A = ei_m_fh;
B = fg_m_di;
C = dh_m_eg;
D = (ch - bi);
E = (ai - cg);
F = (bg - ah);
G = (bf - ce);
H = (cd - af);
I = (ae - bd);

det_A = a*ei_m_fh + b*fg_m_di + c*dh_m_eg;

x1 =  (A*m(1) + D*m(2) + G*m(3)) / det_A;
x2 =  (B*m(1) + E*m(2) + H*m(3)) / det_A;
x3 =  (C*m(1) + F*m(2) + I*m(3)) / det_A;

x = [x1;x2;x3];

가우시안 제거 :

function x = GaussianEliminationSolve(A, m)
%
% FLOPS Count:      Min   Alternate
%
% Multiplications:  11    16
% Divisions:         6     3
% Add/Subtractions: 11    11
% Total:            28    30
%

a = A(1,1);
b = A(1,2);
c = A(1,3);

d = A(2,1);
e = A(2,2);
f = A(2,3);

g = A(3,1);
h = A(3,2);
i = A(3,3);

b1 = m(1);
b2 = m(2);
b3 = m(3);

% Get to echelon form

op1 = d/a;

e_dash  = e  - op1*b;
f_dash  = f  - op1*c;
b2_dash = b2 - op1*b1;

op2 = g/a;

h_dash  = h  - op2*b;
i_dash  = i  - op2*c;
b3_dash = b3 - op2*b1; 

op3 = h_dash / e_dash;

i_dash2  = i_dash  - op3*f_dash;
b3_dash2 = b3_dash - op3*b2_dash;

% Back substitution

x3 = (b3_dash2                  ) / i_dash2;
x2 = (b2_dash        - f_dash*x3) / e_dash;
x1 = (b1      - b*x2 -      c*x3) / a;

x = [x1 ; x2 ; x3];

참고 : 이 게시물에 자신의 방법과 개수를 자유롭게 추가하십시오.


두 가지 방법으로 해결하는 데 걸리는 시간을 계산 했습니까?
nicoguaro

아니요. 위 코드는 전혀 빠르게 실행되지 않습니다. 중요한 점은 명시적인 FLOPS 수를 얻고 무언가를 놓친 경우 검토 할 코드를 제공하는 것이 었습니다.
Damien

LU에서 5 개의 부서는 2 개의 추가 상호 연산 (1 / U11 및 1 / U22)을 희생하여 5 개의 MUL로 변환 될 수 있습니다. 그것은 거기에 이익이 있는지에 대해 아치에 따라 다릅니다.
Damien

2
내가 잘못 계산하지 않았다고 가정하면 근사치 A1b 으로 2bAb12 곱하기, 9 더하기 / 빼기, 나누기가 필요하지 않습니다. 근사A1b 으로 3(bAb)+A2b21 곱하기와 18 더하기 / 빼기가 필요합니다. 계산A1b통해 이 명시 화학식 보이는 승산 33, 17 가산 / 감산하고, 1 분할한다. 내가 말했듯이 내 번호가 꺼져있을 수 있으므로 다시 확인하고 싶을 수도 있습니다.
Geoff Oxberry

@GeoffOxberry, 나는 그것을 조사하고보고 할 것입니다.
Damien

4

아마도 Cramer 's Rule. 피봇을 피할 수 있다면 LU 인수 분해 일 수 있습니다. 3x3 행렬이므로 루프를 수동으로 풀면 쉽습니다. 다른 것은 아마도 분기와 관련이있을 것입니다 .Krylov 하위 공간 방법이 가치가 있기 위해 1 ~ 2 회 반복하여 충분히 수렴하는 것이 의심됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.