简体   繁体   中英

Invert a 2D --> 2D non-linear function

I'm sorry if this is an unusual way to write a question here, since the scope of it seems quite large (to me). I'd be happy to be directed to pre-defined packages that already do what I'm needing, indeed I hope there is (should be?) a standardised solution to my question. I was wondering if there is any help out there? I'm still learning Python through a project I'm doing, and I feel I'm slightly weak on certain points...

Ok so here goes: I would like to invert a 2D --> 2D function in python, but none of my efforts have succeeded yet.

Let's say I have two relationships in a (non-linear) systems of equations, so

a = f(x,y)

b = g(x,y)

where both f and g are continuous and invertible, and x and y have a certain pre-defined rectangular domain. a and b also have their own rectangular domain, but it is different from that of x and y.

Some extra info on f and g: One of the functions will be linear, let's call this f. So, a = f(x,y) = q x + p y + r (where q, p and r are known constants). In Python terms, I guess you would write a[ i, j ] = q x[ i ] + p y[ j ]. The other function, g, has no analytic expression but looks similar to k sin(x) + l sin(y), for x and y between 0 and pi/2.

Moreover, the overall "mother-function" that I wish to make a 3D surface plot of, takes a and b as arguments. Calling the mother function M, we then have that M = M(a,b) = M(f(x,y),g(x,y)). So far so good.

The essence of the problem is that I need to first choose a pair (a,b) on the "mother-grid", then find the corresponding pair (x,y) that gives rise to this particular (a,b). f and g do not have any analytically "simple" inverses however, and I need to find these numerically.

So the basic question is, "given a[ i ] and b[ j ] as two sorted lists, and given x[ ii ] and y [ jj ] that are used to obtain each a and b, how do I find the two inverse functions x = inv1 (a,b) and y = inv2 (a,b)?"

PS. I have tried the "cheap way" of circumventing this problem by first choosing a (x,y) pair, calculating a tentative (A,B) pair and then interpolate this into the pre-defined (a,b) mesh as best as I could. However, since the (x,y) mesh and the (a,b) meshes are (quite) different, the corresponding "fitting error" always make the end result come out jagged and messy (I have a control scenario where I know what the end result should look like, before doing my own cases). This is because I am essentially forcing the values of A and B onto the height of the M function at position (a,b) if that makes sense. I've tried averaging and smoothing "cheats" to this, but it is still not passable imo. Hence, I really need to choose an (a,b) pair FIRST, and then only finding the relevant (x,y) pair after that.

Note: Some parameters in the M-function depends directly on x and y, hence the need for knowing the exact values of x and y.

Thanks for the additional information. I think you can solve this directly and then analytically.

Starting with your final result (a, b) :

First solve against a to find your xy line, eg:

a = qx + py + r
y = (qx + r - a) / -p

Since you said it is monotonically increasing, I just solve for y for simplicity.

Next, plug this into your non-analytic g using a simple binary search across x :

def invert(a, b):
    def get_y(x):
        return (Q * x + R - a) / -P
    
    def g_constrained(x):
        return g(x, func(x))

    x = binary_search(g_constrained, b, min_x, max_x, guess_x)
    y = get_y(x)
    return x, y

Note that your function is not guaranteed to have a single solution in general, consider a planar solution for g that looks like an arc, since f is a line, you can have two intersections. You will need to decide what you want to do with this information.


Previous concerns

I am suspicious of your claim that a = f(x,y) is continuous and invertible.

Put succinctly: if your function z = f(x, y) doesn't intersect the plane z = K in exactly one point for every K , it is not invertible .

For a detailed example:

Consider some point, and 4 points around it - here I use (0,0) and unit length, for convenience.

z = f(0,0)

a = f(-1,0)
b = f(1,0)

p = f(0,-1)
q = f(0,1)

If f provides a scalar value (or anything where x < y and y < z implies x < z ), then we have a problem.

Since f is continuous and invertible, either a < z < b or b < z < a , and likewise for p and q . So f-inv(z+) will map to two different values, one on the line (-1, 0) -> (1, 0) and one on the line (0, -1) -> (0, 1) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM