How to get analytic expression for experimental data?

19 views (last 30 days)
Hello to everyone, I am new here!
I can't really formulate a single question but rather would like to describe what I have been doing so far. Being a rather unexperienced programmer I would appreciate help not only on the main issue but on anything that can be done better. So feel free to comment!
I am solving a system of partial differential equations with "pdepe" which works fine. For the calculation of the discrete intermediate steps I provide a function that is based on experimental data. The experimental data is not easily fit by one analytic expression so I am fitting it piecewise like so
function W = W_of_DeltaF(dF,material)
if nargin < 2
fprintf('You have to declare a material first!\n');
end
switch material
case 'APO-Tric'
dF_sp1 = 21.2179113385874;
dF_sp2 = 127.07205949453;
dF_sp3 = 294.787905198327;
dF_sp4 = 409.01335594804;
dF1 = dF(dF<=dF_sp1);
W_coef=[0.33051,0.031024,0.087042];
W1 = W_coef(1)+W_coef(2)*exp(-W_coef(3)*dF1);
W1 = W1(:);
dF2 = dF(dF>dF_sp1 & dF<=dF_sp2);
W_coef=[0.34346,-0.00138,8.488e-005,-2.7283e-006,4.1173e-008,-2.8788e-01
W_const = 9.9778;
W2 = W_coef(1) ...
+ W_coef(2) * (dF2-W_const).^1 ...
+ W_coef(3) * (dF2-W_const).^2 ...
+ W_coef(4) * (dF2-W_const).^3 ...
+ W_coef(5) * (dF2-W_const).^4 ...
+ W_coef(6) * (dF2-W_const).^5 ...
+ W_coef(7) * (dF2-W_const).^6;
W2 = W2(:);
dF3 = dF(dF>dF_sp2 & dF<=dF_sp3);
W_coef=[-0.78166,0.048418,-0.00079418,6.4215e-006,-2.7697e-008,6.1208e-0
W3 = W_coef(1) ...
+ W_coef(2) * (dF3).^1 ...
+ W_coef(3) * (dF3).^2 ...
+ W_coef(4) * (dF3).^3 ...
+ W_coef(5) * (dF3).^4 ...
+ W_coef(6) * (dF3).^5 ...
+ W_coef(7) * (dF3).^6;
W3 = W3(:);
dF4 = dF(dF>dF_sp3 & dF<=dF_sp4);
W_coef=[1.2677,-0.0044196,3.3883e-006];
W4 = W_coef(1) ...
+ W_coef(2) * (dF4).^1 ...
+ W_coef(3) * (dF4).^2;
W4 = W4(:);
dF5 = dF(dF>dF_sp4);
W_coef=[0.0015397,0.027218,10.426];
W_const = 408.14;
W5 = W_coef(1)+W_coef(2)*exp(-(dF5-W_const)/W_coef(3));
W5 = W5(:);
W = [W1; W2; W3; W4; W5];
case 'some other material'
do this
otherwise
sprintf('Sorry, you did not provide a valid string for "material".\n');
end
This has some disadvantages. The intersection of the analytic functions are often not smooth, i.e. differentiable, which might cause problems. Also this piecewise fitting can get quite tedious and time consuming since it has to be repeated and tuned for every new 'material'.
I thought about doing something like tracing the limited number of experimental data points with something like GIMP to achieve a smooth curve following the data points.
I know this might sound a little unscientific since it creates data where there is no evidence for it, but I can follow certain physical guidelines when tracing the data that are sensible and I need a qualitative behavior rather than the exact shape.
This curve could then be converted back to a larger amount of data points with some sort of plot digitizer. At this point I am still using the data points for piecewise fitting but was thinking that there might be some way of interpolating the points in order to being able to return data between discrete points. I have tried this once briefly but the program became orders of magnitude slower.
I hope this wasn't too much babble and someone might still be following up to this point. If further input from my side is needed or would be helpful, anytime!
Until then!
Cheers!
  4 Comments
Stephen23
Stephen23 on 1 Sep 2014
Edited: Stephen23 on 1 Sep 2014
The shape of the data, with sharp corners and long straight-ish sections, and your need to have differentiable smooth fitted curves, really means that PCHIP would be a viable interpolation method.
"The experimental data is not easily fit by one analytic expression so I am fitting it piecewise like so"
Why do you need to explicitly create your own piecewise analytic function to model this data? In MATLAB, the spline functions (e.g. spline , pchip ) do not require calculation of piecewise boundaries, and they can fit arbitrary sets of data points. They calculate piecewise functions internally, and can optionally return these as a piecewise polynomial structure (output pp ).
Are you trying to fit splines individually to different sections of data, such as those shown marked in green and red in the above image? This is hardly a fast or reliable method for fitting a curve to data points, considering that MATLAB already has several spline fitting functions built in, none of which requires splitting the data into sections.
John D'Errico
John D'Errico on 1 Sep 2014
The point is, you are better off using a spline (better, a variant thereof like pchip) to do your fit than you are to do the fit using a cobbled up approach as you have shown.
PCHIP is a IBG improvement here over a spline, because while a spline will be twice differentiable, it will show some serious ringing near those breaks in the curve. PCHIP is designed not to do that, while still being reasonably smooth.
There are other tools that have been written to do shape preserving interpolation that are also twice continuously differentiable, but none that I know of are provided in MATLAB. (The tools I wrote are not in the public domain, although one day I should probably provide one.)

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 29 Aug 2014
Edited: Stephen23 on 1 Sep 2014
Presumably you have a good understanding of the underlying data behavior, and simply need to model this...
If a simple linear fit is not adequate, then a cubic spline fit gives nice smooth curves, and is differentiable. PCHIP has some nice properties too, and of course there are plenty more interpolation tools to try out.
If you require subsampling/interpolation, then writing your own function is not likely to produce results faster that these, and of course it will be slower than not doing any interpolation at all.
If speed is an issue, remember to vectorize (you seem to have done this, but a reminder just in case...).
PS: the second argument material is unused, and a "switch" call is missing.
  2 Comments
Markus
Markus on 29 Aug 2014
Thanks Stephen, I appreciate your answer. Considering your P.S. I updated my original edit, i.e. the piece of code, and included the switch statement that I had forgotten. Thanks for that.
Maybe my reply to dpb's comment will make my question a bit clearer. Until a potential further answer I'll definitely look in the direction you pointed.
Cheers!
dpb
dpb on 29 Aug 2014
We're both pointing to the same direction; probably an actual typical dataset would be more helpful to play with than the figures but don't see that should be too difficult to work out a reasonable interpolating function more simply than what you've outlined above. pchip has advantage over cubic splines for some shapes as shown in the help example that "ringing" isn't such an issue...

Sign in to comment.

More Answers (1)

Markus
Markus on 2 Sep 2014
Thank you Stephen, dpb, and John for your help and for pointing out the correct way of performing the task.
Till next time!
Cheers

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!