1

I am trying to use the lusolve function from mathjs 3.8.0 to solve a linear system. However, I have some trouble interpreting the returned result with respect to the input.

I will explain based upon the example from the docs: The example sources begin

var m = [[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]];

var x = math.lusolve(m, [-1, -1, -1, -1]);        // x = [[-1], [-0.5], [-1/3], [-0.25]]

So far, so good - this represents the system

1a          = -1
   2b       = -1
      3c    = -1
         4d = -1

The solution is, obviously

a = -1
b = -0.5
c = -1/3
d = -0.25

as stated in the comment from the original example. The actual return value is an array with the values in the same order as the input vectors, i.e. [[-1], [-0.5], [-1/3], [-0.25]].

However, now I try to switch to of the input vectors:

var m = [[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 4], [0, 0, 3, 0]];

var x = math.lusolve(m, [-1, -1, -1, -1]);

I thought this should represent the system

1a          = -1
   2b       = -1
         3d = -1
      4c    = -1

If so, the solution should be

a = -1
b = -0.5
c = -0.25
d = -1/3

or [[-1], [-0.5], [-0.25], [-1/3]] in JavaScript.

However, the actual return value of the function for this input is still [[-1],[-0.5],[-1/3],[-0.25]], like with the original input vector ordering.

Why is that? How does the ordering of returned coefficients match with the ordering of input vectors?

O. R. Mapper
  • 20,083
  • 9
  • 69
  • 114
  • The second example you give is not correctly written. The matrix input given is `[[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 4], [0, 0, 3, 0]]`. If you then use `[-1, -1, -1, -1]` to solve it the input matrix can be changed to `[[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]]` with the same `[-1, -1, -1, -1]`. Since is diagonal the solution is `a=-1`, `b=-1/2`, `c=-1/3` and `d=-1/4`. You only have that small mistake :P – stringparser Jan 05 '17 at 17:24
  • @stringparser: What do you mean by "not correctly written"? I deliberately reordered the input vectors that way to check whether my understanding of the output is correct - which it apparently is not. Of course, in my actual use case, the values will not be so nicely rounded and probably will not be diagonal, either - as I wrote below, they are arbitrary vectors in a 3D scene. – O. R. Mapper Jan 05 '17 at 17:37
  • The input matrix `[[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 4], [0, 0, 3, 0]]` has a `4` in the 3rd row and a `3` in the 3rd and is written the other way around. It should also be `3c` and `4d` I think. – stringparser Jan 05 '17 at 17:46
  • Wait, I get you... you see each of the inner vectors as columns but they seem to be rows. That is, if I think of the inner vectors as columns I see how this does **not** make sense. – stringparser Jan 05 '17 at 17:52
  • Go here: http://mathjs.org/docs/datatypes/matrices.html#creation you will see the example matrix `math.matrix([[0, 1], [2, 3], [4, 5]]); /* Matrix, size [3, 2] */`. So it seems to be `rows x columns`. That is each inner vector is a row not a column. – stringparser Jan 05 '17 at 17:56
  • @stringparser: Oh, my, that's it. If you add that to your answer, I'll accept it. I guess I was too fixated on trying to find coefficients for several vectors. – O. R. Mapper Jan 09 '17 at 08:26
  • Yeah, this little things really bite. Just added it to the answer :). It could well have been the other way around too (columns x rows). – stringparser Jan 10 '17 at 14:02

1 Answers1

0

LU decomposition method returns the upper and lower triangular matrices which then might be used to solve the linear system. This means that the matrices will be reordered to have this shape (zeros under the diagonal and up of it).

For the example you give, you can see how this looks like doing:

math.lup([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]])

See math.lusolve source for more specific info.

Also note how the matrices map to a vector

http://mathjs.org/docs/datatypes/matrices.html#creation

there you will see an example matrix of

math.matrix([[0, 1], [2, 3], [4, 5]]); /* Matrix of size [3, 2] */

which means that each inner vector is a row not a column. That is:

[[0, 1], [2, 3], [4, 5]]

is written as

0 1

2 3

4 5

stringparser
  • 735
  • 1
  • 6
  • 16
  • Ok, but then how do I get back to a usable result? i.e. a set of coefficients that I can apply to my input vectors? If I decompose the matrix explicitly with [`lup`](http://mathjs.org/docs/reference/functions/lup.html), I get a permutation vector that seems promising, but that only works in cases where the coefficients are merely reordered compared to the original input vector ordering. – O. R. Mapper Jan 05 '17 at 17:11
  • The method will always give you a result in the form `[ [a], [b], [c], ... ]`. The values for `a`, `b`, ... can be extracted from that column vector. What is your use case? – stringparser Jan 05 '17 at 17:18
  • My use case is that I'm trying to decompose a vector from a 3D scene into a linear combination of three (non-parallel) vectors. My problem in particular is that in examples like the one shown in my question, I do not know how to extract the values for `a`, `b`, `c`, and `d` because I do not know which is which. In the particular example I am showing towards the end of my question, the ordering seems to be `[ [a], [b], [d], [c] ]`. – O. R. Mapper Jan 05 '17 at 17:23
  • See the comment I've left under the question. I think is just that small typo what is confusing you. `lusolve` should always return the solution in order i.e. `[ [a], [b], [c], ... ]` – stringparser Jan 05 '17 at 17:26