【问题标题】:Sum Of Functions in MathematicaMathematica 中的函数总和
【发布时间】:2011-07-19 23:40:04
【问题描述】:

我正在尝试将任意分布的高斯总和曲线拟合到一个函数中——每个函数都有自己的一组参数。目前,如果我想使用 20 个函数,我会执行以下操作

φ[α_?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];

这很有效,但手动创建这些线性组合很乏味。用 a、xi 和 c 的系数向量创建函数的线性组合会很棒。我只是不确定如何处理这个问题,我希望你们能对此提供一些见解。

最好的,

托马斯

【问题讨论】:

    标签: wolfram-mathematica


    【解决方案1】:

    你可以试试:

    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]
    

    编辑

    未测试,但我认为为了让高斯数不定,您也可以执行以下操作:

    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]
    

    【讨论】:

    • 你在最后错过了一个 x。我喜欢我们最终发布几乎完全相同的内容的方式。
    • @belisarius 哇,这个效果很好!谢谢!我绝对错过了 Flatten 命令,哇。
    【解决方案2】:

    我以前做过这样的事情:

    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]];
    

    只需将 n 替换为您需要的任意数量的高斯。显然,如果您有不同的基函数,您将不得不做其他事情,但是当您只处理一组(甚至两个)基函数时,这很有效。

    这是一些概念验证代码:

    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]
    

    【讨论】:

    • 我觉得你把fPhi搞混了
    • 是的,我做到了。我尝试做FindFit 并且显然FindFit 可以得到与NonlinearModelFit 相同的适合度,所以我从答案中删除了它。我想NonlinearModelFit 更普遍是意料之中的。
    • @Mike,我对上面的代码进行了修改(pastebin.com/Xwmn18UT),我得到了以下错误:LinearAlgebraBLASTRSV::oflow:在计算过程中遇到机器溢出,但仅用于 22 个基础功能或更多。您对如何正确处理此问题有 ant 建议吗?
    • @Thomas:您是否尝试过提高计算的精度?我将添加一个修改来演示如何执行此操作。
    • @Thomas:溢出也可能是由于大量的基函数。它在优化参数时尝试的一种拟合可能会产生太大而无法表示的结果。在这种情况下,您可能必须减少基函数的数量或提高计算的准确度和精度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多