Pack Solve results into a vector

I am currently using a really easy function to get the eigenvectors of a corresponding eigenspace:

Eigenspace[mat_, ev_] :=
Solve[
(mat - IdentityMatrix[Part[Dimensions[mat], 1]] * ev) .
Table[Subscript[x, i], {i, Part[Dimensions[mat], 1]}]
== Table[0, {i, Part[Dimensions[mat], 1]}
]
]


where ev is the representation of one eigenvalue $\lambda$ of the matrix $A$. So this is basically my first function I ever wrote based on the knowledge that $E_\lambda=\ker(A-I_n\cdot\lambda)$.

My example matrix is

$$C=\frac{1}{49}\cdot \left( \begin{array}{ccc} 9 & -48 & 4 \\ 36 & 4 & -33 \\ 32 & 9 & 36 \\ \end{array} \right)$$

and I can compute Eigenspace[C, 1] and get $\left\{\left\{x_1\to \frac{x_3}{2},x_2\to -\frac{x_3}{3}\right\}\right\}$ and I do substitute $x_3$ as it is a free parameter with Eigenspace[C, 1] /. Subscript[x, 3] -> 1 and get $\left\{\left\{x_1\to \frac{1}{2},x_2\to -\frac{1}{3}\right\}\right\}$.

How can I now return with my function the appropriate eigenvector $(1/2,\;-1/3,\; 1)^T$?

-

First off, two suggestions:

• I would strongly recommend not using subscripts the way you have used. They can lead to several issues if you're not aware of how subscripts are handled (for instance, when you try to clear them). It is best to use them only for typesetting purposes. Use DownValues instead.

• Use Block to localize x so that it is not affected by prior assignments to x.

Combining these, you just need to use replacement rules in the right order to get your answer. Here's a modification of your attempt:

Clear@Eigenspace
Eigenspace[mat_, ev_] := Block[{x},
With[{vec = Table[x[i], {i, Length@mat}], n = Length@mat},
vec /. Solve[(mat - IdentityMatrix[n] ev).vec == 0 vec] /. x[n] -> 1
]
]


Eigenspace[1/49 {{9, -48, 4}, {36, 4, -33}, {32, 9, 36}}, 1]
(* {{1/2, -(1/3), 1}} *)

-

It seems to have been missed that NullSpace[] is a built-in function:

mat = {{9, -48, 4}, {36, 4, -33}, {32, 9, 36}}/49;

evs = Eigenvalues[mat]
{I, -I, 1}

NullSpace[mat - # IdentityMatrix[Length[mat]]] & /@ evs
{{{-18/13 + 14 I/13, 12/13 + 21 I/13, 1}},
{{-18/13 - 14 I/13, 12/13 - 21 I/13, 1}},
{{1/2, -1/3, 1}}}


Since NullSpace[] returns a list of vectors instead of a single vector (as it should), one might want to execute Flatten[%, 1] afterwards to get the eigenvectors as a list of vectors. Note that the result in this case matches the output of Eigenvectors[mat].

-

If you have a matrix:

Your function can be written as

Eigenspace[mat_, ev_] := Select[Transpose[Eigensystem[mat]], #[[1]] == ev &][[1, 2]]


The usage is the same:

Eigenspace[m, 1]


{1/2, -(1/3), 1}

It utilizes built-in function Eigensystem:

Grid[Eigensystem[m], Frame -> All]


So, obviously you just need:

Eigensystem[m][[2, 3]]


{1/2, -(1/3), 1}

or

Eigenvectors[m][[3]]


{1/2, -(1/3), 1}

this is why and how the Eigenspace function works. Some more elaborate cases - due to @R.M comment.

----- Case 1 - symbolic -----

m = RandomInteger[{1, 100}, {10, 10}];


pick an eigenvalue:

Eigenvalues[m][[3]]


Root[3839155271581433876 + 19229531029350717 #1 - 2777786534122499 #1^2 + 9456285206854 #1^3 + 145246087272 #1^4 - 25506275853 #1^5 - 140468898 #1^6 + 242270 #1^7 - 61201 #1^8 - 427 #1^9 + #1^10 &, 8]

and corresponding vector is

Eigenspace[m, %]


----- Case 2 - numeric -----

m = RandomReal[1, {1000, 1000}];


pick an eigenvalue:

Eigenvalues[m][[13]]


-6.12777 - 6.75546 I

and corresponding vector is

Eigenspace[m, %]


-
@R.M it works ;) See update. – Vitaliy Kaurov Sep 4 '12 at 16:46
@Vitality Hehe, I didn't realize that your grid example was only to show how it works... I thought that you were suggesting that he visually scan for the right part and pick that out, hence the comment :D – R. M. Sep 4 '12 at 17:02

Is this what you are looking for:

Eigenspace[mat_, ev_] :=
Module[{vars =
Table[Subscript[x, i], {i, Part[Dimensions[mat], 1]}]},
vars /. Solve[(mat -
IdentityMatrix[Part[Dimensions[mat], 1]]*ev).vars ==
Table[0, {i, Part[Dimensions[mat], 1]}]]]

-