Month: August 2025
Heatmap in uipanel resizing in normal mode but not when debugging
Hi,
I have created a grid layout ([3,2]) in a tab in a programmatical app. The column width for the grid layout is set to ‘fit’ for both columns. In the first row, I have a uitable and a uiaxes next to each other and in the second row, I have a uipanel and another uiaxes next to one another. The final row contains a button.
The content of the uipanel in the second row, is a heatmap based on the correlations between variables. I am using a uipanel as a parent since heatmap cannot be the child of uiaxes.
When I debug the code, the heatmap fills the uipanel perfectly and everything runs as expected. However, if I remove the breakpoints and run the code in normal mode, the heatmap resizes for some reason and becomes very small in the uipanel.
This is the code used to create the gridlayout:
g3=uigridlayout(tab3,[3 2]);
g3.RowHeight = {‘fit’,’fit’,’fit’};
g3.ColumnWidth = {‘fit’,’fit’};
testdata=array2table(zeros(13,4),"RowNames",variables,"VariableNames",{‘Variable 1′,’Variable 2′,’Variable 3′,’Variable 4’});
t14=uitable(g3,"Data",testdata);
t14.ColumnEditable = repelem(false,4);
t14.Layout.Row=1;
t14.Layout.Column=1;
s1=uistyle(HorizontalAlignment=’right’);
addStyle(t14,s1);
ax1=uiaxes(g3);
ax1.Layout.Row=1;
ax1.Layout.Column=2;
ax_heat=uipanel(g3);
ax_heat.Layout.Row=2;
ax_heat.Layout.Column=1;
ax_box=uiaxes(g3);
ax_box.Layout.Row=2;
ax_box.Layout.Column=2;
The heatmap is calculated and assigned to the uipanel as follows:
R=corr(Data);
hm=heatmap(ax_heat,variables, variables,R,’Colormap’,jet);
Is there a way to "force" the size of the heatmap to fill the entire uipanel?
Why is the behaviour different between debugging (perfect) and normal mode?
Thanks in advance!Hi,
I have created a grid layout ([3,2]) in a tab in a programmatical app. The column width for the grid layout is set to ‘fit’ for both columns. In the first row, I have a uitable and a uiaxes next to each other and in the second row, I have a uipanel and another uiaxes next to one another. The final row contains a button.
The content of the uipanel in the second row, is a heatmap based on the correlations between variables. I am using a uipanel as a parent since heatmap cannot be the child of uiaxes.
When I debug the code, the heatmap fills the uipanel perfectly and everything runs as expected. However, if I remove the breakpoints and run the code in normal mode, the heatmap resizes for some reason and becomes very small in the uipanel.
This is the code used to create the gridlayout:
g3=uigridlayout(tab3,[3 2]);
g3.RowHeight = {‘fit’,’fit’,’fit’};
g3.ColumnWidth = {‘fit’,’fit’};
testdata=array2table(zeros(13,4),"RowNames",variables,"VariableNames",{‘Variable 1′,’Variable 2′,’Variable 3′,’Variable 4’});
t14=uitable(g3,"Data",testdata);
t14.ColumnEditable = repelem(false,4);
t14.Layout.Row=1;
t14.Layout.Column=1;
s1=uistyle(HorizontalAlignment=’right’);
addStyle(t14,s1);
ax1=uiaxes(g3);
ax1.Layout.Row=1;
ax1.Layout.Column=2;
ax_heat=uipanel(g3);
ax_heat.Layout.Row=2;
ax_heat.Layout.Column=1;
ax_box=uiaxes(g3);
ax_box.Layout.Row=2;
ax_box.Layout.Column=2;
The heatmap is calculated and assigned to the uipanel as follows:
R=corr(Data);
hm=heatmap(ax_heat,variables, variables,R,’Colormap’,jet);
Is there a way to "force" the size of the heatmap to fill the entire uipanel?
Why is the behaviour different between debugging (perfect) and normal mode?
Thanks in advance! Hi,
I have created a grid layout ([3,2]) in a tab in a programmatical app. The column width for the grid layout is set to ‘fit’ for both columns. In the first row, I have a uitable and a uiaxes next to each other and in the second row, I have a uipanel and another uiaxes next to one another. The final row contains a button.
The content of the uipanel in the second row, is a heatmap based on the correlations between variables. I am using a uipanel as a parent since heatmap cannot be the child of uiaxes.
When I debug the code, the heatmap fills the uipanel perfectly and everything runs as expected. However, if I remove the breakpoints and run the code in normal mode, the heatmap resizes for some reason and becomes very small in the uipanel.
This is the code used to create the gridlayout:
g3=uigridlayout(tab3,[3 2]);
g3.RowHeight = {‘fit’,’fit’,’fit’};
g3.ColumnWidth = {‘fit’,’fit’};
testdata=array2table(zeros(13,4),"RowNames",variables,"VariableNames",{‘Variable 1′,’Variable 2′,’Variable 3′,’Variable 4’});
t14=uitable(g3,"Data",testdata);
t14.ColumnEditable = repelem(false,4);
t14.Layout.Row=1;
t14.Layout.Column=1;
s1=uistyle(HorizontalAlignment=’right’);
addStyle(t14,s1);
ax1=uiaxes(g3);
ax1.Layout.Row=1;
ax1.Layout.Column=2;
ax_heat=uipanel(g3);
ax_heat.Layout.Row=2;
ax_heat.Layout.Column=1;
ax_box=uiaxes(g3);
ax_box.Layout.Row=2;
ax_box.Layout.Column=2;
The heatmap is calculated and assigned to the uipanel as follows:
R=corr(Data);
hm=heatmap(ax_heat,variables, variables,R,’Colormap’,jet);
Is there a way to "force" the size of the heatmap to fill the entire uipanel?
Why is the behaviour different between debugging (perfect) and normal mode?
Thanks in advance! uipanel, uigridlayout, heatmap, debugging MATLAB Answers — New Questions
Unexpected Microsoft Defender for Office 365 License Requirement for Shared Mailboxes
If a Tenant Has Microsoft Defender for Office 365, Its Shared Mailboxes Need Licenses
When discussing the need to license Exchange Online shared mailboxes, the usual answer is that Exchange Online Plan 2 licenses are needed when shared mailboxes have an extended quota (100 GB instead of 50 GB), an archive mailbox, or are on litigation hold. In other areas of functionality, like Microsoft 365 retention policies, Microsoft makes it clear that no licenses are needed unless premium features like auto-label policies or adaptive scopes are used.
The usual line taken by Microsoft for licensing shared mailboxes is anchored on the features available in Exchange Server. For example, basic retention processing doesn’t require licenses because Exchange Server includes similar retention policies. But Exchange Server doesn’t support adaptive scopes, so use of that feature creates the need for licenses.
Microsoft Defender for Office 365 Plan 1 and Plan 2
This brings me neatly to the question of licensing shared mailboxes for Microsoft 365 Defender for Office 365 (MDO), an advanced version of Exchange Online Protection (EOP) that offers significantly better protection against threats communicated in email. MDO is available in two plans: MDO Plan 1 for small to medium businesses and included in SKUs like Microsoft 365 Business Premium, and MDO Plan 2, which is targeted at enterprises but can be bought and deployed by SME tenants.
From an enterprise perspective, the thing to remember is that MDO Plan 2 is only included in E5 SKUs like Microsoft 365 E5 (see this chart for more information). Figure 1 shows the Threat Analytics feature licensed by MDO Plan 2.

