Skip to main content

syntax - Orthonormalization of non-hermitian matrix eigenvectors


When using Orthogonalize[] one can specify which definition of "inner product" is to be used. For example, Orthogonalize[vectors,Dot] presupposes that all values are real.


When dealing with non-hermitian matrices, the "inner product" definition (apparently) needs to be $|z|^2 = zz$, just like with real numbers.


Consider this matrix:


mat = {{0. + 1.002 I, -1}, {-1, -I}}


The following code does not orthonormalize the eigenvectors of my matrix, as can be seen:


Orthogonalize[N[Eigenvectors[mat]]];
N[%[[1]].%[[2]]]

-2.90378*10^-15 + 0.999 I

The Dot option does not work, it presents me with an error



Orthogonalize::ornfa: The second argument Dot is not an inner product function, which always should return a number or symbol. If its two numeric arguments are the same, it should return a non-negative real number.




which is not surprising, since I have complex entries.


How can I force Orthogonalize[] to use the real number inner product definition, without Dot?


I'm using the words "inner product", but feel free to correct me as it seems they're not appropriate. Maybe I should say "involution"?


EDIT


As there's a bounty on this question, I'm leaving it open until the last day it's effective. Thanks for the answers.


After talking with my supervisor, turns out we'll have to "manually" orthonormalize eigenvectors that share the same eigenvalue, since the eigenvectors are otherwise already orthonormal, as in this case:


Mathematica graphics



Answer



The way I am interpreting this question, it has nothing to do with the vectors in question being eigenvectors of any particular matrix. If this interpretation is wrong, the question needs to be clarified.



The next point is that orthogonality requires an actual scalar product, and for a complex vector space this rules out the Dot product because Dot[{I,0},{I,0}] == -1 which is obviously not positive.


Therefore, the only way that it could make sense to speak of orthogonalization with respect to the Dot product for complex vectors is that you might wish for some reason to apply the orthogonalization algorithm (e.g., Gram-Schmidt) to a set of vectors with complex entries.


Doing this is completely legitimate, but it will not lead to vectors that are orthogonal with respect to the Dot product because the Dot product is not a scalar product. It just doesn't make sense to use the term "orthogonality" in this case.


Here is a function that performs the algorithm as described:


orthoDotize[vecs_] := Module[{s, a, e, ortho},
s = Array[a, Dimensions[vecs]];
ortho = Orthogonalize[s];
ortho /. Thread[Flatten[s] -> Flatten[vecs]]
]


This function has the property that its output satisfies the expected Euclidean orthogonality relations when the vectors in the list vecs are real. If they are not real, then the dot product after "pseudo-orthogonalization" can have imaginary parts:


mat = {{0. + 1.002 I, -1}, {-1, -I}};
evecs = N[Eigenvectors[mat]];
ovecs = orthoDotize[evecs]


{{0.722734 + 0. I, -2.69948*10^-16 + 0.691127 I}, {3.67452*10^-15 + 0.691127 I, 0.722734 - 3.56028*10^-15 I}}



Chop[ovecs[[1]].ovecs[[2]]]



0. + 0.999001 I



Edit: a possible cause of confusion


However, as I mentioned in my comment to the question (March 28), it could also be that there is a mathematical misunderstanding of a different kind here: equating orthogonality with biorthogonality.


As explained on this MathWorld page, we can define left and right eigenvectors of the matrix mat, which in this case are transposes of each other because mat is symmetric. To get these (generally different) sets of eigenvectors, you can do


eR = Eigenvectors[mat];
eL = Transpose[Eigenvectors[Transpose[mat]]];

The last line follows from



$\begin{eqnarray*}\vec{x}_{L}^{\top}M & = & \lambda \vec{x}_{L}^{\top}\\\Leftrightarrow\,\,\,M^{\top}\vec{x}_{L} & = & \lambda \vec{x}_{L}\end{eqnarray*}$


Then the following holds:


eL.eR // Chop


$\begin{pmatrix}0.0446879 & 0\\0 & 0.0446879\end{pmatrix}$



The appearance of the diagonal matrix here means that the rows of the matrix eL (the left eigenvectors) are orthogonal to the columns of eR (the right eigenvectors) in the sense of the matrix product. This is automatically true, and there is no need to do any further orthogonalization.


Edit 2


In case it needs further clarification: for any symmetric matrix mat we have that Transpose[eR] == eL. This implies that Transpose[eR].eR is diagonal (see above) and therefore eR[[1]].eR[[2]] == 0. That's why there is no need for any further orthogonalization in the example given in the question.



Edit 3


If mat is not symmetric, then its (right) eigenvectors are not orthogonal in the dot multiplication sense. Forming any kind of linear combination of those eigenvectors with the intention of orthogonalizing them will lead to new vectors which in general are no longer eigenvectors (unless the vectors in question share the same eigenvalue). So the orthogonalization idea is either trivial (for symmetric matrices) or violates the eigenvector property (for general non-symmetric matrices with non-degenerate spectrum).


Comments

Popular posts from this blog

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Adding a thick curve to a regionplot

Suppose we have the following simple RegionPlot: f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}] Now I'm trying to change the curve defined by $y=g[x]$ into a thick black curve, while leaving all other boundaries in the plot unchanged. I've tried adding the region $y=g[x]$ and playing with the plotstyle, which didn't work, and I've tried BoundaryStyle, which changed all the boundaries in the plot. Now I'm kinda out of ideas... Any help would be appreciated! Answer With f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 You can use Epilog to add the thick line: RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}, PlotPoints -> 50, Epilog -> (Plot[g[x], {x, 0, 2}, PlotStyle -> {Black, Thick}][[1]]), PlotStyle -> {Directive[Yellow, Opacity[0.4]], Directive[Pink, Opacity[0.4]],