15 views (last 30 days)

Show older comments

I am trying to solve a constraint problem regarding minimax error. Basically, I want to fit data to a specific type of function where I minimize the maximum error as the polynomial fit oscillates. This might involve weighting the data differently, fixing some coeffs, etc. The excel file is attached.

I have this code:

clear; clc; close all;

mat =xlsread('C:\example2.xlsx','Sheet1','A2:C32');

density = mat(:,1);

eta = mat(:,2);

Z_MD = mat(:,3);

eta_c = 1/1.55;

I want to fit the x data (eta) vs. y data (Z_MD) to the following functional form:

So I need to solve for my Ak values. How I can I minimize the maximums of the relative error? Obviously, since it's a polynomial, the error will fluctuate. Can I use MATLAB to minimize the maximums?

Currently, when I use cftool to fit the data, when I plot the error of the fit with respect to Z_MD, the maximum error is not minimized, meaning as the polynomial fluctuates through the data points, the error is not bound a constant max error.

Edit: Note that it could be fitting eta and Z_MD. density and eta are the same thing, just multiplied by a constant basically.This is why I changed it to eta, so I want to minimize the maximum error of the polynomial fit to my equation that is fit to x = eta and y = Z_MD.

John D'Errico
on 2 Apr 2019

Edited: John D'Errico
on 2 Apr 2019

mat =xlsread('example2.xlsx','Sheet1','A2:C32');

density = mat(:,1);

Z_MD = mat(:,3);

eta = mat(:,2);

eta_c = 1/1.55;

Your model is:

Z(eta) = 1 + 3*eta/(eta_c - eta) + sum(k*A_k*(eta/eta_c)^k)

where the sum operates over k = 1:4. The goal being a minimax fit. Since the first two terms in that model are not variable at all, we will just subtract them for the fit. But at first, plot EVERYTHING. Always plot your data. Look at it. Think about it.

plot(eta,Z_MD,'ro')

The result being a simple power type function. It might seem things will work at least reasonably well, as polynomials like that sort of stuff. So plot more. Think more. Look at what we see. First, remember that your function has a singularity in it. The singularity lives at eta==eta_c.

eta_c

eta_c =

0.64516

plot(eta,Z_MD - (1 + 3*eta./(eta_c - eta)),'ro')

So this is the function you wish to fit with a polynomial.

The first problem is, it does not seem to pass throughzero at eta==0. It is less than zero down there.

Z(eta) - 1 - 3*eta/(eta_c - eta) = sum(k*A_k*(eta/eta_c)^k)

You should observe that the right hand side is identically zero when eta == 0. The left hand side (what I just plotted)is not so. So this will create some amount of lack of fit down there. But worse, what happens when eta approaches 0.64516? The left hand side has a singularity.

Does the right hand side? NO. There can be NO singularities in a polynomial. And the right hand side is purely a polynomial, and only a 4th degree one at that.

Do you really want to go through with this? Sigh.

First, ets see what happens when we just use a simple linear least squares. Backslash can handle that well enough.

A2 = [(eta./eta_c).^(1:4).*(1:4)]\(Z_MD - (1 + 3*eta./(eta_c - eta)))

A2 =

5.302

-20.991

33.224

-16.441

So A2 is the 2-norm solution. Given those coefficients, we can look at the fit.

Zpred = [(eta./eta_c).^(1:4).*(1:4)]*A2;

plot(eta,Z_MD - (1 + 3*eta./(eta_c - eta)),'ro')

hold on

grid on

plot(eta,Zpred,'b-')

Sigh. Double sigh. Well, it does look reasonably close to a minimax fit as it is. A 2-norm fit like this will often not be unreasonable. Lets look at the residuals.

plot(eta,Z_MD - (1 + 3*eta./(eta_c - eta)) - Zpred,'ro')

grid on

yline(0);

So indeed pretty close to a minimax fit, as I said. It only deviates by a bit. Is it really worth the effort, for a fit that does not fit that well in the first place?

I'd suggest that looking for a true minimax fit here is a bit extreme, given the significant problems in the fit. Do you really need it? Regardless, fminimax is much easier to use than you seem to be making it appear. Two lines suffice, although it would always be a good idea to use the 2-norm solution as a start point. So three lines.

mmfun = @(A) abs(Z_MD - 1 - 3*eta./(eta_c - eta) - [(eta./eta_c).^(1:4).*(1:4)]*A);

[Amm,~,maxres,exitflag] = fminimax(mmfun,A2)

Local minimum possible. Constraints satisfied.

fminimax stopped because the size of the current search direction is less than

twice the default value of the step size tolerance and constraints are

satisfied to within the default value of the constraint tolerance.

<stopping criteria details>

Amm =

5.7492

-23.245

36.892

-18.375

maxres =

0.15832

exitflag =

4

So a little different from A2. But honestly, hardly worth the effort. Note that I was carful to use abs in mmfun, since fminimax minimizes the maxima, but not the absolute max. From the help:

fminimax finds a minimax solution of a function of several variables.

fminimax attempts to solve the following problem:

min (max {FUN(X} ) where FUN and X can be vectors or matrices.

So you do need an abs in there.

Zpredmm = [(eta./eta_c).^(1:4).*(1:4)]*Amm;

plot(eta,Z_MD - (1 + 3*eta./(eta_c - eta)) - Zpredmm,'ro')

yline(0);

grid on

From a different perspective, can you honestly see the difference below, between the green and blue curves? Is that difference significant?

plot(eta,Z_MD,'ro',eta,(1 + 3*eta./(eta_c - eta)) + Zpredmm,'b-',eta,(1 + 3*eta./(eta_c - eta)) + Zpred,'g-')

grid on

Whatever floats your boat. Personally, I think focusing on a minimax approximation here is somewhat misguided, because there are essential flaws in that approximation that far exceed the tiny differences.

Catalytic
on 4 Apr 2019

You should remove abs and instead use AbsoluteMaxObjectiveCount (that's what it's meant for). I don't know why John's version works without it. Freakish luck, I suppose.

Also, you shouldn't set AbsoluteMaxObjectiveCount blindly to some value like 1. Read about what it does and how to use it!

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

Start Hunting!