Author Topic: Yet another matrices question  (Read 4829 times)

Offline lómbido

  • Newcomer
  • Posts: 15
Yet another matrices question
« on: 2015 January 05 02:13:15 »
Good morning,

Sorry if the subject is not new but I am very new on this. I have started a script (my first script), which is very nice because inmediately you can develop a dialog and begin to work. I have reached a point where I have to invert three big sparse matrices (size of the image per color). I am very used to do it in C++. My question is, is there a nice PJSR method?,  may I connect Javascript to C++ and go back to Javascript, how? Should I have taken PCL C++ since the beginning, how?

Many thanks

Offline mschuster

  • PTeam Member
  • PixInsight Jedi
  • *****
  • Posts: 1087
Re: Yet another matrices question
« Reply #1 on: 2015 January 05 08:26:08 »
Maybe this will help.

Check out Array Math.svd(Matrix A) which computes the singular value decomposition of A (square or rectangular). Here is a recap from PTVF Numerical Recipes book:

[u, w, v] = Math.svd(a). u, w,  and v form a decomposition of a. u and v are orthogonal, w is a vector that represents a diagonal matrix, a = u.diag(w).transpose(v). Since u and v are orthogonal, inverse(a) is easy to compute inverse(a) = v.diag(1/w).transpose(u). If a is singular or near singular some wi values may be zero or near zero, so 1/wi may be undefined. Solution, amazingly, is to simply replace 1/wi by zero when wi is zero or near zero. This replacement is controlled by a tolerance (i.e. like 1e-10).

Here is code that returns the so-called pseudo inverse. Tested to solve over-determined systems (least squares solutions to over-determined linear systems) on ~30 x 100k matricies with good performance.

Mike

Code: [Select]
   // Gives the pseudo inverse, singular values smaller than threshold will be dropped.
   function pseudoInverse(matrix, threshold) {
      var svd = Math.svd(matrix);
      var u = svd[0];
      var w = svd[1];
      var v = svd[2];

      var iw = new Matrix(w.length, w.length);
      for (var row = 0; row != w.length; ++row) {
         for (var col = 0; col != w.length; ++col) {
            iw.at(row, col, row == col ? Math.abs(w.at(row)) < threshold ? 0 : 1 / w.at(row) : 0);
         }
      }

      return v.mul(iw).mul(u.transpose());
   };
« Last Edit: 2015 January 05 10:52:30 by mschuster »

Offline lómbido

  • Newcomer
  • Posts: 15
Re: Yet another matrices question
« Reply #2 on: 2015 January 05 16:03:32 »
Hello Mike,
many thanks for your answer. I will try it of course. SVD is a very nice algorithm valid also for non square matrices as you say, providing the pseudo inverse matrix. This is not my case, I have a square and invertible matrix very large and sparse. I am not sure how time consuming will be the SVD algorithm, if the picture is taken with 3500 pixels width and 2500 pixels height, the matrix to invert is (3000x2500)x(3000x2500). If your proposal works quick, I will use it, if not, taking advantage of the sparsity, I would like to use MUMPS, a multifrontal parallel algorithm with a sorting algorithm first, like metis, parmetis or pord. I will let you know.

Best regards.

Offline mschuster

  • PTeam Member
  • PixInsight Jedi
  • *****
  • Posts: 1087
Re: Yet another matrices question
« Reply #3 on: 2015 January 05 16:15:45 »
IMO you will need to exploit sparsity on a problem that big.
Mike