2
$\begingroup$

I'd like to compute the kernel of a complex matrix $M$, but only allow for real solutions $x$ of the matrix equation $M\cdot x=0$. Of course just kicking out the vectors in NullSpace[M] which have complex entries does in general not work since a linear combination of those can be real. Is there a simple way to do this with Mathematica?

Here is a sample code:

myM = Uncompress[
   "1:eJxTTMoPSuNnYGAoZgESPpnFJWnKyLxMIM0wdIhRxw8nx6cxgczkABJBiSWZ+\
XmJOZn/gSCTiXquBtvADiSc83MLclIrcNnLCNKB117qBQAVHUXP4B5NvsPE8USnP5pkRnJ\
SOKUBQK+8RbMwHU2+\
Q6quoDQAhmgNQeUUMPTKKfICYMiXTjRLAfQlIOHBCiRCMnNTi8GBgRALyC9PLcrkJxBuxJ\
jBRQUz2KhgBjMxaQAAebDYew=="];
NullSpace[myM]

I'd like to project on the linearly independent real vectors that are in the null space.

$\endgroup$

2 Answers 2

3
$\begingroup$

Here is a way to get the general solution without any complex entries:

dim = Last[Dimensions[myM]];
Clear[a];
vars = Array[a, dim];
solutionVector = 
 vars /. ToRules[
   Reduce[And @@ 
     Join[Thread[Re[myM].vars == 0], Thread[Im[myM].vars == 0]], vars]]

(*
==> {a[1], a[2], a[3], 0, a[5], a[6], a[7], 0, 0, 
 a[10], 0, 0, 0, 0, 0, a[16], a[17], a[18], 0, a[20], a[21], 
 a[22], 0, 0, a[25], 0, 0, 0, 0, 0, a[31], a[32], 
 a[33], -(a[31]/Sqrt[5]) - Sqrt[3/10] a[32] - a[33]/Sqrt[2], a[35]}
*)

Simplify[myM.solutionVector]

(* ==> {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} *)

The independent real variables that can be chosen arbitrarily to get linearly independent vectors are

Variables[solutionVector]

(*
==> {a[1], a[2], a[3], a[5], a[6], a[7], a[10], a[16], a[17], 
 a[18], a[20], a[21], a[22], a[25], a[31], a[32], a[33], a[35]}
*)
$\endgroup$
1
  • $\begingroup$ Thanks, it seems to work! My example was trivial in the sense that the true solution is the same as the one obtained by just dropping the vectors with complex entries. But I checked you method in a situation where this is not the case, and it worked. $\endgroup$
    – user46676
    Commented Mar 18, 2017 at 15:19
4
$\begingroup$

After I got the above answer by @Jens, I learned an arguably even more elegant answer from Renato Fonseca, to whom I give full credit. The basic observation is that the equations $$ M\cdot x=0\quad\text{and}\quad x=x^*$$ are equivalent to $$ \text{Re}\, M\cdot x=0\quad\text{and}\quad \text{Im}\, M\cdot x=0\;.$$ This leads to the solution

myM = Uncompress["1:eJxTTMoPSuNnYGAoZgESPpnFJWnKyLxMIM0wdIhRxw8nx6cxgczkABJBiSWZ+XmJOZn/gSCTiXquBtvADiSc83MLclIrcNnLCNKB117qBQAVHUXP4B5NvsPE8USnP5pkRnJSOKUBQK+8RbMwHU2+Q6quoDQAhmgNQeUUMPTKKfICYMiXTjRLAfQlIOHBCiRCMnNTi8GBgRALyC9PLcrkJxBuxJjBRQUz2KhgBjMxaQAAebDYew=="];
myMmod = Join[Re[myM], Im[myM]];
NullSpace[myMmod]
$\endgroup$
2
  • $\begingroup$ That works, too (+1). Of course I used the same math in my answer, just didn't circle back to NullSpace... $\endgroup$
    – Jens
    Commented Mar 20, 2017 at 21:20
  • $\begingroup$ @Jens: I agree and give the credit to both of you. I guess that Fonseca's trick is slightly faster. In principle, Mathematica could multiply any vector in the kernel by i, but this does not seem to happen. $\endgroup$
    – user46676
    Commented Mar 20, 2017 at 22:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.