6

I can't understand why this behavior with my code... I'm trying to visually adjust the best parameters to fit my model, everything is working fine, less the part of adjusting the model.

WRCFit[data_] := Manipulate[

  Dynamic@
   Switch[dataa, data1, 
    Show[ListLogLinearPlot[dataa, PlotRange -> All, Frame -> True], 
     LogLinearPlot[model[h], {h, 0.001, 20000}]],
    data2, 
    Show[ListPointPlot3D[
      Transpose[{Log[dataa[[All, 1]]], dataa[[All, 2]], 
        dataa[[All, 3]]}], PlotRange -> All, 
      PlotTheme -> "Scientific"], 
     Plot3D[model[Exp@h, Ds], {h, Log@0.001, Log@20000}, {Ds, 1, 2}]]],

  Row[{Control@{{dataa, data1, "Type"}, {data1 -> "Data 1", 
       data2 -> "Data 2"}, PopupMenu},

    Control@{{model, m1, "Model"}, {m1 -> "Model 1", m2 -> "Model 2", 
       m3 -> "Model 3"}, PopupMenu}}],

  Button["Fit", 
   Dynamic@Switch[model, m1, 
     NonlinearModelFit[data1, 
      model[h], {{HoldForm@r, Dynamic@r}, {HoldForm@s, 
        Dynamic@s}, {HoldForm@a, Dynamic@a}, {HoldForm@n, Dynamic@n}},
       h],
     m2, NonlinearModelFit[data1, 
      model[h], {{HoldForm@r, Dynamic@r}, {HoldForm@s, 
        Dynamic@s}, {HoldForm@h0, Dynamic@h0}, {HoldForm@l, 
        Dynamic@l}}, h]]],

  Dynamic@Switch[model,
    m1, Column[{Control@{{r, 0.1}, 0, 1}, Control@{{s, 0.5}, 0, 1}, 
      Control@{{a, 20}, 0, 30}, Control@{{n, 1.2}, 1, 2}}],
    m2, Column[{Control@{{r, 0.1}, 0, 1}, Control@{{s, 0.5}, 0, 1}, 
      Control@{{h0, 0.2}, 0.001, 3}, Control@{l, 0.01, 2}}], m3, 
    Column[{Control@{{r, 0.1}, 0, 1}, Control@{{Dss, 2.65}, 2, 3}, 
      Control@{{a, 20}, 0, 30}, Control@{{n0, 1.2}, -2, 2}, 
      Control@{{n1, 1.2}, -2, 2}, Control@{{n2, 1}, -2, 2}}]],

  TrackedSymbols :> {r, s, a, n, h0, l, n0, n1, n2, model, Dss},

  Initialization :> {
    m1[h_] := r + (s - r)/(1 + (a h)^n)^(1 - 1/n),
    m2[h_] := Piecewise[{{r + (s - r) (h0/h)^l, h > h0}, {s, h < h0}}],
    m3[h_, Ds_] := 
     r + ((1 - Ds/Dss) - 
         r)/(1 + (a h)^(n0 + n1 Ds + n2 Ds^2))^(1 - 
          1/(n0 + n1 Ds + n2 Ds^2)),
    data1 = data[[All, {1, 3}]],
    data2 = data
    }]

When I click "Fit", i get this messsage

FittedModels`FindNonlinearModelFit::vloc: The variable FE`r$$2126 cannot be localized so that it can be assigned to numerical values.

2 Answers2

3

I believe HoldForm cannot be used in the manner you are attempting. Taking the first example from the NonlinearModelFit documentation and adding HoldForm causes the same error:

data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}, {6, 4}, {7, 5}};

nlm = NonlinearModelFit[data, Log[a + b x^2], {HoldForm[a], b}, x];

