给定径向距离绘制球面坐标?

时间:2018-02-26 05:31:59

标签: python matplotlib linear-algebra

对于家庭作业问题,我们被要求

编写一个计算矩阵A的所有特征值的程序,使用瑞利商数迭代找到每个特征值。

我。报告您为每个特征值使用的初始猜测。在n迭代中针对每个特征值(在日志日志中)n+1迭代中的错误绘制错误。

II。计算在单位球体的离散化上采样的x的瑞利商(使用球面坐标)。绘制结果,例如使用网格(Θ,ϕ,r(Θ,ϕ))。解释关键点的数量和位置。

我已经完成了问题的第一部分,但我不确定我是否理解如何完成第二部分。经过一些研究,我发现了各种方法(HereHere)来绘制Python中的球面坐标,这为我提供了一些线索。借用这些链接以及我所拥有的其他一些来源

# The matrix for completness
A = np.matrix([[4,3,4], [3,1,3], [4,3,4]])
A = scipy.linalg.hessenberg(A)

num_points = 50
theta, phi = np.linspace(0, 2 * np.pi, num_points), np.linspace(0, np.pi, num_points)
x = np.sin(phi) * np.cos(theta)
y = np.sin(phi) * np.sin(theta)
z = np.cos(phi)

xyz = np.stack((x, y, z), axis=1)
rqs = np.array([np.dot(x, np.dot(A, np.conj(x).T)).item(0) for _,x in enumerate(xyz)])

在第一个代码块(Θ,ϕ)中创建并转换为笛卡尔坐标,实际上是R^3中单位圆的discritization。这样我就可以创建用于计算每个discritization点的瑞利商(上面x)的xyz向量(rqs),球坐标为r(Θ,ϕ)

虽然,现在我有径向距离,但我不确定如何再次正确地为x, y, z重新创建meshgrid以绘制为曲面。这可能超出了StackOverflow的范围,而且对Math.Stack来说更多,但我也不确定这个情节是否应该最终成为“扭曲的平面”或“扭曲的球体”。

在上面链接的SO answer中,我认为答案就在于此。在代码块中

theta, phi = np.linspace(0, 2 * np.pi, 40), np.linspace(0, np.pi, 40)
THETA, PHI = np.meshgrid(theta, phi)
R = np.cos(PHI**2)
X = R * np.sin(PHI) * np.cos(THETA)
Y = R * np.sin(PHI) * np.sin(THETA)
Z = R * np.cos(PHI)

R这里我假设是指径向距离,但是R在计算x, y, z时位于网格中。我尝试将reshape rqs放在同一维度上,但rqs的值不与后续网格对齐,因此会产生明显错误的图。

我几乎需要一种方法来计算meshgridx的计算。但计算似乎很复杂,直接应用于meshgrid ..

如何根据径向距离生成基于球面坐标的绘图?

编辑:经过一番搜索,我发现this MatLab code产生了所需的情节,尽管我仍然希望在Python中重现这一点。我想说这个MatLab代码概述了如何在Python中实现它,但它似乎是一些非常陈旧和深奥的代码。这是它产生的情节

enter image description here

1 个答案:

答案 0 :(得分:1)

我不知道数学或瑞利商数,但从我收集的数据中,你想要计算rqs作为单位球体点的函数。为此,我建议您使用meshgrid为所有Θϕ生成值对。然后,由于你的矩阵公式是为笛卡尔坐标而不是球面坐标定义的,我会将我的网格转换为它并插入到公式中。

然后,最后,可以使用单位范围内的plot_surface来说明结果,其中(缩放的)RQS数据用于facecolor

import numpy as np
import scipy.linalg
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt

# The matrix for completness
A = np.matrix([[4,3,4], [3,1,3], [4,3,4]])
A = scipy.linalg.hessenberg(A)

num_points = 25
theta = np.linspace(0, 2 * np.pi, num_points)
phi = np.linspace(0, np.pi, num_points)

THETA, PHI = np.meshgrid(theta, phi)

X = np.sin(PHI) * np.cos(THETA)
Y = np.sin(PHI) * np.sin(THETA)
Z = np.cos(PHI)

# Calculate RQS for points on unit sphere:
RQS = np.empty(PHI.shape)
for theta_pos, phi_pos in itertools.product(range(num_points), range(num_points)):
    x = np.array([X[theta_pos, phi_pos],
                  Y[theta_pos, phi_pos],
                  Z[theta_pos, phi_pos]])
    RQS[theta_pos, phi_pos] = np.dot(x, np.dot(A, np.conj(x).T))

# normalize in range 0..1
maxRQS = abs(RQS).max()
N = (RQS+maxRQS)/(2*maxRQS)

fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(
    X, Y, Z, rstride=1, cstride=1,
    facecolors=cm.jet(N),
    linewidth=0, antialiased=False, shade=False)
plt.show()

这给出了以下结果,这似乎与OP中的Matlab轮廓图一致。

enter image description here

请注意,将XYZ网格转换为向量可能有更好的方法(向量化),但主要的执行时间似乎也在于plottting ,所以我不会花时间试图找出确切的方法。