How to stop unwanted rows being added when constructing a matrix in a for loop

3 vues (au cours des 30 derniers jours)
Hi there,
just a simple question I think.
I am trying to construct a matrix in a quick way using a for loop. Because the values for diagonals are the same I can using indexing like (i,i) and (i+1,i) etc. However, apart from the first diagonal I input (i,i), the second diagonal (i,i+1) adds an extra row and column to my original matrix.
Here is my code:
clear, clc, close all
mat = zeros(7,7)
n = size(mat,1)
for i = 1:n
mat(i,i) = 6
mat(i,i+1) = -4
end
If you run the code, the diagonal containing -4 adds on a extra row and column at the end; making a 7x7 matrix to an 8x8. This is very frustraing and I do not want this!
Can I ask what its the trick to getting around this, please?
Many thanks
Scott
  1 commentaire
Stephen23
Stephen23 le 5 Sep 2024
n = 7;
toeplitz([6,zeros(1,n-1)],[6,-4,zeros(1,n-2)])
ans = 7x7
6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

Connectez-vous pour commenter.

Réponse acceptée

Star Strider
Star Strider le 5 Sep 2024
The reason is that there are the same number of ‘6’ and ‘-4’ being created in the loop. There needs to be one less ‘-4’.
clear, clc, close all
mat = zeros(7,7);
n = size(mat,1);
for i = 1:n
mat(i,i) = 6;
mat(i,i+1) = -4;
end
mat
mat = 7x8
6 -4 0 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 0 6 -4
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
N = 7;
mat2 = diag(ones(1,N)*6); % Use 'diag'
mat2 = + mat2 + diag(ones(1,N-1)*-4, 1)
mat2 = 7x7
6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
One way to get around that iis to use the diag function to creeate the matrix.
.

Plus de réponses (3)

ScottB
ScottB le 5 Sep 2024
mat = zeros(7,7)
n = size(mat,1)
for i = 1:n
mat(i,i) = 6
if i ==7
else
mat(i,i+1) = -4
end
end
mat =
6 -4 0 0 0 0 0
0 6 -4 0 0 0 0
0 0 6 -4 0 0 0
0 0 0 6 -4 0 0
0 0 0 0 6 -4 0
0 0 0 0 0 6 -4
0 0 0 0 0 0 6
  1 commentaire
Voss
Voss le 5 Sep 2024
Or
mat = zeros(7,7);
n = size(mat,1);
for i = 1:n
mat(i,i) = 6;
if i ~= n
mat(i,i+1) = -4;
end
end
mat
mat = 7x7
6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

Connectez-vous pour commenter.


Steven Lord
Steven Lord le 5 Sep 2024
Since you're creating matrices with diagonal bands, consider using the diag or spdiags functions.
n = 7;
mainDiagonal = diag(6*ones(n, 1))
mainDiagonal = 7x7
6 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 6
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
upperDiagonal = diag(-4*ones(n-1, 1), 1)
upperDiagonal = 7x7
0 -4 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
A = mainDiagonal + upperDiagonal
A = 7x7
6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Note that when I created upperDiagonal I used a vector of all -4 values that had length one shorter than the vector of 6 values I used to create mainDiagonal. This made it so upperDiagonal was n-by-n rather than (n+1)-by-(n+1) as it would have been had I used -4*ones(n, 1).
B = diag(-4*ones(n, 1), 1)
B = 8x8
0 -4 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
For bands below the diagonal, use a negative value as the second input.
lowerDiagonal = diag(-8*ones(n-1, 1), -1)
lowerDiagonal = 7x7
0 0 0 0 0 0 0 -8 0 0 0 0 0 0 0 -8 0 0 0 0 0 0 0 -8 0 0 0 0 0 0 0 -8 0 0 0 0 0 0 0 -8 0 0 0 0 0 0 0 -8 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Here are the numbers for which band contains each element of the matrix.
bandNumbers = toeplitz(0:-1:-(n-1), 0:(n-1))
bandNumbers = 7x7
0 1 2 3 4 5 6 -1 0 1 2 3 4 5 -2 -1 0 1 2 3 4 -3 -2 -1 0 1 2 3 -4 -3 -2 -1 0 1 2 -5 -4 -3 -2 -1 0 1 -6 -5 -4 -3 -2 -1 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
For spdiags you don't have to create each band individually, though the syntax is a little bit more complicated. The command below puts 6 on the 0 (main) diagonal of S and -4 on the +1 (upper) diagonal, and makes S an n-by-n matrix.
S = spdiags([6 -4], [0 1], n, n)
S =
(1,1) 6 (1,2) -4 (2,2) 6 (2,3) -4 (3,3) 6 (3,4) -4 (4,4) 6 (4,5) -4 (5,5) 6 (5,6) -4 (6,6) 6 (6,7) -4 (7,7) 6
Since S is sparse it's displayed slightly differently. Convert it to full and it looks like A above.
F = full(S)
F = 7x7
6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6 -4 0 0 0 0 0 0 6
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

Scott Banks
Scott Banks le 5 Sep 2024
Briiliant, thanks guys for all youre help!

Catégories

En savoir plus sur Data Type Identification dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by