简体   繁体   English

试图找到所有有序对(x,y),使得f(x,y)= 0且g(x,y)= 0; 即,我正在尝试找到多变量函数的根

[英]Trying to find all ordered pairs (x,y) such that f(x,y) = 0 and g(x,y) = 0; i.e., I'm trying to find the roots of a multi-variable function

Note: I originally had chi = 1 but I've changed it to chi = 0 (This is the simpler case). 注意:我本来是chi = 1,但已将其更改为chi = 0(这是更简单的情况)。

My equations f(x,y) and g(x,y) come from the following code: 我的方程式f(x,y)和g(x,y)来自以下代码:

import numpy as np
from pylab import *

def stress(X,Y):
    chi = 0
    F = 1
    a = 1
    c = (1.0*a)/(np.sqrt(np.power(X,2)+np.power(Y,2))*1.0)
    A = 0.5*(1 - c**2. + (1 - 4*c**2 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    B = 0.5*(1 - c**2. - (1 - 4*c**2 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    C = 0.5*(1 + c**2. - (1 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    D = 0.5*(1 + c**2. + (1 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    E = 0.5*((1 + 2*c**2. - 3*c**4.)*np.sin(2*np.arctan(Y/X)))

    f = 1.0*F*c**2 + (A-1.0*chi*B) # Radial stress
    g = -1.*F*c**2 + (C - 1.0*chi*D) # Tangential stress
    return f,g

def f(X,Y):
    return stress(X,Y)[0]
def g(X,Y):
    return stress(X,Y)[1]

def find_points(X_max,Y_max,X_steps,Y_steps):
    Xs = np.linspace(-X_max,X_max,X_steps)
    Ys = np.linspace(-Y_max,Y_max,Y_steps)

    radials = f(Xs,Ys)
    tangentials = g(Xs,Ys)

    return radials, tangentials

find_points(10,10,100,100)

This returns arrays of values for f and g. 这将返回f和g的值数组。

I would like to find all of the (X,Y) ordered pairs where both f(X,Y) = 0 and g(X,Y) = 0. I was looking at different scipy packages and I couldn't find anything that seem to work for a multi-variable function like this. 我想找到f(X,Y)= 0和g(X,Y)= 0的所有(X,Y)有序对。我正在寻找不同的scipy包,但找不到任何东西似乎适用于这样的多变量函数。 Also, my answers right now are being returned in arrays, so could I use something like np.where()? 另外,我的答案现在正以数组形式返回,所以我可以使用类似np.where()的东西吗? The problem with this is that because I'm storing exact values, I don't necessarily ever see f(x,y) or g(x,y) explicitly equal zero. 这样做的问题是,因为我要存储精确的值,所以我不一定会看到f(x,y)或g(x,y)显式等于零。 My end goal is to plot these points. 我的最终目标是绘制这些点。 Also, does what I did so far make sense with the Xs and Ys as linspaces over these ranges? 另外,到目前为止,我对Xs和Ys在这些范围内的行距是否有意义?

Thank you 谢谢

Update: I went back and wrote up a little script using a guideline I found on a somewhat similar question see This link . 更新:我回过头来,使用了在一个类似问题上发现的指南编写了一个小脚本,请参阅此链接 I used scipy.optimize. 我使用了scipy.optimize。

from scipy import optimize

def equations(p):
    X, Y = p
    a = 1
    F = 1
    chi = 0
    c = (1.0*a)/(np.sqrt(np.power(X,2)+np.power(Y,2))*1.0)
    A = 0.5*(1 - c**2. + (1 - 4*c**2 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    B = 0.5*(1 - c**2. - (1 - 4*c**2 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    C = 0.5*(1 + c**2. - (1 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    D = 0.5*(1 + c**2. + (1 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))

    f = 1.0*F*c**2 + (A-1.0*chi*B) # Radial stress
    g = -1.*F*c**2 + (C - 1.0*chi*D) # Tangential stress
    return (f,g)

X, Y =  optimize.fsolve(equations, (1, 1))

print equations((X, Y))

This requires me to put in different initial guesses to get different (X,Y) roots. 这要求我输入不同的初始猜测以得出不同的(X,Y)根。 It would be awesome if somehow I could solve all of the solutions. 如果我能以某种方式解决所有解决方案,那将是非常棒的。 Also, the answers I'm getting seem kind of off. 另外,我得到的答案似乎有点过时。 Thanks again. 再次感谢。

Note: The original equations, before I converted them to Cartesian coordinates, were as follows: 注意:在将原始方程式转换为笛卡尔坐标之前,其原始方程式如下:

def stress(R,theta):
    chi = 0
    F = 1
    a = 1
    c = (1.0*a)/(R*1.0)
    A = 0.5*(1 - c**2. + (1 - 4*c**2 + 3*c**4.)*np.cos(2*theta))
    B = 0.5*(1 - c**2. - (1 - 4*c**2 + 3*c**4.)*np.cos(2*theta))
    C = 0.5*(1 + c**2. - (1 + 3*c**4.)*np.cos(2*theta))
    D = 0.5*(1 + c**2. + (1 + 3*c**4.)*np.cos(2*theta))
    E = 0.5*((1 + 2*c**2. - 3*c**4.)*np.sin(2*theta))

    f = 1.0*F*c**2. + (A-1.0*chi*B) # Radial stress
    g = -1.0*F*c**2. + (C-1.0*chi*D) # Tangential stress
    return f,g

Maybe this will help sort out some of the confusion with the arctan(Y/X) aspect of the equation. 也许这将有助于理清与方程的arctan(Y / X)方面的某些混淆。

As @Azad has already noted in a comment, you probably need scipy.optimize to do the bulk of the work for you. 正如@Azad在评论中指出的那样,您可能需要scipy.optimize才能为您完成大部分工作。 Specifically, either scipy.optimize.fsolve or scipy.optimize.root . 具体地说,是scipy.optimize.fsolvescipy.optimize.root As the latter seems more general, I'll demonstrate that. 由于后者似乎更笼统,我将对此进行演示。 Since it can use multiple methods, have a look at the help. 由于可以使用多种方法,请查看帮助。

Both of these functions are capable of finding roots for functions mapping from R^n to R^m, ie multivariate vector-valued functions. 这两个函数都能够找到从R ^ n到R ^ m映射的函数的根,即多元向量值函数。 If you consider your stress function, that's exactly what you have: it maps from R^2 to R^2. 如果您考虑stress函数,那正是您所拥有的:它从R ^ 2映射到R ^ 2。 For clarity, you could even define it as 为了清楚起见,您甚至可以将其定义为

def stress2(Rvec):
    X,Y=Rvec
    chi = 1
    F = 1
    a = 1
    c = (1.0*a)/(np.sqrt(np.power(X,2)+np.power(Y,2))*1.0)
    A = 0.5*(1 - c**2. + (1 - 4*c**2 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    B = 0.5*(1 - c**2. - (1 - 4*c**2 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    C = 0.5*(1 + c**2. - (1 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    D = 0.5*(1 + c**2. + (1 + 3*c**4.)*np.cos(2*np.arctan(Y/X)))
    E = 0.5*((1 + 2*c**2. - 3*c**4.)*np.sin(2*np.arctan(Y/X)))
    f = 1.0*F*c**2 + (A-1.0*chi*B) # Radial stress
    g = -1.*F*c**2 + (C - 1.0*chi*D) # Tangential stress
    return f,g

Now, with this definition you can simply call 现在,有了这个定义,您可以简单地调用

import scipy.optimize as opt
sol=opt.root(stress2,[0.5,0.5])

wich will try to find a zero starting from [0.5,0.5] . wich将尝试从[0.5,0.5]开始寻找零。 Note that the root of the vector-valued function is exactly where both of its components are zero, which is what you're after. 请注意,向量值函数的根恰恰是两个分量均为零的位置,这就是您要追求的。

The return OptimizeResult looks like this: 返回的OptimizeResult看起来像这样:

In [224]: sol
Out[224]: 
  status: 1
 success: True
     qtf: array([  2.94481987e-09,   4.76366933e-25])
    nfev: 47
       r: array([ -7.62669534e-06,   7.62669532e-06,   2.16965211e-21])
     fun: array([  2.25125258e-10,  -2.25125258e-10])
       x: array([ 167337.87789902,  167337.87786433])
 message: 'The solution converged.'
    fjac: array([[-0.70710678,  0.70710678],
       [ 0.70710678,  0.70710678]])

It has a bunch of information. 它有很多信息。 First of all, sol.status will tell you if it converged successfully. 首先, sol.status会告诉您是否成功收敛。 This is the most important output: your root and the possibility of finding it very sensitively depends on your starting point. 这是最重要的输出:您的根以及非常敏感地找到它的可能性取决于您的起点。 If you try a starting point where X=0 or Y=0 in your example, you'll see that it has difficulties finding a root. 如果在示例中尝试从X=0Y=0的起点开始,则会发现很难找到根。

If you do have a root, sol.x will tell you the coordinates, and sol.fun will tell you the value of your function (near 0 if sol.status==1 ). 如果有一个根, sol.x会告诉你的坐标, sol.fun会告诉你,你的函数的值(接近0,如果sol.status==1 )。

Now, as you also noticed, each call will tell you at most a single root. 现在,正如您还注意到的,每个调用最多将告诉您一个根。 To find multiple roots, you can't avoid searching for them. 要找到多个根,就不可避免地要搜索它们。 You can do this by going over an X,Y grid of your choice, starting root/fsolve from there, and checking whether the search succeeded. 您可以通过选择一个X,Y网格,从此处开始root/fsolve并检查搜索是否成功来完成此操作。 If it did: store the values for post-processing. 如果是这样:存储值以进行后处理。

Unfortunately, finding the zeros of a nonlinear multivariate function is far from easy, so you have to get your hands dirty sooner or later. 不幸的是,要找到非线性多元函数的零点远非易事,因此您迟早都要动手。

Update 更新

You're in for some trouble. 您遇到了一些麻烦。 Consider: 考虑:

v=np.linspace(-10,10,100)
X,Y=np.meshgrid(v,v)

fig = plt.figure()
hc=plt.contourf(X,Y,stress2([X,Y])[0].clip(-1,1),levels=np.linspace(-1,1,20))
plt.contour(X,Y,stress2([X,Y])[0].clip(-1,1),levels=[0],color=(1,0,0))
plt.colorbar(hc)

and the same for the other function. 与其他功能相同。 Here's how the x and y components of your function look like, respectively: 这是函数的xy分量分别如下所示:

x分量 y分量

They both have zeros along some hyperbolic-like curves. 它们都沿某些双曲线样曲线具有零。 Which seem to be identical . 这似乎是相同的 This figure strongly suggests that there is a line of points where your function is zero: both components. 此图强烈暗示您的函数为零的点是一行 :两个组件。 This is as bad as it can get for numerical root-finding algorithms, as there are no clear-cut (isolated) zeroes. 由于没有明确的(隔离的)零,这与数值根查找算法所能达到的效果一样糟糕。

I suggest checking your function on paper for the case of X==Y , you might indeed see that your function disappears there, at least asymptotically. 我建议您在纸上检查函数是否为X==Y ,您可能确实会看到函数消失了,至少是渐近地消失了。

Update2 UPDATE2

You added the original, polar form of your function. 您添加了函数的原始极性形式。 While I can't see where you went wrong (apart from using np.arctan instead of np.arctan2 , but that doesn't seem to fix the problem), I tried plotting your polar function: 虽然我看不到您出了什么问题(除了使用np.arctan而不是np.arctan2 ,但这似乎无法解决问题),但我尝试绘制极坐标函数:

def stress_polar(Rvec):
    R,theta=Rvec
    chi = 0
    F = 1
    a = 1
    c = (1.0*a)/(R*1.0)                                   
    A = 0.5*(1 - c**2. + (1 - 4*c**2 + 3*c**4.)*np.cos(2*theta))
    B = 0.5*(1 - c**2. - (1 - 4*c**2 + 3*c**4.)*np.cos(2*theta))
    C = 0.5*(1 + c**2. - (1 + 3*c**4.)*np.cos(2*theta))
    D = 0.5*(1 + c**2. + (1 + 3*c**4.)*np.cos(2*theta))
    E = 0.5*((1 + 2*c**2. - 3*c**4.)*np.sin(2*theta))
    f = 1.0*F*c**2. + (A-1.0*chi*B)
    g = -1.0*F*c**2. + (C-1.0*chi*D)
    return f,g

v1=np.linspace(0.01,10,100)
v2=np.linspace(-np.pi,np.pi,100)
R,theta=np.meshgrid(v1,v2)

fig = plt.figure()
ax=plt.subplot(111, polar=True)
hc=plt.contourf(theta,R,stress_polar([R,theta])[0].clip(-1,1),levels=np.linspace(-1,1,20))
plt.contour(theta,R,stress_polar([R,theta])[0].clip(-1,1),levels=[0],color=(1,0,0))
plt.colorbar(hc)

and the same for the tangential component. 与切向分量相同。 Note that the polar plot needs to get theta first, then R . 请注意,极坐标图需要首先获得theta ,然后是R The result: 结果:

径向分量 切向分量

this shows a quite different picture, with a finite support for the zeros of the radial component. 这显示了截然不同的画面,对径向分量的零点有有限的支持。 Now, I've never used polar plots before in matplotlib, so it's equally possible that I messed something up during plotting. 现在,我以前从未在matplotlib中使用极坐标图,因此同样有可能在绘制过程中弄乱了某些东西。 But it might be worth looking at the A,B,C,D parameters that are computed by your polar and Cartesian functions, to make sure they compute the same thing. 但是可能需要查看由极函数和笛卡尔函数计算的A,B,C,D参数,以确保它们计算的是相同的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我正在尝试使用 math.pow 找到 2 个数字的幂和它的模 ((x**y)%z) 并给出错误 - I'm Trying to find power of 2 numbers and modulo of it ((x**y)%z) with math.pow and its giving an Error 如何找到映射 f: X -> Y 来表征 2 个时间序列 X 和 Y 之间的关系? - How do I find a mapping f : X -> Y to characterize the relationship between 2 time-series X and Y? 我在(y)函数中使用for(x)遇到麻烦 - I'm having trouble with the for(x) in (y) function 如何求解函数y = f(x,y),即函数值取决于自身 - How to solve a function y=f(x,y), i.e, the functional value depends on itself FInd(X,Y)对和关联的Z坐标 - FInd (X, Y) pairs and associated Z coordinates 如何在x和y中找到f(x,y)的偏导数:python中的del ^ 2 f(x,y)/ [del(x)] [del(y)] - How to find Partial derivative of f(x,y) along x and y: del^2 f(x,y)/[del(x)][del (y)] in python 在拱上找到 x 和 y - Find x and y on arch 使用变量 X 找到 Y 的最大值 - Use variable X to find maximum value of Y 灰度图像转换为 function g(x,y) = f(a*x,b*y) - Greyscale image transformation as a function g(x,y) = f(a*x,b*y) 我有两个方程 f(x,y,k)=0 和 g(x,y,k)=0。 我想在 Python 中绘制 x,y 平面中的相交曲线 - I have two equations f(x,y,k)=0 and g(x,y,k)=0. I would like to plot the intersection curve in the x,y plane in Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM