注意:我最初使用chi = 1但是我已将其更改为chi = 0(这是更简单的情况)。
我的方程式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)
这将返回f和g的值数组。
我想找到所有(X,Y)有序对,其中f(X,Y)= 0和g(X,Y)= 0.我看着不同的scipy包,我不能&#39 ;找到任何似乎适用于这样的多变量函数的东西。另外,我现在的答案是以数组形式返回的,所以我可以使用像np.where()这样的东西吗?这个问题是因为我存储了确切的值,所以我不一定会看到f(x,y)或g(x,y)明确等于零。我的最终目标是绘制这些点。此外,到目前为止,我所做的事情是否有理由将X和Y作为这些范围内的空间?
谢谢
更新:我回过头使用我在类似问题上找到的指南编写了一个小脚本,请参阅This link。我使用了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))
这要求我进行不同的初步猜测以获得不同的(X,Y)根。如果能以某种方式解决所有解决方案,那将是非常棒的。而且,我得到的答案似乎有点不对劲。 再次感谢。
注意: 在将它们转换为笛卡尔坐标之前,原始方程式如下:
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
也许这有助于解决与方程式的arctan(Y / X)方面的一些混淆。
答案 0 :(得分:1)
正如@Azad已在评论中指出,您可能需要scipy.optimize
才能完成大部分工作。具体而言,scipy.optimize.fsolve
或scipy.optimize.root
。由于后者似乎更为笼统,我将证明这一点。由于它可以使用多种方法,请查看帮助。
这两个函数都能够找到从R ^ n映射到R ^ m的函数的根,即多元向量值函数。如果你考虑你的stress
函数,那就是你拥有的函数:它从R ^ 2映射到R ^ 2。为清楚起见,您甚至可以将其定义为
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
现在,通过此定义,您只需调用
即可import scipy.optimize as opt
sol=opt.root(stress2,[0.5,0.5])
将尝试从[0.5,0.5]
开始寻找零。请注意,向量值函数的根恰好是两个组件都为零的位置,这就是你所追求的。
返回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]])
它有很多信息。首先,sol.status
会告诉您它是否成功融合。这是最重要的输出:你的根和发现非常敏感的可能性取决于你的出发点。如果您在示例中尝试使用X=0
或Y=0
的起点,则会发现找到根目录时遇到困难。
如果您做有根,sol.x
会告诉您坐标,sol.fun
会告诉您函数的值(如果sol.status==1
,则接近0 })。
现在,正如您也注意到的,每个电话会告诉您最多一个根。要找到多个根,您无法避免搜索它们。您可以通过选择X,Y
网格,从那里开始root/fsolve
并检查搜索是否成功来执行此操作。如果是的话:存储后处理的值。
不幸的是,找到非线性多变量函数的零点并不容易,所以你迟早要弄清楚。
你遇到了麻烦。考虑:
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)
和其他功能相同。以下是函数的x
和y
组件的外观:
它们都有一些类似双曲线的曲线。 似乎相同。这个数字强烈表明你的函数为零的点有行:两个组件。这与数值根寻找算法一样糟糕,因为没有明确的(孤立的)零。
我建议在X==Y
的情况下在纸上查看你的功能,你可能确实看到你的功能在那里消失了,至少是渐近的。
您添加了函数的原始极坐标形式。虽然我看不到你出错的地方(除了使用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)
和切向分量相同。请注意,极坐标图需要先theta
,然后R
。结果:
这显示了一幅截然不同的图片,对径向分量的零点有一定的支持。现在,我之前从未在matplotlib中使用极坐标图,因此在绘图过程中我也可能搞砸了。但是可能值得查看由极坐标和笛卡尔函数计算的A,B,C,D
参数,以确保它们计算相同的东西。