Sum of functions in mathematics

I am trying to tune an arbitrary amount of distributed gaussians to a function - each with its own set of parameters. Currently, if I want to use twenty functions, I do the following

Ο†[Ξ±_?NumberQ, x_?NumberQ, xi_?NumberQ, c_?NumberQ] := ( c E^(- Ξ± (x - xi)^2/2))/Sqrt[Ξ±/Ο€]; Data := Table[{n/50, N[f[n/50]]}, {n, -300, 300}]; model = Ο†[a1, x, x1, c1] + Ο†[a2, x, x2, c2] + Ο†[a3, x, x3, c3] + Ο†[a4, x, x4, c4] + Ο†[a5, x, x5, c5] + Ο†[a6, x, x6, c6] + Ο†[a7, x, x7, c7] + Ο†[a8, x, x8, c8] + Ο†[a9, x, x9, c9] + Ο†[a10, x, x10, c10] + Ο†[a11, x, x11, c11] + Ο†[a12, x, x12, c12] + Ο†[a13, x, x13, c13] + Ο†[a14, x, x14, c14] + Ο†[a15, x, x15, c15] + Ο†[a16, x, x16, c16] + Ο†[a17, x, x17, c17] + Ο†[a18, x, x18, c18] + Ο†[a19, x, x19, c19] + Ο†[a20, x, x20, c20]; nlm = NonlinearModelFit[Data, model, {a1, x1, c1, a2, x2, c2, a3, x3, c3, a4, x4, c4, a5, x5, c5, a6, x6, c6, a7, x7, c7, a8, x8, c8, a9, x9, c9, a10, x10, c10, a11, x11, c11, a12, x12, c12, a13, x13, c13, a14, x14, c14, a15, x15, c15, a16, x16, c16, a17, x17, c17, a18, x18, c18, a19, x19, c19, a20, x20, c20}, x]; 

This works well, but it is tedious to create these linear combinations manually. It would be great to create a linear combination of functions with a coefficient vector for a, xi and c. I just don’t know how to approach this, and I was hoping you guys could talk about this.

Best

Thomas

+6
source share
2 answers

I did something like this:

 params = Flatten[ Table[{Subscript[a, i], Subscript[m, i], Subscript[c, i]}, {i, 1, n}]]; model = Sum[ Phi[Subscript[a, i], x, Subscript[m, i], Subscript[c, i]], {i, 1, n}]; fit = NonlinearModelFit[data, model, params, x]]; 

Just replace n with as many Gaussians as you like. Obviously, if you have different basic functions, you will have to do other things, but it works well when you only work with a set (or even two) basic functions.

Here are some proof of concept code:

 Phi[x_, a_, b_, c_] := c Exp[-(x - a)^2/b^2]/(b Sqrt[\[Pi]]) n = 10; Ap = RandomReal[{-5, +5}, {n}]; Bp = RandomReal[{0.2, 2}, {n}]; Cp = RandomReal[{-3, +3}, {n}]; f[x_] := Evaluate[Sum[Phi[x, Ap[[i]], Bp[[i]], Cp[[i]]], {i, n}]] data = Module[{x, y}, x = RandomReal[{-10, +10}, {3000}]; y = f[x]; Transpose[{x, y}]]; (* Force data to be precision to be 50 digits, so we can use higher precision in NLMF *) data = N[Round[data * 10^50] / 10^50, 50]; params = Flatten@Table [{ a@i , b@i , c@i }, {i, n}]; model = Sum[Phi[x, a@i , b@i , c@i ], {i, n}]; fit = Normal@NonlinearModelFit [data, model, params, x, WorkingPrecision->50]; Show[ListPlot[data, PlotStyle -> Red], Plot[fit, {x, -5, +5}], PlotRange -> All] 
+3
source

You may try:

 Phi[Ξ±_, x_, xi_, c_] := (c E^(- Ξ± (x - xi)^2/2))/Sqrt[Ξ±/Ο€]; model = Sum[Phi[ a@i , x, xx@i , c@i ], {i, 20}]; nlm = NonlinearModelFit[Data, model, Flatten@Table [{ a@i , xx@i , c@i }, {i, 20}], x] 

Edit

Not tested, but I think that in order to leave the number of insecure Gaussians, you can also do something like:

 nlm[n_] := NonlinearModelFit[Data, Sum[Phi[ a@i , x, xx@i , c@i ], {i, n}] Flatten@Table [{ a@i , xx@i , c@i }, {i, n}], x]; nlm[20] 
+4
source

Source: https://habr.com/ru/post/893040/


All Articles