curve fitting of a complex data

I'm currently working on fitting some experimental data to a complex-valued function using MATLAB's lsqcurvefit function. However, I seem to encounter issues, and I'm not getting the desired solution. I'm hoping to get some guidance on what might be going wrong with my approach. I have tried changing the values of initial guesses
VALUE OF P1=102; P3=326;
w1=8000;
xdata = [0 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000 7500 8000 8500 9000 9500 10000 10500 11000 11500 12000 12500 13000 13500 14000 14500 15000];
ydata = [0 23.23166979 43.89101766 61.37336819 76.13374067 88.63427978 99.17236163 107.96827 115.2289659 121.1585778 125.9542122 129.7976768 132.8504967 135.2544369 137.1234954 138.5545735 139.6310041 140.4137722 140.960863 141.3115956 141.5020398 141.5603911 141.5098635 141.3688178 141.150192 140.8714973 140.5392011 140.1625248 139.7464364 139.3025573 138.8344027];
function= -1j .* ((params(1) .* (xdata ./ 60) ./ (1 + (xdata ./ w1).^2)) + (params(2) .* (xdata ./ 60) ./ (1 + (xdata ./ params(3)).^2))) .* 0.001;
i want to fit the ydata to the function given, i have tried least square methods. But i am not getting the solution.

9 Comments

Please share your code for performing the fit as well. If you know what the solution should be, share that, too.
clear;
clc;
% Given data
xdata = [0 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000 7500 8000 8500 9000 9500 10000 10500 11000 11500 12000 12500 13000 13500 14000 14500 15000];
ydata = [0 23.23166979 43.89101766 61.37336819 76.13374067 88.63427978 99.17236163 107.96827 115.2289659 121.1585778 125.9542122 129.7976768 132.8504967 135.2544369 137.1234954 138.5545735 139.6310041 140.4137722 140.960863 141.3115956 141.5020398 141.5603911 141.5098635 141.3688178 141.150192 140.8714973 140.5392011 140.1625248 139.7464364 139.3025573 138.8344027];
w1 = 8000;
% Define the complex function
complex_func = @(xdata, params) -1j .* ((params(1) .* (xdata) ./ (1 + (xdata ./ w1).^2)) + (params(2) .* (xdata) ./ (1 + (xdata ./ params(3)).^2))) .* 0.001;
% Define the cost function for lsqcurvefit
cost_func = @(params) abs(abs(complex_func(xdata, params)) - ydata);
% Initial guess for the parameters
p0 = [1, 2, 16000];
% Use lsqcurvefit to find the best-fitting parameters
best_params = lsqcurvefit(complex_func, p0, xdata, ydata);
Error using lsqcurvefit
Function value and YDATA sizes are not equal.
% Evaluate the fitted complex function at the data points using the optimized parameters
yfit = abs(complex_func(xdata, best_params));
% Plot the data and the fitted function
figure;
plot(xdata, ydata, 'o', xdata, yfit, '-')
legend('Data', 'Fit');
xlabel('xdata');
ylabel('ydata');
title('Complex Curve Fitting Example');
grid on;
% Display the optimized parameters
disp('Optimized Parameters:');
disp(['k1: ', num2str(best_params(1))]);
disp(['k2: ', num2str(best_params(2))]);
disp(['w2: ', num2str(best_params(3))]);
THE SOLUTION FOR K1 AND K2 ARE 102 AND 328
The argument list for ‘complex_func’ is reversed from the MATLAB convention. The parameter argument must be the first argument, the independent variable data the second argument.
% Given data
xdata = [0 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000 7500 8000 8500 9000 9500 10000 10500 11000 11500 12000 12500 13000 13500 14000 14500 15000];
ydata = [0 23.23166979 43.89101766 61.37336819 76.13374067 88.63427978 99.17236163 107.96827 115.2289659 121.1585778 125.9542122 129.7976768 132.8504967 135.2544369 137.1234954 138.5545735 139.6310041 140.4137722 140.960863 141.3115956 141.5020398 141.5603911 141.5098635 141.3688178 141.150192 140.8714973 140.5392011 140.1625248 139.7464364 139.3025573 138.8344027];
w1 = 8000;
% Define the complex function
% complex_func = @(xdata, params) -1j .* ((params(1) .* (xdata) ./ (1 + (xdata ./ w1).^2)) + (params(2) .* (xdata) ./ (1 + (xdata ./ params(3)).^2))) .* 0.001;
complex_func = @(params, xdata) -1j .* ((params(1) .* (xdata) ./ (1 + (xdata ./ w1).^2)) + (params(2) .* (xdata) ./ (1 + (xdata ./ params(3)).^2))) .* 0.001;
% Define the cost function for lsqcurvefit
cost_func = @(params) abs(abs(complex_func(xdata, params)) - ydata);
% Initial guess for the parameters
p0 = [1, 2, 16000];
% Use lsqcurvefit to find the best-fitting parameters
best_params = lsqcurvefit(complex_func, p0, xdata, ydata)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
best_params =
1.0e+05 * -0.0000 + 0.0003i 0.0000 + 0.0000i 7.6909 + 1.4219i
% Evaluate the fitted complex function at the data points using the optimized parameters
yfit = abs(complex_func(best_params,xdata)); % <— CHANGED (Argument Order Reversed)
% Plot the data and the fitted function
figure;
plot(xdata, ydata, 'o', xdata, yfit, '-')
legend('Data', 'Fit');
xlabel('xdata');
ylabel('ydata');
title('Complex Curve Fitting Example');
grid on;
% Display the optimized parameters
disp('Optimized Parameters:');
Optimized Parameters:
disp(['k1: ', num2str(best_params(1))]);
k1: -0.000472615+32.8539i
disp(['k2: ', num2str(best_params(2))]);
k2: 0.00030824+1.6596i
disp(['w2: ', num2str(best_params(3))]);
w2: 769090.6699+142186.7674i
With that change, it works, and the fit seems to be reasonably good!
.
The fit is now looking good, but the obtained values for K1 and K2 are 102 and 328, respectively
The lsqcurvefit function allows bounding the parameters. That is likely preferable to fixing the values of ‘K1’ and ‘K2’ and solving only for the ‘W2’, although that is certainly an option.
I want to mention that I obtained the values of K1 and K2 from the literature, and I am currently in the process of validating them using MATLAB's lsqcurvefit function. Instead of fixing the values of K1 and K2 and solving only for W2, I have chosen to use the option of bounding the parameters in lsqcurvefit.
By bounding the parameters, I am allowing them to vary within certain limits during the fitting process. This approach provides more flexibility and may lead to improved fits, as the fitting algorithm can explore a wider range of parameter values to find the best match with my experimental data.
I have set appropriate bounds for K1 and K2 based on the literature values and the expected range for these parameters in my specific experimental context. This way, I can ensure that the fitted values of K1 and K2 remain consistent with the available literature information.
After performing the fitting, I will visually inspect the fit to see how well the model matches the experimental data. Additionally, I plan to use goodness-of-fit metrics to quantitatively evaluate the quality of the fit.
If anyone has experience with bounding parameters in lsqcurvefit or has insights on how to choose appropriate bounds for K1 and K2 in this context, I would greatly appreciate your input and suggestions
Bounding the parameters is straightforward. See the lsqcurvefit documentation for those details.
I have tried that, but still i am not getting the solution. i want VALUE OF P1=102; P3=326;

Sign in to comment.

Answers (0)

Categories

Asked:

on 25 Jul 2023

Commented:

on 27 Jul 2023

Community Treasure Hunt

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

Start Hunting!