5

I have a system of equations of the form y=Ax+b where y, x and b are n×1 vectors and A is a n×n (symmetric) matrix.

So here is the wrinkle. Not all of x is unknown. Certain rows of x are specified and the corresponding rows of y are unknown. Below is an example

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

where * designates unknown quantities.

I have built a solver for problems such as the above in Fortran, but I wanted to know if there is a decent robust solver out-there as part of Lapack or MLK for these types of problems?


My solver is based on a sorting matrix called pivot = [1,3,2] which rearranges the x and y vectors according to known and unknown

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

and the solving using a block matrix solution & LU decomposition

! 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

For the example above the solution is

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

PS. The linear systems have typically n<=20 equations.

John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • the usual approach is to perform the required algebraic manipulation to put the system into standard form, then use a standard solver. – agentp Apr 17 '17 at 15:22
  • @agentp I think this is what I show above. I re-arrange the equations in block form in order to bring it into `Ax=b` form. But, is there common way to do this. To me this is general enough problem to warrant more formalism. – John Alexiou Apr 17 '17 at 17:13

2 Answers2

1

The problem with only unknowns is a linear least squares problem.

Your a-priori knowledge can be introduced with equality-constraints (fixing some variables), transforming it to an linear equality-constrained least squares problem.

There is indeed an algorithm within lapack solving the latter, called xGGLSE.

Here is some overview.

(It also seems, you need to multiply b with -1 in your case to be compatible with the definition)

Edit: On further inspection, i missed the unknowns within y. Ouch. This is bad.

sascha
  • 32,238
  • 6
  • 68
  • 110
  • @ja72 You got an solution to share for your example above? (i'm not really a fortran-user) – sascha Apr 17 '17 at 14:12
  • The solution is `x_1 = 3.5`, `x_3=-4.5` and `y_2=-4.0`. The algo doesn't really need to be Fortran, although most linear solvers are. – John Alexiou Apr 17 '17 at 19:18
0

First, i would rewrite your system into a AX=b form where A and b are known. In your example, and provided that i didn't make any mistakes, it would give :

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

Then you can use plenty of methods coming from various libraries, like LAPACK or BLAS depending on the properties of your matrix A (positive-definite ,...). As a starting point, i would suggest a simple method with a direct inversion of the matrix A, especially if your matrix is small. There are also many iterative approach ( Jacobi, Gradients, Gauss seidel ...) that you can use for bigger cases.

Edit : An idea to solve it in 2 steps

First step : You can rewrite your system in 2 subsystem that have X and Y as unknows but dimension are equals to the numbers of unknowns in each vector. The first subsystem in X will be AX = b which can be solved by direct or iterative methods.

Second step : The second system in Y can be directly resolved once you know X cause Y will be expressed in the form Y = A'X + b'

I think this approach is more general.

Fryz
  • 2,119
  • 2
  • 25
  • 45
  • Are you aware that *"Not all of `x` is unknown"*? – Vladimir F Героям слава Apr 24 '17 at 10:27
  • in the rewritten form x2 is the unknown in the Y vector and x1, x3 are unknown in the X vector. – Fryz Apr 24 '17 at 10:35
  • Perhaps you could describe how you did that as it is the most important part of your answer? – Vladimir F Героям слава Apr 24 '17 at 10:55
  • This seems like an ad-hoc solution and not a systematic way of dealing with these problems. Please describe the process to calculate the new `A` matrix and new `y` vector. – John Alexiou Apr 24 '17 at 12:57
  • Well it's actually quiet easy, you first replace unknows "*" with x1,x2,x3 ( or whatever names you want to give ) and then you write the system into 3 equations ( one for each dimension ). Finally, this system of 3 equations is easy to rewrite in a more convenient form by factorizing and grouping the terms in their appropriate place , after you just need to rewrite it in the vectorial form. – Fryz Apr 24 '17 at 13:00
  • 1
    IMHO, there is no systematic way to rearrange a linear system into another that is more convenient to solve. However some formal calculus softwares like Mathematica, Maple, Maxima can do some refactoring even for complex equations but i don't know if you can use them in this particular case – Fryz Apr 24 '17 at 13:06
  • I know it is easy for a symbolic solver, but I want systematic numeric solver (algo or library) given the information of `A`, `b`, `x_knowns`, `y_knowns` and which rows have which. – John Alexiou Apr 24 '17 at 13:06
  • One approach to combine the symbolic and numerical is to use a symbolic system to do the rearrangement and generate the problem that can be solved by the numerical system. Of course that makes more sense if the same problem needs to be solved over and over. – Robert Dodier Apr 24 '17 at 14:37
  • This sounds similar to the solution I proposed in my question as an example where the equations are re-arranged and then partitioned into two subsystems. The solution solves `A1*x_unknown = (b1-A3*x_known)` first and then `y= A*x+b` in the end. – John Alexiou Apr 24 '17 at 19:43