How can I fit my data to an inverse tangent function?

37 visualizaciones (últimos 30 días)
Max
Max el 23 de Oct. de 2013
Respondida: John D'Errico el 21 de Jul. de 2023
I'm trying to fit my data to an inverse tangent function. The function is:
y = atan(x*a/b/(a^2-x^2));
where a and b are the constants that I'd like to determine by fitting the data.
What I would like most is a working example of how to go about doing this. The data that I'm working with can be seen below.
%%Fit data to inverse tangent function
% y = atan(x*a/b/(a^2-x^2));
clear all; close all; clc;
x = [0.7 0.8 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4,2.6];
y = [10 11 15 15 15 17 20 25 34 47 75 100 140 155 162 170 171 176];
plot(x,y,'bo');

Respuestas (4)

David Sanchez
David Sanchez el 23 de Oct. de 2013
x = [0.7 0.8 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4,2.6];
y = [10 11 15 15 15 17 20 25 34 47 75 100 140 155 162 170 171 176];
% y = atan(x*a/b/(a^2-x^2))
modelFun = @(p,x) atan(x.*p(1)./p(2)./(p(1)^2-x.^2)); % p(1) = a; p(2) = b
startingVals = [1 1]; % try with any other starting values.
coefEsts = nlinfit(x,y, modelFun, startingVals);
  1 comentario
Max
Max el 23 de Oct. de 2013
Editada: Max el 23 de Oct. de 2013
Trying to plot modelFun with coefEsts doesn't seem to be producing the desired result.
plot(x,y,'bo');
hold on
plot(x,modelFun(coefEsts,x),'m-');
I put the image below.

Iniciar sesión para comentar.


Runze Ma
Runze Ma el 26 de Mayo de 2022
Don't know if you guys have solved the problem or not. As I understand, this fitting is to get the resonance frequency and quality factor out of a phase sweep.
I figured out that the formula of y = atan(x*a/b/(a^2-x^2)) is not suitable for fitting in MATLAB due to the different period settings for the formula and the atan function in MATLAB. This will result in a discontinuity at resonance position f=f0. Instead, you should be using y=atan(b*(a^2-x^2)/a/x). This way, the funciton can run smoothly from -inf to inf and suitable for fitting.
Hope this will help anyone to solve the resonance problem.

Gabriel Felix
Gabriel Felix el 21 de Jul. de 2023
This site has a useful complete guide to tangent/arctangent curve fitting. It uses python,though. However it had success using a certaing kind of tangent function for the fitting.

John D'Errico
John D'Errico el 21 de Jul. de 2023
x = [0.7 0.8 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4,2.6];
y = [10 11 15 15 15 17 20 25 34 47 75 100 140 155 162 170 171 176];
First, LOOK AT YOUR DATA. PLOT IT. ALWAYS! Does it have the fundamental shape of an inverse tangent function?
plot(x,y,'o')
fplot(@atan)
And we see the curve does look like an atan function, though many other basic curves in the general sigmoidal family of functions might also apply. (So I might have chosen a sigmoid function, a cumulative normal, an atan, etc. Give me a minute or so, and I could pick at least a few more.) However, your specific question actually is not a simple atan function.
yfun = @(x,a,b) atan(x*a/b./(a^2-x.^2));
Note my use of the dotted operators to allow the function to be evaluated at many points at once. I'll just pick some simple values for a and b.
fplot(@(x) yfun(x,1,1))
And there we see the function family you are looking at does not have even a close to reasonable shape as that of your data. It cannot be used to fit your data. The result would be complete and utter garbage. I'm sorry, but it would.
mdl = fittype('a + b*atan((x - c)/d)','indep','x')
mdl =
General model: mdl(a,b,c,d,x) = a + b*atan((x - c)/d)
I've picked some starting corefficients directly from the plot itself, NOT by trying a fit, and then choosing and re-choosing new sets of start points. Admitedly, I was off by a bit on the parameter d, and had I thought just a bit longer when I was typing them in, I would have known a better value. But anything within a factor of 5 or so is close enough most of the time.
fittedmdl = fit(x',y',mdl,'start',[100 50 2 1])
fittedmdl =
General model: fittedmdl(x) = a + b*atan((x - c)/d) Coefficients (with 95% confidence bounds): a = 96.01 (94.07, 97.96) b = 59.88 (57.55, 62.21) c = 1.872 (1.859, 1.885) d = 0.16 (0.1393, 0.1808)
plot(fittedmdl,x,y)
That simple atan model fits your data really quite well. I don't know why you think the model you chose would be appropriate.

Community Treasure Hunt

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

Start Hunting!

Translated by