Creating a manual fit to a plot

i have a frequency data and amplitude data. i have to figure out the stiffness with the help of the resonance frequency of an freely damped oscillator. i have been asked to fit the data manually without using fit function. how can i do that ? this is my code. my plan was to create 2 plots: 1 with the ideal data and another with the constants given in the equation. and the match the graphs by changing the value of kn. as other values are known and constant
T = 300;
Q = 384.61;
f_n = 62460;
kB = 1.380648520000000e-23;
kn = 20; % initial guess
total_d_z = 1.095866243071940e-20;
frequency = linspace(total_freq(1000), total_freq(6300), 54001);
d_tot = normalized_psd(900:0.1:6300);
x = frequency;
% Define the function y
y = @(x, kn)((((2 * kB * T)./(pi * kn * f_n * Q))./((x.^2./((f_n^2)-1)).^2 + (x./(f_n^2*Q)).^2) + total_d_z^2));
% Plot the data
plot(x, d_tot, 'DisplayName', 'Measured Data', 'LineWidth', 1);
hold on;
%Plot the initial model with the initial guess for kn
plot(x,y(x, kn), 'LineWidth', 1, 'DisplayName', ['Initial Model (kn=' num2str(kn_initial) ')'],'Marker','+');

5 Comments

undefined total_freq
total_freq(frequency) and d_tot(total psd value) are the known dataset
A best practice when asking a question is to include all information, including data, required to run the code.
Hello !
Sorry, i am new here, thanks for the suggestion, i'll remember this for future. My data is in around 60k samples which is why i didnt upload it.
No worries.
Often times, the full data is not needed - just a sample that sufficiently shows what's going on.
Just wanting to make sure: have you noticed the answer below?
Best wishes,
Harald

Sign in to comment.

Answers (1)

Harald
Harald on 8 Mar 2024
Hi,
one way to do that sort of "manual fit" would be to use a slider or comparable interactive component in Live Editor.
However, the intention may be that you write an own simple optimization algorithm to automatically find the best kn.
Best wishes,
Harald

7 Comments

Thankyou for your answer. That works. i would still be needing the code for it. since it has to be mentioned in my research paper.
The question then to me is why you are not supposed to use the fit function.
If it's just a preference not to, you could use other suitable functions such as lsqcurvefit (Optimization Toolbox).
If the intention is to avoid toolbox functionality, you can use fminsearch or fminbnd to minimize the summed squares of the deviations. There are a lot of related answers, e.g.
Best wishes,
Harald
The reason i cannot use the fit directly is because the amplitude is really small and the CFT is not giving the right fit.
here is a glimpse of the data.
d_tot = [2.2133122e-24 2.2383747e-24 2.1275454e-24 2.2140277e-24]
Here i am tryin to fit the equation on the resonance curve formed by the dataset d_tot. other than that i have to find the value of kn for which i have to manually tweak the value of kn until it matches the graph created by d_tot.
Hi,
This information is very helpful. Next time, please specify it from the beginning.
If CFT is not giving the right fit, the reason is typically starting values that are not good enough. If you provide a starting value that is reasonably close to the solution, you will often get better results.
To further assist you with this, a reproducible example will be needed.
Best wishes,
Harald
Additionally, have you tried the other options I have suggested?
Best wishes,
Harald
Hi Herald,
really appriciate your help. Yes i did try other options. lsqcurvefit says
Optimization completed because the size of the gradient is less than
the value of the optimality tolerance.
Optimization completed: The first-order optimality measure, 2.917292e-27,
is less than options.OptimalityTolerance = 1.000000e-06.
##### With fminsearch :
i am trying to use fminsearch with the frequency vector but its bit hard for me right now. See the code below.
the reason why i am using total_freq, total_freq1 and frequency because matlab says its an unknown variable. so i was just trying to convince it. I already have my frequency data as total_freq. here i am trying to estimate 2 values one is kn and another is Q which is supposed to be 384
%% With fminsearch
x0 = [20 ; 384.61];
fmin_result = fminsearch(@Stiffness,x0);
total_d_z = 2.190266219650838e-21;
function [f] = Stiffness(x)
frequency = linspace(total_freq1(1000), total_freq1(2621), 345);
total_freq1 = total_freq;
T = 300;
f_n = 62460;
kB = 1.38e-23;
f = ((((2 * kB *T)/(pi* x(1) * f_n * x(2))) ./ ( ((frequency.^2)./(f_n^2-1)).^2 + (frequency ./(f_n^2)*x(2)).^2 )) + total_d_z^2);
end
Even if the optimality measures look good, this might only be a local minimum, not the global minimum that you are looking for.
To use fminsearch, you need to use an anonymous function handle, see the example "Minimize with Extra Parameters" in the doc of fminsearch.
Again, please share sample data for further assistance.
Best wishes,
Harald

Sign in to comment.

Asked:

on 8 Mar 2024

Commented:

on 10 Mar 2024

Community Treasure Hunt

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

Start Hunting!