フィルターのクリア

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

12 ビュー (過去 30 日間)
Scott Banks
Scott Banks 2024 年 9 月 5 日 18:39
コメント済み: Stephen23 2024 年 9 月 5 日 23:09
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 件のコメント
Stephen23
Stephen23 2024 年 9 月 5 日 23:09
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>

サインインしてコメントする。

採用された回答

Star Strider
Star Strider 2024 年 9 月 5 日 19:04
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.
.

その他の回答 (3 件)

ScottB
ScottB 2024 年 9 月 5 日 18:57
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 件のコメント
Voss
Voss 2024 年 9 月 5 日 19:05
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>

サインインしてコメントする。


Steven Lord
Steven Lord 2024 年 9 月 5 日 19:12
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 2024 年 9 月 5 日 22:18
Briiliant, thanks guys for all youre help!

カテゴリ

Help Center および File ExchangeData Type Identification についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by