Exponential Curve Fitting in Matlab - matlab

I have a data-set which is loaded into matlab. I need to do exponential fitting for the plotted curve without using the curve fitting tool cftool.
I want to do this manually through executing a code/function that will output the values of a and b corresponding to the equation:
y = a*exp(b*x)
Then be using those values, I will do error optimization and create the best fit for the data I have.
Any help please?
Thanks in advance.

Try this...
f = fit(x,y,'exp1');

I think the typical objective in this type of assignment is to recognize that by taking the log of both sides, various methods of polynomial fit approaches can be used.
ln(y) = ln(a) + ln( exp(x).^b )
ln(y) = ln(a) + b * ln( exp(x) )
There can be difficulties with this approach when errors such as noise are involved due to the behavior of ln as it approaches zero.

In this exercise I have a set of data that present an exponential curve and I want to fit them exponentially and get the values of a and b. I used the following code and it worked with the data I have.
"trail.m" file:
%defining the data used
load trialforfitting.txt;
xdata= trialforfitting(:,1);
ydata= trialforfitting(:,2);
%calling the "fitcurvedemo" function
[estimates, model] = fitcurvedemo(xdata,ydata)
disp(sse);
plot(xdata, ydata, 'o'); %Data curve
hold on
[sse, FittedCurve] = model(estimates);
plot(xdata, FittedCurve, 'r')%Fitted curve
xlabel('Voltage (V)')
ylabel('Current (A)')
title('Exponential Fitting to IV curves');
legend('data', ['Fitting'])
hold off
"fitcurvedemo.m" file:
function [estimates, model] = fitcurvedemo(xdata, ydata)
%Call fminsearch with a random starting point.
start_point = rand(1, 2);
model = #expfun;
estimates = fminsearch(model, start_point);
%"expfun" accepts curve parameters as inputs, and outputs
%the sum of squares error [sse] expfun is a function handle;
%a value that contains a matlab object methods and the constructor
%"FMINSEARCH" only needs sse
%estimate returns the value of A and lambda
%model computes the exponential function
function [sse, FittedCurve] = expfun(params)
A = params(1);
lambda = params(2);
%exponential function model to fit
FittedCurve = A .* exp(lambda * xdata);
ErrorVector = FittedCurve - ydata;
%output of the expfun function [sum of squares of error]
sse = sum(ErrorVector .^ 2);
end
end
I have a new set of data that doesn't work with this code and give the appropriate exponential fit for the data curve plotted.

Related

Ways to plot rectangular window function (u[n]-u[n-5]) in MATLAB

I am trying to plot the rectangular window function Graph in MATLAB for:-
x[n] = u[n] - u[n-5]
I have written the following MATLAB Code for the same:-
x = [ones(1,5), zeros(1,43)]
But, this works only for a specific number of points on a graph (for ex: 48 points for this graph)
I wanted to ask whether there is a better way to plot the rectangular window function plots in MATLAB for a discrete time signals? Thanks for the help:)
Calling your signal y,
x = [ones(1, 5), zeros(1, length(y) - 5)];
You may want to create a function for this:
x=#(n)double(floor(n)==ceil(n)&n>=0&n<=4);
nn=(-4:24)/4;
subplot(211);
stem(nn,x(nn));
subplot(212);
stem(nn,x(nn-1));
Notice that x() returns 0 for non-integer n, which may or may not be sensible depending on how you use the function.
Using Anonymous Functions/Function Handles
To create a discrete plot that has unit step function I usually like to declare the unit step beforehand and use that in larger function. Here I use anonymous functions/function handles which are indicated by the #() holding the input parameters. In this case the only input parameter is n. The vector N can then be passed to x() and it'll plot all the x[n] values respectively. Density can be used to play with the number of stems plotted as well as Start_Index and End_Index.
Start_Index = -10;
End_Index = 10;
Density = 1;
N = (Start_Index:Density:End_Index);
%Unit step function%
u = #(n) 1.0.*(n >= 0);
x = #(n) u(n) - u(n-5);
stem(N,x(N));
title('x[n] = u[n] - u[n-5]');
xlabel('[n]'); ylabel('x[n]');
ylim([0 1.1]);
grid on

Plotting of complex exponential function using Matlab