FittedModels`FindNonlinearModelFit::vloc: The variable a cannot be localized so that it can be assigned to numerical values.

I think you should be using different Symbols entirely for the model.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • I just realized that Dynamic[Some Expression] has the Head Dynamic, not Real or Symbol. –  Jun 06 '17 at 02:06
  • @user48983 Yes, that's a common trip-up, and I wrote a pitfalls post on the subject; sorry I didn't think to point that out. I used to point it out with some regularity, e.g. (2973), (5820); I guess I feared sounding like a broken record. – Mr.Wizard Jun 06 '17 at 02:19
0

My solution

WRCFit[data_] := Manipulate[

  Dynamic@
   Switch[dataa, data1, 
    Show[ListLogLinearPlot[dataa, PlotRange -> All, Frame -> True], 
     LogLinearPlot[model[h], {h, 0.001, 20000}]],
    data2, 
    Show[ListPointPlot3D[
      Transpose[{Log[dataa[[All, 1]]], dataa[[All, 2]], 
        dataa[[All, 3]]}], PlotRange -> All, 
      PlotTheme -> "Scientific"], 
     Plot3D[model[Exp@h, Ds], {h, Log@0.001, Log@20000}, {Ds, 1, 2}, 
      MeshShading -> {{None, None}, {None, None}}]]],

  Row[{Control@{{dataa, data1, "Type"}, {data1 -> "Data 1", 
       data2 -> "Data 2"}, PopupMenu},

    Control@{{model, m1, "Model"}, {m1 -> "Model 1", m2 -> "Model 2", 
       m3 -> "Model 3"}, PopupMenu}}],

  Button["Fit", 
   Dynamic@Switch[model, m1, 
     Print@Normal@
       NonlinearModelFit[data1, 
        m1fit, {{r0, r}, {s0, s}, {a0, a}, {n00, n}}, h],
     m2, Print@
      Normal@NonlinearModelFit[data1, 
        m2fit, {{r0, r}, {s0, s}, {h00, h0}, {l0, l}}, h]]],

  Dynamic@Switch[model,
    m1, Column[{Control@{{r, 0.1}, 0, 1, Appearance -> "Labeled"}, 
      Control@{{s, 0.5}, 0, 1, Appearance -> "Labeled"}, 
      Control@{{a, 20}, 0, 30, Appearance -> "Labeled"}, 
      Control@{{n, 1.2}, 1, 2, Appearance -> "Labeled"}}],
    m2, Column[{Control@{{r, 0.1}, 0, 1, Appearance -> "Labeled"}, 
      Control@{{s, 0.5}, 0, 1, Appearance -> "Labeled"}, 
      Control@{{h0, 0.2}, 0.001, 3, Appearance -> "Labeled"}, 
      Control@{l, 0.01, 2, Appearance -> "Labeled"}}],
    m3, Column[{Control@{{r, 0.1}, 0, 1, Appearance -> "Labeled"}, 
      Control@{{Dss, 2.65}, 2, 3, Appearance -> "Labeled"}, 
      Control@{{a, 20}, 0, 30, Appearance -> "Labeled"}, 
      Control@{{n0, 1.2}, -2, 2, Appearance -> "Labeled"}, 
      Control@{{n1, 1.2}, -2, 2, Appearance -> "Labeled"}, 
      Control@{{n2, 1}, -2, 2, Appearance -> "Labeled"}}]],

  TrackedSymbols :> {r, s, a, n, h0, l, n0, n1, n2, model, Dss, r0, 
    s0, a0, n00, h00, l0},

  Initialization :> {
    m1[h_] := r + (s - r)/(1 + (a h)^n)^(1 - 1/n),
    m2[h_] := Piecewise[{{r + (s - r) (h0/h)^l, h > h0}, {s, h < h0}}],
    m3[h_, Ds_] := 
     r + ((1 - Ds/Dss) - 
         r)/(1 + (a h)^(n0 + n1 Ds + n2 Ds^2))^(1 - 
          1/(n0 + n1 Ds + n2 Ds^2)),
    data1 = data[[All, {1, 3}]],
    data2 = data,
    m1fit = r0 + (s0 - r0)/(1 + (a0 h)^n00)^(1 - 1/n00),
    m2fit = 
     Piecewise[{{r0 + (s0 - r0) (h00/h)^l0, h > h00}, {s0, h < h00}}],
     Dynamic@
     Switch[model, 
      m1, {r -> Dynamic@r, s -> Dynamic@s, a -> Dynamic@a, 
       n -> Dynamic@n},
      m2, {r -> Dynamic@r, s -> Dynamic@s, h0 -> Dynamic@h0, 
       l -> Dynamic@l}]
    }]

WRCFit[data]

But it's far from being a good code.