Fitting data with custom equation and custom interval

5 views (last 30 days)
I am trying to fit my data using the following code, but I couldnt find what is the problem in my code.
fy = @(a,b,x) 0.001*((a-x)/(a(1-x))).^(-b*a/(1-a));
x = [0,0.1, 0.2, 0.3, 0.4, 0.46, 0.55, 0.6];
y = [0.001, 0.00111499, 0.0011926, 0.0013699, 0.00161633, 0.00192075, 0.00274991, 0.00357156];
B = fmincon(@(c) norm(y - fy(c(1),c(2),x)), [1; 1], [],[],[],[], [0 0],[1 90]);
fprintf('PhiMax = %.15f\nVisco = %.15f\n', B)
xv = linspace(min(x), max(x));
figure(1)
plot(x, y, 'pg')
hold on
plot(xv, fy(B(1),B(2),xv), '-r')
hold off
grid
I also tried with this function :
fitfun = fittype( @(a,b,x) 0.001*((a-x)/(a(1-x))).^(-b*a/(1-a)));
my last question is it possible to add a custom interval for the variable for this fitfun function

Accepted Answer

Walter Roberson
Walter Roberson on 23 May 2022
The fundamental problem is that you have an expression raised to a negative power, and if that expression can ever be 0, that gives you an infinite contribution. Your expression includes (a-x) so if your a parameter can ever exactly equal any of the x values, you generate the infinity. If (a-x) is negative (so if a is less than any x value) then you get a complex result, since you would then have negative to a fraction.
The reason the problem showed up on the initial call, is that your initial guess of [1 1] had a value that exactly matches the upper bound of 1 for the first parameter. The internal processing of bounds pushed the guess to an interior point, and the interior point happened to be 0.55 ... which happens to be exactly one of the x values, so you got 0^negative giving you the infinity.
In the below, I set the lower bound for the first parameter to be the maximum x value; that could potentially still give you 0^ but since it avoids touching the bound itself it moves the guess to a valid range.
fy = @(a,b,x) 0.001*((a-x)./(a.*(1-x))).^(-b.*a./(1-a));
x = [0,0.1, 0.2, 0.3, 0.4, 0.46, 0.55, 0.6];
y = [0.001, 0.00111499, 0.0011926, 0.0013699, 0.00161633, 0.00192075, 0.00274991, 0.00357156];
fun = @(c) y - fy(c(1),c(2),x)
fun = function_handle with value:
@(c)y-fy(c(1),c(2),x)
residue = @(c) norm(y - fun(c));
lb = [0 0];
ub = [1 90];
lb(1) = max(x);
guess = [1;1];
B = fmincon(residue, guess, [],[],[],[], lb, ub);
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
fprintf('PhiMax = %.15f\nVisco = %.15f\n', B)
PhiMax = 0.815240648112584 Visco = 0.000196530702283
xv = linspace(min(x), max(x));
figure(1)
plot(x, y, 'pg')
hold on
plot(xv, fy(B(1),B(2),xv), '-r')
hold off
grid
  3 Comments
Walter Roberson
Walter Roberson on 23 May 2022
If you are asking to know what starting point will be used if the initial guess is not strictly on the interior of the lb ub range, then unfortunately that logic is implemented by toolbox/shared/optimlib/private/shiftInitPtToInterior.p which we cannot see the source for.
If your initial guess is strictly within the lb ub then your initial guess will be used.

Sign in to comment.

More Answers (0)

Categories

Find more on Interpolation in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!