I am using matlab to plot complex exponential function.But i am not getting the required waveform as output.
My Signal is exp ( j2πmf ) where m takes various positive values.
My code is shown below.
close all;
clc;
f= -0.5:0.5;
Rez = cos(2*pi*1*f);
Imz = sin(2*pi*1*f)*j;
z = Rez + Imz;
z_n = exp(z);
plot(f,z_n);
xlabel('Frequency ->');
ylabel('Amplitude->');
grid on
axis tight
My Output Signal
But I want the signal shown below as my output
First of all, you try to make a plot of complex numbers z_n.
This does not make any sense.
You can plot the real part (real(z_n), the imaginary part (imag(z_n) or the absolute values (abs(z_n).
However, your exceptions in the second diagram are wrong too.
Your function exp(j2πmf) is a rotating vector with absolute amplitude 1.
This results in:
real(exp(j2πmf) = cos(2πmf)
imag (exp(j2πmf) = sin(2πmf); By the way, imag does not include j, it is the value which has j as a factor.
abs(exp(j2πmf) = 1

Estimate Poisson PDF Parameters Using Curve Fitting in MATLAB

I am trying to fit histogram data that seem to follow a poisson distribution. I declare the function as follows and try to fit it by using the least squares method.
xdata; ydata; % Arrays in which I have stored the data.
%Ydata tell us how many times the xdata is repeated in the set.
fun= #(x,xdata) (exp(-x(1))*(x(1).^(xdata)) )./(factorial(xdata)) %Function I
% want to use in the fit. It is a poisson distribution.
x0=[60]; %Approximated value of the parameter lambda to help the fit
p=lsqcurvefit(fun,x0,xdata,ydata); % Fit in the least square sense
I however encounter the next problem
Error using snls (line 48)
Objective function is returning undefined values at initial point.
lsqcurvefit cannot continue.
I have seen online that it sometimes had to do with a division by zero for example. This can be solved by adding a small amount in the denominator so that that indetermination never happens. However, that is not my case. What is the problem then?
I implemented both methods (Maximum Likelihood and PDF Curve Fitting).
You can see the code in my Stack Overflow Q45118312 Github Repository.
Results:
As you can see, the Maximum Likelihood is simpler and better (MSE Wise).
So you have no reason to use the PDF Curve Fitting method.
Part of the code which does the heavy lifting is:
%% Simulation Parameters
numTests = 50;
numSamples = 1000;
paramLambdaBound = 10;
epsVal = 1e-6;
hPoissonPmf = #(paramLambda, vParamK) ((paramLambda .^ vParamK) * exp(-paramLambda)) ./ factorial(vParamK);
for ii = 1:ceil(1000 * paramLambdaBound)
if(hPoissonPmf(paramLambdaBound, ii) <= epsVal)
break;
end
end
vValGrid = [0:ii];
vValGrid = vValGrid(:);
vParamLambda = zeros([numTests, 1]);
vParamLambdaMl = zeros([numTests, 1]); %<! Maximum Likelihood
vParamLambdaCf = zeros([numTests, 1]); %<! Curve Fitting
%% Generate Data and Samples
for ii = 1:numTests
paramLambda = paramLambdaBound * rand([1, 1]);
vDataSamples = poissrnd(paramLambda, [numSamples, 1]);
vDataHist = histcounts(vDataSamples, [vValGrid - 0.5; vValGrid(end) + 0.5]) / numSamples;
vDataHist = vDataHist(:);
vParamLambda(ii) = paramLambda;
vParamLambdaMl(ii) = mean(vDataSamples); %<! Maximum Likelihood
vParamLambdaCf(ii) = lsqcurvefit(hPoissonPmf, 2, vValGrid, vDataHist, 0, inf); %<! Curve Fitting
end
This is the wrong way to do so.
You have data you believe acts according to Poisson Distribution.
Since the Poisson Distribution is parameterized by single parameter (Lambda) then what you need to do is apply Parameter Estimation.
The classic way to do so is by Maximum Likelihood Estimation.
For this case, Poisson Distribution, you need to follow the MLE of Poisson Distribution.
Namely, just calculate the sample mean of data as can be seen in poissfit().

Get the points from a MatLab fit object plot

I am a Matlab amateur so please bear with me -
I currently use Matlab to fit a complex equation to two-dimensional data. Right now I have a program which uses f = fit(xdata, ydata, function, options) to generate a fit object.
I can then use confint(f) and f.parameter etc. to get the fitted coefficients and confidence intervals, and I can use plot(f,x,y) to make a plot of the data and the fit.
From that point on the only way I know how to get the points which were plotted is to use the brush(?) tool and select all of the line, then copy the data to clipboard and paste it into excel or some such thing. I would much rather get those points directly from Matlab, perhaps into an array, but I have no idea how.
Can any MatLab veteran tell me if what I want is even possible? It would be very difficult due to the complexity of my equation to plot those points myself, but I will if need be (it can take ~30 minutes to do this fit and my computer is no slouch).
Since you have not shared any code or data, I use an example from MATLAB documentation:
load franke
f = fit([x, y],z,'poly23');
plot(f,[x,y],z)
So as you can sew, it first loads a dataset including x,y,z vectors. Then fits a surface to the data using 'poly23'. In your case it can be different sets of vectors and function and still as you said you will get the f function.
Now we can take a look at the function f
>> f
Linear model Poly23:
f(x,y) = p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p21*x^2*y
+ p12*x*y^2 + p03*y^3
Coefficients (with 95% confidence bounds):
p00 = 1.118 (0.9149, 1.321)
p10 = -0.0002941 (-0.000502, -8.623e-05)
p01 = 1.533 (0.7032, 2.364)
p20 = -1.966e-08 (-7.084e-08, 3.152e-08)
p11 = 0.0003427 (-0.0001009, 0.0007863)
p02 = -6.951 (-8.421, -5.481)
p21 = 9.563e-08 (6.276e-09, 1.85e-07)
p12 = -0.0004401 (-0.0007082, -0.0001721)
p03 = 4.999 (4.082, 5.917)
It shows you the form of the function and the coefficients. So you can use it as follows:
zz = f(x,y);
To make sure you can plot the data again:
figure;
scatter3(x,y,zz,'.k');
hold on
scatter3(x,y,z,'.');
When you call f = fit(xdata, ydata, function, options), function name decides the equation. See list of official equations.
Simply iterate through data points and compute results using corresponding polynomial. So in your case lets say if function=poly2 you'll be doing computation as follows:
#Fit your data
f = fit([xdata, ydata],'poly2');
#Print name of coefficients (Just for Verification)
coeffnames(f)
#Fetch values of coefficients like p1, p2, ...
p = coeffvalues(c)
#Compute output points from min(xdata) to max(xdata) spaced at deltaX
deltaX = 0.1;
x = [min(xdata):deltaX:max(xdata)];
Y = p(1)*x^2+p(2)*x+p(3); #This is equation for function
I understand there can be alternate complex Java code to iterate through objects on a matlab figure and plot its value but using equations is a quick and valid approach.

Curve fitting with 5 parameters in Matlab

I am working on a curve fitting problem with the input function of the form
n=((xi-xa)-a*cos(theta))^2+(h-a*sin(theta))^2;
d=((xi-xa)+a*cos(theta))^2+(h+a*sin(theta))^2;
v=k*log(n/d) : Input function
Here xa,a,theta,h and k are parameters and we are required to compute v(xi)
The plot looks like this
Here blue dots represent observed value and red line is the theoretical curve obtained from the input function.
This fitting process was done by manually varying the parameters and matching the curves using hit and trial.
Could this be accomplished using any optimization technique in Matlab. if so how ?
You can try to use lsqcurvefit (http://nl.mathworks.com/help/optim/ug/lsqcurvefit.html), e.g.
function F = myfun(x,xdata)
%your parameters xa,a,theta,h,k
%map to parameter vector x(1),x(2),x(3),x(4),x(5)
n = ((xdata-x(1))-x(2)*cos(x(3)))^2+(x(4)-x(2)*sin(x(3)))^2;
d = ((xdata-x(1))+acos(x(3)))^2+(x(4)+asin(x(3)))^2;
F = x(5)*log(n/d);
end
and a call to solver
x0 = [1;1;1;1;1]; % your guess for starting values of the x vector of parameters
x = lsqcurvefit(#myfun,x0,xdata,ydata);