필터 지우기
필터 지우기

Double-Checked Sizes but Still Get 'Index Exceeds Matrix Dimensions' Error

조회 수: 2 (최근 30일)
Hello,
I had a post yesterday talking about the error I keep getting, and thought I understood the issue enough to fix it.
However, I keep getting the same error, mainly in line 71 (denoted below).
A, B, and C are all the same size (1x4). I know BB is larger, but that is my text issue to tackle.
For now, I'm struggling to figure this one out. I attached my code below:
%Given Parameters
a = 10;
b = 1E-4;
d = 400000;
e = 2E-3;
TH = 2000;
TC = 400;
hH = 900;
hL = 1100;
L = .10;
IL = 5;
DX = L/(IL-1);
T(1)=200;
T(2) = (b*T(1)^2+(hH*DX+a)*T(1)-hH*DX*TH)/(a+b*T(1));
T(IL)=50;
T(IL-1)=(b*T(IL)^2+(hL*DX+a)*T(IL)-hL*DX*TC)/(a+b*T(IL));
%Define For-Loop to determine all temperatures based off of initial guesses
for i=3:(IL-2)
T(i)= ((e-(2*a)/(DX^2))*T(i-1)-((2*b)/(DX^2))*T(i-1)^2+...
(1/DX^2-b/(2*DX))*T(i-2)+(b/DX^2)*T(i-1)*T(i-1)+d)/...
(1/DX^2+b/(2*DX)+(b/DX^2)*T(i-1));
end
%Define First and Last Row of Matrix for the BC
% at i=1:
dFi_dTi(1) = (-2*b*T(1))/(DX)-a/DX-hH+(b*T(2))/DX;
dFi_dTip1(1) = (b*T(1))/(DX)+a/DX;
% at i = IL
dFi_dTim1(IL) = (-b*T(IL))/(DX)-a/DX;
dFi_dTi(IL) = (2*b*T(IL))/(DX)+a/DX+hL+(b*T(IL-1))/DX;
for i=2:(IL-1)
dFi_dTim1(i) = a/DX^2-b/(2*DX)+(b*T(i))/(DX^2);
dFi_dTi(i) = e-(2*a)/(DX^2)+(b*T(i+1))/...
(DX^2)+(b*T(i-1))/(DX^2)-(4*b*T(i))/(DX^2);
dFi_dTip1(i) = a/DX^2+b/(2*DX)+(b*T(i))/(DX^2);
end
%Matrix Stuff for Thomas Algorithm
%Matrix Parameters
A(i) = dFi_dTi(i);
B(i) = dFi_dTip1(i);
C(i) = dFi_dTim1(i);
BB = 1:DX:IL;
B(1)=B(1)/A(1);
for i=2:IL
A(i)=A(i)-C(i)*B(i-1); %***LINE 71****
B(i)=B(i)/A(i);
end
BB(1)=BB(1)/A(1);
for i=2:IL
BB(i)=(BB(i)-C(i)*BB(i-1))/A(i);
end
NMI=IL-1;
for i=1:NMI
ii=IL-1;
BB(ii)=BB(ii)-B(ii)*BB(ii+1);
end
I believe all function/variables that rely on i all run from 1 to IL, so I'm not sure how the sizes are mismatched, specifically in line 71, where I keep getting the error.
Any help is appreciated, thank you. If there's more detail or information I can give please ask.

채택된 답변

Walter Roberson
Walter Roberson 2021년 2월 11일
for i=2:(IL-1)
dFi_dTim1(i) = a/DX^2-b/(2*DX)+(b*T(i))/(DX^2);
C has not been defined up to that point, and that particular for loop does not define it. However, that particular for loop defines i, and is going to leave i set to the last value assigned to it, so after that loop i = IL-1
A(i) = dFi_dTi(i);
B(i) = dFi_dTip1(i);
C(i) = dFi_dTim1(i);
Those statements all use whatever value happens to be in i, so as indicated above, the value i = IL-1 . Before those statements, A, B, C do not exist; after those statements, A, B, C will be length IL-1 with positions 1:IL-2 being 0.
B(1)=B(1)/A(1);
0 divided by 0 since A and B are initialized to 0 except for position IL-1
for i=2:IL
A(i)=A(i)-C(i)*B(i-1); %***LINE 71****
B(i)=B(i)/A(i);
end
Eventually you get to i = IL. But you only created A and C up to IL-1 so A(i) and C(i) will be out of range when i becomes IL.
  댓글 수: 6
Walter Roberson
Walter Roberson 2021년 2월 12일
When you are working on a vector, you have a few possibilities:
  • You can initialize all of it at the beginning to a constant such as nan or inf (or perhaps 0) Then you can loop and be careful to never read from a location before you write a new value at the location. For example, when you are at location K, reading P(K), then you write to P(K+1) before you read from that location (next loop iteration)
  • You can initialize all of it at the beginning to a relevant constant such as 0. Then you can loop and be careful in your calculations that if you read from a location before you write a new value at the location, that it is meaningful to do so (e.g., checking to see if it was written to yet), or that your choose your constant to not affect the calculation. For example sum(P(K:end)) is fine if the spaces not written to yet are all 0.
  • You can grow the vector, being careful not to read from a location before it exists. For example, when you are at location K, reading P(K), then you write to P(K+1) before you read from that location (next loop iteration). The difference compared to the first option is that it is more expensive to keep growing the vector step by step, and sometimes the code needs to know what the final size will be before it can do the calculations correctly
Your code was initializing T to a proper length, but was constructing A, B, and C by writing to somewhere near the end of the final size without writing to the elements at the beginning of the vector. You then had problems because you were counting on the elements at the beginning of the vector to have a meaningful value when they were just the 0 you get from writing past the end of an array; and you had the problem that you did not write A, or C long enough to be able to read the last element. You should probably not have been reading the last element before you wrote something specific to it.
For example, perhaps your code should be along the lines of
for i=1:IL-1
A(i+1)=A(i)-C(i)*B(i); %***LINE 71****
B(i+1)=B(i)/A(i+1);
end
Jon Stapchuck
Jon Stapchuck 2021년 2월 17일
Thank you for the analogy, likening it to the paper examples helped with the explanation in my opinion.
I'll be sure to utilize this for my script as well as for future programs I write.
I appreciate your help.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Get Started with MATLAB에 대해 자세히 알아보기

태그

제품


릴리스

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by