Sort eigenvalue matrix with eigenvector matrix - sorting

I have N eigenvalues in column vector form.
Thus there are N eigenvectors corresponding to these eigenvalues, forming an eigenvector matrix.
Now, the problem I am working on requires me to sort the eigenvalues column vector in descending order. How do I sort the eigenvectors matrix in the same order as their eigenvalues in order to preserve correspondence?

For example,
m = RandomReal[{0, 1}, {5, 5}];
{evals, evecs} = Eigensystem[m];
SortBy[Transpose[{evals, evecs}], First]
or if you want them in the same form, replace the last line by
Transpose#SortBy[Transpose[{evals, evecs}], First]
EDIT: while I used {evals,evecs}=Eigensystem[m], that's not necessary. I could just have used s=Eigensystem[m] and then used s wherever I currently have {evals,evecs}.

While #acl and #yoda's ways of sorting (i.e. pairing the list elements then sorting together) is easy and commonly used, I'd like to show another generic method to easily sort an arbitrary number of lists based on one particular list (list1):
oo = Ordering[list1]; (* this finds the sorting order of list1 *)
list1[[oo]]
list2[[oo]]
list3[[oo]] (* these order some other lists in the same way *)

You can use the Sort function to sort the eigensystem according to the eigenvalues.
mat = (#*Transpose##) &#RandomReal[NormalDistribution[], {4, 4}];
eigsys = Sort#Transpose#Eigensystem[mat];
Sort's default behavior is to sort by the first column.

Using Mathematica:
matrix = RandomReal[{0, 1}, {4, 4}];
{evals, evecs} = Chop[Transpose[Sort[Transpose[Eigensystem[matrix]]]]];
OutPut:
evals
{-0.296769, 0.187003, 0.52714, 2.00376}
evecs
{{-0.412673,0.844056,-0.0718614,-0.334823},
{-0.370973, -0.472126, 0.76248, 0.241042},
{-0.253163, 0.1719, -0.786782, 0.536034},
{0.557741, 0.381364, 0.65039, 0.347102}}

Related

Arranging diagonal matrix in ascending order

I have a diagonal matrix and a matrix of same dimensions. How do I arrange the diagonal matrix in ascending order and then do the same steps on the other matrix ? For example if my matrix is 3 x 3, and I have to swap the 1st and 2nd column entries in diagonal to make it ascending, how do I apply this same set of steps to the other matrix but here I swap the whole 1st and 2nd column?
I thought about using some kind of merge sort but then it will not arrange the values on the diagonals. How do I do that ?
To sort a set of values, you usually have to reorder them. You can do so by sorting the directly, but you can also sort them indirectly, by first computing a sequence of indices which tells you how you would reorder the sequence. In Python, this sequence can be obtained by the numpy.argsort method. Once you have the sequence, you can apply it to sort your set of numbers, but you can also use it to rearrange any array of values in the same way. Here is an example:
import numpy as np
# construct example matrices
n = 4
D = np.diag(np.random.rand(n))
A = np.random.rand(n,n)
# obtain a sequence of indices that would sort the array.
idx = np.argsort(np.diag(D))
# order the diagonal entries according to the sequence
Dp = np.diag(np.diag(D)[idx])
# order the columns according to the sequence
Ap = A[:,idx]
print('idx')
print(idx)
print('D:')
print(D)
print('Dp:')
print(Dp)
print('A:')
print(A)
print('Ap:')
print(Ap)
Note, in Matlab the index sequence that sorts a sequence is given in the second return value of the sort function.

Create NxN matrix mathematica

Having a bit of trouble generating an NxN matrix in Mathematica. Given the value of N, I need to construct the NxN matrix that looks like the following:
N = Input["Enter value for N:"];
matrix = ConsantArray[0,{N,N}];
Do[matrix[[i,j]] = **"???"** ,{i,N}, {j,N}]
matrix // Matrix Form
Not sure in what should go as my statement in Do-Loop. Any help would appreciate it.
You could create a 1D array [1 ... n2] and then reshape or partition it to a matrix.
matrix = ArrayReshape[Range[n^2], {n, n}]
(* also works: *)
matrix = Partition[Range[n^2], n]
a couple more ways.
matrix=Table[j+(i-1) n,{i,n},{j,n}]
matrix=Array[#2+(#1-1) n &,{n,n}]
the Table form should give a clue how to fix your Do as well, but that's usually a poor approach performance-wise.
do not use capital N by the way its a reserved symbol.

Eigensystem Sort in Wolfram Mathematica

I'm trying to implement in Mathematica a method for analytical solution of reaction kinetics.
Numerically it is not a problem but in a symbolic form, one have to rearrange by hand columns of EigenVectors in order to get the "right" result.
Please check www.biokin.com/tools/pdf/Koro11-Kinetics-Maple-Chap2.pdf, page 41-44 for example.
I'm using a matrix
K={{-k1 - k2, 0, 0, 0}, {k1, 0, 0, 0}, {k2, 0, -k3, k4}, {0, 0, k3, -k4}}
as pointed out in example on page 43. {vals,vect}=Eigensystem[K] gives a different answer.
As a result my final solution vect.DiagonalMatix[Exp[vals]].Inverse[vect] is a mess.
Is there way to Sort the answer when it is in symbolic form? Or how to "force" Mathematica, not to arrange Eigenvalues and Eigenvectors?
The sorting of Eigenvalues and Eigenvectors is entirely arbitrary, the important part is that that you get the right ones together.
The issue with your code is that vect is a list of the eigenvectors, which when you use it as a matrix is a matrix whose rows are the eigenvectors, whereas you need a matrix whose columns are the eigenvectors. Use Transpose to fix this. Once you've done this, if you simultaneously permute the eigenvectors and eigenvalues nothing changes:
randsamp = RandomSample[Range[4]];
vals[[randsamp]]
Transpose#vect[[randsamp]].DiagonalMatrix[Exp[vals[[randsamp]] t]].Inverse[
Transpose#vect[[randsamp]]] // Simplify
Also there is a specific stack exchange site for Mathematica: http://mathematica.stackexchange.com

How to apply function involving elements in a column of a table

I have a n x m matrix of data.
How do I create a function that has a sum that includes elements of each column, such that if I input a value, I would get a 1 x m row (where m > 100)?
More specifically, I am computing a discrete Fourier transform of the data in each column that should work for any input frequency I put in.
Here is my code for a single column:
(* Length of time data *)
n = Length[t]
(* Compute discrete fourier transform at specified frequency f *)
DFT[f_] := (t[[2]] - t[[1]]) Sum[
mat[[i + 1]] * Exp[2 Pi I f mat[[i + 1]]], {i, 0, n - 1}];
I'd like to extend this to m columns so that if I want to compute the DFT for a given column at a specific frequency, I can just extract an element of a 1 x m row.
I've considered a function like Map, but it seems like it'll directly apply my function by inputting the value of each element in the row, which isn't exactly what I want.
I am guessing you meant you just want to map a function on a column?
mat = RandomInteger[{0, 10}, {5, 6}];
map[f_, mat_?(MatrixQ[#] &), c_Integer /; c > 0] := f /# mat[[All, c]]
map[f, mat, 2]
It seems like you just need to get the column. The way that matrices are stored in Mathematica has the first coordinate as the row and the second as the column. All coordinates start at 1, not 0. To get an element at a specific coordinate, you use matrix[[row, column]]. If you want a whole row, matrix[[row]]. If you want a column, matrix[[All, column]]. Accordingly, here is one way you might adjust the DFT function:
DFT[f_, list_] := (t[[2]] - t[[1]]) Sum[
list[[i]] * Exp[2 Pi I f list[[i]]], {i, 1, n}];
yourColumnDFT = DFT[f, matrix[[All, columnNumber]]]
In fact, you can make this even simpler by removing the call to Sum because these operations automatically map over lists by index:
DFT[f_, list_] := (t[[2]] - t[[1]]) Total[list Exp[2 Pi I f list]]
By the way, there is a built-in function for this, Fourier (documentation here), which gives a slightly different DFT than yours but is also useful. I recommend looking for built-in functions for these tasks in the future, because Mathematica has a wide range of functionality like this and will save you a lot of trouble.

mathematica -creating lists and vectors of specific length

In Mathematica,
How can I create a list of length n
and fill with zeroes?
How can I
create a vector of length n and fill
with zeroes?
Version 6.0 and up include a new function ConstantArray for doing exactly this, and is more efficient than using Table:
In[2]:= ConstantArray[0,10]
Out[2]= {0,0,0,0,0,0,0,0,0,0}
Documentation here:
http://reference.wolfram.com/mathematica/ref/ConstantArray.html
In Mathematica, there's no distinction between lists and vectors. You can use the Table function to generate a list of length n:
x = Table[0, {n}]
(* If n was 4, x would now be the list {0, 0, 0, 0} *)

Resources