# Fitting parameters of a function

Imagine a graph where the x-axis is time in minutes (continuous) from 0 to 360. And the y-axis represents 'z' values. Of this continuous time course graph, I have 8 time points w/ their corresponding real z-values. Here is the data frame 'real_df' with that real data.

real_df:

timepoints     real_z
0  1.0000000
20  0.7202642
40  0.8000305
60  1.7430986
120 16.5172242
180 25.6521268
240 33.9140056
360 34.5735984


Now, I have 'z' values that I'm making artificially for the same time points of the real 'z' values. I use 'a' and 'b' values as shown below, to find the modeled z-values. And this 'mod_df' contains hundreds of combinations of 'a' and 'b' values, but here is an example of 2 combos of 'a' and 'b':

mod_df

  a   b   t     model_z
30 120   0    0.000000
30 120  20    0.000000
30 120  40    2.881133
30 120  60    8.643400
30 120 120   25.930199
30 120 180   34.573598
30 120 240   34.573598
30 120 360   34.573598
30 121   0    0.000000
30 121  20    0.000000
30 121  40    2.857322
30 121  60    8.571967
30 121 120   25.715900
30 121 180   34.573598
30 121 240   34.573598
30 121 360   34.573598


What I want to do is find a single 'a' and 'b' combination which results in the best fit of all 8 modeled z-values to the 8 real z-values (i.e., fit the modeled z-values to real z-values at corresponding time points).

I've been thinking a least squares fit would be just fine, but I'm curious if there is a better way to fit.

So far, I've been making 'mod_df' by running all combos of 'a' and 'b' that I put into an equation I've created. But I hear that there may be a way to get a better estimate for my variables 'a' and 'b'. Because now, obviously, they're limited to the values of 'a' and 'b' I put into the equation.

Maybe what I'm saying isn't true could someone shed some light on this?

Least squares should work fine for me now, but could I get some help w/ writing a least squares fit based on the 8 modeled z-values vs. 8 real z-values?

Here is some code that I have, but it actually squares the difference of the sum of all 8 values. Which will not give me anything very precise.

mod_df[seq(from=1, to=nrow(mod_df), by=8),1:2][which.min(colSums((matrix(mod_df$model_z, nrow=8) - real_df$real_z)**2)),]


There's probably a better way of doing this, could I get some help?

-
what are a and b and where do they come from? –  Peter Ellis Sep 9 '12 at 6:01
Let the $8$ values be $z_1,\ldots,z_8$. The lower table appears to sample some function $f(a,b)$. You seem to be asking how to estimate $a_i$ and $b_i$ so that $z_i=f(a_i,b_i)$ for $i=1,\ldots,8$. If so, this is an overparameterized problem: you have twice as many parameters to fit as data points ($8$ $a$'s and $8$ $b$'s). To obtain a unique answer, you need to add constraints (at least eight dimensions of constraints, in fact). –  whuber Sep 9 '12 at 14:56
@PeterEllis, I dont' think it matters to know what a and b are, aside from the fact that i used them to obtain the modeled z value. All I want to do is run a function that will find a sum of the differences of each of the 8 values, for all combos of a and b. and then select the minimized sum of all those values. –  Doug Sep 9 '12 at 17:24
@whuber, I'm not sure I follow your comment, but I think what your describing is the best fit z value that doesn't need 8 parameters? But I want to fit to these 8 time points, remember I have 8 data values. –  Doug Sep 10 '12 at 3:25

What values can a and b take? Are they constrained such as: a must be positive, or b must be less than a?

You can treat this as an optimization problem and use R's optim function (or another optimization function, depending on your constraints) to find (local) minimal sum of squared deviations. Since this solution is prone to local minima, as a minimum you'll want to start from a bunch of different random a's and b's.

(You're currently doing something akin to a grid search, and so alternatives would include gradient descent, etc.)

-
# find minimized least squares
mod_df[seq(from=1, to=nrow(mod_df), by=8),1:2][which.min(colSums((real_df$real_z - matrix(mod_df$model_z, nrow=8))**2)),]