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

3 visualizzazioni (ultimi 30 giorni)
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 Commento
Stephen23
Stephen23 il 5 Set 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>

Accedi per commentare.

Risposta accettata

Star Strider
Star Strider il 5 Set 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.
.

Più risposte (3)

ScottB
ScottB il 5 Set 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 Commento
Voss
Voss il 5 Set 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>

Accedi per commentare.


Steven Lord
Steven Lord il 5 Set 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 il 5 Set 2024
Briiliant, thanks guys for all youre help!

Categorie

Scopri di più su Data Type Identification in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by