Take two complex matrices depending on one variable, for example:
m1 = {{1. + 1. I, 1. - 1. I}, {a (1. + .2 I) + 2. I, 0. + 3. I}};
m2 = {{1. - 3. I, 1. - 2. I}, {a (- 1. - .2 I) + 5. I, 0. - 2. I}};
Using LinearSolve
we can find the matrix m3
satisfying m1.m3 == m2
:
m3 = Block[{a = 1. - .5 I}, LinearSolve[m1, m2]];
Block[{a = 1. - .5 I}, m1.m3 - m2] // Chop
(* {{0,0},{0,0}} *)
I want to turn this LinearSolve
into a compiled function of a
, for example as:
linSol = Hold[Compile][{{a, _Complex, 0}}, Hold[LinearSolve][m1, m2]] /. Hold[x_] :> x;
(The Hold
's are because I don't want LinearSolve
to evaluate symbolically)
Now linSol[1.-.5I]
does give the correct answer, but it does not compile properly, giving the error message
CompiledFunction::cfex: Could not complete external evaluation at instruction 7; proceeding with uncompiled evaluation. >>
Furthermore, if we either make both matrices real, or replace the second matrix by a vector, the problem disappears, i.e. if we define,
v1 = m2[[1]];
linSol2 = Hold[Compile][{{a, _Complex, 0}}, Hold[LinearSolve][m1, v1]] /. Hold[x_] :> x;
m1Re = Assuming[{a > 0}, m1 // Re // Simplify];
m2Re = Assuming[{a > 0}, m2 // Re // Simplify];
linSol3 = Hold[Compile][{{a, _Complex, 0}}, Hold[LinearSolve][m1Re, m2Re]] /. Hold[x_] :> x;
Then linSol2
and linSol3
work without any problems.
Am I missing something, or is this a bug? I took care that each numeric entry in m1
and m2
is a machine precision complex number.
I get this in version 10.4.0 on a mac with OS X.
LinearSolve
can't be compiled without a call toMainEvaluate
? This I know, but I find compiling still speeds it up, i.e. inlinSol3
which does compile, if i make it a pure function instead it is 10x slower for 40x40 matrices. But I'm not able to get this speed increase from compiling in the complex case. $\endgroup$