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

4 views (last 30 days)
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!

Answers (2)

Matt J
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
  5 Comments
Matthew Graham
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
print("These are your eigenvalues for your matrix M: ")
end
end.
Hopefully this clears some things up. My question is "how do I do these five things I've listed here?"
Matt J
Matt J on 11 Jan 2020
Edited: 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

Sign in to comment.


Guillaume
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.
  3 Comments
John D'Errico
John D'Errico on 11 Jan 2020
Another invalid piece of MATLAb syntax is just the function header:
function[k] MatrixExp[k];
Instead, READ THE HELP about functions! At least this is a valid function header:
function [k] = MatrixExp(k)
I might ask whay you are returning k as an output when you are passing it into the function. And that is the only output of interest? Strange, but your choice.
Matthew Graham
Matthew Graham on 11 Jan 2020
I've read the help about functions. If I understood them I wouldn't be asking here. It's been a while. I'm trying to learn how to code in Matlab, chill.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!