In [36]:
import numpy as np
from math import sin, cos, pi, sqrt, factorial, fabs
In [37]:
Lmax = 10
In [38]:
rand = np.random.normal(size = (Lmax+1, 2*Lmax+1))
In [39]:
# initial algorithm
teta = pi
phi = 0.3
P = np.zeros((Lmax+1, Lmax+1))
P_ = np.zeros((Lmax+1, Lmax+1))
# Diagonal
P_[0][0] = 1/sqrt(4*pi)
for m in xrange(1, Lmax+1):
P_[m][m] = P_[m-1][m-1]*(- sin(teta))*sqrt(2*m+3)/sqrt(2*m+2)
# Back to P
for m in xrange(0, Lmax+1):
P[m][m] = P_[m][m]*sqrt(4*pi*factorial(2*m))/sqrt(2*m+1)
# Above the diagonal for P_
for m in xrange(0, Lmax):
P_[m][m+1] = P[m][m]*cos(teta)*(2*m+1)*sqrt(2*m+3)/sqrt(4*pi*factorial(2*m+1))
# Back to P again
for m in xrange(0, Lmax):
P[m][m+1] = P_[m][m+1]*sqrt(4*pi*factorial(2*m+1))/sqrt(2*m+3)
# Recursive
for m in xrange(0, Lmax-1):
for l in xrange(m+2, Lmax+1):
P[m][l] = (cos(teta)*(2*l-1)*P[m][l-1] - (l+m-1)*P[m][l-2])/(l-m)
# Generating for function
f = 0.0
for l in xrange(0, Lmax+1):
for m in xrange(-l, 0):
f = f + sin(m*phi)*rand[l][m]*P[fabs(m)][l]
for l in xrange(0, Lmax+1):
for m in xrange(0, l+1):
f = f + cos(m*phi)*rand[l][m]*P[fabs(m)][l]
In [40]:
f
Out[40]:
In [41]:
N = 200
In [42]:
field = np.zeros((N, N/2+1))
x = np.zeros((N, N/2+1))
y = np.zeros((N, N/2+1))
In [43]:
mu, sigma = 1.0, 1.0
rand = np.random.normal(mu, sigma, size = (Lmax+1, 2*Lmax+1))
In [44]:
for i in xrange(0, N):
for j in xrange(-N/4, N/4+1):
phi = i*2/float(N)*pi
teta = pi/2*j*4/float(N)
P = np.zeros((Lmax+1, Lmax+1))
P_ = np.zeros((Lmax+1, Lmax+1))
P_[0][0] = 1/sqrt(4*pi)
for m in xrange(1, Lmax+1):
P_[m][m] = P_[m-1][m-1]*(-sin(teta))*sqrt(2*m+3)/sqrt(2*m+2)
for m in xrange(0, Lmax+1):
P[m][m] = P_[m][m]*sqrt(4*pi*factorial(2*m))/sqrt(2*m+1)
for m in xrange(0, Lmax):
P_[m][m+1] = P[m][m]*cos(teta)*(2*m+1)*sqrt(2*m+3)/sqrt(4*pi*factorial(2*m+1))
for m in xrange(0, Lmax):
P[m][m+1] = P_[m][m+1]*sqrt(4*pi*factorial(2*m+1))/sqrt(2*m+3)
for m in xrange(0, Lmax-1):
for l in xrange(m+2, Lmax+1):
P[m][l] = (cos(teta)*(2*l-1)*P[m][l-1] - (l+m-1)*P[m][l-2])/float(l-m)
f = 0.0
for l in xrange(0, Lmax+1):
for m in xrange(-l, 0):
f = f + sin(m*phi)*rand[l][m]*P[fabs(m)][l]
#f = f + rand[l][m]*P[fabs(m)][l]
#f = f + P[fabs(m)][l]
for l in xrange(0, Lmax+1):
for m in xrange(0, l+1):
f = f + cos(m*phi)*rand[l][m]*P[fabs(m)][l]
#f = f + rand[l][m]*P[fabs(m)][l]
#f = f + P[fabs(m)][l]
field[i][j + N/4] = f
x[i][j + N/4] = (i-N/2)*2/float(N)*pi
y[i][j + N/4] = teta
In [45]:
import pylab as plt
plt.figure(figsize=(13,10))
ax = plt.subplot(111, projection = 'mollweide')
ax.contourf(x,y,field,100)
#ax.contour(x,y,field,10,colors='k')
plt.show()
In [46]:
plt.figure(figsize=(13,10))
ax = plt.pcolormesh(x, y, field)
plt.show()
In [77]:
for i in xrange(0, N):
for j in xrange(-N/4, N/4+1):
phi = i*2/float(N)*pi
teta = pi/2*(j+N/4)*4/float(N)
P = np.zeros((Lmax+1, Lmax+1))
P_ = np.zeros((Lmax+1, Lmax+1))
P_[0][0] = 1/sqrt(4*pi)
for m in xrange(1, Lmax+1):
P_[m][m] = P_[m-1][m-1]*(-sin(teta))*sqrt(2*m+3)/sqrt(2*m+2)
for m in xrange(0, Lmax):
P_[m][m+1] = P_[m][m]*cos(teta)*sqrt(2*m+3)
for m in xrange(0, Lmax-1):
for l in xrange(m+2, Lmax+1):
P_[m][l] = sqrt((2*l+1)*(l-1-m))/sqrt(l**2-m**2)*(cos(teta)*sqrt(2*l-1)/sqrt(l-1-m)*P_[m][l-1] - sqrt(l+m-1)/sqrt(2*l-3)*P_[m][l-2])
for m in xrange(0, Lmax+1):
for l in xrange(m, Lmax+1):
P[m][l] = sqrt(4*pi*factorial(l+m))/sqrt((2*l+1)*factorial(l-m))*P_[m][l]
f = 0.0
m = 3
l = 3
f = cos(m*phi)*P[fabs(m)][l]
field[i][j + N/4] = f
x[i][j + N/4] = (i-N/2)*2/float(N)*pi
y[i][j + N/4] = teta - pi/2*(N/4)*4/float(N)
In [78]:
import pylab as plt
plt.figure(figsize=(13,10))
ax = plt.subplot(111, projection = 'mollweide')
ax.contourf(x,y,field,100)
#ax.contour(x,y,field,10,colors='k')
plt.show()
In [79]:
plt.figure(figsize=(13,10))
ax = plt.pcolormesh(x, y, field)
plt.show()
По версии numerical recipies - это работает правильно - http://www.wikiwand.com/ru/Сферические_функции
На полюсах должны быть большие значения чем на экваторе - http://www.wikiwand.com/en/Table_of_spherical_harmonics
In [ ]: