Eigensystem Sort in Wolfram Mathematica - sorting

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

Related

Algorithm for recovering sparse vector x from Ax - Restricted Isometry Property

I encountered this problem and can't figure out how to do it. Help will be appreciated!
I'm pretty sure that the distribution of matrices need to satisfy the Restricted Isometry Property, but afterwards I don't know how to recover the vector:
Assume that x is s-sparse, for a constant s, which we set as s = 60
for convenience.
Find the best parameter k (you can use O()-notation) and a distribution of matrices A of size k×n, together with an efficient ‘recovery algorithm’, such that both of the
following two properties hold:
(a) With probability at least 0.99, for all s-sparse vectors x ∈ R
n with coefficients in {−1, 0, 1}, the recovery algorithm returns x upon input Ax, and
(b) For all non s-sparse vectors x with coefficients in {−1, 0, 1}, with
probability at least 0.99, the algorithm returns ‘FAIL’.
Note 1: The order of the quantifiers in (a) and (b) is reversed. In [(a)] you have
‘with prob.... for all’ and in[(b) you have ‘for all...with prob’.
Note 2: The requirement of the coefficients being in {−1, 0, 1} can be removed, and a
stronger statement can be made for integer coefficients.
Thank you!

what is the best algorithm to solve 'toy matching puzzle'?

Imagine puzzle like this :
puzzle
I have several shapes, for example :
10 circles
8 triangles
9 squares
I also have some plates to put shapes, for example :
plate A : 2 circle holes, 3 triangle holes, 1 square holes
plate B : 1 circle holes, 0 triangle hole, 3 square holes
plate C : 2 circle holes, 2 triangle holes, 2 square holes
I want to find minimum numbers of plates to put shapes all (plates do not need to fill completely)
for example :
I can pick 6 plates [A, A, A, B, B, C], and I can insert all shapes
but I also can pick [A, A, C, C, C] and this is okay too,
so answer of this problem is : 5
If this problem generalized to N-types of shapes, and M-types of plates,
What is the best algorithm to solve this problem and what is time complexity of the answer?
This problem is a NP-hard problem, it is easier to see it once you realize that there is a very simple polynomial time reduction from the bin packing problem to this problem.
What I would suggest is for you to use integer linear programming techniques in order to solve it.
An ILP that solves your problem can be the following:
// Data
Shapes // array of integers of size n, contains the number of each shape to fit
Plates // 2D array of size n * m, Plates[i][j] represents the number of shape of type i
// that fit on a plate of type j
// Decision variables
X // array of integer of size m, will represent the number of plates of each type to use
// Constraints
For all j in 1 .. m, X[j] >= 0 // number of plates cannot be negative
For all i in 1 .. n, sum(j in 1..m) Plates[i][j] * X[j] >= Shapes[i] // all shapes must fit
Objective function:
minimize sum(j in 1..n) X[j]
Write the pseudo code in OPL, feed it to a linear programming solver, and you should get a solution reasonably fast, given the similarity of this problem with bin packing.
Edit: if you do not want to go though the trouble of learning LP basics, OPL, LP solvers, etc .... then the best and easiest approach for this problem would be a good old branch and bound implementation of this problem. Branch and bound is a very simple and powerful algorithm that can be used to solve a wide range of problem .... a must-know.
A solution to this problem should be done using dynamic programming I think.
Here is a solution in pseudo-code (I haven't tested it, but I think it should work):
parts = the number of shapes we want to fit as a vector
plates = the of plates we can use as a matrix (vector of vector)
function findSolution(parts, usedPlates):
if parts < 0: //all elements < 0
return usedPlates;
else:
bestSolution = null //or anything that shows that there is no solution yet
for X in plates:
if (parts > 0 on any index where X is > 0): //prevents an infinite loop (or stack overflow because of the recursion) that would occur using only e.g. the plate B from your question
used = findParts(parts - X, used.add(X)); //elementwise subtraction; recursion
if (used.length < best.length):
//the solution is better than the current best one
best = used;
//return the best solution that was found
return best
using the values from your question the initial variables would be:
parts = [10, 8, 9]
plates = [[2, 3, 1], [1, 0, 3], [2, 2, 2]]
and you would start the function like this:
solution = findSolution(parts /*= [10, 8, 9]*/, new empty list);
//solution would probably be [A, A, C, C, C], but also [C, C, C, C, C] would be possible (but in every case the solution has the optimal length of 5)
Using this algorithm you divide the problem in smaller problems using recursion (which is what most dynamic programming algorithms do).
The time complexity of this is not realy good, because you have to search every possible solution.
According to the master theorem the time complexity should be something like: O(n^(log_b(a))) where n = a = the number of plates used (in your example 3). b (the base of the logarithm) can't be calculated here (or at least I don't know how) but I assume it would be close to 1 which makes it a quite big exponent. But it also depends on the size of the entries in the parts vector and the entries in the plates vectores (less plates needed -> better time complexity, much plates needed -> bad time complexity).
So the time complexity is not very good. For bigger problems this will take very very long, but for small problems like in your question it should work.

Plotting a random walk using Mathematica

This is my first time posting here. I would really appreciate some help with a question from my mathematica study guide. My question is:
Suppose that a drunk randomly steps either forward, backward, left, or right one unit many times. Create a list of coordinates {{x,y}..} representing his path and then display that path as a set of line segments for each step. [Hint: use NestList to create a list of coordinates, Partition to form a list of segments, map Line onto the segment list, and Show[Graphics[list]] to display the path.]
I have managed to successfully create the function:
Clear[x, n]
Randomwalk[n_] :=
NestList[(# + (-1)^Table[Random[Integer, {0, 1}], {2}]) &, Table[0, {2}], n];
Randomwalk[50]
I, however, need help with the second part, where I need to graph it. MY attempt at the second part is as follows:
Show[Graphics[Line[Randomwalk[50]]]]
and although it gives me a graph, it does not seem to be correct. I would really appreciate some help with this.
You could try the following function
RandomWalk[n_]:=Accumulate[{{1,0},{-1,0},{0,1},{0,-1}}[[RandomInteger[{1,4},n]]]]
where n is the number of steps to take. Plotting works as you wrote
Graphics[Line[RandomWalk[200]]]
However, plotting with colour shows how the walk progressed, as in
With[{n=100},
Graphics[MapIndexed[{Hue[#2[[1]]/(n + 10)], Line[#]} &,
Partition[RandomWalk[n], 2, 1]]]]
Instead of using [[RandomInteger[{1,4},n]]] to pick out the directions, you could use RandomChoice which is designed expressly for this type of operation:
RandomWalk[n_] := Accumulate[RandomChoice[{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, n]]
This gives about the same (maybe slightly faster) speed as the approach using Part and RandomInteger. But if you are working with large walks (n > 10^6, say), then you might want to squeeze some speed out by forcing the list of directions to be a packed array:
NSEWPacked = Developer`ToPackedArray[{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}]
Then use the packed array:
RandomWalkPacked[n_] := Accumulate[RandomChoice[NSEWPacked, n]]
You should see about an order of magnitude speedup with this:
Timing[RandomWalkPacked[10^7];]
For details on packed arrays, see Developer/ref/ToPackedArray or chapter 12 on optimizing Mathematica programs in Programming with Mathematica: An Introduction.

Sort eigenvalue matrix with eigenvector matrix

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}}

How do you programmatically display a partitioned matrix in Mathematica?

I know that using the Insert menu, you can create a matrix with vertical and horizontal lines, but not a more generic partition, such as dividing a 4x4 matrix into 4 2x2 partitions. Nor, can MatrixForm do any sort of partitioning. So, how would I go about programmatically displaying such a partitioned matrix? I would like to retain the ability of MatrixForm to act only as a wrapper and not affect subsequent evaluations, but it is not strictly necessary. I suspect this would involve using a Grid, but I haven't tried it.
After playing around for far too long trying to make Interpretation drop the displayed form and use the matrix when used in subsequent lines, I gave up and just made a wrapper that acts almost exactly like MatrixForm. This was really quick as it was a simple modification of this question.
Clear[pMatrixForm,pMatrixFormHelper]
pMatrixForm[mat_,col_Integer,row_:{}]:=pMatrixForm[mat,{col},row]
pMatrixForm[mat_,col_,row_Integer]:=pMatrixForm[mat,col,{row}]
pMatrixFormHelper[mat_,col_,row_]:=Interpretation[MatrixForm[
{Grid[mat,Dividers->{Thread[col->True],Thread[row->True]}]}],mat]
pMatrixForm[mat_?MatrixQ,col:{___Integer}:{},row:{___Integer}:{}]:=
(CellPrint[ExpressionCell[pMatrixFormHelper[mat,col,row],
"Output",CellLabel->StringJoin["Out[",ToString[$Line],"]//pMatrixForm="]]];
Unprotect[Out];Out[$Line]=mat;Protect[Out];mat;)
Then the postfix command //pMatrixForm[#, 3, 3]& will give the requested 2x2 partitioning of a 4x4 matrix. It maybe useful to change the defaults of pMatrixForm from no partitions to central partitions. This would not be hard.
So this is what I came up with. For a matrix M:
M = {{a, b, 0, 0}, {c, d, 0, 0}, {0, 0, x, y}, {0, 0, z, w}};
you construct two list of True/False values (with True for places where you want separators) that take two arguments; first the matrix and second a list of positions for separators.
colSep = Fold[ReplacePart[#1, #2 -> True] &,
Table[False, {First#Dimensions##1 + 1}], #2] &;
rowSep = Fold[ReplacePart[#1, #2 -> True] &,
Table[False, {Last#Dimensions##1 + 1}], #2] &;
Now the partitioned view using Grid[] is made with the use of Dividers:
partMatrix = Grid[#1, Dividers -> {colSep[#1, #2], rowSep[#1, #3]}] &;
This takes three arguments; first the matrix, second the list of positions for column dividers, and third the list of values for row dividers.
In order for it to display nicely you just wrap it in brakets and use MatrixForm:
MatrixForm#{partMatrix[M, {3}, {3}]}
Which does the 2by2 partitioning you mentioned.

Resources