1
$\begingroup$

I have a fit a data set to the following equation

nlm = NonlinearModelFit[Data, a*Cos[2Pi*x]+(-a*Tan[phase1])*Sin[2Pi*x]+c*Cos[4Pi*x]+(-c*Tan[phase2]*Sin[4Pi*x]+e,{a,phase1,c,phase2,e},x]

I found the mean squared error using the ANOVA table.

MSE = nlm["ANOVATableMeanSquares"][[2]]

Now what I want to do is to find specific phases with twice that mean squared error using the following way. Extract the phase1, phase2 fitting parameters which I've done, so assume phase1, phase2 are constants in the following.

nlm2 = NonlinearModelFit[Data, a*Cos[2Pi*x]+(-a*Tan[phase1 + AddedPhase])*Sin[2Pi*x]+c*Cos[4Pi*x]+(-c*Tan[phase2+2*AddedPhase]*Sin[4Pi*x]+e,{a,c,e},x]

I'm trying to find the value of AddedPhase so that the MSE for nlm2 would be two times as big as the MSE for nlm. How would I go about doing that, if possible at all?

$\endgroup$
0
$\begingroup$

Construct a parametric function for the base model:

ClearAll[model1, model2]
model1[a_, c_, e_, phase1_, phase2_][x_] := a*Cos[2 Pi*x] +
   (-a*Tan[phase1])*Sin[2 Pi*x] + c*Cos[4 Pi*x] + (-c*Tan[phase2]*Sin[4 Pi*x]) + e

Example data constructed using model1 + error for a given set of parameter values:

SeedRandom[1]
fakedata =  With[{a = 1, phase1 = Pi/3, c = 2, phase2 = Pi/5, e = 5}, 
   Table[{x, model1[a, c, e, phase1, phase2][x] + RandomVariate[NormalDistribution[]]}, 
     {x, 0, 10, .1}]];

Estimate model1 parameters:

nlm1 = NonlinearModelFit[fakedata, 
  model1[a, c, e, phase1, phase2][x], {a, c, e, phase1, phase2}, x]

enter image description here

Compute mean squared error:

mse1 = Mean[(fakedata[[All, 2]] - 
   (model1[a, c, e, phase1, phase2] /@ fakedata[[All, 1]]))^2] /.
     nlm1["BestFitParameters"]

0.930157

Estimated parameters:

nlm1["ParameterTable"]

enter image description here

The second model is constructed by injecting the estimated values of the parameters phase1 and phase2 and adding a new parameter (addedPhase):

ClearAll[model2]
model2[a_, c_, e_, addedPhase_][x_] := 
  model1[a, c, e, phase1+addedPhase, phase2+addedPhase][x] /. 
    (Thread[{phase1, phase2} -> ({phase1, phase2} /. 
      nlm1["BestFitParameters"])])

Estimate model2 parameters adding the constraint that the mean squared error of the model is 2 mse1 (a non-linear constraint on the parameters a, c, e and addedPhase):

nlm2constrained = NonlinearModelFit[fakedata, 
 {model2[a, c, e, addedPhase][x], 
  2 mse1 == Mean[(fakedata[[All, 2]] -
    (model2[a, c, e, addedPhase] /@ fakedata[[All, 1]]))^2]},
  {a, c, e, addedPhase}, x]

enter image description here

Compute the mean squared error:

mse2 = Mean[(fakedata[[All, 2]] - (model2[a, c, e, addedPhase] /@ fakedata[[All, 1]]))^2] /.
   nlm2constrained["BestFitParameters"]

1.86031

Verify that the constraint is satisfied:

Chop[2 mse1 - mse2]

0

Estimated parameters:

nlm2constrained["ParameterTable"] 

enter image description here

Note the warning issued with the last table:

FittedModel::constr: The property values {ParameterTable} assume an unconstrained model. The results for these properties may not be valid, particularly if the fitted parameters are near a constraint boundary.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.