How can i optimize the code and connect the functions?

Hi everyone!
I've been dabbling with MatLab for the past three days and 've managed to write the following, working, code.
eta_l = xlsread('calculos.xlsx','Theoretical Predictions','S2');
eta_0 = xlsread('calculos.xlsx','Theoretical Predictions','S3');
l_c = xlsread('calculos.xlsx','Theoretical Predictions','P3');
sigma_f = xlsread('calculos.xlsx','Base Values','B3');
v_f = xlsread('calculos.xlsx','Burn','E23');
E_m = xlsread('calculos.xlsx','Base Values','D2');
E_f = xlsread('calculos.xlsx','Base Values','B2');
d = xlsread('calculos.xlsx','Base Values','B5');
%basically these functions y1 and y2 should be connected but i haven't been able to connect them
%plot of the Kelly-Tyson equation
x=linspace(-10,50);
idx = x < l_c;
y1=((eta_l.*eta_0.*((v_f.*sigma_f.*E_m)./(E_f.*d.*sqrt(3))).*x(idx))+((sigma_f.*E_m.*(1-v_f))./E_f));
y2=(eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x(~idx))+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
plot(x(idx),y1,x(~idx),y2);
ylim([0 1000]);
grid on
hold on
%basically these next two bits are the same and i would like to not repeat
%them and get the same to points in the plot
%plot of the 95% of the max of the Kelly-Tyson equation
syms x
f=(eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
maximus=limit(f,Inf);
eqn=f==0.95.*maximus;
S=solve(eqn,x);
plot(S,0.95.*maximus,'r*')
hold on
%plot of the 98% of the max of Kelly-Tyson equation
syms x
f1=(eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
maximus1=limit(f1,Inf);
eqn1=f1==0.98.*maximus1;
S1=solve(eqn1,x);
plot(S1,0.98.*maximus1,'r*')
hold off
But... The last two bits are basically me writing them again and again. Is there a way where i can optimize the code so that i get a plot with the graphs of the functions connected - that is because they are connected in reality - and the points ploted but without having to write basically the same thing twice?
Thanks in advance!

 Accepted Answer

The syms call is not necessary.
Try something like this instead:
% syms x
f= @(x) (eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
maximus = f(max(x));
eqn = @(x)f(x)*0.95.*maximus;
x0 = rand;
S=fsolve(eqn,x0);
plot(S,0.95.*maximus,'r*')
hold on
%plot of the 98% of the max of Kelly-Tyson equation
% syms x
f1= @(x) (eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
maximus1=f1(max(x));
eqn1= @(x)f1(x)*0.98.*maximus1;
S1=fsolve(eqn1,x0);
plot(S1,0.98.*maximus1,'r*')
hold off
The functions each appear to be an inverse function of ‘x’, so will likely have only one root. (I cannot determine if the functions have a zero-crossing, so it is possible that there are no roots.) I am not certain what the limit call is doing, since the part of the function that contains the term will go to 0 in the limit, leaving only the additive terms that are not a function of ‘x’.
.

6 Comments

The function does have roots, but, i'm constricting it from the l_c point (x~0.969) onwards. I would like to connect y1 and y2 and furthermore, find the assymptote value (max value of the function since it has an inverse 1/x behaviour) and plot two points (with a little bit of a better code since i already have the y2 function written above and am writing it again and again below to plot the points): the 95% value of the assymptote, and the 98% value of the assymptote (and the corresponding x-values of course). The reasoning behind the limit call is to find the value of the assymptote to plot the points since i had some trouble ploting the max value of the function because 'in theory' it doesn't have a maximum value numericaly speaking, it goes on to infinity and only at infinity will it reach the maximum value of itself.
For a visual aid though:
As far as the asymptotes go, a better option than my first approach would be:
maximus = f(1E+10);
maximus1 = f1(1E+10);
It is not possible to run the code (no Excel file provided), so ‘connect the functions’ has no context in the original post.
With respect to an uninterrupted plot for ‘y1’ and ‘y2’, a different approach is necesary:
x = linspace(-10,50);
y1 = @(x) ((eta_l.*eta_0.*((v_f.*sigma_f.*E_m)./(E_f.*d.*sqrt(3))).*x)+((sigma_f.*E_m.*(1-v_f))./E_f));
y2 = @(x) (eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
y = y1(x).* (x < l_c) + y2(x).*(x >= l_c);
figure
plot(x, y)
grid
I still can’t run the code, so I am posting this as UNTESTED CODE. It should work.
.
Right forgot about that one sorry!
I've put the file on this comment.
As for the code this is what i got.
Any thoughts?
This appears to produce the desired result (although I had to make a few changes to make this compatible with the online Run feature, that apparently does not like xlsread) —
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/685458/calculos.xlsx';
eta_l = readmatrix(filename,'Sheet','Theoretical Predictions','Range','S2:S2');
eta_0 = readmatrix(filename,'Sheet','Theoretical Predictions','Range','S3:S3');
l_c = readmatrix(filename,'Sheet','Theoretical Predictions','Range','P3:P3');
sigma_f = readmatrix(filename,'Sheet','Base Values','Range','B3:B3');
v_f = readmatrix(filename,'Sheet','Burn','Range','E23:E23');
E_m = readmatrix(filename,'Sheet','Base Values','Range','D2:D2');
E_f = readmatrix(filename,'Sheet','Base Values','Range','B2:B2');
d = readmatrix(filename,'Sheet','Base Values','Range','B5:B5');
%basically these functions y1 and y2 should be connected but i haven't been able to connect them
%plot of the Kelly-Tyson equation
x=linspace(-10,50);
x = linspace(-10,50);
y1 = @(x) ((eta_l.*eta_0.*((v_f.*sigma_f.*E_m)./(E_f.*d.*sqrt(3))).*x)+((sigma_f.*E_m.*(1-v_f))./E_f));
y2 = @(x) (eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
y = y1(x).*(x < l_c) + y2(x).*(x >= l_c);
figure
plot(x, y)
grid
hold on
%basically these next two bits are the same and i would like to not repeat
%them and get the same to points in the plot
%plot of the 95% of the max of the Kelly-Tyson equation
% syms x
f= @(x) (eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
maximus = f(1E+10);
% eqn = @(x)f(x)*0.95.*maximus;
x0 = rand;
S=fsolve(@(x)f(x)-0.95.*maximus,x0)
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
S = 9.5928
plot(S,0.95.*maximus,'r*')
hold on
%plot of the 98% of the max of Kelly-Tyson equation
% syms x
f1= @(x) (eta_l.*eta_0.*(((-sigma_f.*v_f.*l_c)./2).*(1./x)+(sigma_f.*v_f)))+(((sigma_f.*E_m)./E_f).*(1-v_f));
maximus1=f1(1E+10);
% eqn1= @(x)f1(x)*0.98.*maximus1;
S1=fsolve(@(x)f1(x)-0.98.*maximus1,x0)
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
S1 = 23.9819
plot(S1,0.98.*maximus1,'r*')
hold off
ylim([0 max(ylim)])
text(S, 0.95.*maximus, sprintf('\\uparrow\n(%.4f, %.4f)',S,0.95.*maximus), 'Horiz','left','Vert','top')
text(S1, 0.98.*maximus1, sprintf('(%.4f, %.4f)\n\\downarrow',S1,0.98.*maximus1), 'Horiz','right','Vert','bottom')
So my code works and produces a unified plot, and I corrected the ‘S’ and ‘S1’ calculations as well. (I will let you explore the changes to determine how they work.)
.
This... Is... Perfect!
Thank you so much once again!
As always, my pleasure!
.

Sign in to comment.

More Answers (1)

One quick and easy suggestion is to employ readtable() instead of xlsread().

Tags

Community Treasure Hunt

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

Start Hunting!