The MDO service description says that shared mailboxes in MDO Plan 1 tenants must have licenses if the mailboxes “benefit from Defender for Office 365 protections.” No further guidance is given to define how shared mailboxes benefit from MDO but given that MDO includes features like Safe Attachments and Safe Links, you could say that any shared mailbox that receives email from external senders benefits from malware scanning and threat protection performed by MDO. And because any shared mailbox can send and receive email, Microsoft considers that all shared mailboxes need MDO licenses.
The situation is simpler for enterprise tenants because the guidance here is that MDO licenses are required for “All shared mailboxes on the tenant.” In effect, this means that any Microsoft 365 tenant that implements the features licensed by Microsoft Defender for Office 365 Plan 2 (see the features description) because they have acquired some E5 licenses must license all shared mailboxes for MDO. In fact, the text of the Microsoft Defender for Office 365 service description goes on to say that user accounts that don’t have E5 licenses must also be licensed for MDO. The text says that licenses must be acquired for “All Exchange Online users on the tenant. This is because Plan 2 features and capabilities protect all users in the tenant.”
The Sudden Realization that Shared Licenses Need MDO Licenses
I’m not sure that many tenants with MDO understand the need to license shared mailboxes. The MDO Plan 2 license costs $5/month with a 12-month commitment, or $60 per shared mailbox annually. Some organizations make heavy use of shared mailboxes, including as a method to preserve mailboxes for ex-employees (inactive mailboxes are the recommended approach). A thousand shared mailboxes will therefore rack up an unexpected $60,000 bill, and that amount doesn’t include any additional licenses that might be needed to bring non-E5 mailboxes into compliance.
I haven’t heard of any Microsoft campaign to make tenants aware of how MDO licensing works for shared mailboxes, nor is there a code check in Outlook to detect and advise when MDO licenses are necessary. The Exchange Admin Center (EAC) includes an option to switch a user mailbox to a shared mailbox, and that option doesn’t warn administrators about potential licensing requirements.
To be honest, I was unaware of the need until I read the service description after being asked if shared mailboxes needed MDO licenses because a customer had been unexpectedly told that the licenses were required. I suspect that many others are in the same state of blissful licensing ignorance.
Unexpected Painful Costs
Any unexpected cost is bad news. Suddenly discovering that a tenant has a batch of unlicensed shared mailboxes is firmly in that category. Discovering that some user accounts that don’t have E5 licenses might need MDO licenses is also painful. There’s nothing good to report here.
Error message when rim ‘plot’ or ‘imshow’, etc
Just updated from 2019a to 2025a, both on the same PC running Windows 10, with Inter(R) UHD Graphics 630, driver version 31.0.101.2134. Error appeared when testing, e.g. plot(randn(1, 64)):
Warning: Error in state of SceneNode.
Invalid type of input arguments (should be uint64)
Error using +
Invalid type of input arguments (should be uint64)
Error in matlab.graphics.interaction.graphicscontrol.InteractionsManager/registerInteraction
Error in matlab.graphics.interaction.interactioncontainers.BaseAxesInteractionContainer/createDefaultWebAxesInteractions
Error in matlab.graphics.interaction.interactioncontainers.CartesianAxesInteractionContainer/createDefaultWebAxesInteractions
Error in matlab.graphics.interaction.interactioncontainers.BaseAxesInteractionContainer/setupInteractions
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsOnAxes
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsInSync
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractions>@()matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsInSync(ax,is2dim,numDataSpaces)Just updated from 2019a to 2025a, both on the same PC running Windows 10, with Inter(R) UHD Graphics 630, driver version 31.0.101.2134. Error appeared when testing, e.g. plot(randn(1, 64)):
Warning: Error in state of SceneNode.
Invalid type of input arguments (should be uint64)
Error using +
Invalid type of input arguments (should be uint64)
Error in matlab.graphics.interaction.graphicscontrol.InteractionsManager/registerInteraction
Error in matlab.graphics.interaction.interactioncontainers.BaseAxesInteractionContainer/createDefaultWebAxesInteractions
Error in matlab.graphics.interaction.interactioncontainers.CartesianAxesInteractionContainer/createDefaultWebAxesInteractions
Error in matlab.graphics.interaction.interactioncontainers.BaseAxesInteractionContainer/setupInteractions
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsOnAxes
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsInSync
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractions>@()matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsInSync(ax,is2dim,numDataSpaces) Just updated from 2019a to 2025a, both on the same PC running Windows 10, with Inter(R) UHD Graphics 630, driver version 31.0.101.2134. Error appeared when testing, e.g. plot(randn(1, 64)):
Warning: Error in state of SceneNode.
Invalid type of input arguments (should be uint64)
Error using +
Invalid type of input arguments (should be uint64)
Error in matlab.graphics.interaction.graphicscontrol.InteractionsManager/registerInteraction
Error in matlab.graphics.interaction.interactioncontainers.BaseAxesInteractionContainer/createDefaultWebAxesInteractions
Error in matlab.graphics.interaction.interactioncontainers.CartesianAxesInteractionContainer/createDefaultWebAxesInteractions
Error in matlab.graphics.interaction.interactioncontainers.BaseAxesInteractionContainer/setupInteractions
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsOnAxes
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsInSync
Error in matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractions>@()matlab.graphics.interaction.internal.UnifiedAxesInteractions.createDefaultInteractionsInSync(ax,is2dim,numDataSpaces) plot, graphics engine error MATLAB Answers — New Questions
Can’t figure out what’s wrong with my code
One of the main problems is that there will never be a sign change on the interval so it’ll always execute the first part of the if statement. I commented out the err>errtol part for testing. I don’t know what i’m doing wrong for calculating using the bisection method. I have to use while loops.
% A scale is made with two springs, and when an object is attached to the
% two springs, the springs stretch and the ring at the end of the two
% springs is displaced downwards a distance x.
%
% The relationship between the weight of the object and the distance x is:
% W=(2k/l)(l-lo)(b+x)
% The initial spring length
% lo = sqrt(a^2+b^2)
% The stretched spring length
% l = sqrt(a^2+(b+x)^2)
% for the given scale a=8.0 in. b=5.0 m. and the spring constant k=16.0 lb/in.
% b=5.0 m.=196.85 in.
% Trying to find the deflection x.
%
% Have the user input lower and upper values of the starting
% interval (xl, xu), as well as the weight of the object
% Initialize the error tolerance (errtol)
% and the maximum number of iterations (maxiter)
%
% Check the interval to see if there’s a sign change
%
% while (iterations < maxiter) and (err > errtol)
% Calculate midpoint of the interval xr=(xl+xu)/2
% Calculate error estimate (err)
% Evaluate the function at the midpoint f(xr)
% If the sign of f(xr) is equal to the sign of f(xl)
% if f(xr)*f(xu)>0
% then xr becomes the new xl.
% else xr becomes the new xu.
% end while loop
%
% If err <= errtol
% then solution found, output result
% else display ‘root not found within tolerance
W = input(‘nWhat is the weight of the object attached to the ring in pounds (lb)? ‘);
xl = input(‘nWhat is the lower initial bracket estimate in inches? ‘); %always 0
xu = input(‘nWhat is the upper initial bracket estimate in inches? ‘); %always 10
a = 8.0;
b = 5.0 ;
lo = sqrt(a^2+b^2);
k = 16.0;
errtol = 0.005;
xr = (xl+xu)/2;
maxiter = 10;
iterations = 0;
f = @(x) (2*k/(sqrt(a^2+(b+x)^2)))*((sqrt(a^2+(b+x)^2))-lo)*(b+x);
err = abs((xu-xl)/xu);
xrold = abs((xu-xl)/xu);
while (iterations<maxiter) %|| (err>errtol)
iterations=iterations+1;
xr=(xl+xu)/2;
err = abs((xr-xrold)/xr)*100;
if f(xr)*f(xl)>0
xu = xr;
else
xl = xr;
end
xrold = xr;
endOne of the main problems is that there will never be a sign change on the interval so it’ll always execute the first part of the if statement. I commented out the err>errtol part for testing. I don’t know what i’m doing wrong for calculating using the bisection method. I have to use while loops.
% A scale is made with two springs, and when an object is attached to the
% two springs, the springs stretch and the ring at the end of the two
% springs is displaced downwards a distance x.
%
% The relationship between the weight of the object and the distance x is:
% W=(2k/l)(l-lo)(b+x)
% The initial spring length
% lo = sqrt(a^2+b^2)
% The stretched spring length
% l = sqrt(a^2+(b+x)^2)
% for the given scale a=8.0 in. b=5.0 m. and the spring constant k=16.0 lb/in.
% b=5.0 m.=196.85 in.
% Trying to find the deflection x.
%
% Have the user input lower and upper values of the starting
% interval (xl, xu), as well as the weight of the object
% Initialize the error tolerance (errtol)
% and the maximum number of iterations (maxiter)
%
% Check the interval to see if there’s a sign change
%
% while (iterations < maxiter) and (err > errtol)
% Calculate midpoint of the interval xr=(xl+xu)/2
% Calculate error estimate (err)
% Evaluate the function at the midpoint f(xr)
% If the sign of f(xr) is equal to the sign of f(xl)
% if f(xr)*f(xu)>0
% then xr becomes the new xl.
% else xr becomes the new xu.
% end while loop
%
% If err <= errtol
% then solution found, output result
% else display ‘root not found within tolerance
W = input(‘nWhat is the weight of the object attached to the ring in pounds (lb)? ‘);
xl = input(‘nWhat is the lower initial bracket estimate in inches? ‘); %always 0
xu = input(‘nWhat is the upper initial bracket estimate in inches? ‘); %always 10
a = 8.0;
b = 5.0 ;
lo = sqrt(a^2+b^2);
k = 16.0;
errtol = 0.005;
xr = (xl+xu)/2;
maxiter = 10;
iterations = 0;
f = @(x) (2*k/(sqrt(a^2+(b+x)^2)))*((sqrt(a^2+(b+x)^2))-lo)*(b+x);
err = abs((xu-xl)/xu);
xrold = abs((xu-xl)/xu);
while (iterations<maxiter) %|| (err>errtol)
iterations=iterations+1;
xr=(xl+xu)/2;
err = abs((xr-xrold)/xr)*100;
if f(xr)*f(xl)>0
xu = xr;
else
xl = xr;
end
xrold = xr;
end One of the main problems is that there will never be a sign change on the interval so it’ll always execute the first part of the if statement. I commented out the err>errtol part for testing. I don’t know what i’m doing wrong for calculating using the bisection method. I have to use while loops.
% A scale is made with two springs, and when an object is attached to the
% two springs, the springs stretch and the ring at the end of the two
% springs is displaced downwards a distance x.
%
% The relationship between the weight of the object and the distance x is:
% W=(2k/l)(l-lo)(b+x)
% The initial spring length
% lo = sqrt(a^2+b^2)
% The stretched spring length
% l = sqrt(a^2+(b+x)^2)
% for the given scale a=8.0 in. b=5.0 m. and the spring constant k=16.0 lb/in.
% b=5.0 m.=196.85 in.
% Trying to find the deflection x.
%
% Have the user input lower and upper values of the starting
% interval (xl, xu), as well as the weight of the object
% Initialize the error tolerance (errtol)
% and the maximum number of iterations (maxiter)
%
% Check the interval to see if there’s a sign change
%
% while (iterations < maxiter) and (err > errtol)
% Calculate midpoint of the interval xr=(xl+xu)/2
% Calculate error estimate (err)
% Evaluate the function at the midpoint f(xr)
% If the sign of f(xr) is equal to the sign of f(xl)
% if f(xr)*f(xu)>0
% then xr becomes the new xl.
% else xr becomes the new xu.
% end while loop
%
% If err <= errtol
% then solution found, output result
% else display ‘root not found within tolerance
W = input(‘nWhat is the weight of the object attached to the ring in pounds (lb)? ‘);
xl = input(‘nWhat is the lower initial bracket estimate in inches? ‘); %always 0
xu = input(‘nWhat is the upper initial bracket estimate in inches? ‘); %always 10
a = 8.0;
b = 5.0 ;
lo = sqrt(a^2+b^2);
k = 16.0;
errtol = 0.005;
xr = (xl+xu)/2;
maxiter = 10;
iterations = 0;
f = @(x) (2*k/(sqrt(a^2+(b+x)^2)))*((sqrt(a^2+(b+x)^2))-lo)*(b+x);
err = abs((xu-xl)/xu);
xrold = abs((xu-xl)/xu);
while (iterations<maxiter) %|| (err>errtol)
iterations=iterations+1;
xr=(xl+xu)/2;
err = abs((xr-xrold)/xr)*100;
if f(xr)*f(xl)>0
xu = xr;
else
xl = xr;
end
xrold = xr;
end bisection, while loop MATLAB Answers — New Questions
Error in parallel pool
parpool(‘local’, numWorkers);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Caused by:
Error using
parallel.internal.pool.SpfClientSession
Failed to open any port in the range [27370
28370]. Verify that at least one port is
available in this range and not in use by
another process on this machine. Cause:
Failed to bind to ::1:28370 with error:
Cannot assign requested address.parpool(‘local’, numWorkers);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Caused by:
Error using
parallel.internal.pool.SpfClientSession
Failed to open any port in the range [27370
28370]. Verify that at least one port is
available in this range and not in use by
another process on this machine. Cause:
Failed to bind to ::1:28370 with error:
Cannot assign requested address. parpool(‘local’, numWorkers);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Caused by:
Error using
parallel.internal.pool.SpfClientSession
Failed to open any port in the range [27370
28370]. Verify that at least one port is
available in this range and not in use by
another process on this machine. Cause:
Failed to bind to ::1:28370 with error:
Cannot assign requested address. parfor MATLAB Answers — New Questions
How to create a GUI in App Designer starting from existing code
I am attempting to use AI to generate an initial design for a GUI. I would like to copy the code that is generated and input it directly into the Code View of the App Designer. I would then like to make further adjustments using some of the App Designer tools (i.e. Design View). However, I cannot copy the code directly over, as App Designer doesn’t let the user edit portions of the code. Is there a way to edit the grayed-out code? Or a way to easily integrate the generated code into an .mlapp file?I am attempting to use AI to generate an initial design for a GUI. I would like to copy the code that is generated and input it directly into the Code View of the App Designer. I would then like to make further adjustments using some of the App Designer tools (i.e. Design View). However, I cannot copy the code directly over, as App Designer doesn’t let the user edit portions of the code. Is there a way to edit the grayed-out code? Or a way to easily integrate the generated code into an .mlapp file? I am attempting to use AI to generate an initial design for a GUI. I would like to copy the code that is generated and input it directly into the Code View of the App Designer. I would then like to make further adjustments using some of the App Designer tools (i.e. Design View). However, I cannot copy the code directly over, as App Designer doesn’t let the user edit portions of the code. Is there a way to edit the grayed-out code? Or a way to easily integrate the generated code into an .mlapp file? appdesigner, app designer MATLAB Answers — New Questions
Plot not showing the desired markers and does not match the legend
Hello everyone,
I am trying to plot theta vs Cp. Cp here is calculated based on the function provided. However when plotted, the markers are not showing properly and does not match the legend.
Any help is appreciated!
I have attached the plot as well as the function and the main file.
Function File:
function Cp = Experiment_1(H,Ch11)
cu = 9.8; %mm of H20 to Pascal
%H=[-0.3,-0.5,-2.1,-3.3,-3.5,-3.2,-3.1,-3.1,-3.2,-2.7];
Ch11 = Ch11.*cu; % Converting channel 11 pressure to Pascal
for i=1:length(H)
H(i) = H(i).*cu; % To convert to Pascal
end
% Convert pressure readings to total pressure
P_atm = 99991.7925; % Pascal
for i=1:length(H)
Pt(i) = P_atm + H(i);
end
Ch11 = P_atm + Ch11;
% theta
theta = linspace(0,180,10);
% Generate the plot for total pressure
%{
plot(theta,Pt, ‘o’, ‘MarkerSize’, 5, ‘MarkerEdgeColor’, ‘r’, ‘MarkerFaceColor’, ‘g’);
xlabel("$theta[degrees]$","Interpreter","latex","FontSize",12)
ylabel("$Total Pressure, P_{o}[atm]$","Interpreter","latex","FontSize",12)
grid on
axis equal
set(gca,’TickLabelInterpreter’,’latex’,’layer’,’top’);
set(gca,’TickDir’,’out’)
set(gca, ‘Layer’, ‘bottom’)
%}
% Calculation of Cp experimental
Cp = (Pt- Ch11)./((1.0/2.0)*1.225*6.4*6.4);
% Plot the Cp along the circular cylinder
plot(theta, Cp, ‘-d’, ‘MarkerSize’,5,’MarkerEdgeColor’, ‘r’, ‘MarkerFaceColor’, ‘g’);
hold on
plot(theta, Cp, ‘-o’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-+’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-*’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-x’, ‘MarkerSize’,5)
xlabel(‘$theta [^circ]$’,"Interpreter","latex","FontSize",12)
ylabel(‘$C_p$’,"Interpreter","latex","FontSize",12)
grid on
set(gca,’TickLabelInterpreter’,’latex’,’layer’,’top’);
set(gca,’TickDir’,’out’)
set(gca, ‘Layer’, ‘bottom’)
legend("V=6.4 m/s", "V = 8.7 m/s" , "V = 11 m/s" , "V = 14.3 m/s", "V=12.1 m/s","Interpreter","latex")
%%
sfname = "C:IITM MATLABLAB AS5110Images";
export_fig(strcat(sfname,’Cp20Fan’),’-png’,’-transparent’,’-m4′);
Main File:
figure;
hold on;
H20 = [-0.3,-0.5,-2.1,-3.3,-3.5,-3.2,-3.1,-3.1,-3.2,-2.7];
Ch11_1 = -2.1;
H30 = [-0.3,-1.2,-4.5,-7.4,-7.5,-7.1,-6.9,-7.0,-7.0,-6.5];
Ch11_2 = -4.1;
H40 = [-0.3,-2.2,-7.5,-12.5,-12.4,-11.9,-11.8,-12.3,-12.1,-11.4];
Ch11_3 = -7.0;
H45 = [-0.5,-2.7,-9.4,-15.6,-15.6,-14.8,-14.8,-15.1,-15.0,-14.4];
Ch11_4 = -8.7;
H55 = [-0.5,-3.9,-13.4,-22.4,-22.0,-21.1,-21.0,-21.8,-21.6,-20.9];
Ch11_5 = -12.2;
Cp20 = Experiment_1(H20, Ch11_1);
Cp30 = Experiment_1(H30, Ch11_2);
Cp40 = Experiment_1(H40, Ch11_3);
Cp45 = Experiment_1(H45, Ch11_4);
Cp55 = Experiment_1(H55, Ch11_5);Hello everyone,
I am trying to plot theta vs Cp. Cp here is calculated based on the function provided. However when plotted, the markers are not showing properly and does not match the legend.
Any help is appreciated!
I have attached the plot as well as the function and the main file.
Function File:
function Cp = Experiment_1(H,Ch11)
cu = 9.8; %mm of H20 to Pascal
%H=[-0.3,-0.5,-2.1,-3.3,-3.5,-3.2,-3.1,-3.1,-3.2,-2.7];
Ch11 = Ch11.*cu; % Converting channel 11 pressure to Pascal
for i=1:length(H)
H(i) = H(i).*cu; % To convert to Pascal
end
% Convert pressure readings to total pressure
P_atm = 99991.7925; % Pascal
for i=1:length(H)
Pt(i) = P_atm + H(i);
end
Ch11 = P_atm + Ch11;
% theta
theta = linspace(0,180,10);
% Generate the plot for total pressure
%{
plot(theta,Pt, ‘o’, ‘MarkerSize’, 5, ‘MarkerEdgeColor’, ‘r’, ‘MarkerFaceColor’, ‘g’);
xlabel("$theta[degrees]$","Interpreter","latex","FontSize",12)
ylabel("$Total Pressure, P_{o}[atm]$","Interpreter","latex","FontSize",12)
grid on
axis equal
set(gca,’TickLabelInterpreter’,’latex’,’layer’,’top’);
set(gca,’TickDir’,’out’)
set(gca, ‘Layer’, ‘bottom’)
%}
% Calculation of Cp experimental
Cp = (Pt- Ch11)./((1.0/2.0)*1.225*6.4*6.4);
% Plot the Cp along the circular cylinder
plot(theta, Cp, ‘-d’, ‘MarkerSize’,5,’MarkerEdgeColor’, ‘r’, ‘MarkerFaceColor’, ‘g’);
hold on
plot(theta, Cp, ‘-o’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-+’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-*’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-x’, ‘MarkerSize’,5)
xlabel(‘$theta [^circ]$’,"Interpreter","latex","FontSize",12)
ylabel(‘$C_p$’,"Interpreter","latex","FontSize",12)
grid on
set(gca,’TickLabelInterpreter’,’latex’,’layer’,’top’);
set(gca,’TickDir’,’out’)
set(gca, ‘Layer’, ‘bottom’)
legend("V=6.4 m/s", "V = 8.7 m/s" , "V = 11 m/s" , "V = 14.3 m/s", "V=12.1 m/s","Interpreter","latex")
%%
sfname = "C:IITM MATLABLAB AS5110Images";
export_fig(strcat(sfname,’Cp20Fan’),’-png’,’-transparent’,’-m4′);
Main File:
figure;
hold on;
H20 = [-0.3,-0.5,-2.1,-3.3,-3.5,-3.2,-3.1,-3.1,-3.2,-2.7];
Ch11_1 = -2.1;
H30 = [-0.3,-1.2,-4.5,-7.4,-7.5,-7.1,-6.9,-7.0,-7.0,-6.5];
Ch11_2 = -4.1;
H40 = [-0.3,-2.2,-7.5,-12.5,-12.4,-11.9,-11.8,-12.3,-12.1,-11.4];
Ch11_3 = -7.0;
H45 = [-0.5,-2.7,-9.4,-15.6,-15.6,-14.8,-14.8,-15.1,-15.0,-14.4];
Ch11_4 = -8.7;
H55 = [-0.5,-3.9,-13.4,-22.4,-22.0,-21.1,-21.0,-21.8,-21.6,-20.9];
Ch11_5 = -12.2;
Cp20 = Experiment_1(H20, Ch11_1);
Cp30 = Experiment_1(H30, Ch11_2);
Cp40 = Experiment_1(H40, Ch11_3);
Cp45 = Experiment_1(H45, Ch11_4);
Cp55 = Experiment_1(H55, Ch11_5); Hello everyone,
I am trying to plot theta vs Cp. Cp here is calculated based on the function provided. However when plotted, the markers are not showing properly and does not match the legend.
Any help is appreciated!
I have attached the plot as well as the function and the main file.
Function File:
function Cp = Experiment_1(H,Ch11)
cu = 9.8; %mm of H20 to Pascal
%H=[-0.3,-0.5,-2.1,-3.3,-3.5,-3.2,-3.1,-3.1,-3.2,-2.7];
Ch11 = Ch11.*cu; % Converting channel 11 pressure to Pascal
for i=1:length(H)
H(i) = H(i).*cu; % To convert to Pascal
end
% Convert pressure readings to total pressure
P_atm = 99991.7925; % Pascal
for i=1:length(H)
Pt(i) = P_atm + H(i);
end
Ch11 = P_atm + Ch11;
% theta
theta = linspace(0,180,10);
% Generate the plot for total pressure
%{
plot(theta,Pt, ‘o’, ‘MarkerSize’, 5, ‘MarkerEdgeColor’, ‘r’, ‘MarkerFaceColor’, ‘g’);
xlabel("$theta[degrees]$","Interpreter","latex","FontSize",12)
ylabel("$Total Pressure, P_{o}[atm]$","Interpreter","latex","FontSize",12)
grid on
axis equal
set(gca,’TickLabelInterpreter’,’latex’,’layer’,’top’);
set(gca,’TickDir’,’out’)
set(gca, ‘Layer’, ‘bottom’)
%}
% Calculation of Cp experimental
Cp = (Pt- Ch11)./((1.0/2.0)*1.225*6.4*6.4);
% Plot the Cp along the circular cylinder
plot(theta, Cp, ‘-d’, ‘MarkerSize’,5,’MarkerEdgeColor’, ‘r’, ‘MarkerFaceColor’, ‘g’);
hold on
plot(theta, Cp, ‘-o’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-+’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-*’, ‘MarkerSize’,5)
hold on
plot(theta, Cp, ‘-x’, ‘MarkerSize’,5)
xlabel(‘$theta [^circ]$’,"Interpreter","latex","FontSize",12)
ylabel(‘$C_p$’,"Interpreter","latex","FontSize",12)
grid on
set(gca,’TickLabelInterpreter’,’latex’,’layer’,’top’);
set(gca,’TickDir’,’out’)
set(gca, ‘Layer’, ‘bottom’)
legend("V=6.4 m/s", "V = 8.7 m/s" , "V = 11 m/s" , "V = 14.3 m/s", "V=12.1 m/s","Interpreter","latex")
%%
sfname = "C:IITM MATLABLAB AS5110Images";
export_fig(strcat(sfname,’Cp20Fan’),’-png’,’-transparent’,’-m4′);
Main File:
figure;
hold on;
H20 = [-0.3,-0.5,-2.1,-3.3,-3.5,-3.2,-3.1,-3.1,-3.2,-2.7];
Ch11_1 = -2.1;
H30 = [-0.3,-1.2,-4.5,-7.4,-7.5,-7.1,-6.9,-7.0,-7.0,-6.5];
Ch11_2 = -4.1;
H40 = [-0.3,-2.2,-7.5,-12.5,-12.4,-11.9,-11.8,-12.3,-12.1,-11.4];
Ch11_3 = -7.0;
H45 = [-0.5,-2.7,-9.4,-15.6,-15.6,-14.8,-14.8,-15.1,-15.0,-14.4];
Ch11_4 = -8.7;
H55 = [-0.5,-3.9,-13.4,-22.4,-22.0,-21.1,-21.0,-21.8,-21.6,-20.9];
Ch11_5 = -12.2;
Cp20 = Experiment_1(H20, Ch11_1);
Cp30 = Experiment_1(H30, Ch11_2);
Cp40 = Experiment_1(H40, Ch11_3);
Cp45 = Experiment_1(H45, Ch11_4);
Cp55 = Experiment_1(H55, Ch11_5); matlab, plot, markers, legend MATLAB Answers — New Questions
Triangular-weighted moving average filter
Hi,
I`m looking for function or source code for Triangular-weighted moving average filter to apply it and make my data processing.
High-frequency noise shall be removed from the measured signals using a triangular-weighted moving average with a smoothing width of 100 ms.
can someone share the experience ?Hi,
I`m looking for function or source code for Triangular-weighted moving average filter to apply it and make my data processing.
High-frequency noise shall be removed from the measured signals using a triangular-weighted moving average with a smoothing width of 100 ms.
can someone share the experience ? Hi,
I`m looking for function or source code for Triangular-weighted moving average filter to apply it and make my data processing.
High-frequency noise shall be removed from the measured signals using a triangular-weighted moving average with a smoothing width of 100 ms.
can someone share the experience ? filter, data processing MATLAB Answers — New Questions
MATLAB’s inefficient copy-on-write implementation
MATLAB’s copy-on-write memory management seems to have a serious defect, which I think is the reason behind the abysmal performance of subsasgn overloading. (The same problem probably occurs with parenAssign in the new R2021b RedefinesParen class — I haven’t yet experimented with it.) Normally, an array assignment like b = a simply does a pointer copy; the array data is not copied until b is modified (e.g. b(1) = 1). Thereafter, subsequent modification of b (e.g. b(2) = 1) do not copy the full array; they just modify it in place as long as the reference count is 1. For example,
clear, a = zeros(1e8,1);
memory % 2764 MB used by MATLAB
b = a;
memory % 2764 MB
tic, b(1) = 1; toc, memory % 0.329099 seconds, 3540 MB
tic, b(2) = 1; toc, memory % 0.000123 seconds, 3541 MB
However, the benefit of copy-on-write is lost when the variable is changed in a function, e.g.
% test.m
function x = test(x)
x(1) = 1;
In this case, the x reference count is apparently incremented in test before the assignment is made, so this will always result in a full array copy. For example,
clear, a = zeros(1e8,1);
tic, a = test(a); toc % 0.337475 seconds
tic, a = test(a); toc % 0.310373 seconds
To see what’s happening with copy-on-write, test.m is modified as follows:
function x = test(x)
memory
x(1) = 1;
memory
return
The array modification inside the function forces a full array copy, even though the original array is immediately discarded:
clear, a = zeros(1e8,1);
memory % 2748 MB
a = test(a); % 2748 MB, 3503 MB
memory % 2740 MB
I would think this problem could be easily avoided by treating any variable that appears as both an input and output argument in a function (e.g. function x = test(x)) as a reference variable, i.e. its reference count is not incremented on entering the function and is not decremented upon exiting. If the function is called with different input and output arguments, e.g. y = test(x), then the interpreter would implement this as y = x; y = test(y).
Is there any particular reason why MATLAB does not or cannot do this? There are many applications such as subasgn overloading that could see a big performance boost if this problem is fixed.MATLAB’s copy-on-write memory management seems to have a serious defect, which I think is the reason behind the abysmal performance of subsasgn overloading. (The same problem probably occurs with parenAssign in the new R2021b RedefinesParen class — I haven’t yet experimented with it.) Normally, an array assignment like b = a simply does a pointer copy; the array data is not copied until b is modified (e.g. b(1) = 1). Thereafter, subsequent modification of b (e.g. b(2) = 1) do not copy the full array; they just modify it in place as long as the reference count is 1. For example,
clear, a = zeros(1e8,1);
memory % 2764 MB used by MATLAB
b = a;
memory % 2764 MB
tic, b(1) = 1; toc, memory % 0.329099 seconds, 3540 MB
tic, b(2) = 1; toc, memory % 0.000123 seconds, 3541 MB
However, the benefit of copy-on-write is lost when the variable is changed in a function, e.g.
% test.m
function x = test(x)
x(1) = 1;
In this case, the x reference count is apparently incremented in test before the assignment is made, so this will always result in a full array copy. For example,
clear, a = zeros(1e8,1);
tic, a = test(a); toc % 0.337475 seconds
tic, a = test(a); toc % 0.310373 seconds
To see what’s happening with copy-on-write, test.m is modified as follows:
function x = test(x)
memory
x(1) = 1;
memory
return
The array modification inside the function forces a full array copy, even though the original array is immediately discarded:
clear, a = zeros(1e8,1);
memory % 2748 MB
a = test(a); % 2748 MB, 3503 MB
memory % 2740 MB
I would think this problem could be easily avoided by treating any variable that appears as both an input and output argument in a function (e.g. function x = test(x)) as a reference variable, i.e. its reference count is not incremented on entering the function and is not decremented upon exiting. If the function is called with different input and output arguments, e.g. y = test(x), then the interpreter would implement this as y = x; y = test(y).
Is there any particular reason why MATLAB does not or cannot do this? There are many applications such as subasgn overloading that could see a big performance boost if this problem is fixed. MATLAB’s copy-on-write memory management seems to have a serious defect, which I think is the reason behind the abysmal performance of subsasgn overloading. (The same problem probably occurs with parenAssign in the new R2021b RedefinesParen class — I haven’t yet experimented with it.) Normally, an array assignment like b = a simply does a pointer copy; the array data is not copied until b is modified (e.g. b(1) = 1). Thereafter, subsequent modification of b (e.g. b(2) = 1) do not copy the full array; they just modify it in place as long as the reference count is 1. For example,
clear, a = zeros(1e8,1);
memory % 2764 MB used by MATLAB
b = a;
memory % 2764 MB
tic, b(1) = 1; toc, memory % 0.329099 seconds, 3540 MB
tic, b(2) = 1; toc, memory % 0.000123 seconds, 3541 MB
However, the benefit of copy-on-write is lost when the variable is changed in a function, e.g.
% test.m
function x = test(x)
x(1) = 1;
In this case, the x reference count is apparently incremented in test before the assignment is made, so this will always result in a full array copy. For example,
clear, a = zeros(1e8,1);
tic, a = test(a); toc % 0.337475 seconds
tic, a = test(a); toc % 0.310373 seconds
To see what’s happening with copy-on-write, test.m is modified as follows:
function x = test(x)
memory
x(1) = 1;
memory
return
The array modification inside the function forces a full array copy, even though the original array is immediately discarded:
clear, a = zeros(1e8,1);
memory % 2748 MB
a = test(a); % 2748 MB, 3503 MB
memory % 2740 MB
I would think this problem could be easily avoided by treating any variable that appears as both an input and output argument in a function (e.g. function x = test(x)) as a reference variable, i.e. its reference count is not incremented on entering the function and is not decremented upon exiting. If the function is called with different input and output arguments, e.g. y = test(x), then the interpreter would implement this as y = x; y = test(y).
Is there any particular reason why MATLAB does not or cannot do this? There are many applications such as subasgn overloading that could see a big performance boost if this problem is fixed. memory management, copy-on-write, subsasgn, parenassign MATLAB Answers — New Questions
Getting rid of IntCon in GA
I have code for a genetic algorithm as follows (which I got from a matlab example):
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon, [1,2])
the [1,2] parameter corresponds to IntCon (see https://www.mathworks.com/help/gads/ga.html#d122e40769), and it is restricting x(1) and x(2) to integer values (which I don’t want). I want to get rid of this but when I delete it and run:
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon)
I get this error:
Error using constrValidate (line 59)
Constraint function must return real value.
Error in gacommon (line 125)
[LinearConstr, Iterate,nineqcstr,neqcstr,ncstr] = constrValidate(NonconFcn, …
Error in ga (line 364)
NonconFcn,options,Iterate,type] = gacommon(nvars,fun,Aineq,bineq,Aeq,beq,lb,ub, …
Error in Model_Building_2 (line 101)
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon)
can anyone think of any reason why this happens? the code runs well with any variable in IntCon (ie it can be [3], [4], [2,3] or any other combination) as long as there is at least one. using empty brackets [] returns the same error as above.
thanks in advance!I have code for a genetic algorithm as follows (which I got from a matlab example):
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon, [1,2])
the [1,2] parameter corresponds to IntCon (see https://www.mathworks.com/help/gads/ga.html#d122e40769), and it is restricting x(1) and x(2) to integer values (which I don’t want). I want to get rid of this but when I delete it and run:
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon)
I get this error:
Error using constrValidate (line 59)
Constraint function must return real value.
Error in gacommon (line 125)
[LinearConstr, Iterate,nineqcstr,neqcstr,ncstr] = constrValidate(NonconFcn, …
Error in ga (line 364)
NonconFcn,options,Iterate,type] = gacommon(nvars,fun,Aineq,bineq,Aeq,beq,lb,ub, …
Error in Model_Building_2 (line 101)
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon)
can anyone think of any reason why this happens? the code runs well with any variable in IntCon (ie it can be [3], [4], [2,3] or any other combination) as long as there is at least one. using empty brackets [] returns the same error as above.
thanks in advance! I have code for a genetic algorithm as follows (which I got from a matlab example):
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon, [1,2])
the [1,2] parameter corresponds to IntCon (see https://www.mathworks.com/help/gads/ga.html#d122e40769), and it is restricting x(1) and x(2) to integer values (which I don’t want). I want to get rid of this but when I delete it and run:
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon)
I get this error:
Error using constrValidate (line 59)
Constraint function must return real value.
Error in gacommon (line 125)
[LinearConstr, Iterate,nineqcstr,neqcstr,ncstr] = constrValidate(NonconFcn, …
Error in ga (line 364)
NonconFcn,options,Iterate,type] = gacommon(nvars,fun,Aineq,bineq,Aeq,beq,lb,ub, …
Error in Model_Building_2 (line 101)
[x,fval] = ga(@objfun,4,A,b,Aeq,beq,lb,ub,@nonlcon)
can anyone think of any reason why this happens? the code runs well with any variable in IntCon (ie it can be [3], [4], [2,3] or any other combination) as long as there is at least one. using empty brackets [] returns the same error as above.
thanks in advance! genetic algorithm, ga, optimization, global optimization, optimisation, intcon MATLAB Answers — New Questions
Inquiry on Time Complexity of cumsum
Hello,
My name is Asaro Hong, an M.S. student in Mechanical Engineering at Inha University.
In P2D lithium-ion battery model calculations, I frequently use cumsum on 1D vectors. I’d like to confirm the following:
What is the time complexity (Big-O) of cumsum with respect to input length n?
With Parallel Computing Toolbox or when using GPU arrays (gpuArray), are there documented differences in time complexity or constant factors/overhead?
For citation in a paper, could you point me to any official references (product documentation, technical notes, benchmark materials, etc.)?
Environment: MATLAB R2024a, Windows 10
Thank you for your help.Hello,
My name is Asaro Hong, an M.S. student in Mechanical Engineering at Inha University.
In P2D lithium-ion battery model calculations, I frequently use cumsum on 1D vectors. I’d like to confirm the following:
What is the time complexity (Big-O) of cumsum with respect to input length n?
With Parallel Computing Toolbox or when using GPU arrays (gpuArray), are there documented differences in time complexity or constant factors/overhead?
For citation in a paper, could you point me to any official references (product documentation, technical notes, benchmark materials, etc.)?
Environment: MATLAB R2024a, Windows 10
Thank you for your help. Hello,
My name is Asaro Hong, an M.S. student in Mechanical Engineering at Inha University.
In P2D lithium-ion battery model calculations, I frequently use cumsum on 1D vectors. I’d like to confirm the following:
What is the time complexity (Big-O) of cumsum with respect to input length n?
With Parallel Computing Toolbox or when using GPU arrays (gpuArray), are there documented differences in time complexity or constant factors/overhead?
For citation in a paper, could you point me to any official references (product documentation, technical notes, benchmark materials, etc.)?
Environment: MATLAB R2024a, Windows 10
Thank you for your help. algorithm MATLAB Answers — New Questions
Use string to define variable
Hello guys!
I am looking for a way to name a variable with a string name that will be changing according to the T and V values
My code is the following:
——————————-
T=15; % input variable T
V=1; % input variable V
load(‘FRF_T15_V1.mat’)
load(‘FRF_T15_V2.mat’)
load(‘FRF_T15_V3.mat’)
formatSpec = ‘FRF_T%d_V%d’;
filename = sprintf(formatSpec,T,V);
x=eval(filename);
XP=(x{3,3});
save (‘XP,’XP’)
—————————–
I would like for variable XP to be assigned according to the input values of T and V, e.g.,
FRF_T15_V1_XP=(x{3,3});
And then save it as
save (‘ FRF_T15_V1_XP,’ FRF_T15_V1_XP ‘)
Thanks in advance for your help!
Kind regards,
HugoHello guys!
I am looking for a way to name a variable with a string name that will be changing according to the T and V values
My code is the following:
——————————-
T=15; % input variable T
V=1; % input variable V
load(‘FRF_T15_V1.mat’)
load(‘FRF_T15_V2.mat’)
load(‘FRF_T15_V3.mat’)
formatSpec = ‘FRF_T%d_V%d’;
filename = sprintf(formatSpec,T,V);
x=eval(filename);
XP=(x{3,3});
save (‘XP,’XP’)
—————————–
I would like for variable XP to be assigned according to the input values of T and V, e.g.,
FRF_T15_V1_XP=(x{3,3});
And then save it as
save (‘ FRF_T15_V1_XP,’ FRF_T15_V1_XP ‘)
Thanks in advance for your help!
Kind regards,
Hugo Hello guys!
I am looking for a way to name a variable with a string name that will be changing according to the T and V values
My code is the following:
——————————-
T=15; % input variable T
V=1; % input variable V
load(‘FRF_T15_V1.mat’)
load(‘FRF_T15_V2.mat’)
load(‘FRF_T15_V3.mat’)
formatSpec = ‘FRF_T%d_V%d’;
filename = sprintf(formatSpec,T,V);
x=eval(filename);
XP=(x{3,3});
save (‘XP,’XP’)
—————————–
I would like for variable XP to be assigned according to the input values of T and V, e.g.,
FRF_T15_V1_XP=(x{3,3});
And then save it as
save (‘ FRF_T15_V1_XP,’ FRF_T15_V1_XP ‘)
Thanks in advance for your help!
Kind regards,
Hugo string, variable MATLAB Answers — New Questions
ROS2 communication between docker container and Matlab.
Hello,
I followed this guide to set up a docker container to run gazebo: https://www.mathworks.com/help/ros/ug/install-and-set-up-docker-for-ros-2-and-gazebo.html. I’m now trying to follow this guide to connect to the docker container from Simulink: https://www.mathworks.com/help/ros/ug/connect-to-a-ros-enabled-robot-from-simulink-over-ros2.html. I’m using an intel macOS with Sequoia.
The issue I’m having is that I’m not able to get the ros2 topics to show up in Matlab. They are showing correctly according to the guide inside the container, but on the matlab side they are not reflecting. I’ve set the domain ID on both sides to be 25 and to use rmw_fastrtps_cpp. On the matlab side the only topics that are being picked up are /parameter_events and /rosout.
Any insight into why Matlab is not picking up the topics that are reflecting inside the docker container would be greatly appreciated.
Thanks!Hello,
I followed this guide to set up a docker container to run gazebo: https://www.mathworks.com/help/ros/ug/install-and-set-up-docker-for-ros-2-and-gazebo.html. I’m now trying to follow this guide to connect to the docker container from Simulink: https://www.mathworks.com/help/ros/ug/connect-to-a-ros-enabled-robot-from-simulink-over-ros2.html. I’m using an intel macOS with Sequoia.
The issue I’m having is that I’m not able to get the ros2 topics to show up in Matlab. They are showing correctly according to the guide inside the container, but on the matlab side they are not reflecting. I’ve set the domain ID on both sides to be 25 and to use rmw_fastrtps_cpp. On the matlab side the only topics that are being picked up are /parameter_events and /rosout.
Any insight into why Matlab is not picking up the topics that are reflecting inside the docker container would be greatly appreciated.
Thanks! Hello,
I followed this guide to set up a docker container to run gazebo: https://www.mathworks.com/help/ros/ug/install-and-set-up-docker-for-ros-2-and-gazebo.html. I’m now trying to follow this guide to connect to the docker container from Simulink: https://www.mathworks.com/help/ros/ug/connect-to-a-ros-enabled-robot-from-simulink-over-ros2.html. I’m using an intel macOS with Sequoia.
The issue I’m having is that I’m not able to get the ros2 topics to show up in Matlab. They are showing correctly according to the guide inside the container, but on the matlab side they are not reflecting. I’ve set the domain ID on both sides to be 25 and to use rmw_fastrtps_cpp. On the matlab side the only topics that are being picked up are /parameter_events and /rosout.
Any insight into why Matlab is not picking up the topics that are reflecting inside the docker container would be greatly appreciated.
Thanks! ros2, matlab, docker MATLAB Answers — New Questions
In my laptop J just installed matlab 2020a but is showing the following issue
License checkout failed.
License Manager Error -9
Your username does not match the username in the license file.
To run on this computer, you must run the Activation client to reactivate your license.
Troubleshoot this issue by visiting:
https://www.mathworks.com/support/lme/R2020a/9
Diagnostic Information:
Feature: MATLAB
License path: /home/shishkina/.matlab/R2020a_licenses:/usr/local/MATLAB/R2020a/licenses/license.dat:/usr/local/MAT
LAB/R2020a/licenses/license_shishkina-Inspiron-5379_1096937_R2020a.lic
Licensing error: -9,57.License checkout failed.
License Manager Error -9
Your username does not match the username in the license file.
To run on this computer, you must run the Activation client to reactivate your license.
Troubleshoot this issue by visiting:
https://www.mathworks.com/support/lme/R2020a/9
Diagnostic Information:
Feature: MATLAB
License path: /home/shishkina/.matlab/R2020a_licenses:/usr/local/MATLAB/R2020a/licenses/license.dat:/usr/local/MAT
LAB/R2020a/licenses/license_shishkina-Inspiron-5379_1096937_R2020a.lic
Licensing error: -9,57. License checkout failed.
License Manager Error -9
Your username does not match the username in the license file.
To run on this computer, you must run the Activation client to reactivate your license.
Troubleshoot this issue by visiting:
https://www.mathworks.com/support/lme/R2020a/9
Diagnostic Information:
Feature: MATLAB
License path: /home/shishkina/.matlab/R2020a_licenses:/usr/local/MATLAB/R2020a/licenses/license.dat:/usr/local/MAT
LAB/R2020a/licenses/license_shishkina-Inspiron-5379_1096937_R2020a.lic
Licensing error: -9,57. matlab runnign MATLAB Answers — New Questions
How to improve the loading performance of a large app?
I have a custom app, which is growing continuously, and has become quite large. Thus, the AppDesigner takes a long time to open this app.I have a custom app, which is growing continuously, and has become quite large. Thus, the AppDesigner takes a long time to open this app. I have a custom app, which is growing continuously, and has become quite large. Thus, the AppDesigner takes a long time to open this app. MATLAB Answers — New Questions
Just downloaded MATLAB 2025a: Workspace is blank and greyed out
I just downloaded MATLAB 2025a and no variables show up in the Workspace, even though they are actually saved in memory. For example, if I just open MATLAB and type x = 1, nothing happens. But when I type x, then MATLAB returns the value stored as 1. Nothing appears in the workspace, no named variables, variable types, the size or class, etc. If I right click on the Workspace and try to make a new variable, nothing happens. The "Save Workspace" and "Clear Workspace" are greyed out. Clicking "Refresh" also doesn’t do anything. See the attached screenshot.
I have tried digging into the MATLAB preferences to see what I am missing, but can’t find anything.
Note that I am running a 2024 MacBook Pro Sequoia 15.5.I just downloaded MATLAB 2025a and no variables show up in the Workspace, even though they are actually saved in memory. For example, if I just open MATLAB and type x = 1, nothing happens. But when I type x, then MATLAB returns the value stored as 1. Nothing appears in the workspace, no named variables, variable types, the size or class, etc. If I right click on the Workspace and try to make a new variable, nothing happens. The "Save Workspace" and "Clear Workspace" are greyed out. Clicking "Refresh" also doesn’t do anything. See the attached screenshot.
I have tried digging into the MATLAB preferences to see what I am missing, but can’t find anything.
Note that I am running a 2024 MacBook Pro Sequoia 15.5. I just downloaded MATLAB 2025a and no variables show up in the Workspace, even though they are actually saved in memory. For example, if I just open MATLAB and type x = 1, nothing happens. But when I type x, then MATLAB returns the value stored as 1. Nothing appears in the workspace, no named variables, variable types, the size or class, etc. If I right click on the Workspace and try to make a new variable, nothing happens. The "Save Workspace" and "Clear Workspace" are greyed out. Clicking "Refresh" also doesn’t do anything. See the attached screenshot.
I have tried digging into the MATLAB preferences to see what I am missing, but can’t find anything.
Note that I am running a 2024 MacBook Pro Sequoia 15.5. workspace, variable, variables, mac MATLAB Answers — New Questions
Teams Gets a KeyQL-Powered Search Box
Not a Trace of SQL in the New Teams Search Box
In June 2020, Microsoft introduced support for basic Keyword Query Language (KeyQL) searches against Teams chat and channel messages. I’m not sure how many people dedicated much time to constructing queries, but the facility existed for those who cared. Five years later, Microsoft is revisiting KeyQL search for Teams, and this time it’s done in a more comprehensive manner because Teams now supports KeyQL searches across more than messages.
The news comes in MC1130388 (6 August 2025, Microsoft 365 roadmap item 496590), which announces that “Teams is introducing SQL-like structured search queries (e.g., from:, in:, is:) to filter messages, files, and conversations more precisely.” The reference to SQL-like search queries excited many commentators, but the allusion to SQL is misleading. What the Teams search bar supports is a modified version of KeyQL to build queries tailored for the Teams environment. It’s like the way that KeyQL supports different kinds of queries for Exchange Online (email items) and SharePoint Online/OneDrive for Business (files). There isn’t a sniff of SQL in the vicinity.
The new search box is rolling out to targeted release tenants and is available for desktop and browser clients. The new search isn’t available for mobile clients. Microsoft expects KeyQL-powered searches to be generally available worldwide by mid-August 2025. User documentation is available online.
Target Audience for the Teams Search Box
Microsoft is more accurate that the new feature “is especially useful for developers and power users who prefer to express specific search intent to narrow down search results.” If users put the effort into learning how to use search effectively, they will find it easier to find what they’re looking for. This is especially so in large organizations that have used Teams for several years when people attempt to find something in a mass of chats and channels can be difficult.
Funnily enough, an organization like Microsoft is exactly the type that is likely to benefit most from the new search box. A large population of technical folks who have been using Teams since its 2017 debut and might have participated in hundreds of chats in that time. Despite the best effort of Teams to hide inactive channels from view, those users probably interact with too many channels for their own sanity, and finding material from more than a few months ago is challenging. The new search box should help these people find items faster.
Using the New Search Box
Figure 1 shows an example of using a KeyQL query to find messages. The query includes a keyword followed by three filters to focus on who sent the messages (from:), when they sent the message (sent:), and the is:Messages filter to specify that the query should only return messages rather than any other type of content like a file. The from: filter accepts either a user’s display name or primary SMTP address. In this example, “Office 365” is in quotes to force Teams to look for an exact match. Without the quotes, Teams find messages with Office or 365.

Other useful search options include:
- In:Channel or group chat name. For example: “in:Microsoft 365 News” searches the Microsoft 365 News channel in any team the user has access to that has a channel of this name.
- Subject:Keyword from a channel message with a subject line. For example, subject:Copilot finds messages with Copilot in the subject.
- Is:Meetings searches calendar items for the keyword text. For example, “Teams is:Meetings” returns any calendar items that have Teams in the meeting subject or message body.
- With:username finds messages involving a user. For example, this query finds any message containing the “production” keyword involving Paul Robichaux on 5-May-2024: “production is:Messages with:Paul Robichaux sent:5-May-2024.”
- Use an asterisk (*) for partial matches. For example, “Microsoft 3*” is:Messages finds messages containing “Microsoft 365.”
- Unsupported or badly formed queries force Teams to default to standard search results.
When typing into the search box, you’ll find that Teams attempts to auto-correct or auto-match terms (like people or channel names). Like other auto-correct scenarios, this can sometimes get in the way. If you pick a category, like messages or files, Teams shows a list of recently-accessed objects of that type.
After running the query, the search box has additional built-in refiners to filter the set further. For instance, the date refiner supports setting a date range (it would be nice if the query supported a date range, but it does not seem to), while the More refiner includes options to find messages that @mention the user or have attachments.
Overcoming Muscle Memory
The thing about computer searches is that people tend to accrue muscle memory and search like they have for years. You see people interrogating Teams like they search Google or Bing. I’m unsure how many users, even power users, will embrace the ability of Teams to search more intelligently than before, but it’s nice to have the option.
So much change, all the time. It’s a challenge to stay abreast of all the updates Microsoft makes across the Microsoft 365 ecosystem. Subscribe to the Office 365 for IT Pros eBook to receive insights updated monthly into what happens within Microsoft 365, why it happens, and what new features and capabilities mean for your tenant.
The detectImportOptions not able to recognize and use 2nd row of a file as column name
filename = ‘data.csv’;
opts = detectImportOptions(filename);
% Adjust options to use the second row as headers
opts.DataLines = [3 Inf]; % Start reading data from the third row
opts.VariableNamesLine = 2; % Use the second row for column names
% Read the table
dataTable = readtable(filename, opts);
The above code is not able to return a data table with the columns names same as the names mention in second row of the file, Instead it renames the columns in datatable as Var1, Var2, Var3 and Var4 instead of second, volt, volt and Ampere.filename = ‘data.csv’;
opts = detectImportOptions(filename);
% Adjust options to use the second row as headers
opts.DataLines = [3 Inf]; % Start reading data from the third row
opts.VariableNamesLine = 2; % Use the second row for column names
% Read the table
dataTable = readtable(filename, opts);
The above code is not able to return a data table with the columns names same as the names mention in second row of the file, Instead it renames the columns in datatable as Var1, Var2, Var3 and Var4 instead of second, volt, volt and Ampere. filename = ‘data.csv’;
opts = detectImportOptions(filename);
% Adjust options to use the second row as headers
opts.DataLines = [3 Inf]; % Start reading data from the third row
opts.VariableNamesLine = 2; % Use the second row for column names
% Read the table
dataTable = readtable(filename, opts);
The above code is not able to return a data table with the columns names same as the names mention in second row of the file, Instead it renames the columns in datatable as Var1, Var2, Var3 and Var4 instead of second, volt, volt and Ampere. detectimportoptions, readtable MATLAB Answers — New Questions
Building a continuous-time state-space model for the heat equation
Hello,
I’m struggeling a litle bit with a thermal model based on the two and thre dimensional heat equation.
My aim is to estimate the HCT with the aid of "experimental data" and a grey-box model.
The thermal BC’s are quite simple, and illustrated below.
I generate dummy data via this matalb script:
% generate_dummy_tempdata_and_model_fixed.m
% Generate Dummy-data and prepare (2D/3D)
clc, close all, clear all
%% === Parameter ===
modellTyp = "3D"; % "2D" or "3D"
nx = 4; ny = 4; nz = 4; % Node count
dx = 0.02;dy = 0.03; dz = 0.04; % Node distance [m]
times = 0:1:30; % Time range [s]
T0 = 300; % Initial temperature [K]
dt = times(2) – times(1); % Time step [s]
%% === 1) Generate dummy-data and save as CSV ===
data = [];
switch modellTyp
case "2D"
for iy = 0:ny-1
for ix = 0:nx-1
x = ix * dx;
y = iy * dy;
Tcurve = T0 + 10 * sin(2*pi*times/60 + ix*0.3 + iy*0.5);
data = [data; x, y, Tcurve];
end
end
% Header ass string array
header = ["x","y", "t" + string(times)];
csvFile = ‘example_tempdata2D.csv’;
case "3D"
for iz = 0:nz-1
for iy = 0:ny-1
for ix = 0:nx-1
x = ix * dx;
y = iy * dy;
z = iz * dz;
Tcurve = T0 + 10 * sin(2*pi*times/60 + ix*0.2 + iy*0.3 + iz*0.4);
data = [data; x, y, z, Tcurve];
end
end
end
% Header as string array
header = ["x","y","z", "t" + string(times)];
csvFile = ‘example_tempdata3D.csv’;
end
% Bulid table and save
Ttbl_out = array2table(data, ‘VariableNames’, header);
writetable(Ttbl_out, csvFile);
disp([‘Dummy-data saved: ‘, csvFile]);
The core of the simulation is the transformation of the 2d and 3d diffusion equation into an ode.
I do it with this script:
function [A,B,C,D] = fHeat2D3D(theta, Ts)
% fHeat2D3D Continuous-time grey-box state-space for 2D/3D heat diffusion
% Signature for idgrey: fHeat2D3D(theta, Ts)
% Inputs:
% theta = [Lambda, rho, cp, hBot1, …, hBotN]
% Ts = sample time (ignored in continuous-time model)
% Globals: nx, ny, nz, dx, dy, dz, modellTyp, h_top
global nx ny nz dx dy dz modellTyp h_top
% Extract physical parameters
Lambda = theta(1);
rho = theta(2);
cp = theta(3);
% Determine expected number of bottom convection coefficients
if strcmp(modellTyp,’2D’)
expectedNbot = nx;
else
expectedNbot = nx * nz;
end
% Validate theta length
if length(theta) ~= 3 + expectedNbot
error(‘Theta must have length 3+%d (got %d)’, expectedNbot, length(theta));
end
% Extract bottom convection coefficients
hBot = theta(4:end);
% Number of states
if strcmp(modellTyp,’2D’)
N = nx * ny;
else
N = nx * ny * nz;
end
% Build A matrix (2D/3D Laplacian)
A = zeros(N);
dists = [dx, dx, dy, dy];
for idx = 1:N
tmp = idx – 1;
ix = mod(tmp, nx) + 1;
iy = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
iz = 1;
else
iz = floor(tmp / (nx * ny)) + 1;
end
diagSum = 0;
nbr = [-1,0; 1,0; 0,-1; 0,1];
for k = 1:4
x2 = ix + nbr(k,1);
y2 = iy + nbr(k,2);
if x2>=1 && x2<=nx && y2>=1 && y2<=ny
z2 = iz;
idx2 = x2 + (y2-1)*nx + (z2-1)*nx*ny;
K = Lambda / (rho * cp * dists(k)^2);
A(idx, idx2) = K;
diagSum = diagSum + K;
end
end
A(idx, idx) = -diagSum;
end
% Build B matrix
% Identify side (Dirichlet) nodes
side = false(N,1);
for idx = 1:N
tmp = idx – 1;
x = mod(tmp, nx) + 1;
y = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
side(idx) = (x == 1) || (x == nx);
else
z = floor(tmp / (nx * ny)) + 1;
side(idx) = (x==1)||(x==nx)||(y==1)||(y==ny);
end
end
Nside = sum(side);
B = zeros(N, Nside + 1 + expectedNbot);
% Side BC inputs
sidx = find(side);
for i = 1:Nside
B(sidx(i), i) = 1;
end
% Top convection BC
if strcmp(modellTyp,’2D’)
topIdx = find(~side & floor((0:N-1)/nx)==0);
else
topIdx = find(~side & floor((0:N-1)/(nx*ny))==nz-1);
end
for i = 1:numel(topIdx)
B(topIdx(i), Nside+1) = h_top;
end
% Bottom convection BC
if strcmp(modellTyp,’2D’)
botIdx = find(~side & floor((0:N-1)/nx)==ny-1);
else
botIdx = find(~side & floor((0:N-1)/(nx*ny))==0);
end
for i = 1:numel(botIdx)
B(botIdx(i), Nside+1+i) = hBot(i);
end
% Outputs and feedthrough
C = eye(N);
D = zeros(N, size(B,2));
end
Finally the ode ("function [A,B,C,D] = fHeat2D3D(theta, Ts)") is used as continuous-time state-space model to estimate the system parameter HTC(bottom), heat conductivity, density and specific heat capacity via idgrey and greyest.
% greybox_heat_diffusion.m
% Parametric continuous-time grey-box model for 2D/3D heat conduction
clear; clc; close all;
global nx ny nz dx dy dz modellTyp h_top t_env_top
%% === User setup ===
modellTyp = "2D"; % "2D" or "3D"
nx = 3; ny = 3; nz = 3; % Count of nodes in x, y, z direction(ignore nz for 2D)
dx = 0.02; dy = 0.03; dz = 0.04; % Distance between nodes [m]
dt = 1; % Time step [s]
times = 0:dt:60; % Time range [s]
csv2D = ‘example_tempdata2D.csv’;
csv3D = ‘example_tempdata3D.csv’;
% Fixed values / Top-HTC
t_env_top = 293; % Ambient free stream temperature [K]
h_top = 10; % HTC at the top edge [W/(m^2*K)]
%% === Initial guess of the model parameter ===
theta0.Lambda = 50; % Heat conduction [W/(m*K)]
theta0.rho = 7800;% Density [kg/m^3]
theta0.cp = 460; % Heat capacity [J/(kg*K)]
if modellTyp=="2D"
h_bot0 = 20*ones(nx,1);
else
h_bot0 = 20*ones(nx*nz,1);
end
%% === Read experimental data ===
if modellTyp=="2D"
Tdata = readtable(csv2D);
Texp = Tdata{:,3:end};
Nstates = nx*ny;
else
Tdata = readtable(csv3D);
Texp = Tdata{:,4:end};
Nstates = nx*ny*nz;
end
Nmeas = size(Texp,2);
%% === Calculate side indices ===
sideNodes = false(Nstates,1);
for idx=1:Nstates
tmp=idx-1; ix=mod(tmp,nx)+1; iy=floor(tmp/nx)+1;
if strcmp(modellTyp,"2D")
sideNodes(idx) = ix==1 || ix==nx;
else
iz=floor(tmp/(nx*ny))+1;
sideNodes(idx) = ix==1||ix==nx||iy==1||iy==ny;
end
end
sideIdx = find(sideNodes);
%% === Build input-matrix u ===
T_sideBC = Texp(sideIdx,:); % Side nodes – BC (experimental value)
T_topBC = t_env_top * ones(1,Nmeas);
u = [T_sideBC’ T_topBC’ zeros(Nmeas,length(h_bot0))];
%% === idgrey Setup ===
param0 = [theta0.Lambda theta0.rho theta0.cp h_bot0′];
order = [Nstates Nstates Nstates 0];
[A,B,C,D] = fHeat2D3D(param0, dt);
sysi = idgrey(‘fHeat2D3D’, param0, ‘c’, order, …
‘InputName’,[repmat({‘T_sideBC’},1,length(sideIdx)) {‘T_top’} repmat({‘T_bot’},1,length(h_bot0))], …
‘OutputName’, repmat({‘Tnode’},1,Nstates));
% Release parameters (all)
sysi.Structure.Parameters.Free = true;
%% === Parameter-estimation ===
data_id = iddata(Texp’, u, dt);
opt = greyestOptions(‘Display’,’on’,’InitialCondition’,’zero’);
sys_est = greyest(data_id, sysi, opt);
%% === Extract estimated values ===
th = sys_est.Structure.Parameters;
Lambda_est = th(1).Value; rho_est = th(2).Value; cp_est = th(3).Value;
hBot_est = [th(4:end).Value]’;
%% === Plots ===
Tsim = sim(sys_est, data_id);
% Plot h_bot
figure;
if strcmp(modellTyp,"2D")
plot(unique(Tdata.x), hBot_est, ‘o-‘, ‘LineWidth’, 2);
xlabel(‘x [m]’); ylabel(‘h_{bot} [W/m^2K]’);
title(‘HTC at the bottom edge (2D)’); grid on;
else
% 3D-Surface plot of h_bot at bottom surface
[Xq, Zq] = meshgrid(unique(Tdata.x), unique(Tdata.z));
hq = griddata(Tdata.x, Tdata.z, hBot_est, Xq, Zq, ‘natural’);
surf(Xq, Zq, hq);
xlabel(‘x [m]’); ylabel(‘z [m]’); zlabel(‘h_{bot} [W/m^2K]’);
title(‘HTC at bottom surface (3D)’); colorbar;
shading interp; view(30, 30);
end
% Comparison temperature-simulation vs. temperature-measurement
figure;
Nrow = ceil(sqrt(Nstates));
for i = 1:Nstates
subplot(Nrow, Nrow, i);
plot(times, Texp(i,:), ‘-‘, ‘LineWidth’, 1.5); hold on;
plot(times, Tsim.y(i,:), ‘:’, ‘LineWidth’, 1.5);
title(sprintf(‘Nodes %d’, i));
xlabel(‘Time [s]’); ylabel(‘T [°C]’);
legend(‘Experiment’, ‘Simulation’);
grid on;
end
% 3D-Point: final temperature distribution
if strcmp(modellTyp,"3D")
figure;
scatter3(Tdata.x, Tdata.y, Tdata.z, 50, Tsim.y(:,end), ‘filled’);
xlabel(‘x’); ylabel(‘y’); zlabel(‘z’);
title(‘Simulated temperature distribution at t=tend’);
colorbar; view(30,30);
end
%% End of the script
The call of the script "greybox_heat_diffusion.m" is not working properly and the function "fHeat2D3D" is not called correct.
For the averaging of the corne nodes (2D) respectively the corner & edge nodes (3D). I made this script:
function [A,B,C,D] = fHeat2D3D(theta, Ts)
% fHeat2D3D Continuous-time grey-box state-space for 2D/3D heat diffusion
% Signature for idgrey: fHeat2D3D(theta, Ts)
% Inputs:
% theta = [Lambda, rho, cp, hBot1, …, hBotN]
% Ts = sample time (ignored in continuous-time model)
% Globals: nx, ny, nz, dx, dy, dz, modellTyp, h_top
global nx ny nz dx dy dz modellTyp h_top
% Extract physical parameters
Lambda = theta(1);
rho = theta(2);
cp = theta(3);
% Determine expected number of bottom convection coefficients
if strcmp(modellTyp,’2D’)
expectedNbot = nx;
else
expectedNbot = nx * nz;
end
% Validate theta length
if length(theta) ~= 3 + expectedNbot
error(‘Theta must have length 3+%d (got %d)’, expectedNbot, length(theta));
end
% Extract bottom convection coefficients
hBot = theta(4:end);
% Number of states
if strcmp(modellTyp,’2D’)
N = nx * ny;
else
N = nx * ny * nz;
end
% Build A matrix (2D/3D Laplacian)
A = zeros(N);
dists = [dx, dx, dy, dy];
for idx = 1:N
tmp = idx – 1;
ix = mod(tmp, nx) + 1;
iy = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
iz = 1;
else
iz = floor(tmp / (nx * ny)) + 1;
end
diagSum = 0;
nbr = [-1,0; 1,0; 0,-1; 0,1];
for k = 1:4
x2 = ix + nbr(k,1);
y2 = iy + nbr(k,2);
if x2>=1 && x2<=nx && y2>=1 && y2<=ny
z2 = iz;
idx2 = x2 + (y2-1)*nx + (z2-1)*nx*ny;
K = Lambda / (rho * cp * dists(k)^2);
A(idx, idx2) = K;
diagSum = diagSum + K;
end
end
A(idx, idx) = -diagSum;
end
% Build B matrix
% Identify side (Dirichlet) nodes
side = false(N,1);
for idx = 1:N
tmp = idx – 1;
x = mod(tmp, nx) + 1;
y = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
side(idx) = (x == 1) || (x == nx);
else
z = floor(tmp / (nx * ny)) + 1;
side(idx) = (x==1)||(x==nx)||(y==1)||(y==ny);
end
end
Nside = sum(side);
B = zeros(N, Nside + 1 + expectedNbot);
% Side BC inputs
sidx = find(side);
for i = 1:Nside
B(sidx(i), i) = 1;
end
% Top convection BC
if strcmp(modellTyp,’2D’)
topIdx = find(~side & floor((0:N-1)/nx)==0);
else
topIdx = find(~side & floor((0:N-1)/(nx*ny))==nz-1);
end
for i = 1:numel(topIdx)
B(topIdx(i), Nside+1) = h_top;
end
% Bottom convection BC
if strcmp(modellTyp,’2D’)
botIdx = find(~side & floor((0:N-1)/nx)==ny-1);
else
botIdx = find(~side & floor((0:N-1)/(nx*ny))==0);
end
for i = 1:numel(botIdx)
B(botIdx(i), Nside+1+i) = hBot(i);
end
% Outputs and feedthrough
C = eye(N);
% === Corner and edge nodes averaging ===
for idx = 1:N
bcCount = nnz(B(idx,:)); % Count of BC-Input
if bcCount > 1
% Balanced averaging: scale A- and B-Line
A(idx,:) = A(idx,:) / bcCount;
B(idx,:) = B(idx,:) / bcCount;
end
end
D = zeros(N, size(B,2));(N, size(B,2));
end
I’m not sure if this is the rigth approach.
Maybe someone has a hint how can I get rid of the errors.
With best regards
SteffenHello,
I’m struggeling a litle bit with a thermal model based on the two and thre dimensional heat equation.
My aim is to estimate the HCT with the aid of "experimental data" and a grey-box model.
The thermal BC’s are quite simple, and illustrated below.
I generate dummy data via this matalb script:
% generate_dummy_tempdata_and_model_fixed.m
% Generate Dummy-data and prepare (2D/3D)
clc, close all, clear all
%% === Parameter ===
modellTyp = "3D"; % "2D" or "3D"
nx = 4; ny = 4; nz = 4; % Node count
dx = 0.02;dy = 0.03; dz = 0.04; % Node distance [m]
times = 0:1:30; % Time range [s]
T0 = 300; % Initial temperature [K]
dt = times(2) – times(1); % Time step [s]
%% === 1) Generate dummy-data and save as CSV ===
data = [];
switch modellTyp
case "2D"
for iy = 0:ny-1
for ix = 0:nx-1
x = ix * dx;
y = iy * dy;
Tcurve = T0 + 10 * sin(2*pi*times/60 + ix*0.3 + iy*0.5);
data = [data; x, y, Tcurve];
end
end
% Header ass string array
header = ["x","y", "t" + string(times)];
csvFile = ‘example_tempdata2D.csv’;
case "3D"
for iz = 0:nz-1
for iy = 0:ny-1
for ix = 0:nx-1
x = ix * dx;
y = iy * dy;
z = iz * dz;
Tcurve = T0 + 10 * sin(2*pi*times/60 + ix*0.2 + iy*0.3 + iz*0.4);
data = [data; x, y, z, Tcurve];
end
end
end
% Header as string array
header = ["x","y","z", "t" + string(times)];
csvFile = ‘example_tempdata3D.csv’;
end
% Bulid table and save
Ttbl_out = array2table(data, ‘VariableNames’, header);
writetable(Ttbl_out, csvFile);
disp([‘Dummy-data saved: ‘, csvFile]);
The core of the simulation is the transformation of the 2d and 3d diffusion equation into an ode.
I do it with this script:
function [A,B,C,D] = fHeat2D3D(theta, Ts)
% fHeat2D3D Continuous-time grey-box state-space for 2D/3D heat diffusion
% Signature for idgrey: fHeat2D3D(theta, Ts)
% Inputs:
% theta = [Lambda, rho, cp, hBot1, …, hBotN]
% Ts = sample time (ignored in continuous-time model)
% Globals: nx, ny, nz, dx, dy, dz, modellTyp, h_top
global nx ny nz dx dy dz modellTyp h_top
% Extract physical parameters
Lambda = theta(1);
rho = theta(2);
cp = theta(3);
% Determine expected number of bottom convection coefficients
if strcmp(modellTyp,’2D’)
expectedNbot = nx;
else
expectedNbot = nx * nz;
end
% Validate theta length
if length(theta) ~= 3 + expectedNbot
error(‘Theta must have length 3+%d (got %d)’, expectedNbot, length(theta));
end
% Extract bottom convection coefficients
hBot = theta(4:end);
% Number of states
if strcmp(modellTyp,’2D’)
N = nx * ny;
else
N = nx * ny * nz;
end
% Build A matrix (2D/3D Laplacian)
A = zeros(N);
dists = [dx, dx, dy, dy];
for idx = 1:N
tmp = idx – 1;
ix = mod(tmp, nx) + 1;
iy = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
iz = 1;
else
iz = floor(tmp / (nx * ny)) + 1;
end
diagSum = 0;
nbr = [-1,0; 1,0; 0,-1; 0,1];
for k = 1:4
x2 = ix + nbr(k,1);
y2 = iy + nbr(k,2);
if x2>=1 && x2<=nx && y2>=1 && y2<=ny
z2 = iz;
idx2 = x2 + (y2-1)*nx + (z2-1)*nx*ny;
K = Lambda / (rho * cp * dists(k)^2);
A(idx, idx2) = K;
diagSum = diagSum + K;
end
end
A(idx, idx) = -diagSum;
end
% Build B matrix
% Identify side (Dirichlet) nodes
side = false(N,1);
for idx = 1:N
tmp = idx – 1;
x = mod(tmp, nx) + 1;
y = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
side(idx) = (x == 1) || (x == nx);
else
z = floor(tmp / (nx * ny)) + 1;
side(idx) = (x==1)||(x==nx)||(y==1)||(y==ny);
end
end
Nside = sum(side);
B = zeros(N, Nside + 1 + expectedNbot);
% Side BC inputs
sidx = find(side);
for i = 1:Nside
B(sidx(i), i) = 1;
end
% Top convection BC
if strcmp(modellTyp,’2D’)
topIdx = find(~side & floor((0:N-1)/nx)==0);
else
topIdx = find(~side & floor((0:N-1)/(nx*ny))==nz-1);
end
for i = 1:numel(topIdx)
B(topIdx(i), Nside+1) = h_top;
end
% Bottom convection BC
if strcmp(modellTyp,’2D’)
botIdx = find(~side & floor((0:N-1)/nx)==ny-1);
else
botIdx = find(~side & floor((0:N-1)/(nx*ny))==0);
end
for i = 1:numel(botIdx)
B(botIdx(i), Nside+1+i) = hBot(i);
end
% Outputs and feedthrough
C = eye(N);
D = zeros(N, size(B,2));
end
Finally the ode ("function [A,B,C,D] = fHeat2D3D(theta, Ts)") is used as continuous-time state-space model to estimate the system parameter HTC(bottom), heat conductivity, density and specific heat capacity via idgrey and greyest.
% greybox_heat_diffusion.m
% Parametric continuous-time grey-box model for 2D/3D heat conduction
clear; clc; close all;
global nx ny nz dx dy dz modellTyp h_top t_env_top
%% === User setup ===
modellTyp = "2D"; % "2D" or "3D"
nx = 3; ny = 3; nz = 3; % Count of nodes in x, y, z direction(ignore nz for 2D)
dx = 0.02; dy = 0.03; dz = 0.04; % Distance between nodes [m]
dt = 1; % Time step [s]
times = 0:dt:60; % Time range [s]
csv2D = ‘example_tempdata2D.csv’;
csv3D = ‘example_tempdata3D.csv’;
% Fixed values / Top-HTC
t_env_top = 293; % Ambient free stream temperature [K]
h_top = 10; % HTC at the top edge [W/(m^2*K)]
%% === Initial guess of the model parameter ===
theta0.Lambda = 50; % Heat conduction [W/(m*K)]
theta0.rho = 7800;% Density [kg/m^3]
theta0.cp = 460; % Heat capacity [J/(kg*K)]
if modellTyp=="2D"
h_bot0 = 20*ones(nx,1);
else
h_bot0 = 20*ones(nx*nz,1);
end
%% === Read experimental data ===
if modellTyp=="2D"
Tdata = readtable(csv2D);
Texp = Tdata{:,3:end};
Nstates = nx*ny;
else
Tdata = readtable(csv3D);
Texp = Tdata{:,4:end};
Nstates = nx*ny*nz;
end
Nmeas = size(Texp,2);
%% === Calculate side indices ===
sideNodes = false(Nstates,1);
for idx=1:Nstates
tmp=idx-1; ix=mod(tmp,nx)+1; iy=floor(tmp/nx)+1;
if strcmp(modellTyp,"2D")
sideNodes(idx) = ix==1 || ix==nx;
else
iz=floor(tmp/(nx*ny))+1;
sideNodes(idx) = ix==1||ix==nx||iy==1||iy==ny;
end
end
sideIdx = find(sideNodes);
%% === Build input-matrix u ===
T_sideBC = Texp(sideIdx,:); % Side nodes – BC (experimental value)
T_topBC = t_env_top * ones(1,Nmeas);
u = [T_sideBC’ T_topBC’ zeros(Nmeas,length(h_bot0))];
%% === idgrey Setup ===
param0 = [theta0.Lambda theta0.rho theta0.cp h_bot0′];
order = [Nstates Nstates Nstates 0];
[A,B,C,D] = fHeat2D3D(param0, dt);
sysi = idgrey(‘fHeat2D3D’, param0, ‘c’, order, …
‘InputName’,[repmat({‘T_sideBC’},1,length(sideIdx)) {‘T_top’} repmat({‘T_bot’},1,length(h_bot0))], …
‘OutputName’, repmat({‘Tnode’},1,Nstates));
% Release parameters (all)
sysi.Structure.Parameters.Free = true;
%% === Parameter-estimation ===
data_id = iddata(Texp’, u, dt);
opt = greyestOptions(‘Display’,’on’,’InitialCondition’,’zero’);
sys_est = greyest(data_id, sysi, opt);
%% === Extract estimated values ===
th = sys_est.Structure.Parameters;
Lambda_est = th(1).Value; rho_est = th(2).Value; cp_est = th(3).Value;
hBot_est = [th(4:end).Value]’;
%% === Plots ===
Tsim = sim(sys_est, data_id);
% Plot h_bot
figure;
if strcmp(modellTyp,"2D")
plot(unique(Tdata.x), hBot_est, ‘o-‘, ‘LineWidth’, 2);
xlabel(‘x [m]’); ylabel(‘h_{bot} [W/m^2K]’);
title(‘HTC at the bottom edge (2D)’); grid on;
else
% 3D-Surface plot of h_bot at bottom surface
[Xq, Zq] = meshgrid(unique(Tdata.x), unique(Tdata.z));
hq = griddata(Tdata.x, Tdata.z, hBot_est, Xq, Zq, ‘natural’);
surf(Xq, Zq, hq);
xlabel(‘x [m]’); ylabel(‘z [m]’); zlabel(‘h_{bot} [W/m^2K]’);
title(‘HTC at bottom surface (3D)’); colorbar;
shading interp; view(30, 30);
end
% Comparison temperature-simulation vs. temperature-measurement
figure;
Nrow = ceil(sqrt(Nstates));
for i = 1:Nstates
subplot(Nrow, Nrow, i);
plot(times, Texp(i,:), ‘-‘, ‘LineWidth’, 1.5); hold on;
plot(times, Tsim.y(i,:), ‘:’, ‘LineWidth’, 1.5);
title(sprintf(‘Nodes %d’, i));
xlabel(‘Time [s]’); ylabel(‘T [°C]’);
legend(‘Experiment’, ‘Simulation’);
grid on;
end
% 3D-Point: final temperature distribution
if strcmp(modellTyp,"3D")
figure;
scatter3(Tdata.x, Tdata.y, Tdata.z, 50, Tsim.y(:,end), ‘filled’);
xlabel(‘x’); ylabel(‘y’); zlabel(‘z’);
title(‘Simulated temperature distribution at t=tend’);
colorbar; view(30,30);
end
%% End of the script
The call of the script "greybox_heat_diffusion.m" is not working properly and the function "fHeat2D3D" is not called correct.
For the averaging of the corne nodes (2D) respectively the corner & edge nodes (3D). I made this script:
function [A,B,C,D] = fHeat2D3D(theta, Ts)
% fHeat2D3D Continuous-time grey-box state-space for 2D/3D heat diffusion
% Signature for idgrey: fHeat2D3D(theta, Ts)
% Inputs:
% theta = [Lambda, rho, cp, hBot1, …, hBotN]
% Ts = sample time (ignored in continuous-time model)
% Globals: nx, ny, nz, dx, dy, dz, modellTyp, h_top
global nx ny nz dx dy dz modellTyp h_top
% Extract physical parameters
Lambda = theta(1);
rho = theta(2);
cp = theta(3);
% Determine expected number of bottom convection coefficients
if strcmp(modellTyp,’2D’)
expectedNbot = nx;
else
expectedNbot = nx * nz;
end
% Validate theta length
if length(theta) ~= 3 + expectedNbot
error(‘Theta must have length 3+%d (got %d)’, expectedNbot, length(theta));
end
% Extract bottom convection coefficients
hBot = theta(4:end);
% Number of states
if strcmp(modellTyp,’2D’)
N = nx * ny;
else
N = nx * ny * nz;
end
% Build A matrix (2D/3D Laplacian)
A = zeros(N);
dists = [dx, dx, dy, dy];
for idx = 1:N
tmp = idx – 1;
ix = mod(tmp, nx) + 1;
iy = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
iz = 1;
else
iz = floor(tmp / (nx * ny)) + 1;
end
diagSum = 0;
nbr = [-1,0; 1,0; 0,-1; 0,1];
for k = 1:4
x2 = ix + nbr(k,1);
y2 = iy + nbr(k,2);
if x2>=1 && x2<=nx && y2>=1 && y2<=ny
z2 = iz;
idx2 = x2 + (y2-1)*nx + (z2-1)*nx*ny;
K = Lambda / (rho * cp * dists(k)^2);
A(idx, idx2) = K;
diagSum = diagSum + K;
end
end
A(idx, idx) = -diagSum;
end
% Build B matrix
% Identify side (Dirichlet) nodes
side = false(N,1);
for idx = 1:N
tmp = idx – 1;
x = mod(tmp, nx) + 1;
y = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
side(idx) = (x == 1) || (x == nx);
else
z = floor(tmp / (nx * ny)) + 1;
side(idx) = (x==1)||(x==nx)||(y==1)||(y==ny);
end
end
Nside = sum(side);
B = zeros(N, Nside + 1 + expectedNbot);
% Side BC inputs
sidx = find(side);
for i = 1:Nside
B(sidx(i), i) = 1;
end
% Top convection BC
if strcmp(modellTyp,’2D’)
topIdx = find(~side & floor((0:N-1)/nx)==0);
else
topIdx = find(~side & floor((0:N-1)/(nx*ny))==nz-1);
end
for i = 1:numel(topIdx)
B(topIdx(i), Nside+1) = h_top;
end
% Bottom convection BC
if strcmp(modellTyp,’2D’)
botIdx = find(~side & floor((0:N-1)/nx)==ny-1);
else
botIdx = find(~side & floor((0:N-1)/(nx*ny))==0);
end
for i = 1:numel(botIdx)
B(botIdx(i), Nside+1+i) = hBot(i);
end
% Outputs and feedthrough
C = eye(N);
% === Corner and edge nodes averaging ===
for idx = 1:N
bcCount = nnz(B(idx,:)); % Count of BC-Input
if bcCount > 1
% Balanced averaging: scale A- and B-Line
A(idx,:) = A(idx,:) / bcCount;
B(idx,:) = B(idx,:) / bcCount;
end
end
D = zeros(N, size(B,2));(N, size(B,2));
end
I’m not sure if this is the rigth approach.
Maybe someone has a hint how can I get rid of the errors.
With best regards
Steffen Hello,
I’m struggeling a litle bit with a thermal model based on the two and thre dimensional heat equation.
My aim is to estimate the HCT with the aid of "experimental data" and a grey-box model.
The thermal BC’s are quite simple, and illustrated below.
I generate dummy data via this matalb script:
% generate_dummy_tempdata_and_model_fixed.m
% Generate Dummy-data and prepare (2D/3D)
clc, close all, clear all
%% === Parameter ===
modellTyp = "3D"; % "2D" or "3D"
nx = 4; ny = 4; nz = 4; % Node count
dx = 0.02;dy = 0.03; dz = 0.04; % Node distance [m]
times = 0:1:30; % Time range [s]
T0 = 300; % Initial temperature [K]
dt = times(2) – times(1); % Time step [s]
%% === 1) Generate dummy-data and save as CSV ===
data = [];
switch modellTyp
case "2D"
for iy = 0:ny-1
for ix = 0:nx-1
x = ix * dx;
y = iy * dy;
Tcurve = T0 + 10 * sin(2*pi*times/60 + ix*0.3 + iy*0.5);
data = [data; x, y, Tcurve];
end
end
% Header ass string array
header = ["x","y", "t" + string(times)];
csvFile = ‘example_tempdata2D.csv’;
case "3D"
for iz = 0:nz-1
for iy = 0:ny-1
for ix = 0:nx-1
x = ix * dx;
y = iy * dy;
z = iz * dz;
Tcurve = T0 + 10 * sin(2*pi*times/60 + ix*0.2 + iy*0.3 + iz*0.4);
data = [data; x, y, z, Tcurve];
end
end
end
% Header as string array
header = ["x","y","z", "t" + string(times)];
csvFile = ‘example_tempdata3D.csv’;
end
% Bulid table and save
Ttbl_out = array2table(data, ‘VariableNames’, header);
writetable(Ttbl_out, csvFile);
disp([‘Dummy-data saved: ‘, csvFile]);
The core of the simulation is the transformation of the 2d and 3d diffusion equation into an ode.
I do it with this script:
function [A,B,C,D] = fHeat2D3D(theta, Ts)
% fHeat2D3D Continuous-time grey-box state-space for 2D/3D heat diffusion
% Signature for idgrey: fHeat2D3D(theta, Ts)
% Inputs:
% theta = [Lambda, rho, cp, hBot1, …, hBotN]
% Ts = sample time (ignored in continuous-time model)
% Globals: nx, ny, nz, dx, dy, dz, modellTyp, h_top
global nx ny nz dx dy dz modellTyp h_top
% Extract physical parameters
Lambda = theta(1);
rho = theta(2);
cp = theta(3);
% Determine expected number of bottom convection coefficients
if strcmp(modellTyp,’2D’)
expectedNbot = nx;
else
expectedNbot = nx * nz;
end
% Validate theta length
if length(theta) ~= 3 + expectedNbot
error(‘Theta must have length 3+%d (got %d)’, expectedNbot, length(theta));
end
% Extract bottom convection coefficients
hBot = theta(4:end);
% Number of states
if strcmp(modellTyp,’2D’)
N = nx * ny;
else
N = nx * ny * nz;
end
% Build A matrix (2D/3D Laplacian)
A = zeros(N);
dists = [dx, dx, dy, dy];
for idx = 1:N
tmp = idx – 1;
ix = mod(tmp, nx) + 1;
iy = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
iz = 1;
else
iz = floor(tmp / (nx * ny)) + 1;
end
diagSum = 0;
nbr = [-1,0; 1,0; 0,-1; 0,1];
for k = 1:4
x2 = ix + nbr(k,1);
y2 = iy + nbr(k,2);
if x2>=1 && x2<=nx && y2>=1 && y2<=ny
z2 = iz;
idx2 = x2 + (y2-1)*nx + (z2-1)*nx*ny;
K = Lambda / (rho * cp * dists(k)^2);
A(idx, idx2) = K;
diagSum = diagSum + K;
end
end
A(idx, idx) = -diagSum;
end
% Build B matrix
% Identify side (Dirichlet) nodes
side = false(N,1);
for idx = 1:N
tmp = idx – 1;
x = mod(tmp, nx) + 1;
y = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
side(idx) = (x == 1) || (x == nx);
else
z = floor(tmp / (nx * ny)) + 1;
side(idx) = (x==1)||(x==nx)||(y==1)||(y==ny);
end
end
Nside = sum(side);
B = zeros(N, Nside + 1 + expectedNbot);
% Side BC inputs
sidx = find(side);
for i = 1:Nside
B(sidx(i), i) = 1;
end
% Top convection BC
if strcmp(modellTyp,’2D’)
topIdx = find(~side & floor((0:N-1)/nx)==0);
else
topIdx = find(~side & floor((0:N-1)/(nx*ny))==nz-1);
end
for i = 1:numel(topIdx)
B(topIdx(i), Nside+1) = h_top;
end
% Bottom convection BC
if strcmp(modellTyp,’2D’)
botIdx = find(~side & floor((0:N-1)/nx)==ny-1);
else
botIdx = find(~side & floor((0:N-1)/(nx*ny))==0);
end
for i = 1:numel(botIdx)
B(botIdx(i), Nside+1+i) = hBot(i);
end
% Outputs and feedthrough
C = eye(N);
D = zeros(N, size(B,2));
end
Finally the ode ("function [A,B,C,D] = fHeat2D3D(theta, Ts)") is used as continuous-time state-space model to estimate the system parameter HTC(bottom), heat conductivity, density and specific heat capacity via idgrey and greyest.
% greybox_heat_diffusion.m
% Parametric continuous-time grey-box model for 2D/3D heat conduction
clear; clc; close all;
global nx ny nz dx dy dz modellTyp h_top t_env_top
%% === User setup ===
modellTyp = "2D"; % "2D" or "3D"
nx = 3; ny = 3; nz = 3; % Count of nodes in x, y, z direction(ignore nz for 2D)
dx = 0.02; dy = 0.03; dz = 0.04; % Distance between nodes [m]
dt = 1; % Time step [s]
times = 0:dt:60; % Time range [s]
csv2D = ‘example_tempdata2D.csv’;
csv3D = ‘example_tempdata3D.csv’;
% Fixed values / Top-HTC
t_env_top = 293; % Ambient free stream temperature [K]
h_top = 10; % HTC at the top edge [W/(m^2*K)]
%% === Initial guess of the model parameter ===
theta0.Lambda = 50; % Heat conduction [W/(m*K)]
theta0.rho = 7800;% Density [kg/m^3]
theta0.cp = 460; % Heat capacity [J/(kg*K)]
if modellTyp=="2D"
h_bot0 = 20*ones(nx,1);
else
h_bot0 = 20*ones(nx*nz,1);
end
%% === Read experimental data ===
if modellTyp=="2D"
Tdata = readtable(csv2D);
Texp = Tdata{:,3:end};
Nstates = nx*ny;
else
Tdata = readtable(csv3D);
Texp = Tdata{:,4:end};
Nstates = nx*ny*nz;
end
Nmeas = size(Texp,2);
%% === Calculate side indices ===
sideNodes = false(Nstates,1);
for idx=1:Nstates
tmp=idx-1; ix=mod(tmp,nx)+1; iy=floor(tmp/nx)+1;
if strcmp(modellTyp,"2D")
sideNodes(idx) = ix==1 || ix==nx;
else
iz=floor(tmp/(nx*ny))+1;
sideNodes(idx) = ix==1||ix==nx||iy==1||iy==ny;
end
end
sideIdx = find(sideNodes);
%% === Build input-matrix u ===
T_sideBC = Texp(sideIdx,:); % Side nodes – BC (experimental value)
T_topBC = t_env_top * ones(1,Nmeas);
u = [T_sideBC’ T_topBC’ zeros(Nmeas,length(h_bot0))];
%% === idgrey Setup ===
param0 = [theta0.Lambda theta0.rho theta0.cp h_bot0′];
order = [Nstates Nstates Nstates 0];
[A,B,C,D] = fHeat2D3D(param0, dt);
sysi = idgrey(‘fHeat2D3D’, param0, ‘c’, order, …
‘InputName’,[repmat({‘T_sideBC’},1,length(sideIdx)) {‘T_top’} repmat({‘T_bot’},1,length(h_bot0))], …
‘OutputName’, repmat({‘Tnode’},1,Nstates));
% Release parameters (all)
sysi.Structure.Parameters.Free = true;
%% === Parameter-estimation ===
data_id = iddata(Texp’, u, dt);
opt = greyestOptions(‘Display’,’on’,’InitialCondition’,’zero’);
sys_est = greyest(data_id, sysi, opt);
%% === Extract estimated values ===
th = sys_est.Structure.Parameters;
Lambda_est = th(1).Value; rho_est = th(2).Value; cp_est = th(3).Value;
hBot_est = [th(4:end).Value]’;
%% === Plots ===
Tsim = sim(sys_est, data_id);
% Plot h_bot
figure;
if strcmp(modellTyp,"2D")
plot(unique(Tdata.x), hBot_est, ‘o-‘, ‘LineWidth’, 2);
xlabel(‘x [m]’); ylabel(‘h_{bot} [W/m^2K]’);
title(‘HTC at the bottom edge (2D)’); grid on;
else
% 3D-Surface plot of h_bot at bottom surface
[Xq, Zq] = meshgrid(unique(Tdata.x), unique(Tdata.z));
hq = griddata(Tdata.x, Tdata.z, hBot_est, Xq, Zq, ‘natural’);
surf(Xq, Zq, hq);
xlabel(‘x [m]’); ylabel(‘z [m]’); zlabel(‘h_{bot} [W/m^2K]’);
title(‘HTC at bottom surface (3D)’); colorbar;
shading interp; view(30, 30);
end
% Comparison temperature-simulation vs. temperature-measurement
figure;
Nrow = ceil(sqrt(Nstates));
for i = 1:Nstates
subplot(Nrow, Nrow, i);
plot(times, Texp(i,:), ‘-‘, ‘LineWidth’, 1.5); hold on;
plot(times, Tsim.y(i,:), ‘:’, ‘LineWidth’, 1.5);
title(sprintf(‘Nodes %d’, i));
xlabel(‘Time [s]’); ylabel(‘T [°C]’);
legend(‘Experiment’, ‘Simulation’);
grid on;
end
% 3D-Point: final temperature distribution
if strcmp(modellTyp,"3D")
figure;
scatter3(Tdata.x, Tdata.y, Tdata.z, 50, Tsim.y(:,end), ‘filled’);
xlabel(‘x’); ylabel(‘y’); zlabel(‘z’);
title(‘Simulated temperature distribution at t=tend’);
colorbar; view(30,30);
end
%% End of the script
The call of the script "greybox_heat_diffusion.m" is not working properly and the function "fHeat2D3D" is not called correct.
For the averaging of the corne nodes (2D) respectively the corner & edge nodes (3D). I made this script:
function [A,B,C,D] = fHeat2D3D(theta, Ts)
% fHeat2D3D Continuous-time grey-box state-space for 2D/3D heat diffusion
% Signature for idgrey: fHeat2D3D(theta, Ts)
% Inputs:
% theta = [Lambda, rho, cp, hBot1, …, hBotN]
% Ts = sample time (ignored in continuous-time model)
% Globals: nx, ny, nz, dx, dy, dz, modellTyp, h_top
global nx ny nz dx dy dz modellTyp h_top
% Extract physical parameters
Lambda = theta(1);
rho = theta(2);
cp = theta(3);
% Determine expected number of bottom convection coefficients
if strcmp(modellTyp,’2D’)
expectedNbot = nx;
else
expectedNbot = nx * nz;
end
% Validate theta length
if length(theta) ~= 3 + expectedNbot
error(‘Theta must have length 3+%d (got %d)’, expectedNbot, length(theta));
end
% Extract bottom convection coefficients
hBot = theta(4:end);
% Number of states
if strcmp(modellTyp,’2D’)
N = nx * ny;
else
N = nx * ny * nz;
end
% Build A matrix (2D/3D Laplacian)
A = zeros(N);
dists = [dx, dx, dy, dy];
for idx = 1:N
tmp = idx – 1;
ix = mod(tmp, nx) + 1;
iy = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
iz = 1;
else
iz = floor(tmp / (nx * ny)) + 1;
end
diagSum = 0;
nbr = [-1,0; 1,0; 0,-1; 0,1];
for k = 1:4
x2 = ix + nbr(k,1);
y2 = iy + nbr(k,2);
if x2>=1 && x2<=nx && y2>=1 && y2<=ny
z2 = iz;
idx2 = x2 + (y2-1)*nx + (z2-1)*nx*ny;
K = Lambda / (rho * cp * dists(k)^2);
A(idx, idx2) = K;
diagSum = diagSum + K;
end
end
A(idx, idx) = -diagSum;
end
% Build B matrix
% Identify side (Dirichlet) nodes
side = false(N,1);
for idx = 1:N
tmp = idx – 1;
x = mod(tmp, nx) + 1;
y = floor(tmp / nx) + 1;
if strcmp(modellTyp,’2D’)
side(idx) = (x == 1) || (x == nx);
else
z = floor(tmp / (nx * ny)) + 1;
side(idx) = (x==1)||(x==nx)||(y==1)||(y==ny);
end
end
Nside = sum(side);
B = zeros(N, Nside + 1 + expectedNbot);
% Side BC inputs
sidx = find(side);
for i = 1:Nside
B(sidx(i), i) = 1;
end
% Top convection BC
if strcmp(modellTyp,’2D’)
topIdx = find(~side & floor((0:N-1)/nx)==0);
else
topIdx = find(~side & floor((0:N-1)/(nx*ny))==nz-1);
end
for i = 1:numel(topIdx)
B(topIdx(i), Nside+1) = h_top;
end
% Bottom convection BC
if strcmp(modellTyp,’2D’)
botIdx = find(~side & floor((0:N-1)/nx)==ny-1);
else
botIdx = find(~side & floor((0:N-1)/(nx*ny))==0);
end
for i = 1:numel(botIdx)
B(botIdx(i), Nside+1+i) = hBot(i);
end
% Outputs and feedthrough
C = eye(N);
% === Corner and edge nodes averaging ===
for idx = 1:N
bcCount = nnz(B(idx,:)); % Count of BC-Input
if bcCount > 1
% Balanced averaging: scale A- and B-Line
A(idx,:) = A(idx,:) / bcCount;
B(idx,:) = B(idx,:) / bcCount;
end
end
D = zeros(N, size(B,2));(N, size(B,2));
end
I’m not sure if this is the rigth approach.
Maybe someone has a hint how can I get rid of the errors.
With best regards
Steffen thermal, grey-box, matlab, ode MATLAB Answers — New Questions
Edit Excel files to automatically update into MATLAB
I am trying to figure out how to edit an excel file and have those changes automatically update into MATLAB. Currently I am stuck copy and pasting the data into MATLAB to keep those updated numbers. Finally, this excel is in a shared folder on Microsoft Teams. I am unable to download to my drive or import directly to MATLAB because anyone can make that update to change the values.
I’ve tried "actxserver(‘excel.application’)" but received an error that it’s not supported.
Thanks!I am trying to figure out how to edit an excel file and have those changes automatically update into MATLAB. Currently I am stuck copy and pasting the data into MATLAB to keep those updated numbers. Finally, this excel is in a shared folder on Microsoft Teams. I am unable to download to my drive or import directly to MATLAB because anyone can make that update to change the values.
I’ve tried "actxserver(‘excel.application’)" but received an error that it’s not supported.
Thanks! I am trying to figure out how to edit an excel file and have those changes automatically update into MATLAB. Currently I am stuck copy and pasting the data into MATLAB to keep those updated numbers. Finally, this excel is in a shared folder on Microsoft Teams. I am unable to download to my drive or import directly to MATLAB because anyone can make that update to change the values.
I’ve tried "actxserver(‘excel.application’)" but received an error that it’s not supported.
Thanks! excel, importing excel data MATLAB Answers — New Questions









