,快速显式解决方案,低条件数


9

我正在寻找一种3x3线性实数问题的快速(敢于说最佳吗​​?)显式解决方案,,。 一个X=bAR3×3,bR3

矩阵是通用的,但与单位矩阵接近,条件编号接近1。因为实际上是传感器测量值,精度约为5位,所以我不介意由于数值而损失几位问题。Ab

当然,不难得出基于多种方法的显式解决方案,但是如果已经证明某些方法在FLOPS计数方面是最佳的,那将是理想的(毕竟,整个问题可能会适合FP寄存器!)。

(是的,该例程经常被调用。我已经摆脱了低落的果实,这是我的分析列表中的下一个……)


每个仅使用一次,还是存在多个具有相同矩阵的线性系统?这将改变成本。A
Federico Poloni 2014年

在这种情况下,A仅使用一次。
Damien 2014年

Answers:


14

您无法击败明确的公式。您可以写下解决方案的公式x=A1b在一张纸上。让编译器为您优化事物。任何其他方法几乎都将不可避免地具有if语句或for循环(例如,对于迭代方法),这将使您的代码比任何直线代码都要慢。


9

由于矩阵非常接近恒等式,因此以下Neumann级数将很快收敛:

A1=k=0(IA)k

根据所需的精度,甚至可以截断2个术语就足够了:

A1I+(IA)=2IA.

这可能比直接公式要快一些(如Wolfgang Bangerth的答案所建议),但准确性要低得多。


使用3个术语可以提高准确性:

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

但是如果您为 3一世-3一个+一个2b,您正在寻找与直接3x3矩阵逆公式相当的浮点运算量(尽管您不必进行除法,这会有所帮助)。


划分仍然比其他失败者昂贵吗?我认为那是过去的遗物。
Federico Poloni 2014年

部门之间的架构不尽如人意(ARM是当代的例子)
Damien 2014年

@FedericoPoloni使用Cuda,您可以在此处看到指令吞吐量,乘法/加法的指令吞吐量是除法的六倍。
Kirill

@Damien和Kirill我明白了,谢谢你的指点。
Federico Poloni 2014年

5

FLOPS计算基于以上建议:

  • LU,无枢轴:

    • Mul = 11,Div / Recip = 6,Add / Sub = 11,Total = 28; 要么
    • Mul = 16,Div / Recip = 3,Add / Sub = 11,Total = 30
  • 高斯淘汰制,无替代:

    • Mul = 11,Div / Recip = 6,Add / Sub = 11,Total = 28; 要么
    • Mul = 16,Div / Recip = 3,Add / Sub = 11,Total = 30
  • 通过辅助因子扩展的克莱默法则

    • Mul = 24,Div = 3,Add / Sub = 15,总计= 42;要么
    • Mul = 27,Div = 1,Add / Sub = 15,总计= 43
  • 显式逆然后相乘:

    • Mul = 30,Div = 3,Add / Sub = 17,总计= 50;要么
    • Mul = 33,Div = 1,Add / Sub = 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 2014年

在LU中,可以将5个除法器转换为5个MUL,而要花费2个额外的对等运算(即1 / U11和1 / U22)。关于是否在那里取得收益,这将是特定的。
Damien 2014年

2
假设我没有算错,大概 一个-1个b 通过 2b-一个b将需要12个乘法,9个加法/减法和无除法。近似值一个-1个b 通过 3b-一个b+一个2b将需要21个乘法和18个加/减。计算中一个-1个b通过这个明确的公式看起来是33乘法,17加法/减法和1除法。就像我说的那样,我的电话可能关闭了,所以您可能需要仔细检查。
Geoff Oxberry 2014年

@GeoffOxberry,我将对其进行调查并报告。
Damien 2014年

4

可能是克莱默法则。如果可以避免旋转,则可以考虑LU分解;它是3x3矩阵,因此手动展开循环会很容易。其他任何事情都可能涉及分支,而且我怀疑Krylov子空间方法是否经常会收敛1或2次迭代,以使其值得使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.