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

3 Ansichten (letzte 30 Tage)
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 Kommentar
Stephen23
Stephen23 am 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>

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Star Strider
Star Strider am 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.
.

Weitere Antworten (3)

ScottB
ScottB am 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 Kommentar
Voss
Voss am 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>

Melden Sie sich an, um zu kommentieren.


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

Kategorien

Mehr zu Data Type Identification finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by