2
$\begingroup$

I'm attempting to constrain the values of some of the model fit variables to a list of defined numbers. Here are a sample dataset and model.

data = {{0.375, 0}, {0.376, 0.01}, {0.377, 0.02}, {0.381, 0.05}, 
        {0.386, 0.1}, {0.396, 0.2},{0.425, 0.5}, {0.470, 1}, {0.549, 2}, 
        {0.727, 5}, {0.944, 10}};

nlm = NonlinearModelFit[d2, {(a/b)*x^2 + (a/c)*x^3 + d}, {a, b, c, d}, x]

I want a, b, and c (not d) to be one of the following numbers:

{10.0, 10.2, 10.5, 10.7, 11.0, 11.3, 11.5, 11.8, 12.1, 12.4, 
12.7, 13.0, 13.3, 13.7, 14.0, 14.3, 14.7, 15.0, 15.4, 15.8, 16.2, 
16.5, 16.9, 17.4, 17.8, 18.2, 18.7, 19.1, 19.6, 20.0, 20.5, 21.0, 
21.5, 22.1, 22.6, 23.2, 23.7, 24.3, 24.9, 25.5, 26.1, 26.7, 27.4, 
28.0, 28.7, 29.4, 30.1, 30.9, 31.6, 32.4, 33.2, 34.0, 34.8, 35.7, 
36.5, 37.4, 38.3, 39.2, 40.2, 41.2, 42.2, 43.2, 44.2, 45.3, 46.4, 
47.5, 48.7, 49.9, 51.1, 52.3, 53.6, 54.9, 56.2, 57.6, 59.0, 60.4, 
61.9, 63.4, 64.9, 66.5, 68.1, 69.8, 71.5, 73.2, 75.0, 76.8, 78.7, 
80.6, 82.5, 84.5, 86.6, 88.7, 90.9, 93.1, 95.3, 97.6, 100, 102, 
105, 107, 110, 113, 115, 118, 121, 124, 127, 130, 133, 137, 140, 
143, 147, 150, 154, 158, 162, 165, 169, 174, 178, 182, 187, 191, 
196, 200, 205, 210, 215, 221, 226, 232, 237, 243, 249, 255, 261, 
267, 274, 280, 287, 294, 301, 309, 316, 324, 332, 340, 348, 357, 
365, 374, 383, 392, 402, 412, 422, 432, 442, 453, 464, 475, 487, 
499, 511, 523, 536, 549, 562, 576, 590, 604, 619, 634, 649, 665, 
681, 698, 715, 732, 750, 768, 787, 806, 825, 845, 866, 887, 909, 
931, 953, 976};

Assistance is appreciated.

$\endgroup$
5
  • 1
    $\begingroup$ It seems to me that your model is overparametrized. You could rewrite it as $p\ x^2+q\ x^3+ r$ and impose some constraints on the values of p and q. $\endgroup$ – MarcoB Feb 28 at 1:41
  • $\begingroup$ The purpose of (a/b) and (a/c) is that these are resistor ratios. They are used in a summing op-amp, so a is the same for both scale factors. $\endgroup$ – Young Feb 28 at 1:44
  • $\begingroup$ Just curious: usually there is some random error in the response and the response will rarely be a set of "nice" numbers. So I have to ask: is the order of the data {predictor, response} or {response, predictor}? $\endgroup$ – JimB Feb 28 at 1:54
  • $\begingroup$ {predictor, response} $\endgroup$ – Young Feb 28 at 2:00
  • 2
    $\begingroup$ @MarcoB is correct. You really only have 3 parameters: a/b, a/c, and d. So your model is overparametrized. $\endgroup$ – JimB Feb 28 at 3:31
5
$\begingroup$

Updated to include OP's updated abc list.

I assume that you want the triplet of a, b, and c (all from that list) that has the best fit (in the sense of minimizing the sum of squares).

You won't need NonlinearModelFit to do that (although you certainly could use NonlinearModelFit or LinearModelFit to get the same answer in this case).

Once a, b, and c are set, there is just a single parameter to be estimated: d. The maximum likelihood estimate of d will be

data = {{0.375, 0}, {0.376, 0.01}, {0.377, 0.02}, {0.381, 0.05}, {0.386, 0.1}, 
  {0.396, 0.2}, {0.425, 0.5}, {0.470, 1}, {0.549, 2}, {0.727, 5}, {0.944, 10}};
d = Mean[data[[All, 2]] - ((a/b)*data[[All, 1]]^2 + (a/c)*data[[All, 1]]^3)]
(* 1/11 (18.88 - (2.99769 a)/b - (1.90592 a)/c) *)

and the sum of squares will be

