使用 "min" 的函数水平集
Level sets of a function using "min"
更新
为了总结我最初的 post 下面,我很难绘制涉及 'min' 的函数级别集,例如以下函数:
def f(x,y):
return min(x,x-y,x**2,y+1)
我用来绘制水平集的代码是:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x_ = np.linspace(-180,180,num=40)
y_ = np.linspace(-180,180,num=40)
x,y = np.meshgrid(x_,y_)
levels = f(x,y)
c = plt.contour(x,y,levels,50)
plt.colorbar()
plt.show()
这对于涉及常规算术运算(+、-、**、*、/)的函数来说效果很好。使用函数 f
,出现此错误:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
指向 f
的 return 行。
如何绘制函数 f
的水平集?
初始值POST
我正在尝试绘制定义如下的两个函数 f1 和 f2 的水平集:
A = -73.95, 48.73
L=180
######## f1
def distance(a,b):
""" a and b tuples """
return np.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2)
def f1(x,y):
""" simple distance """
p = x,y
#print p
return distance(p,A)
######## f2
def images(p):
""" p tuple """
#print "len(p) in images : "+str(len(p))+"\n"
#print p
pHC = (p[0],p[1]+L)
pHR = (p[0]+L,p[1]+L)
pHL = (p[0]-L,p[1]+L)
pCR = (p[0]+L,p[1])
pCL = (p[0]-L,p[1])
pDC = (p[0],p[1]-L)
pDR = (p[0]+L,p[1]-L)
pDL = (p[0]-L,p[1]-L)
return pHC,pHR,pHL,pCR,pCL,pDC,pDR,pDL
def minD(p,focal):
"""
distance with images (p and focal are tuples)
"""
#print p
pHC,pHR,pHL,pCR,pCL,pDC,pDR,pDL = images(p)
dHC = distance(focal,pHC)
dHR = distance(focal,pHR)
dHL = distance(focal,pHL)
dCR = distance(focal,pCR)
dCL = distance(focal,pCL)
dDC = distance(focal,pDC)
dDR = distance(focal,pDR)
#print "len(dHC) : "+str(len(dHC))
#print "len(dHC[0]) : "+str(len(dHC[0]))
#print dHC
d = min([dHC,dHR,dHL,dCR,dCL,dDC,dDR,dDL,distance(p,focal)])
return d
def f2(phi,psi):
p = phi,psi
return minD(p,A)
这是我绘制水平集的代码:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x_ = np.linspace(-180,180,num=40)
y_ = np.linspace(-180,180,num=40)
x,y = np.meshgrid(x_,y_)
levels1 = f1(x,y)
#levels2 = f2(x,y)
c = plt.contour(x,y,levels,50)
#c = plt.contour(x,y,levels2,50)
plt.colorbar()
plt.show()
我的情节似乎与函数 f1
是正确的(至少没有代码错误)。但是,对于函数 f2
,我在 minD
的最后一行之前有一个错误:
d = min([dHC,dHR,dHL,dCR,dCL,dDC,dDR,dDL,distance(p,focal)])
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
通过一些打印,我发现在 f2
的情况下,我执行 min 的列表元素(在 minD
函数中)是数组,而不是单个元素f1
。
如何绘制函数 f2 的水平集?
最终,我会直截了当,不使用 numpy
的 meshgrid
函数:
x=np.linspace(-180,180,num=40)
y=np.linspace(-180,180,num=40)
levels=np.zeros((len(x),len(y)))
for i in range(len(x)):
for j in range(len(y)):
levels[i,j]=f2(x[i],y[j])
plt.contour(x,y,levels.T)
这在时间上不是最佳的,因为 meshgrid
函数就是这种情况,但我宁愿使用它也不愿了解我在 meshgrid
中的数据发生了什么。不幸的是,我没有时间。
输出:
您想调用 min 的 numpy 版本,而不是 python 的版本,它期望数字作为输入并为您提供其中的最小值——这就是 ValueError 的来源。 numpy 有两个版本; np.min 和 np.minimum。 np.min 会给你一个数组的最小值(所以是一个数字)并且 np.minimum 会做一个点- 数组的最小值(所以是另一个数组)。你想要后者。
不幸的是,我不认为你可以像上面那样简单地做 np.minimum(array1, array2, array3),所以我认为你需要嵌套 np.minimum 调用。尽管 if 会经常这样做,但我认为您可以创建一个函数来嵌套这些调用,以便于您阅读。这就是我得到的,它似乎有效:
def f(x,y):
return np.minimum(np.minimum(np.minimum(x,x-y),x**2),y+1)
plt.figure()
x_ = np.linspace(-180, 180, num=200)
y_ = np.linspace(-180, 180, num=200)
x,y = np.meshgrid(x_, y_)
levels = f(x, y)
c = plt.contour(x, y, levels, 50)
plt.colorbar()
这产生:
(注意,我将 num 从 40 增加到 200 以帮助 matplotlib 处理非平滑部分)
更新
为了总结我最初的 post 下面,我很难绘制涉及 'min' 的函数级别集,例如以下函数:
def f(x,y):
return min(x,x-y,x**2,y+1)
我用来绘制水平集的代码是:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x_ = np.linspace(-180,180,num=40)
y_ = np.linspace(-180,180,num=40)
x,y = np.meshgrid(x_,y_)
levels = f(x,y)
c = plt.contour(x,y,levels,50)
plt.colorbar()
plt.show()
这对于涉及常规算术运算(+、-、**、*、/)的函数来说效果很好。使用函数 f
,出现此错误:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
指向 f
的 return 行。
如何绘制函数 f
的水平集?
初始值POST
我正在尝试绘制定义如下的两个函数 f1 和 f2 的水平集:
A = -73.95, 48.73
L=180
######## f1
def distance(a,b):
""" a and b tuples """
return np.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2)
def f1(x,y):
""" simple distance """
p = x,y
#print p
return distance(p,A)
######## f2
def images(p):
""" p tuple """
#print "len(p) in images : "+str(len(p))+"\n"
#print p
pHC = (p[0],p[1]+L)
pHR = (p[0]+L,p[1]+L)
pHL = (p[0]-L,p[1]+L)
pCR = (p[0]+L,p[1])
pCL = (p[0]-L,p[1])
pDC = (p[0],p[1]-L)
pDR = (p[0]+L,p[1]-L)
pDL = (p[0]-L,p[1]-L)
return pHC,pHR,pHL,pCR,pCL,pDC,pDR,pDL
def minD(p,focal):
"""
distance with images (p and focal are tuples)
"""
#print p
pHC,pHR,pHL,pCR,pCL,pDC,pDR,pDL = images(p)
dHC = distance(focal,pHC)
dHR = distance(focal,pHR)
dHL = distance(focal,pHL)
dCR = distance(focal,pCR)
dCL = distance(focal,pCL)
dDC = distance(focal,pDC)
dDR = distance(focal,pDR)
#print "len(dHC) : "+str(len(dHC))
#print "len(dHC[0]) : "+str(len(dHC[0]))
#print dHC
d = min([dHC,dHR,dHL,dCR,dCL,dDC,dDR,dDL,distance(p,focal)])
return d
def f2(phi,psi):
p = phi,psi
return minD(p,A)
这是我绘制水平集的代码:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
x_ = np.linspace(-180,180,num=40)
y_ = np.linspace(-180,180,num=40)
x,y = np.meshgrid(x_,y_)
levels1 = f1(x,y)
#levels2 = f2(x,y)
c = plt.contour(x,y,levels,50)
#c = plt.contour(x,y,levels2,50)
plt.colorbar()
plt.show()
我的情节似乎与函数 f1
是正确的(至少没有代码错误)。但是,对于函数 f2
,我在 minD
的最后一行之前有一个错误:
d = min([dHC,dHR,dHL,dCR,dCL,dDC,dDR,dDL,distance(p,focal)])
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
通过一些打印,我发现在 f2
的情况下,我执行 min 的列表元素(在 minD
函数中)是数组,而不是单个元素f1
。
如何绘制函数 f2 的水平集?
最终,我会直截了当,不使用 numpy
的 meshgrid
函数:
x=np.linspace(-180,180,num=40)
y=np.linspace(-180,180,num=40)
levels=np.zeros((len(x),len(y)))
for i in range(len(x)):
for j in range(len(y)):
levels[i,j]=f2(x[i],y[j])
plt.contour(x,y,levels.T)
这在时间上不是最佳的,因为 meshgrid
函数就是这种情况,但我宁愿使用它也不愿了解我在 meshgrid
中的数据发生了什么。不幸的是,我没有时间。
输出:
您想调用 min 的 numpy 版本,而不是 python 的版本,它期望数字作为输入并为您提供其中的最小值——这就是 ValueError 的来源。 numpy 有两个版本; np.min 和 np.minimum。 np.min 会给你一个数组的最小值(所以是一个数字)并且 np.minimum 会做一个点- 数组的最小值(所以是另一个数组)。你想要后者。
不幸的是,我不认为你可以像上面那样简单地做 np.minimum(array1, array2, array3),所以我认为你需要嵌套 np.minimum 调用。尽管 if 会经常这样做,但我认为您可以创建一个函数来嵌套这些调用,以便于您阅读。这就是我得到的,它似乎有效:
def f(x,y):
return np.minimum(np.minimum(np.minimum(x,x-y),x**2),y+1)
plt.figure()
x_ = np.linspace(-180, 180, num=200)
y_ = np.linspace(-180, 180, num=200)
x,y = np.meshgrid(x_, y_)
levels = f(x, y)
c = plt.contour(x, y, levels, 50)
plt.colorbar()
这产生:
(注意,我将 num 从 40 增加到 200 以帮助 matplotlib 处理非平滑部分)