function solve2d(f, MAX_ITERATIONS, eps) {
if (MAX_ITERATIONS === undefined) MAX_ITERATIONS = 40;
if (eps === undefined) eps = epsilon2;
return function(x, y, a, b) {
var err2, da, db;
a = a === undefined ? 0 : +a;
b = b === undefined ? 0 : +b;
for (var i = 0; i < MAX_ITERATIONS; i++) {
var p = f(a, b),
tx = p[0] - x,
ty = p[1] - y;
if (abs(tx) < eps && abs(ty) < eps) break;
var h = tx * tx + ty * ty;
if (h > err2) {
a -= da /= 2;
b -= db /= 2;
continue;
}
err2 = h;
var ea = (a > 0 ? -1 : 1) * eps,
eb = (b > 0 ? -1 : 1) * eps,
pa = f(a + ea, b),
pb = f(a, b + eb),
dxa = (pa[0] - p[0]) / ea,
dya = (pa[1] - p[1]) / ea,
dxb = (pb[0] - p[0]) / eb,
dyb = (pb[1] - p[1]) / eb,
D = dyb * dxa - dya * dxb,
l = (abs(D) < 0.5 ? 0.5 : 1) / D;
da = (ty * dxb - tx * dyb) * l;
db = (tx * dya - ty * dxa) * l;
a += da;
b += db;
if (abs(da) < eps && abs(db) < eps) break;
}
return [a, b];
};
}