# Creating a Random Upper Triangular Matrix with Unique Entries for Efficiently Computing Matrix Exponential.

6 views (last 30 days)
Matthew Graham on 10 Jan 2020
Edited: Matt J on 11 Jan 2020
Hi there.
So I'm trying to create a function that does the following:
1. Declares a parameter k
2. Checks that k is a natural number greater than or equal to two
3. If k is greater than or equal to two, prints "k is good!" and then creates a square matrix M of size k that is upper triangular and has unique real valued entries not just along the diagonal, but above it too.
4. If k is not greater than or equal to two and is not a natural number, prints out "k is not good! please fix!" and prevents the user from proceeding with the program. Ideally they would be returned to the first step.
5. Once the matrix M is created, what we are going to do is find its eigenvalues and eigenvectors.
6. Once we have the eigenvalues and eigen vectors, we want to create the diagonal matrix D so that way we can have M = Q*D*inv(Q) where Q is the matrix consisting of columns that are the eigenvectors of M.
7. Now we specify an n. Again, sort of the exact same situation as bullet point 2. Actually it's the exact same just with a very minor change. For this we are calculating a sum of up to the nth term and for this we want n greater than or equal to 0 since the taylor expansion of exp(x) starts at 0. So yeah, here, we are just declaring another parameter n.
8. if n is a nonnegative integer, print "n is good!" and then calculates the sum of (M^n)/n!
9. if n is not an integer greater than or equal to 0, print "k is not good! please fix!" and then prevents the user from proceeding with finding the sum because they are not prompted to enter a value for n again.
So far, here is my crappy code that (unsuccessfully) attempts to do this (sorry, it's been a while since I've programmed in Matlab).
function[k] MatrixExp[k];
k = input('Enter a natural number greater than or equal to 2'); %declaring k
%checking to see if k is good. If so, we create M and display it. Otherwise, we fix k.
if k >= 2
print('k is good!')
M = triu(rand((k,k),0));
disp(M)
else
print('k is not good! please fix!')
while(true)
if k >= k
print('k is good!')
M = triu(rand(k,k),0);
disp(M)
break
end
end
end
%Finding the eigenvalues and eigenvectors of M and then creating the matrix Q and the diagonal matrix D.
eigenvectors = eig(M);
eig(M) = [Q,D];
disp(Q);
disp(D);
%now we declare the parameter n and check that it is good, and if it is good, we find the sum of exp(M) up to the nth term and display it.
%otherwise we go back and fix n.
n = input('Enter a nonnegative integer: ');
if n>=0
print('n is good!')
M_exp = Q*exp(D)*inv(Q)
disp(M_exp)
else
print('n is not good, please fix!')
while(true)
if n>=0
print('n is good!')
M_exp = Q*exp(D)*inv(Q)
disp(M_exp)
end
end
end
end
My main gripe (other than this not wanting to work) is that while
M = triu(rand(k,k),0)
returns a random upper triangular square matrix M of size k, I'd like to be able to know how to have the entries of the matrix be "nice" numbers like positive integers, integers, or even rational numbers (which I realize encompasses the previous two number sets and as well as that my current setup allows for these since real numbers encase all these number sets I've listed so far). This is mainly for my own visualization, but still, it would be nice.
That way, all I have to do is call my function, input k, and it returns all this. But I've never been that great with making functions in Matlab so there's probably more to it than that.
Thank you!

Matt J on 10 Jan 2020
Edited: Matt J on 10 Jan 2020
Just use randi, e.g.,
>> k=8; M = triu(randi(10,k,k))
M =
9 10 5 7 3 5 8 10
0 10 10 8 1 4 8 4
0 0 8 8 1 8 3 6
0 0 0 4 9 8 7 3
0 0 0 0 7 2 7 8
0 0 0 0 0 5 2 3
0 0 0 0 0 0 2 6
0 0 0 0 0 0 0 7
For rational numbers,
>> k=6; M = triu(randi(10,k,k))./randi(10,k,k)
M =
0.7778 1.6667 0.3333 1.1429 0.2000 0.7778
0 1.6000 8.0000 1.6667 0.8889 1.0000
0 0 0.2222 0.9000 6.0000 9.0000
0 0 0 0.5714 2.5000 1.5000
0 0 0 0 5.0000 0.3333
0 0 0 0 0 0.6000

Guillaume on 10 Jan 2020
And if it's not resolved, then please clarify what you need help with.
Matthew Graham on 10 Jan 2020
So what I ultimately want is to have this be a function I can summon and then have it do the following (have added a few things since the time I posted this)
1. Display "This is your matrix M: "
2. Display "These are your eigenvalues for your matrix M: " and perform a check to see that they are all unique and if they are not unique M is recalculated and then check it again and if it's good then, then display this message. That is, check that the eigenvalues are unique and if they are then display the message.
3. Display "This is your diagonal matrix D: "
4. Display "This is your eigenvector matrix Q: "
5. Then lastly display "Your matrix exponential is: " and it will display the value of M_exp to the specified nth value.
The problems I'm having are mainly getting this chunk of code I've got listed above to be a proper function--I've always struggled with making these. The display messages are some fprintf argument if I had to guess but I can't quite get them to work. I'm not exactly sure how I would check to see if each entry in eig(M) is unique. Maybe a nested for loop? something like
for i in length(eig(M))
for j in length(eig(M))
if i == j
calculate new upper triangular matrix M
else
end
end.
Hopefully this clears some things up. My question is "how do I do these five things I've listed here?"
Matt J on 11 Jan 2020
To display the various messages, you can use the disp command,
>> disp ' ', disp 'This is a line of text with line skips', disp ' '
This is a line of text with line skips
To test for uniqueness,
small_tolerance = 0.00001; %considered different if separated by at least this
if all( diff(sort(myEigenvalues)) > small_tolerance)
%response
end

Guillaume on 10 Jan 2020
The main issue is that a lot of your code is not valid matlab syntax, or doesn't make much sense, e.g
if k >= k
when is a value not equal to itself? (for the record it's actually possible if the value is NaN).
With regards to: " I'd like to be able to know how to have the entries of the matrix be "nice" numbers like positive integers"
As documented, rand generates a uniform distribution between 0 and 1. If you want a uniform distribution of random integers you can use randi instead, e.g
n = randi(100, 1, 10); %10 random integers between 1 and 100
n = randi([-10, 10], 1, 20); %20 random integers between -10 and 10
You do need to specify an upper bound for randi. An absolute upper-bound would be 9007199254740992 (flintmax). Most integers above that can't be stored accurately as doubles.

Matthew Graham on 10 Jan 2020
Yeah, I figured it would have some errors. I fixed as many of them as I could as soon as I posted it. Thanks for the comment though, definitely helpful!
John D'Errico on 11 Jan 2020
Another invalid piece of MATLAb syntax is just the function header:
function[k] MatrixExp[k];