How to create a large matrix using another matrix

Hello everyone, I want to make a large matrix (10^7 x 10^7) but it needs to have the following matrix being repeated around its main diagonal.
a=4;
A=[1 0 a+1 0;
a+2 2 0 a+1;
0 a+2 3 0;
0 0 a+2 4];
As you can see it is a main diagonal with 1:10^7 and 1 row lower repeating the number 6 and 2 rows higher repeating the number 5.
Everything I have tried turns out to be huge in terms of memory and unable to be performed like that. I suppose the trick is by somehow making use of a sparse matrix, but I cannot get it to work properly.
Thanks a lot in advance!

8 Comments

What are you trying to do with this large matrix? Are you trying to use it to solve a system of equations? If so consider instead using one of the iterative solvers in MATLAB. Most if not all of those solvers can operate on either an explicit coefficient matrix A or a function that performs one or both of A*x or A'*x, where x is a column vector. If your coefficient matrix has a pattern (as yours apparently does) you may be able to compute A*x and A'*x without explicitly forming A.
Thanks for your interest Steven!
The main goal is to solve for x in the following equation:
B*x=C
Where C=ones(10^7,1)
Finding the inv(B) to solve it is not possible at this size.
You should rarely be using inv() on any matrix that is more than about 4 x 4, and even then only on symbolic matrices. In other cases you should be using the \ operator. The \ operator should be able to detect that it is a band-restricted sparse system and use a more efficient solver.
Noted! But yet again x=C\B displays the same error concerning output's size.
What error is that?
a=4;
N=1E7;
Adiag=(1:N).';
A1=ones(N,1)*(a+2);
A2=ones(N,1)*(a+1);
Acom=[A2, Adiag, zeros(N,1), A1];
B=spdiags(Acom,-1:2,N,N);
C = ones(N,1);
sol = B\C;
On my system the solution is found about 1.6 seconds with no memory problems. Memory use peaks about less than 6 gigabytes on my system.
Found out the difference, I have calculated the Acom as follows:
Adiag=(1:N);
A1=ones(1,N)*(a+2);
A2=ones(1,N)*(a+1);
Acom=[A1; zeros(1,N); Adiag; A2];
B=spdiags(Acom',-1:2,N,N);
Which results to
Acom:
instead of:
and B:
instead of:
Not sure which approach is the mathematically correct one.
Your original request shows the a+2 below the diagonal, so anything that ends up with the 6 above the diagonal is a wrong approach ;-)
The approach I used of constructing columns instead of rows has the advantage of not needing to transpose Acom, and so is more efficient.
Then I will have to aggree with you and tell you a huge thanks once more!! Have a good day!

Sign in to comment.

 Accepted Answer

Walter Roberson
Walter Roberson on 30 May 2020
Edited: Walter Roberson on 1 Jun 2020

4 Comments

Thanks for your answer Walter! It was really helpful
I tried the following:
a=4;
Adiag=1:10^3;
A1=ones(1,10^3)*(a+2);
A2=ones(1,10^3)*(a+1);
Acom=[A1; zeros(1,10^3); Adiag; A2];
B=spdiags(Acom',1,10^3,10^3);
The result is a 1000x1000 matrix but is way too big to display in matlab. So I tried at 100x100 and the result is this:
val =
(1,2) 6
(2,3) 6
(3,4) 6
(4,5) 6
(5,6) 6
(6,7) 6
(7,8) 6
(8,9) 6
(9,10) 6
(10,11) 6
(11,12) 6
....... until (99,100)
your d should not be 1, it should be -1:2
Got it! Thanks a alot for the help! Is there anyway to upscale this to a 10^7 x 10^7 matrix?
a=4;
N=1E7;
Adiag=(1:N).';
A1=ones(N,1)*(a+2);
A2=ones(N,1)*(a+1);
Acom=[A2, Adiag, zeros(N,1), A1];
B=spdiags(Acom,-1:2,N,N);

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2019b

Community Treasure Hunt

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

Start Hunting!