How can I get this code to work? I am trying to fit the equation that contains step and delta function to experimental data. But I am getting the following error.
1 visualizzazione (ultimi 30 giorni)
Mostra commenti meno recenti
Bibek Dhami
il 24 Giu 2022
Commentato: Bibek Dhami
il 30 Giu 2022
A=xlsread('Data');
xdata= A(:,1);
ydata = A(:,2) ;
plot(xdata,ydata,'r.','markersize',30);
set(gca,'XDir','reverse');
box on
options =optimoptions(@lsqcurvefit,'Algorithm','trust-region-reflective','StepTolerance',1e-19,'MaxFunctionEvaluations',1e10)
MI=lsqcurvefit(@model,[0.2,0.0403,2.03],xdata,ydata,[],[],options);
fitdata=model(MI,xdata);
hold on
plot(xdata, fitdata,'k--','linewidth',2);
function alpha=model(var,energy)
alpha = var(1)*heaviside(energy-var(3)).*((pi.*exp(pi.*energy))./sinh(pi.*energy))+...
dirac(energy-var(3)+(var(2)))+dirac(energy-var(3)+(var(2)./4))+...
dirac(energy-var(3)+(var(2)./9));
end
1 Commento
dpb
il 24 Giu 2022
>> F=model([0.2,0.043,2.03],A(:,1));
'heaviside' requires Symbolic Math Toolbox.
Error in model (line 2)
alpha = x(1)*heaviside(energy-x(3)).*((pi.*exp(pi.*energy))./sinh(pi.*energy))+...
>>
so can't run your function here...first thing to do, however, is to debug your model function before trying it inside lsqcurvefit
The error is telling you something ain't right there -- you've not returning values that are defined and finite at the start point...
Risposta accettata
Walter Roberson
il 24 Giu 2022
Your Energy are in the 500 range. exp(pi*energy) overflows double precision. Your code then divides by large values, but you have already overflowed.
Ideally your code should be revised to deliberately avoid overflowing. For example, instead of exp(pi*energy)/sinh(something) you could try exp(pi*energy - log(sinh(something)) expecting the sinh to be large enough for the log to be comparable to pi*energy.
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/1044920/Data.xlsx';
A = readmatrix(filename);
xdata = A(:,1);
ydata = A(:,2) ;
plot(xdata, ydata, 'r.', 'markersize', 30);
set(gca,'XDir','reverse');
box on
options =optimoptions(@lsqcurvefit,'Algorithm','trust-region-reflective','StepTolerance',1e-19,'MaxFunctionEvaluations',1e10)
MI = lsqcurvefit(@model,[0.2,0.0403,2.03],xdata,ydata,[],[],options);
fitdata = model(MI,xdata);
hold on
plot(xdata, fitdata,'k--','linewidth',2);
function alpha = model(var,Energy)
energy = sym(Energy);
alpha = var(1)*heaviside(energy-var(3)).*((pi.*exp(pi.*energy))./sinh(pi.*energy))+...
dirac(energy-var(3)+(var(2)))+dirac(energy-var(3)+(var(2)./4))+...
dirac(energy-var(3)+(var(2)./9));
alpha = double(alpha);
end
4 Commenti
Walter Roberson
il 29 Giu 2022
Your energy is your x data, which is input. It does not make sense to integrate over your input.
There is a sense in which Heaviside is the integral of dirac delta; see https://en.wikipedia.org/wiki/Heaviside_step_function .
Reminder: you can only int() a symbolic expression or symbolic function, and the result will be a symbolic expression (or possibly the unevaluated int() expression, if MATLAB cannot figure out what the integral is.) But for lsqcurvefit you need to return double()
Reminder: if you have an input variable named energy and you do
syms energy
then that is equivalent to
energy = sym('energy');
which overwrites the input parameter energy with a new value.
Più risposte (1)
Cris LaPierre
il 24 Giu 2022
Modificato: Cris LaPierre
il 27 Giu 2022
The problem is that your objective function is returning NaN values. It is specifically the exp and sinh parts of the equation. You may need to consider the scale of your x values.
A=readmatrix('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1044920/Data.xlsx')
xdata= A(:,1);
ydata = A(:,2);
var = [0.2,0.0403,2.03];
energy = xdata;
% exp part retuning inf
pi.*exp(pi.*energy)
% sinh part returning inf
sinh(pi.*energy)
% dividing an inf by inf returns a nan
((pi.*exp(pi.*energy))./sinh(pi.*energy))
5 Commenti
Walter Roberson
il 27 Giu 2022
syms energy
is the same as
energy = sym('energy') ;
which creates a variable named energy inside the symbolic toolbox workspace, and stores a reference to it inside the local function workspace, overwriting the parameter named energy that was passed in. It does not convert the parameter into symbolic representation. To convert the input energy to symbolic form, use the technique I used in my code involving sym()
Vedere anche
Categorie
Scopri di più su Calculus in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!