从 Matlab 到 Python 的算法等价性
Algorithm equalivence from Matlab to Python
我在 Matlab
中绘制了一个 3-d 网格,下面是 m-file
:
[x,n] = meshgrid(0:0.1:20, 1:1:100);
mu = 0;
sigma = sqrt(2)./n;
f = normcdf(x,mu,sigma);
mesh(x,n,f);
我将通过以下代码片段利用 Python
及其相应模块获得相同的结果:
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
sigma = 1
def integrand(x, n):
return (n/(2*sigma*np.sqrt(np.pi)))*np.exp(-(n**2*x**2)/(4*sigma**2))
tt = np.linspace(0, 20, 2000)
nn = np.linspace(1, 100, 100)
T = np.zeros([len(tt), len(nn)])
for i,t in enumerate(tt):
for j,n in enumerate(nn):
T[i, j], _ = quad(integrand, -np.inf, t, args=(n,))
x, y = np.mgrid[0:20:0.01, 1:101:1]
plt.pcolormesh(x, y, T)
plt.show()
但是 Python
的输出与 Matlab
的输出有很大不同,事实上是不可接受的。
我怕函数用错了 linespace
, enumerate
or mgrid
...
有人知道吗?!...
PS。不幸的是,我无法在此线程中插入输出图...!
最佳
.............................
编辑:我更改了 linespace
和 mgrid
间隔并替换了 plot_surface
方法...输出现在是 3d,具有合适的精度和平滑度...
您的 Matlab 代码通过 x:
生成 201 个点
[x,n] = meshgrid(0:0.1:20, 1:1:100);
虽然您的 Python 代码仅生成 20 分:
tt = np.linspace(0, 19, 20)
可能导致准确性问题?
试试这个代码:
tt = np.linspace(0, 20, 201)
解决问题的重要要点是:
1- 关于 linespace
和 mgrid
函数的提供维度等价的必要性...
2-利用密度更大的网格使蜜蜂线变得平滑度高...
3- 应用 3d 绘图仪功能,如 plot_surf
...
当前代码完全有效...
据我所知,等效的解决方案是:
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
x, n = np.mgrid[0:20:0.01, 1:100:1]
mu = 0
sigma = np.sqrt(2)/n
f = norm.cdf(x, mu, sigma)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(x, n, f, rstride=x.shape[0]//20, cstride=x.shape[1]//20, alpha=0.3)
plt.show()
不幸的是,使用 matplotlib 进行 3D 绘图并不像使用 matlab 那样直接。
这是这段代码的情节:
我在 Matlab
中绘制了一个 3-d 网格,下面是 m-file
:
[x,n] = meshgrid(0:0.1:20, 1:1:100);
mu = 0;
sigma = sqrt(2)./n;
f = normcdf(x,mu,sigma);
mesh(x,n,f);
我将通过以下代码片段利用 Python
及其相应模块获得相同的结果:
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
sigma = 1
def integrand(x, n):
return (n/(2*sigma*np.sqrt(np.pi)))*np.exp(-(n**2*x**2)/(4*sigma**2))
tt = np.linspace(0, 20, 2000)
nn = np.linspace(1, 100, 100)
T = np.zeros([len(tt), len(nn)])
for i,t in enumerate(tt):
for j,n in enumerate(nn):
T[i, j], _ = quad(integrand, -np.inf, t, args=(n,))
x, y = np.mgrid[0:20:0.01, 1:101:1]
plt.pcolormesh(x, y, T)
plt.show()
但是 Python
的输出与 Matlab
的输出有很大不同,事实上是不可接受的。
我怕函数用错了 linespace
, enumerate
or mgrid
...
有人知道吗?!...
PS。不幸的是,我无法在此线程中插入输出图...!
最佳
.............................
编辑:我更改了 linespace
和 mgrid
间隔并替换了 plot_surface
方法...输出现在是 3d,具有合适的精度和平滑度...
您的 Matlab 代码通过 x:
生成 201 个点[x,n] = meshgrid(0:0.1:20, 1:1:100);
虽然您的 Python 代码仅生成 20 分:
tt = np.linspace(0, 19, 20)
可能导致准确性问题? 试试这个代码:
tt = np.linspace(0, 20, 201)
解决问题的重要要点是:
1- 关于 linespace
和 mgrid
函数的提供维度等价的必要性...
2-利用密度更大的网格使蜜蜂线变得平滑度高...
3- 应用 3d 绘图仪功能,如 plot_surf
...
当前代码完全有效...
据我所知,等效的解决方案是:
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
x, n = np.mgrid[0:20:0.01, 1:100:1]
mu = 0
sigma = np.sqrt(2)/n
f = norm.cdf(x, mu, sigma)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(x, n, f, rstride=x.shape[0]//20, cstride=x.shape[1]//20, alpha=0.3)
plt.show()
不幸的是,使用 matplotlib 进行 3D 绘图并不像使用 matlab 那样直接。
这是这段代码的情节: