# Calculate ratio/proportion using a table as reference?

I'm a programmer and I have very little math knowledge (it just doesn't go through, but I can program, so go figure :P) so I'm here to ask for some advice. This said, I'm not really good with equations/formulas so if you can please explain to me in a linear way (so I can make my calculation inside a single variable), I'd be really glad!. Now, onto the problem:

I have a table where:

this.lngZoomTable = {
13: 0.015,
14: 0.01,
15: 0.005,
16: 0.002,
17: 0.001,
18: 0.0005,
}


I don't want to keep a hardcoded table in my code. I'm sure there's some way to calculate the proportion so instead of doing a lookup inside the table, I can do, for instance, for 13 I should get 0.015, for 10 I should get something like 0.2 (or whatever, I haven't calculated it yet) but the ultimate goal is to just use a small formula to get the value for any other number other than [13-18].

The optimal value is 0.015 for 13. The values shown here are for reference as I calculated them by trial and error in my app. I'd like to know if there's a way to get it precisely for the other values. They range from 1 to 18, and I have (badly) calculated [14-18].

While having the formula is good, I'd also like an explanation on how to figure that for future reference and learning. I'm sure this could be a piece of cake for the gurus out here :).

Thanks!

What you are looking for, it seems, is generally called regression, function fitting, or just modelling. In general, this requires the user to make some assumptions concerning the function they are trying to construct. Indeed, some extra details would be necessary to help you fully (e.g. must the output be positive).

However, I'll show you something simple you can do. Looking at your values, it is halving at roughly a linear rate. So I'll first transform the data logarithmically: $$y_{\text{new}} = \ln(y)$$ and fit a linear model to it: $$f_t(x) = ax+b$$ so that once $a,b$ are known, the final function you are looking for can be written: $$f(x) = \exp( ax+b )$$ The following code does this:

import os, sys, numpy as np
from sklearn import linear_model
x = np.array([13,14,15,16,17,18]).reshape((6,1))
yRaw = [0.015,0.01,0.005,0.002,0.001,0.0005]
y = np.array([ np.log(v) for v in yRaw ])
w = [100] + ([1]*4) + [10] # Weight the various data points
print("Transformed data\n"+str(x)+"\n"+str(y))
# Fit linear function to transformed data
regr = linear_model.LinearRegression()
regr.fit(x,y,sample_weight=w)
print('Coefficient: \n', regr.coef_)
print('Intercept: \n', regr.intercept_)
# Look at function explicitly
a,b = regr.coef_[0],regr.intercept_
f = lambda x: np.exp( a*x + b )
print('Outputs of function')
for x in range(1,19): print(str(x)+": "+str(f(x)))


Note: the linear model being fit here is using sample weights, which basically say that some data (e.g. for $0.015$) is more important than others. You can play with them as you wish.

This gives me the following output:

Transformed data
[[13]
[14]
[15]
[16]
[17]
[18]]
[-4.19970508 -4.60517019 -5.29831737 -6.2146081  -6.90775528 -7.60090246]
Coefficient:
[-0.67772455]
Intercept:
4.61443743389
Outputs of function
1: 51.2498600531
2: 26.0231972143
3: 13.2138271705
4: 6.70959940293
5: 3.40694059086
6: 1.72994593159
7: 0.878416528378
8: 0.446034516593
9: 0.226483431909
10: 0.115001738702
11: 0.0583945580167
12: 0.0296510682748
13: 0.0150559552071
14: 0.00764497876085
15: 0.00388189918541
16: 0.00197111617404
17: 0.00100087580485
18: 0.00050821579668


Of course, any function could work as a model! E.g. a quadratic function or exponentiated cubic function. See also splines, which are commonly used for such tasks.