ss = (data[[All, 2]] - (d + (a/b)*data[[All, 1]]^2 + (a/c)*data[[All, 1]]^3))^2 // Total // Expand
(* 97.8981 + (0.556633 a^2)/b^2 - (14.7613 a)/b + (0.587834 a^2)/c^2 - (

15.1159 a)/c + (1.13778 a^2)/(b c) *)

So now just loop through all of the possibilities and choose the set of a, b, and c values that minimize the sum of squares.

abc = {10.0, 10.2, 10.5, 10.7, 11.0, 11.3, 11.5, 11.8, 12.1, 12.4, 
   12.7, 13.0, 13.3, 13.7, 14.0, 14.3, 14.7, 15.0, 15.4, 15.8, 16.2, 
   16.5, 16.9, 17.4, 17.8, 18.2, 18.7, 19.1, 19.6, 20.0, 20.5, 21.0, 
   21.5, 22.1, 22.6, 23.2, 23.7, 24.3, 24.9, 25.5, 26.1, 26.7, 27.4, 
   28.0, 28.7, 29.4, 30.1, 30.9, 31.6, 32.4, 33.2, 34.0, 34.8, 35.7, 
   36.5, 37.4, 38.3, 39.2, 40.2, 41.2, 42.2, 43.2, 44.2, 45.3, 46.4, 
   47.5, 48.7, 49.9, 51.1, 52.3, 53.6, 54.9, 56.2, 57.6, 59.0, 60.4, 
   61.9, 63.4, 64.9, 66.5, 68.1, 69.8, 71.5, 73.2, 75.0, 76.8, 78.7, 
   80.6, 82.5, 84.5, 86.6, 88.7, 90.9, 93.1, 95.3, 97.6, 100, 102, 
   105, 107, 110, 113, 115, 118, 121, 124, 127, 130, 133, 137, 140, 
   143, 147, 150, 154, 158, 162, 165, 169, 174, 178, 182, 187, 191, 
   196, 200, 205, 210, 215, 221, 226, 232, 237, 243, 249, 255, 261, 
   267, 274, 280, 287, 294, 301, 309, 316, 324, 332, 340, 348, 357, 
   365, 374, 383, 392, 402, 412, 422, 432, 442, 453, 464, 475, 487, 
   499, 511, 523, 536, 549, 562, 576, 590, 604, 619, 634, 649, 665, 
   681, 698, 715, 732, 750, 768, 787, 806, 825, 845, 866, 887, 909, 
   931, 953, 976};

results = Sort[Flatten[Table[{a, b, c, d, a/b // N, a/c // N, ss},
  {a, abc}, {b, abc}, {c, abc}], 2], #1[[7]] <= #2[[7]] &];

TableForm[results[[1 ;; 10]], 
 TableHeadings -> {None, {"\na", "\nb", "\nc", "\nd", "\na/b", "\na/c", "Sum of\nsquares"}}]

Table of sums of squares with parameter values

Note that the top sets of parameters have pretty much the same values for a/b and a/c. That is because the model really only has 3 parameters rather than 4. Fitting the basic model with 3 parameters with NonlinearFit:

nlm = NonlinearModelFit[data, ab x^2 + ac x^3 + dd, {ab, ac, dd}, x];
nlm["BestFitParameters"]
(* {ab -> 10.9112, ac -> 2.29764, dd -> -1.65524} *) 

The results match well with the table of parameter values above.

In short, the parameters a/b, a/c, and d can be estimated. However, one cannot estimate a, b, and c.

$\endgroup$
12
  • $\begingroup$ So the abc values can be the list of numbers given or those times 10, and I ran your code with the extended list and the values actually plotted versus the fit isn't as good as I've done by guessing from nonlinearmodel fit values and picking from the abc list. $\endgroup$ – Young Feb 28 at 2:34
  • $\begingroup$ I think ss should be ss = (data[[All, 2]] - (d + (a/b)*data[[All, 1]]^2 + (a/c)* data[[All, 1]]^3))^2 // Total // Expand? $\endgroup$ – Young Feb 28 at 2:57
  • $\begingroup$ You're right. I forgot to add in d. I'll fix that. $\endgroup$ – JimB Feb 28 at 3:23
  • $\begingroup$ The abc values multiplied by anything but zero will give you the same predictions. $\endgroup$ – JimB Feb 28 at 3:27
  • 1
    $\begingroup$ You added new numbers that were multiples of the original numbers. My statement is about multiplying any set of numbers by 10 (or Pi or the square root of 2, etc.) and you will get the same set of sums of squares. There is a difference in those two scenarios. This is because you can only estimate the ratio of a and b, the ratio of a and c, and d. $\endgroup$ – JimB Feb 28 at 20:07

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.