I'm trying to fit a number depending on two inputs via a bilinear fit using python.
I have random sets of data of x and y inputs and the corresponding z output.
I need the output coefficients a, b, c, and d for
z(x,y) = a*x + b*y + c*x*y + d
The input data I have is not a quadratic "grid" It might have more elements in the x direction than in the y space. Furthermore, there might be values missing. So basically, I have a random set of x and y pairs that I need to find bilinear cofficients for to match the given data as good as possible.
I already tried:
- from sklearn import linear_model: I realized too late, that this does not allow a bilinear fit.
- from scipy.interpolate import LinearNDInterpolator: This does work, but somehow does not allow using the full input range of parameters and I found no way of actually getting any coefficients out of it.
I could calculate the bilinear coefficients based on 4 points manually, but this wouldn't give me the best result.
Any ideas how to approach this problem? I'm completely stuck. Searching for "bilinear fit python" did not turn up much useful information.
As requested. A little sample data:
x y z
1056 8 50.89124679
1056 16 61.62827273
1056 32 78.83079982
1056 48 92.90073197
1056 64 105.103744
1056 80 116.0303753
1056 96 126.0130906
1056 112 135.2610439
1056 128 143.9159512
1056 144 152.0790946
2048 8 63.71675604
2048 16 77.15971099
2048 32 98.69757849
2048 48 116.313387
2048 64 131.5917779
2048 80 145.2721136
2048 96 157.7706532
2048 112 169.3492575
2048 128 180.1853546
2048 144 190.4057615
4096 8 86.7357654
4096 16 105.0352703
4096 32 134.3541477
4096 48 158.334033
4096 64 179.1320602
4096 80 197.7547066
4096 96 214.7686034
4096 112 230.5302193
4096 128 245.2810877
4096 144 259.193829
Least squares fit. (Sorry: home-grown, distinctly Fortran-like solution! I expect there's a better library function somewhere in scipy.):
Form S = sum( ( ax+by+cxy+d - z )^2 )
Set dS/da = dS/db = dS/dc = dS/dd = 0 and solve the resulting matrix equation for [a,b,c,d].
You can uncomment the test values to see if it works. It's far from a perfect fit to your data.
Code: