1
$\begingroup$

Perhaps a rather simple question, but the suggested questions seem to all be covering something slightly different. What I have can be described as follows.

One takes a dataset, call it Data; it has dimensions 10 by 1000 by 2 lets say, which is to say it is 10 arrays of {x,y} data of length 1000.

Now I know the following about it: it behaves according to a model Model[x,a,b,c]. Moreover, all 10 arrays have the same a,bbut not the same cparameter. What I am interested in is how one does a NonLinearModelFit over such a dataset, fitting a,b,c1...c10 in a single go. I should note that I have an initial value array cinit of dimensions 10 as well.

One way I thought of that should in principle work is with KroneckerDelta; I could prepend each dataset with some coordinate that I could use in addition to x and then make a model with the deltafunctions, but this feels very sloppy. There should be an easy way, should there not?

I would post the full model and the data I am working with, but not only is it a big dataset, the parameters and the model are still very much undetermined. I think it would make the question rather offtopic as it is my job to figure out the parameters, not you. So I thought it would make sense to just stick to the concept.

$\endgroup$
2
  • 1
    $\begingroup$ mathematica.stackexchange.com/a/119044/41016 $\endgroup$
    – Young
    Commented Aug 2, 2016 at 21:53
  • $\begingroup$ @Young Indeed, that was the idea I had in mind, which a friend of mine suggested. I can only assume that he had already seen that answer at some point. This seems to work, but it is incredibly slow and somehow I feel there should be a prettier way to do it; it seems rather forced. But it does work, and if there is no alternative I will stick with that $\endgroup$
    – user129412
    Commented Aug 2, 2016 at 22:00

1 Answer 1

2
$\begingroup$

Here is a crude way to do it. First the dataset id is appended to the 1000 x 10 x 2 data array. Then the function you have is modified to create a dummy variable vector and the dot product is used to select the parameter of interest: c1, c2, c3,...., or c10.

(* Number of different values of c *)
nc = 10;
(* Number of observations per dataset *)
n = 1000; 

(* Create some data for a 1000 x 10 x 2 array *)
xx = Table[i/n, {i, n}];
data = Table[
   Transpose[{xx, 
     5 + 2 xx + xx^2 + RandomVariate[NormalDistribution[0, 1], n]}], {i, nc}];

(* Add in dataset number: 1 through nc *)
data2 = Flatten[
   Table[{i, data[[i, j, 1]], data[[i, j, 2]]}, {i, nc}, {j, n}], 1];

model[x_, a_, b_, i_, c_] := Module[{d, j},
   (* Create dummy variables *)
   d = Table[If[j == i, 1, 0], {j, Length[c]}];
   (* Determine function value *)
   a + b x + (c.d) x^2];

nlm = NonlinearModelFit[data2, 
   model[x, a, b, z, nc, {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10}],
   {a, b, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10}, {z, x}];
nlm["BestFitParameters"]
(* {a -> 4.99484, b -> 1.93603, c1 -> 1.18239, c2 -> 1.0829, 
 c3 -> 1.21282, c4 -> 1.06046, c5 -> 1.13936, c6 -> 1.07549, 
 c7 -> 1.01086, c8 -> 0.960816, c9 -> 0.979848, c10 -> 1.03909} *)

But note that I get a warning:

Experimental`NumericalFunction::dimsl: {x} given in {z,x} should be a list of dimensions for a particular argument.

Also, besides assuming common values for a and b , you are also assuming a common error variance. Residuals should be checked to see if there are any departures from that assumption or if a more complex error structure is warranted.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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