Error in size of matrix and vectorization and loop not working and non-singleton rhs dimension
1 view (last 30 days)
Show older comments
Jamil Dudhwala
on 4 Mar 2019
Commented: Walter Roberson
on 5 Mar 2019
Hi,
I have been trying to create a code, where I end up with temperature values for different surfaces over a time period and should end up with 5x5 array. However, I only seem to end up getting a 1x5 array and also the calculation is not correct as it does not use the element I want it to. The script is below.
Thank you
clc,clear
V = [1;2;3;4;5]
ho = 0.6 + 6.64.*sqrt(V)
k = [1 2 3 4 5]
lamda = [6 7 8 9 10]
hi = 2
x = (1./ho)
y = (1/hi)
z = (lamda./k)
S = [11 12 13 14 15;]
U = x + y + z
ma=1
ca=2
DTM=1
deltat=1
Tout=5
ms=1
cs=1
index=1:5;
SQAmb = zeros(numel(index), numel(S)); %Preallocation of Ambient Load (Surface) matrix
SQAmb_Tot = zeros(size(index)); %Preallocation of Total Ambient Load (Surface) matrix
QAmb = zeros(numel(index), numel(S)); %Preallocation of Ambient Load (Air) matrix
QAmb_Tot = zeros(size(index)); %Preallocation of Total Ambient Load (Air) matrix
SQTot = zeros(size(index)); %Preallocation of Total Surface Heat Load matrix
deltaTs = zeros(size(index)); %Preallocation of deltaTs matrix
Ts = zeros(size(index)); %Preallocation of Surface temperature matrix
QTot = zeros(size(index)); %Preallocation of Total Heat Load matrix
deltaTin = zeros(size(index)); %Preallocation of deltaTin matrix
Tin = zeros(size(index)); %Preallocation of car cabin temperature matrix
for i=index
if (i)==1
%Ambient Load (Surface), where 20 is the intial temperature at t=0
SQAmb(i,:) = S*U*(Tout-20)
(the first value of this array should be: the first element of S which is (11) * first element of U* temp diff (-15), this should come out to -1095.2865 but does not)
(if vectorization is used i.e. S.*U.*(Tout-20) then an error to do with "Assignment has more non-singleton rhs dimensions than non-singleton subscripts is produced")
(and if element is selected one at a time by SQAmb(i,:) = S*U(i)*(Tout-20) , the array that is formed for the Temperature at the end is not a 5x5 array)
%Total Ambient Load (Surface) in Array Form
SQAmb_Tot(i) = sum(SQAmb(i,:))
%Ambient Load (Air), where 20 is the intial air and surface temperatures at t=0
QAmb(i,:) = S*U*(20-20);
%Total Ambient Load (Air) in Array Form
QAmb_Tot(i) = sum(QAmb(i,:))
%Total Surface Heat Transfer Load
SQTot(i) = SQAmb_Tot(i)
%change in surface temperature where deltat is timestep
deltaTs(i) = (SQTot(i)/((ms*cs)+DTM))*(deltat)
%New surface temperature
Ts(i) = 20 + deltaTs(i)
%Total Heat Transfer Load
QTot(i) = QAmb_Tot(i)
%change in air cabin temperature where deltat is timestep
deltaTin(i) = (QTot(i)/((ma*ca)+DTM))*(deltat)
%New car cabin temperature
Tin(i) = 20 + deltaTin(i)
else
%Ambient Load (Surface)
SQAmb(i,:) = S*U*(Tout-(2*Ts(i-1))+Tin(i-1))
%Total Ambient Load (Surface) in Array Form
SQAmb_Tot(i) = sum(SQAmb(i,:))
%Ambient Load (Air)
QAmb(i,:) = S*U*((Ts(i-1))-Tin(i-1))
%Total Ambient Load (Air) in Array Form
QAmb_Tot(i) = sum(QAmb(i,:))
%Total Surface Heat Transfer Load
SQTot(i) = SQAmb_Tot(i)
%change in surface temperature where deltat is timestep
deltaTs(i) = (SQTot(i)/((ms*cs)+DTM))*(deltat)
%New surface temperature
Ts(i) = Ts(i-1) + deltaTs(i)
%Total Heat Transfer Load
QTot(i) = QAmb_Tot(i)
%change in air cabin temperature where deltat is timestep
deltaTin(i) = (QTot(i)/((ma*ca)+DTM))*(deltat)
%New car cabin temperature
Tin(i) = Tin(i-1)+deltaTin(i)
end
end
0 Comments
Accepted Answer
Walter Roberson
on 4 Mar 2019
Your S is 1 x 5. Your U is 5 x 5. Your Tout is scalar.
S*U is valid in MATLAB because the "inner dimensions" agree for the matrix multiplication: (1x5) * (5x5) gives a 1 x 5 resulting inner product. The first element of that output would be dot(S,U(:,1)) * (Tout-20)
When you vectorize S.*U.*(Tout-20) you are asking to do element-by-element multiplication between a 1 x 5 and a 5 x 5. In R2016a and earlier, that was an error. In R2016b and later, the effect is as-if you had done
bsxfun(@times, S, U) .* (Tout-20)
which would be like
repmat(S, size(U,1), 1) .* U .* (Tout-20)
and the size of that output is going to be 5 x 5, same size as U.
If you are wondering why U is 5 x 5: U = x + y + z. x is 5 x 1, y is scalar, z is 1 x 5. The operation is like
bsxfun(@plus, bsxfun(@plus, x, y), z)
which is like
repmat(x, 1, size(z,2)) + y + repmat(z, size(x,1), 1)
2 Comments
Walter Roberson
on 5 Mar 2019
* is algebraic matrix multiplication. dot product is one way of representing the calculation for one element. I could have written sum(S .* U(:,1).') * (Tout-20)
You probably should not select one element of U at a time; You should probably calculate
U = x(:) + y(:) + z(:)
or perhaps the transpose of that. And then use .*
S.*U.*(Tout-20)
If you are expecting Ts(i) and T(i) to be 5x5 arrays then you probably should not be using linear indexing of numeric arrays.
More Answers (0)
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!