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.