5
$\begingroup$

I want to compute the action of matrix exponential on a vector. My matrix $B$ is of a very large size and it is sparse, e.g., it is written as follows:

size = 350;
vector0 = Range[0., 300., 300./(size - 1)];
B0 = NDSolve`FiniteDifferenceDerivative[2, vector0, 
    "DifferenceOrder" -> 20]["DifferentiationMatrix"];

B = SparseArray@KroneckerProduct[B0, B0];
vector = Flatten@KroneckerProduct[vector0, vector0];
Dimensions[B]

Based on the documentation and the discussion in https://mathematica.stackexchange.com/questions/83730/possible-method-for-matrixexp/83732?noredirect=1#comment431557_83732, I keep going simply as comes next:

sol2 = MatrixExp[B, vector, Method -> "Krylov"]; // AbsoluteTiming

This took 31 seconds in my office laptop. It computes the action successfully, BUT it is getting slower and slower when the dimension grows. In the above example, the dimension of $B$ is $122500\times 122500$, while in my real practice I wish to compute this action for matrices of dimension up to million.

So, I wish to know that is it possible to speed up such a computation by imposing a Compile or by a tolerance or something like that? Since, I am not looking for a result which is correct up to 15 digits! A lower accuracy, maybe up to 6 digits is enough.

Any hints would be welcomed and thanks to Mr. Wizard for encouraging asking this question.

$\endgroup$
  • $\begingroup$ Is this matrix built correctly? It is not symmetric. While that is okay mathematically, it might be easier if it was symmetric... $\endgroup$ – Henrik Schumacher Dec 30 '17 at 17:59
  • $\begingroup$ Moreover, it would be nice to know what B should represent... $\endgroup$ – Henrik Schumacher Dec 30 '17 at 18:04
  • $\begingroup$ Maybe the implicit-Euler method (also known as backward-Euler) or the Crank-Nicolson method may help... $\endgroup$ – Henrik Schumacher Dec 30 '17 at 18:50
  • $\begingroup$ In general such a matrix is constructed in the process of solving high dimensional PDEs and after imposing the boundaries, which are of mixed type, the matrix does not admit a precise structure! $B$ is used as the coefficient matrix for a system of large ODEs after discretization. The above $B$ is just a simple example. I do not know what you mean with the backward-Euler here! $\endgroup$ – Fazlollah Dec 30 '17 at 19:29
  • $\begingroup$ We just know that all the eigenvalues of the matrix $B$ have negative (and zero) real parts. $\endgroup$ – Fazlollah Dec 30 '17 at 19:35
5
$\begingroup$

Let me propose a simple solution using the integration of PDE. Maybe, you try to avoid it, but I did not find such request in the question.

size = 100;
vector0 = Range[0., 300., 300./(size - 1)];
B0 = NDSolve`FiniteDifferenceDerivative[2, vector0, 
    "DifferenceOrder" -> 20]["DifferentiationMatrix"];

B = SparseArray@KroneckerProduct[B0, B0];
vector = Flatten@KroneckerProduct[vector0, vector0];
Dimensions[B]
(* {10000, 10000} *)

sol2 = MatrixExp[B, vector, Method -> "Krylov"]; // AbsoluteTiming
(* {0.205314, Null} *)


exp[m_, v_] := Module[{f, u},
  f[x_List] := m.v;
  NDSolveValue[{u'[t] == -f[u[t]], u[0] == v}, u, {t, 1, 1}][1]
  ]

sol3 = exp[B, vector]; // AbsoluteTiming
Norm[sol2 - sol3]/Norm[sol2]
(* {0.060318, Null} *)
(* 4.45283*10^-8 *)

I have reduced size because the result of MatrixExp seems to be unstable for large values of size. The proposed solution uses all cores of CPU since the multiplication of SparseArray and a vector is parallelized.

$\endgroup$
  • 1
    $\begingroup$ This is a nice response. However, the absolute error is not that accurate, but it is OK. I am just worrying that when the size grows, the MatrixExp gives a better response for me. I mean in practice, it is more reliable rather than this NDSolveValue approach. Please, write more about what is happening in the background of this approach. I still think that the solution based on your approach loses much accuracy and stability for larger values of size! $\endgroup$ – Fazlollah Dec 30 '17 at 22:14
  • $\begingroup$ @Fazlollah I'm sorry, I did a mistake because sol2 is almost the same as vector in this case. There should be f[x_List] := m.x; and u'[t] == f[u[t]]. As a result, the code becomes much slower. I have an another idea, but it takes a more time to think about it. Do you have a more reliable example of B? Moreover, it seems to me that some eigenvalues of B have positive real part. $\endgroup$ – ybeltukov Dec 31 '17 at 9:48
  • 1
    $\begingroup$ I think with correcting this typo, the final results would be better, but the point is in this way, MatrixExp[matrix,vector] is faster than your approach! I try to edit the question by giving a practical $B$. $\endgroup$ – Fazlollah Dec 31 '17 at 11:03
  • 1
    $\begingroup$ Another question is that what sort of "Krylov" method does the MMA use internally for the action in the question? GMRES, BiCGStab or something else? $\endgroup$ – Fazlollah Dec 31 '17 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.