Considering Subpixel


Using follow expression indicates cone, I want to do accuracy improvement of block matching. 

```math

z	=	a\sqrt{b\left(x-c\right)^{2}+d\left(y-e\right)^{2}}+f

```

Tentatively, omit $b$ and $d$, that is not eliptic cone. For example, test function is set to $a\exp\left(-\frac{(x-10) ^2 + (y-30) ^ 2}{8000}\right)$, so I want to get $c=10$ and $e=30$.



```python
from lmfit import minimize, Parameters, Parameter, report_fit
import numpy as np
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import pylab


x = 100*random.rand(100) - 50;x=x.flatten() 
y = 100*random.rand(100) - 50;y=y.flatten()
data = exp(-((x-10) ** 2 + (y-30) ** 2)/8000) 


x = x[argsort(data)][-50:]
y = y[argsort(data)][-50:]
data = data[argsort(data)][-50:]


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, data, c="r", marker="o")

def fcn2min(params, x, y, data):
    a = params['a'].value  
    b = params['b'].value    
    c = params['c'].value
    d = params['d'].value
    e = params['e'].value
    f = params['f'].value
    model = a*sqrt((x-c) ** 2 + (y-e) ** 2) + f
    return model - data

params = Parameters()
params.add('a',   value= 0)
params.add('b', value= 0)
params.add('c',   value= 0)
params.add('d', value= 0)
params.add('e',   value= 0)
params.add('f',   value= 0)
params.add('theta', value= 0)


result = minimize(fcn2min, params, args=(x, y, data))

report_fit(result.params)
a = result.values["a"]
b = result.values["b"]
c = result.values["c"]
d = result.values["d"]
e = result.values["e"]
f = result.values["f"]
theta = result.values["theta"]


x = linspace(-100,100,100)[:,None] * ones(100);x=x.flatten()
y = linspace(-100,100,100) * ones(100)[:,None];y=y.flatten()
z = a*sqrt((x-c) ** 2 + (y-e) ** 2) + f

ax.plot(x.flatten(),y.flatten(),z.flatten(), c="b")
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

plt.show()

```

```result1

[[Variables]]
    a:      -0.00585698 +/- 0        (-0.00%) (init= 0)
    b:       0          +/- 0        (nan%) (init= 0)
    c:       10.4107053 +/- 0        (0.00%) (init= 0)
    d:       0          +/- 0        (nan%) (init= 0)
    e:       29.9422853 +/- 0        (0.00%) (init= 0)
    f:       1.05816223 +/- 0        (0.00%) (init= 0)
    theta:   0          +/- 0        (nan%) (init= 0)
[[Correlations]] (unreported correlations are <  0.100)
```

![sub_pixel.png](https://qiita-image-store.s3.amazonaws.com/0/85968/cae73e71-1885-b328-c6a9-ef96322bb327.png "sub_pixel.png")

Almost $c=10$ and $e=30$.

Next, add $b$ and change the test function as $z	=	-10\sqrt{10\left(x-20\right)^{2}+\left(y-10\right)^{2}}+30$


```python
from lmfit import minimize, Parameters, Parameter, report_fit
import numpy as np
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import pylab


x = 100*random.rand(100) - 50;x=x.flatten() 
y = 100*random.rand(100) - 50;y=y.flatten()
data = -10*sqrt(10*(x-20) ** 2 + (y-10) ** 2) + 30



fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, data, c="r", marker="o")

def fcn2min(params, x, y, data):
    a = params['a'].value  
    b = params['b'].value    
    c = params['c'].value
    d = params['d'].value
    e = params['e'].value
    f = params['f'].value
    model = a*sqrt(b*(x-c) ** 2 + (y-e) ** 2) + f
    return model - data

params = Parameters()
params.add('a',   value= 0)
params.add('b', value= 0)
params.add('c',   value= 0)
params.add('d', value= 0)
params.add('e',   value= 0)
params.add('f',   value= 0)
params.add('theta', value= 0)


result = minimize(fcn2min, params, args=(x, y, data))

report_fit(result.params)
a = result.values["a"]
b = result.values["b"]
c = result.values["c"]
d = result.values["d"]
e = result.values["e"]
f = result.values["f"]
theta = result.values["theta"]


x = linspace(-100,100,100)[:,None] * ones(100);x=x.flatten()
y = linspace(-100,100,100) * ones(100)[:,None];y=y.flatten()
z = a*sqrt(b*(x-c) ** 2 + (y-e) ** 2) + f

ax.plot(x.flatten(),y.flatten(),z.flatten(), c="b")
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

plt.show()
```

```result2
[[Variables]]
    a:      -10         +/- 0        (-0.00%) (init= 0)
    b:       10         +/- 0        (0.00%) (init= 0)
    c:       20         +/- 0        (0.00%) (init= 0)
    d:       0          +/- 0        (nan%) (init= 0)
    e:       10         +/- 0        (0.00%) (init= 0)
    f:       30         +/- 0        (0.00%) (init= 0)
    theta:   0          +/- 0        (nan%) (init= 0)
[[Correlations]] (unreported correlations are <  0.100)
```


It seemed to be sucseed(sorry for obscurely).

![sub_pixel_2.png](https://qiita-image-store.s3.amazonaws.com/0/85968/926d9763-10b9-e128-68a2-93e96efa70c3.png "sub_pixel_2.png")

Next, add $d$.

```
from lmfit import minimize, Parameters, Parameter, report_fit
import numpy as np
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import pylab


x = 100*random.rand(100) - 50;x=x.flatten() 
y = 100*random.rand(100) - 50;y=y.flatten()
data = -10*sqrt(10*(x-20) ** 2 + 20*(y-10) ** 2) + 30



fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, data, c="r", marker="o")

def fcn2min(params, x, y, data):
    a = params['a'].value  
    b = params['b'].value    
    c = params['c'].value
    d = params['d'].value
    e = params['e'].value
    f = params['f'].value
    model = a*sqrt(b * (x-c) ** 2 + c * (y-e) ** 2) + f
    return model - data

params = Parameters()
params.add('a',   value= 0)
params.add('b', value= 0)
params.add('c',   value= 0)
params.add('d', value= 0)
params.add('e',   value= 0)
params.add('f',   value= 0)
params.add('theta', value= 0)


result = minimize(fcn2min, params, args=(x, y, data))

report_fit(result.params)
a = result.values["a"]
b = result.values["b"]
c = result.values["c"]
d = result.values["d"]
e = result.values["e"]
f = result.values["f"]
theta = result.values["theta"]


x = linspace(-100,100,100)[:,None] * ones(100);x=x.flatten()
y = linspace(-100,100,100) * ones(100)[:,None];y=y.flatten()
z = a*sqrt(b*(x-c) ** 2 + c * (y-e) ** 2) + f

ax.plot(x.flatten(),y.flatten(),z.flatten(), c="b")
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

plt.show()
```

```result3
[[Variables]]
    a:       0          +/- 0        (nan%) (init= 0)
    b:       0          +/- 0        (nan%) (init= 0)
    c:       0          +/- 0        (nan%) (init= 0)
    d:       0          +/- 0        (nan%) (init= 0)
    e:       0          +/- 0        (nan%) (init= 0)
    f:      -1493.84374 +/- 0        (-0.00%) (init= 0)
    theta:   1.4901e-08 +/- 0        (0.00%) (init= 0)
[[Correlations]] (unreported correlations are <  0.100)
```

![sub_pixel_3.png](https://qiita-image-store.s3.amazonaws.com/0/85968/98b3d351-b0e3-c96c-9536-df232b699cd8.png "sub_pixel_3.png")

It is faild to fit.