求解约束线性方程组

时间:2017-04-06 19:17:32

标签: matrix fortran linear-algebra lapack fortran95

我有一个形式为 y = Ax + b 的方程组,其中 y x b 是n×1个向量, A 是×n(对称)矩阵。

所以这就是皱纹。并非所有 x 都是未知。指定了 x 的某些行,并且 y 的相应行未知。以下是一个例子

| 10  |   |  5  -2  1 | | * |   | -1 |
|  *  | = | -2   2  0 | | 1 | + |  1 |
|  1  |   |  1   0  1 | | * |   |  2 |

其中*表示未知数量。

我已经为Fortran中的上述问题构建了一个求解器,但是我想知道是否是一个体面的强大求解器,作为Lapack或MLK 的一部分用于解决这些类型的问题?

我的求解器基于一个名为pivot = [1,3,2]的排序矩阵,根据已知和未知的方法重新排列 x y 向量

| 10  |   |  5  1 -2 | | * |   | -1 |
|  1  |   |  1  1  0 | | * | + |  2 |
|  *  |   | -2  0  2 | | 1 |   |  1 |

使用块矩阵解决方案& LU分解

! solves a n×n system of equations where k values are known from the 'x' vector
function solve_linear_system(A,b,x_known,y_known,pivot,n,k) result(x)
use lu
integer(c_int),intent(in) :: n, k, pivot(n)
real(c_double),intent(in) :: A(n,n), b(n), x_known(k), y_known(n-k)
real(c_double) :: x(n), y(n), r(n-k), A1(n-k,n-k), A3(n-k,k), b1(n-k)
integer(c_int) :: i, j, u, code, d, indx(n-k)

    u = n-k
    !store known `x` and `y` values
    x(pivot(u+1:n)) = x_known
    y(pivot(1:u)) = y_known

    !define block matrices
    ! |y_known| = | A1  A3 | |    *    | + |b1|
    | |   *   | = | A3` A2 | | x_known |   |b2|

    A1 = A(pivot(1:u), pivot(1:u))
    A3 = A(pivot(1:u), pivot(u+1:n))
    b1 = b(pivot(1:u))

    !define new rhs vector
    r = y_known -matmul(A3, x_known)-b1

    % solve `A1*x=r` with LU decomposition from NR book for 'x'
    call ludcmp(A1,u,indx,d,code)
    call lubksb(A1,u,indx,r)

    % store unknown 'x' values (stored into 'r' by 'lubksb')
    x(pivot(1:u)) = r

end function

对于上面的示例,解决方案是

    | 10.0 |        |  3.5 | 
y = | -4.0 |    x = |  1.0 |
    |  1.0 |        | -4.5 |

PS。线性系统通常具有n<=20方程式。

2 个答案:

答案 0 :(得分:1)

只有未知数的问题是线性最小二乘问题

可以使用等式约束(修复某些变量)引入您的先验知识,将其转换为线性等式约束最小二乘问题

在lapack中确实存在一个解决后者的算法,称为 xGGLSE

Here is some overview

(看起来,你需要在你的情况下将b乘以-1以与定义兼容)

编辑:在进一步检查时,我错过了y中的未知数。哎哟。这很糟糕。

答案 1 :(得分:0)

首先,我会将您的系统重写为AX = b形式,其中A和b是已知的。在你的例子中,如果我没有犯任何错误,它会给出:

    5 0 1     x1         13
A = 2 1 0 X = x2 and b =  3
    1 0 1     x3         -1

然后您可以使用来自各种库的大量方法,例如LAPACK或BLAS,具体取决于矩阵A的属性(正定,...)。作为一个起点,我建议一个简单的方法,直接反转矩阵A,特别是如果你的矩阵很小。还有许多迭代方法(Jacobi,Gradients,Gauss seidel ......),您可以将它们用于更大的案例。

修改:分两步解决问题的想法

第一步:您可以在2个子系统中重写您的系统,其中X和Y为unknows但维度等于每个向量中的未知数。 X中的第一个子系统将是AX = b,可以通过直接或迭代方法求解。

第二步:一旦你知道X,Y中的第二个系统可以直接解析,因为Y将以Y = A&#39; X + b&#39;的形式表示。

我认为这种方法更为通用。