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

2 visualizaciones (últimos 30 días)
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.

Respuesta aceptada

Walter Roberson
Walter Roberson el 11 de Feb. de 2021
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 comentarios
Walter Roberson
Walter Roberson el 12 de Feb. de 2021
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 el 17 de Feb. de 2021
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.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Get Started with MATLAB en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by