Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Simultaneous Nonlinear Data Fits

774 views
Skip to first unread message

Dan O'Brien

unread,
Apr 10, 2010, 6:53:58 AM4/10/10
to
Hello everyone,

A small statement of my problem: I have 4 data sets consisting of
spectroscopic data (intensity vs frequency data). The data contain
resonant peaks that are fit with the modulus squared of a sum of complex
functions (one for each peak for a total of 6 peaks) and is such that I
must use nonlinear fitting algorithms. Within the four data sets there
are peaks that should be fit to the same parameters and then there are
peaks that vary slightly from data set to data set.

The bottom line is this: I am looking for a solution of the form of a
nonlinear fitting function that is capable of simultaneously fitting
multiple data sets where some parameters apply to all the data sets and
others are specific to only one of the data sets.

I have tried fitting each data set independently using the mathematica
function NonlinearModelFit but the model is such that the
bestfitparameters can vary wildly from data set to data set. Using the
option to constrain leads to computations that never end. It would be
best, in my mind, if Mathematica's fitting algorithm was constrained by
having to minimize the function of the residuals when forced to consider
all data sets at once.

I am relatively new to mathematica (I have been hacking at it for about
a year or so) and appreciate any help this group can offer.

Thanks,

-DanO

dh

unread,
Apr 12, 2010, 6:50:35 AM4/12/10
to

Hi Dan,
you must merge all the different data sets into one. There are different
possibilities for this, you may e.g. shift the sets that they do not
overlap or you may introduce an additional dimension.
Here is an example where I fit 2 spectra containing one independent and
one common Gaussian peak. Note that you need reasonable starting values
for the fit to succeed.

d1 = Table[Exp[- 0.02 (x - 30)^2], {x, 100}];
d2 = Table[Exp[- 0.02 (x - 70)^2], {x, 100}];
d3 = Table[Exp[- 0.02 (x - 50)^2], {x, 100}];
ones = Table[1, {100}];
xs = Range[100];
data = Join[Transpose[{xs, -ones, d1}], Transpose[{xs, ones, d2}],
Transpose[{xs, 0 ones, d3}]];
mod1[x_, z_, x0_] := If[z <= 0, Exp[-0.02 (x - x0)^2], 0];
mod2[x_, z_, x0_] := If[z >= 0, Exp[-0.02 (x - x0)^2], 0];
mod3[x_, z_, x0_] := Exp[-0.02 (x - x0)^2];

sol = FindFit[data, mod1[x, z, x1] + mod2[x, z, x2] + mod3[x, z, x3],
{{x1, 50}, {x2, 50}, {x3, 50}}, {x, z}]

cheers,
Daniel

--

Daniel Huber
Metrohm Ltd.
Oberdorfstr. 68
CH-9100 Herisau
Tel. +41 71 353 8585, Fax +41 71 353 8907
E-Mail:<mailto:d...@metrohm.com>
Internet:<http://www.metrohm.com>


da...@wolfram.com

unread,
Apr 12, 2010, 6:51:46 AM4/12/10
to
> Hello everyone,
>
> A small statement of my problem: I have 4 data sets consisting of
> spectroscopic data (intensity vs frequency data). The data contain
> resonant peaks that are fit with the modulus squared of a sum of complex
> functions (one for each peak for a total of 6 peaks) and is such that I
> must use nonlinear fitting algorithms. Within the four data sets there
> are peaks that should be fit to the same parameters and then there are
> peaks that vary slightly from data set to data set.
>
> The bottom line is this: I am looking for a solution of the form of a
> nonlinear fitting function that is capable of simultaneously fitting
> multiple data sets where some parameters apply to all the data sets and
> others are specific to only one of the data sets.
>
> I have tried fitting each data set independently using the mathematica
> function NonlinearModelFit but the model is such that the
> bestfitparameters can vary wildly from data set to data set. Using the
> option to constrain leads to computations that never end. It would be
> best, in my mind, if Mathematica's fitting algorithm was constrained by
> having to minimize the function of the residuals when forced to consider
> all data sets at once.
>
> I am relatively new to mathematica (I have been hacking at it for about
> a year or so) and appreciate any help this group can offer.
>
> Thanks,
>
> -DanO

This came up in house several weeks ago. A way to go about this, suggested
to me by Darren Glosemeyer, is as follows.

(1) Prepend integer indices to your data, so e.g. elements from the third
set of the form {x,y} would become {3,x,y}.

(2) Join the data sets. Call resulting list "alldata", say.

(3) Define the function of the parameters you want to find. Call it
myPeak, say.

(4) Define your several parameter sets. Those that are to be common values
across several sets will simply appear in each of those sets. Take a
simple example of multiple Gaussians with a common variance. Would be
specified as
params1 = {m1,var};
params2 = {m2,var};
...
so they use the same variance parameter "var" but separate mean parameters
"m1", "m2", etc.

(5) Now you can invoke e.g. NonlinearModelFit as

fitall = NonlinearModelFit[alldata,
KroneckerDelta[index-1]*myPeak[params1] +
KroneckerDelta[index-2]*myPeak[params2] + ...,
<list of union of all parameters perhaps with starting values>,
...]


Daniel Lichtblau
Wolfram Research

Niek Buurma

unread,
May 9, 2011, 6:19:34 AM5/9/11
to
I can confirm that the Wolfram suggestion works - I used it a few years ago for a similar problem. Unfortunately, I found this answer while trying to avoid doing the same for a new set of data ... Guess I'm back to combining arrays of data after all ...

DrMajorBob

unread,
May 9, 2011, 8:22:24 PM5/9/11
to
What Wolfram suggestion would that be? I see nothing below.

Bobby


--
DrMaj...@yahoo.com

basarir

unread,
May 25, 2012, 5:01:18 AM5/25/12
to
Dear All,

Here is an implementation of Daniel Lichtblau's algorithm using partial code from Daniel Huber. This way you could also compare the two methods. Hope this helps.
Cheers,
Basarir

d1 = Table[Exp[-0.02 (x - 30)^2], {x, 100}];
d2 = Table[Exp[-0.02 (x - 70)^2], {x, 100}];
d3 = Table[Exp[-0.02 (x - 50)^2], {x, 100}];
ones = Table[1, {100}];
xs = Range[100];

data = Join[Transpose[{xs, ones, d1}], Transpose[{xs, 2*ones, d2}],Transpose[{xs, 3* ones, d3}]];

mod1[Params_]:= Exp[Params[[1]]* (x - Params[[2]])^2];

modtotal[index_, x1_, x2_, x3_, a_]:= KroneckerDelta[index - 1]*mod1[{a, x1}] + KroneckerDelta[index - 2]*mod1[{a, x2}] + KroneckerDelta[index - 3]*mod1[{a, x3}];

sol = NonlinearModelFit[data, modtotal[index, x1, x2, x3, a], {{x1, 20}, {x2, 60}, {x3, 40}, {a, -0.001}}, {x, index}];

sol["BestFitParameters"]
sol["RSquared"]

Result:

{x1 -> 30., x2 -> 70., x3 -> 50., a -> -0.02}
1.




0 new messages