Using lsqcurvefit with 2 input vectors

10 views (last 30 days)
Davneet Kaur
Davneet Kaur on 29 Nov 2021
Answered: Nipun on 16 Apr 2024 at 10:03
I wrote the following function to make an exponential decay fit to my ydata (inputArg1). My xdata is made up of two input vectors [X1 X2].
I originally had one input parameter, X1 and the function worked (produced a 1x10000 matrix) and executed quickly. However, the fit didn't account for all the features of my data, so I updated the fit function to include the X2 term-- the equation is a bit more complicated with an extra coefficient. Once I introduced X2, instead of a fit line, the function outputs only a point (one-by-one matrix). It should be 1x10000. The function ran for a very long time and sometimes crashed the software. Is there something wrong with my code or is the lsqcurvefit function not appropriate for this function? Is it computationally too heavy for my laptop? If yes, any suggestions on a different function to use?
xaxis= 1.0e+05 *
0.1983 0.1292
0.0918 0.0607
0.0800 0.0812
0.0421 0.0721
0.0532 0.0492
0.0496 0.0259
0.3333 0.0681
0.5700 0.1118
1.3762 0.3193
1.6224 0.5828
1.4950 0.6984
1.7067 1.1286
function [GR_DecayFit,GRfitvar,RESIDUAL,JACOBIAN]=GR_Exponential_Decay(inputArg1,xaxis)
% MAPPING:
Expdecay_fit = @(b,x) log(b(1)) - (b(2) +b(3).*x(:,2)).*x(:,1); % Original function that works with only X1: log(b(1)) - (b(2)).*x;
b0 = [mean(log(inputArg1(1:3))); 0;0];% Initial Parameter Estimates
[GRfitvar,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA,JACOBIAN] = lsqcurvefit(Expdecay_fit, b0, xaxis, (log(inputArg1)));
AgVct = (linspace(min(xaxis(:,1)), max(xaxis(:,1)),10000)); % Plot Finer Resolution
figure(1)
GR_DecayFit=Expdecay_fit((GRfitvar),AgVct);
plot((xaxis(:,1)), ((inputArg1)), 'bp')
hold on
plot((AgVct), (exp(real(Expdecay_fit(GRfitvar,AgVct)))),'r')
end

Answers (1)

Nipun
Nipun on 16 Apr 2024 at 10:03
Hi Davneet,
I understand that you are trying to perform an exponential decay fit to your dataset using MATLAB's lsqcurvefit function. After updating your model to include an additional coefficient for the X2 term to better capture the features of your data, you encountered issues.
Based on the shared information, I find that the issue is the current use of AgVct with Expdecay_fit for plotting. The original Expdecay_fit function is designed to work with a two-column x input, where x(:,1) and x(:,2) correspond to X1 and X2 respectively. However, when plotting the fit, you are only providing AgVct (which seems to only represent a range of values for X1), but not any corresponding values for X2. This mismatch in expected input dimensions is likely why you're seeing unexpected output.
Here is a revised approach assuming you want to hold X2 constant at some average value for plotting (or you could adjust this to vary X2 as needed):
% Assuming you want to use an average value for X2 or any specific value for plotting
averageX2 = mean(xaxis(:,2));
% Now, create a 2-column matrix for plotting where the first column is AgVct (your X1 range)
% and the second column is the constant averageX2
AgVct2 = [linspace(min(xaxis(:,1)), max(xaxis(:,1)), 10000)', repmat(averageX2, 10000, 1)];
% Now when you call Expdecay_fit for plotting, use the new AgVct2 which includes both X1 and X2
GR_DecayFit = Expdecay_fit(GRfitvar, AgVct2);
% Plotting the original data
figure(1)
plot(xaxis(:,1), log(inputArg1), 'bp'); % Assuming you want to plot the log of inputArg1 to match the fit function's output
hold on;
% Plotting the fit - make sure to exponentiate the result if your original data isn't in log space
plot(AgVct2(:,1), exp(real(GR_DecayFit)), 'r');
This revision involves creating a 2-column matrix AgVct2 where the first column is your finely spaced X1 values (AgVct) and the second column is a constant value for X2 (here, I used the mean of your X2 values from xaxis, but you can adjust this to match your specific needs).
Hope this helps.
Regards,
Nipun

Community Treasure Hunt

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

Start Hunting!