This commit is contained in:
2025-07-18 11:25:48 -04:00
parent c12e3b10ed
commit 728688fbd4
28 changed files with 25202 additions and 0 deletions

View File

@ -0,0 +1,7 @@
{
"folders": [
{
"path": "."
}
]
}

17
amspyigrf13/__init__.py Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/python3
"""
Aaron M. Schinders python library for working with the IGRF geomagnetic field model
Intended to be self contained. Will contain some earlier work for evaluating spherical harmonics.
"""
from .amspyigrf_loader import *
from .amssphharmonics import gso_cosharmonic
from .amssphharmonics import gso_sinharmonic
from .amspyigrf_eval import igrf_potential, igrf_bfield
from .amsgrs80geom import *

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

461
amspyigrf13/amsgrs80geom.py Normal file
View File

@ -0,0 +1,461 @@
#!/usr/bin/python3
import os,sys,math
import numpy as np
import matplotlib.pyplot as plt
__all__ = ["geodetic_rhoz_to_latalt",
"geodetic_rhoz_to_latalt",
"grs80_lonlatalt_to_xyz",
"grs80_xyz_to_lonlatalt",
"grs80_uvw_coordsys",
"grs80_xyzvectors_to_uvw",
"grs80_uvwvectors_to_xyz"
]
pi = np.pi
cos = np.cos
sin = np.sin
tan = np.tan
atan = np.atan
atan2 = np.atan2
sqrt = np.sqrt
abs = np.abs
def arg(x,y):
x = np.array(x)
y = np.array(y)
single = False
if(len(x.shape)==0):
single = True
x = np.reshape(x,[1])
y = np.reshape(y,[1])
th = np.atan2(y,x)
if(th<0.0):
th = th + 2*pi
if(single):
th = th[0]
y = y[0]
return th
def azel(x,y,z):
x = np.array(x)
y = np.array(y)
z = np.array(z)
single = False
if(len(x.shape)==0):
single = True
x = np.reshape(x,[1])
y = np.reshape(y,[1])
z = np.reshape(z,[1])
th = arg(x,y)
rho = np.sqrt(x**2+y**2)
el = np.atan(z/rho)
if(single):
th = th[0]
el = el[0]
return [th,el]
def geodetic_rhoz_to_latalt(p, z):
"""
[lat, alt] = geodetic_rhoz_to_latalt(p, z):
Inputs:
p - radial sqrt(x**2+y**2) coordinate [km]
z - altitude [km]
Outputs:
geodetic latitude [deg]
geodetic altitude [km]
"""
#GRS-80 ellipsoid parameters
a = 6378.137
finv = 298.257222101
b = a*(1.0-1.0/finv)
e2 = (a**2-b**2)/(a**2)
e2p = (a**2-b**2)/(b**2)
#Input conditioning
p = np.array(p)
z = np.array(z)
single = False
if(len(p.shape)==0):
single = True
p = p.reshape([1])
z = z.reshape([1])
"""
//Ferari's Direct Quartic Solution for k
//float ksi,rho2,s,t,u,v,w,k;
// ksi = (1.0f-e*e)*(z/a)*(z/a);
// rho2 = 1.0f/6.0f*((rho/a)*(rho/a)+ksi-e*e*e*e);
// s = e*e*e*e*ksi*(rho/a)*(rho/a)/(4.0f*rho2*rho2*rho2);
// t = powf(1+s+::sqrt(s*(s+2)),1.0f/3.0f);
// u = rho2*(t+1+1/t);
// v = ::sqrtf(u*u+e*e*e*e*ksi);
// w = e*e*(u+v-ksi)/(2.0f*v);
// k = 1+e*e*(::sqrtf(u+v+w*w)+w)/(u+v);
// ret = ::atanf(k*z/rho);
//given further down the wikipedia page
// https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_ECEF_to_geodetic_coordinates
"""
p = np.abs(p)
F = 54.0*b*b*z*z
G = p*p+(1-e2)*z*z-e2*(a*a-b*b)
c = (e2*e2*F*p*p)/(G*G*G)
s = (1.0 + c + np.sqrt(c*c+2*c))**(1.0/3.0)
k = s + 1.0 + 1.0/s
P = F/(3.0*k*k*G*G)
Q = np.sqrt(1.0+2.0*e2*e2*P)
r0 = -(P*e2*p)/(1.0+Q) + np.sqrt(0.5*a*a*(1.0+1.0/Q)-(P*(1.0-e2)*z*z)/(Q*(1.0+Q))-0.5*P*p*p)
U = np.sqrt((p-e2*r0)*(p-e2*r0)+z*z)
V = np.sqrt((p-e2*r0)*(p-e2*r0)+(1.0-e2)*z*z)
z0 = b*b*z/(a*V)
alt = U*(1.0-b*b/(a*V))
lat = np.atan((z+e2p*z0)/p)
lat = lat * 180.0/pi
#Output conditioning
if(single):
lat = lat[0]
alt = alt[0]
return [lat,alt]
def geodetic_latalt_to_rhoz(lat,alt):
"""
[lat, alt] = geodetic_latalt_to_rhoz(lat, alt):
Inputs:
geodetic latitude [deg]
geodetic altitude [km]]
Outputs:
p - radial sqrt(x**2+y**2) coordinate [km]
z - altitude [km]
"""
#GRS-80 ellipsoid parameters
a = 6378.137
finv = 298.257222101
b = a*(1.0-1.0/finv)
e2 = (a**2-b**2)/(a**2)
e2p = (a**2-b**2)/(b**2)
#Input Conditioning
lat = np.array(lat)
alt = np.array(alt)
single = False
if(len(lat.shape)==0):
single = True
lat = lat.reshape([1])
alt = alt.reshape([1])
lat = lat * pi/180.0
# lat[lat>90.0] = 90.0-lat[lat>90.0]
# lat[lat<-90.0] = -90.0 - lat[lat<-90.0]
N = a**2/np.sqrt(a**2*cos(lat)**2+b**2*sin(lat)**2)
p = np.abs((N+alt)*np.cos(lat))
z = ((b/a)**2*N+alt)*np.sin(lat)
#Output Conditioning
if(single):
p = p[0]
z = z[0]
return [p,z]
def grs80_lonlatalt_to_xyz(lon,lat,alt):
"""
[x,y,z] = grs80_lonlatalt_to_xyz(lon,lat,alt)
Inputs:
lon [deg]
lat [deg]
alt [km]
Outputs:
x,y,z [km] ECEF coordinates
"""
lon = np.array(lon)
lat = np.array(lat)
alt = np.array(alt)
single = False
if(len(lon.shape)==0):
single = True
lon = lon.reshape([1])
lat = lat.reshape([1])
alt = alt.reshape([1])
[rho,z] = geodetic_latalt_to_rhoz(lat,alt)
x = rho*np.cos(lon*pi/180.0)
y = rho*np.sin(lon*pi/180.0)
if(single):
x = x[0]
y = y[0]
z = z[0]
return [x,y,z]
def grs80_xyz_to_lonlatalt(x,y,z):
"""
[lon,lat,alt] = grs80_xyz_to_lonlatalt(x,y,z)
Inputs:
x,y,z [km] ECEF coordinates
Outputs:
lon [deg]
lat [deg]
alt [km]
"""
x = np.array(x); y = np.array(y); z = np.array(z)
single = False
if(len(x.shape)==0):
single = True
x = x.reshape([1]); y = y.reshape([1]); z = z.reshape([1])
rho = np.sqrt(x**2+y**2)
[lat,alt] = geodetic_rhoz_to_latalt(rho,z)
lon = np.atan2(y,x)*180.0/pi
if(single):
lon = lon[0]
lat = lat[0]
alt = alt[0]
return [lon,lat,alt]
def grs80_uvw_coordsys(x,y,z):
"""
[u,v,w] = grs80_uvw_coordsys(x,y,z)
Args:
x,y,z - [km] vectors of ECEF coordinates
Returns:
[u,v,w] - each [3,N] unit vectors pointing along zonal, meridional, and vertical directions
"""
x = np.array(x); y = np.array(y); z = np.array(z)
single = False
if(len(x.shape)==0):
single = True
x = x.reshape([1]); y = y.reshape([1]); z = z.reshape([1])
N = x.shape[0]
u = np.zeros([3,N])
v = np.zeros([3,N])
w = np.zeros([3,N])
rho = np.sqrt(x**2+y**2)
[lat,alt] = geodetic_rhoz_to_latalt(rho,z)
lat = lat * pi/180.0
lon = np.atan2(y,x)
u[0,:] = -sin(lon)
u[1,:] = cos(lon)
u[2,:] = 0.0
v[0,:] = -cos(lon)*sin(lat)
v[1,:] = -sin(lon)*sin(lat)
v[2,:] = cos(lat)
w[0,:] = cos(lon)*cos(lat)
w[1,:] = sin(lon)*cos(lat)
w[2,:] = sin(lat)
return [u,v,w]
def _local_vdot(v1,v2):
v1 = np.array(v1)
v2 = np.array(v2)
single = False
if(len(v1.shape)==1):
single = True
v1 = v1.reshape([3,1])
v2 = v2.reshape([3,1])
dots = np.sum(v1*v2,axis=0)
if(single):
dots = dots[0]
return dots
def grs80_xyzvectors_to_uvw(xyzpos,xyzvect):
"""
[lonlatalt, uvwvect] = grs80_xyzvectors_to_uvw(xyzpos,xyzvect)
Inputs:
xyzpos [km] - [3,N] array of vector ECEF positions
xyzvect - [3,N] array of vectors
Outputs:
lonlatalt [deg, deg, km] - [3,N] array of vector geodetic coordinates
uvwvect - [3,N] array of vectors in terms of local zonal, meridional, and vertical components
"""
xyzpos = np.array(xyzpos)
xyzvect = np.array(xyzvect)
single = False
if(len(xyzpos.shape)==1):
single = True
xyzpos = xyzpos.reshape([3,1])
xyzvect = xyzvect.reshape([3,1])
N = xyzpos.shape[1]
[lon,lat,alt] = grs80_xyz_to_lonlatalt(xyzpos[0,:],xyzpos[1,:],xyzpos[2,:])
lonlatalt = np.stack([lon,lat,alt],axis=0)
[u,v,w] = grs80_uvw_coordsys(xyzpos[0,:],xyzpos[1,:],xyzpos[2,:])
uc = _local_vdot(xyzvect,u)
vc = _local_vdot(xyzvect,v)
wc = _local_vdot(xyzvect,w)
uvwvect = np.stack([uc,vc,wc],axis=0)
if(single):
lonlatalt = np.squeeze(lonlatalt)
uvwvect = np.squeeze(uvwvect)
return [lonlatalt, uvwvect]
def grs80_uvwvectors_to_xyz(lonlatalt, uvwvect):
"""
[xyzpos, xyzvect] = grs80_uvwvectors_to_xyz(lonlatalt, uvwvect)
Inputs:
lonlatalt [deg, deg, km] - [3,N] array of vector geodetic coordinates
uvwvect - [3,N] array of vectors in terms of local zonal, meridional, and vertical components
Outputs:
xyzpos [km] - [3,N] array of vector ECEF positions
xyzvect - [3,N] array of vectors
"""
lonlatalt = np.array(lonlatalt)
uvwvect = np.array(uvwvect)
single = False
if(len(lonlatalt.shape)==1):
single = True
lonlatalt = lonlatalt.reshape([3,1])
uvwvect = uvwvect.reshape([3,1])
[x,y,z] = grs80_lonlatalt_to_xyz(lonlatalt[0,:],lonlatalt[1,:],lonlatalt[2,:])
xyzpos = np.stack([x,y,z],axis=0)
N = lonlatalt.shape[1]
xyzvect = np.zeros([3,N])
[u,v,w] = grs80_uvw_coordsys(x,y,z)
xyzvect[0,:] = u[0]*uvwvect[0,:] + v[0]*uvwvect[1,:] + w[0]*uvwvect[2,:]
xyzvect[1,:] = u[1]*uvwvect[0,:] + v[1]*uvwvect[1,:] + w[1]*uvwvect[2,:]
xyzvect[2,:] = u[2]*uvwvect[0,:] + v[2]*uvwvect[1,:] + w[2]*uvwvect[2,:]
if(single==True):
xyzpos = np.squeeze(xyzpos)
xyzvect = np.squeeze(xyzvect)
return [xyzpos, xyzvect]
###########
## Tests ##
###########
def test_geodetic_latitude():
th = np.linspace(0,2*pi,100)
a = 6378.137
p = cos(th)*a
z = sin(th)*a
[lat,alt] = geodetic_rhoz_to_latalt(p,z)
[p2,z2] = geodetic_latalt_to_rhoz(lat,alt)
[lat2,alt2] = geodetic_rhoz_to_latalt(p2,z2)
err1 = np.abs(np.abs(p2)-np.abs(p))
err2 = np.abs(z2-z)
err3 = np.abs(lat2-lat)
err4 = np.abs(alt2-alt)
for I in range(0,len(th)):
ln = "{:1.3f}: {:1.3f},{:1.3f}: {:1.3f},{:1.3f} : {:1.3f} {:1.3f} {:1.3f} {:1.3f}".format(th[I],p[I],z[I],lat[I],alt[I],err1[I],err2[I],err3[I],err4[I])
print(ln)
a = 360000.0
p = cos(th)*a
z = sin(th)*a
[lat,alt] = geodetic_rhoz_to_latalt(p,z)
[p2,z2] = geodetic_latalt_to_rhoz(lat,alt)
[lat2,alt2] = geodetic_rhoz_to_latalt(p2,z2)
err1 = np.abs(np.abs(p2)-np.abs(p))
err2 = np.abs(z2-z)
err3 = np.abs(lat2-lat)
err4 = np.abs(alt2-alt)
for I in range(0,len(th)):
ln = "{:1.3f}: {:1.3f},{:1.3f}: {:1.3f},{:1.3f} : {:1.3f} {:1.3f} {:1.3f} {:1.3f}".format(th[I],p[I],z[I],lat[I],alt[I],err1[I],err2[I],err3[I],err4[I])
print(ln)
a = 100.0
p = cos(th)*a
z = sin(th)*a
[lat,alt] = geodetic_rhoz_to_latalt(p,z)
[p2,z2] = geodetic_latalt_to_rhoz(lat,alt)
[lat2,alt2] = geodetic_rhoz_to_latalt(p2,z2)
err1 = np.abs(np.abs(p2)-np.abs(p))
err2 = np.abs(z2-z)
err3 = np.abs(lat2-lat)
err4 = np.abs(alt2-alt)
for I in range(0,len(th)):
ln = "{:1.3f}: {:1.3f},{:1.3f}: {:1.3f},{:1.3f} : {:1.3f} {:1.3f} {:1.3f} {:1.3f}".format(th[I],p[I],z[I],lat[I],alt[I],err1[I],err2[I],err3[I],err4[I])
print(ln)
return
def test_grs80_1():
[x,y,z] = grs80_lonlatalt_to_xyz(45,0,0)
print(x,y,z)
[x,y,z] = grs80_lonlatalt_to_xyz(0,45,0)
print(x,y,z)
[lon,lat,alt] = grs80_xyz_to_lonlatalt(6371,0,0)
print(lon,lat,alt)
lon = np.linspace(-180,180,50)
lat = np.linspace(-90,90,25)
[lon2,lat2] = np.meshgrid(lon,lat,indexing='ij')
[x,y,z] = grs80_lonlatalt_to_xyz(lon2,lat2,0)
[x2,y2,z2] = grs80_lonlatalt_to_xyz(lon2,lat2,-6600)
plt.figure().add_subplot(projection="3d")
plt.plot(x,y,z,'k.',markersize=1)
plt.plot(x2,y2,z2,'r.',markersize=1)
plt.show()
return
if(__name__=="__main__"):
#test_geodetic_latitude()
test_grs80_1()
exit(0)

143
amspyigrf13/amslegendre.py Normal file
View File

@ -0,0 +1,143 @@
import os,sys,math
import numpy as np
factorial = math.factorial
comb = math.comb
perm = math.perm
from .amspolyfuns import poly_pow
from .amspolyfuns import poly_derivative
from .amspolyfuns import polyval
def legendre_poly(L):
"""
generates polynomial coefficients for Legendre
polynomial of order L
"""
L = int(L)
if(L<0):
return np.float64([0.0])
elif(L==0):
return np.float64([1.0])
p = np.float64([-1,0,1])
p = poly_pow(p,L)
for I in range(1,L+1):
p = poly_derivative(p)
p = p/2/I
return p
def legendre_eval(x,L):
p = legendre_poly(L)
y = polyval(x,p)
return y
def alegendre_polypart(L,M):
"""
Polynomial part of associated legendre function
The full associated legendre function, including condon-shortley phase
is (1-x^2)*(M/2) * alegendre_polypart(L,M)
"""
M = int(M)
L = int(L)
if(L<0):
return np.float64([0])
if(abs(M)>L):
return np.float64([0])
Ma = abs(M)
CSP = (-1)**Ma
p = legendre_poly(L)
if(Ma>0):
p = poly_derivative(p,Ma)
p = CSP*p
if(M<0):
Nrm = factorial(L-Ma)/factorial(L+Ma)*(-1)**Ma*p
p = Nrm*p
return p
def alegendre_eval(x,L,M):
"""
Evaluates associated legendre function
y = P^m_l(x)
"""
L = int(L)
M = int(M)
Ma = abs(M)
if(L<0):
y = np.zeros(x.shape)
return y
if(Ma>L):
y = np.zeros(x.shape)
return y
if(Ma>0):
#sqpart = np.sign(1-x**2)*np.sqrt(1-x**2)**(Ma)
#sign doesn't work here - need to convert sqrt(1-cos2) to sin
sqpart = np.sqrt(1-x**2)**(Ma)
else:
sqpart = np.ones(x.shape)
p = alegendre_polypart(L,M)
y = polyval(x,p)
y = y*sqpart
return y
def gso_cosinealegendre(theta, m, n):
"""
Returns the Graham-Schmidt semi-normalized associated legendre function
as described in Winch et. al. 2005.
y = P^m_n(cos(theta))
P^m_n(cos(theta)) = sqrt((2-del^0_m)(n-m)!/(n+m)!) * sin(theta)^m *(d/dcos(theta))^m [P_n(cos(theta))]
normalization of associated cosine and sine harmonics is 4*pi/(2*n+1)
for use in the IGRF-13 model
"""
n = int(n)
m = int(m)
theta = np.array(theta)
ma = abs(m)
if(n<0):
y = np.zeros(theta.shape)
return y
if(ma>n):
y = np.zeros(theta.shape)
return y
if(ma>0):
#sqpart = np.sign(1-x**2)*np.sqrt(1-x**2)**(Ma)
#sign doesn't work here - need to convert sqrt(1-cos2) to sin
sqpart = np.sin(theta)**(ma)
nrm = np.sqrt(2*factorial(n-m)/factorial(n+m))
else:
sqpart = np.ones(theta.shape)
nrm = np.sqrt(factorial(n-m)/factorial(n+m))
p = legendre_poly(n)
if(ma>0):
p = poly_derivative(p,ma)
y = polyval(np.cos(theta),p)
y = y*nrm*sqpart
return y

192
amspyigrf13/amspolyfuns.py Normal file
View File

@ -0,0 +1,192 @@
import os,sys,math
import numpy as np
factorial = math.factorial
comb = math.comb
perm = math.perm
#print (math.comb(n, k))
"""
Coefficients used in this library are [ a0, a1, ..., an ] for y = a0 + a1*x + ... an*x**n
Otherwise I'd go crazy reversing indices everywhree.
Polynomial order n is length(poly)-1
"""
def poly_inputscreen(poly):
"""
regularizes the input for a polynomial coefficient array
"""
poly = np.array(poly)
poly = np.reshape(poly,[np.prod(poly.shape)])
if(poly.size==0):
poly = np.float32([0])
return poly
def poly_string(poly):
"""
Returns a string representation of the polynomial,
omitting zero coefficeints.
"""
poly = poly_inputscreen(poly)
s = ""
poly = poly_inputscreen(poly)
if(poly.shape[0]==0):
s = "0.0"
return s
if(poly.shape[0]==1):
s = "{}".format(poly[0])
return s
for I in range(0,poly.shape[0]):
skip = np.abs(poly[I])<1E-15 #skip zero coefficients
if(not skip):
if(I==0):
s = s + "{}".format(poly[I])
else:
s = s + "{}*x^{}".format(poly[I],I)
if(I<poly.shape[0]-1):
s = s + " + "
return s
def poly_print(poly):
"""
Prints the string representation of the polynomial
"""
print(poly_string(poly))
return
def polyval(x,poly):
poly = poly_inputscreen(poly)
x = np.array(x)
y = np.zeros(x.shape)
for I in range(0,poly.shape[0]):
y = y + poly[I]*x**I
return y
def poly_trimorder(poly):
"""
Trims the polynomial array size to the leading nonzero order
"""
poly = poly_inputscreen(poly)
ind = poly.shape[0]
for I in range(ind-1,-1,-1):
if(np.abs(poly[I])>1E-15):
ind = I+1
break
poly = poly[0:ind]
return poly
def poly_mult(poly1, poly2):
"""
Multiplies two polynomials together, returning
poly1*poly2
[1,1] * [-1,1] = [-1,0,1]
[1,1] * [1,1] = [1,2,1]
"""
poly1 = poly_inputscreen(poly1)
poly2 = poly_inputscreen(poly2)
N1 = poly1.shape[0]
N2 = poly2.shape[0]
poly3 = np.zeros([N1+N2],dtype=np.float64)
for I in range(0,N1):
for J in range(0,N2):
poly3[I+J] = poly3[I+J] + poly1[I]*poly2[J]
poly3 = poly_trimorder(poly3)
return poly3
def poly_derivative(poly,N=1):
"""
derivative of polynomial, of positive integer order
returns d^N/dx^N(poly)
"""
poly = poly_inputscreen(poly)
N = int(N)
if(N<=0):
return poly
for J in range(0,N):
for I in range(0,poly.shape[0]-1):
poly[I] = poly[I+1]*(I+1)
poly[poly.shape[0]-1] = 0
poly = poly_trimorder(poly)
return poly
def poly_integral(poly,N=1):
"""
Returns indef. integral of polynomial, compounded N times
integral(poly(x)*dx)
"""
poly = poly_inputscreen(poly)
N = int(N)
if(N<=0):
return poly
N1 = poly.shape[0]
N2 = N1 + N
poly1 = np.zeros([N2])
poly1[0:N1] = poly[:]
for J in range(0,N):
for I in range(poly1.shape[0]-1,0,-1):
poly1[I] = poly1[I-1]*1.0/(I)
poly1[I-1] = 0
poly1 = poly_trimorder(poly1)
return poly1
def poly_pow(poly,N):
"""
Raises polynomial to Nth positive integer power
poly(x)^N
naive algorithm for now
can make a faster one by squaring, but ...
"""
N = int(N)
if(N<0):
return np.array([0])
if(N==0):
return np.array([1])
poly = poly_inputscreen(poly)
N1 = poly.shape[0]
N2 = (N1-1)*N+1
poly1 = np.zeros([N2])
poly2 = np.zeros([N2])
poly2[0:N1] = poly[:]
for I in range(1,N):
#swap addresses
tmp = poly1
poly1 = poly2
poly2 = tmp
poly2[:] = 0
for J in range(0,N1):
for K in range(0,N2-N1+1):
poly2[J+K] = poly2[J+K] + poly1[K]*poly[J]
poly2 = poly_trimorder(poly2)
return poly2

View File

@ -0,0 +1,136 @@
#!/usr/bin/python3
import os,sys,math
import numpy as np
from .amspyigrf_loader import *
from .amssphharmonics import gso_cosharmonic
from .amssphharmonics import gso_sinharmonic
pi = np.pi
sin = np.sin
cos = np.cos
sqrt = np.sqrt
def ams_xyz_rthetaphi(xyz):
"""
Returns astronomical latitude and longitude [radians]
(elevation and azimuth)
Input:
xyz [3] or [3xN] array
Output:
[radius lat lon] [radians] [3] or [3xN] array
"""
xyz = np.array(xyz)
singles = 0
if(len(xyz.shape)==1):
singles = 1
xyz = np.reshape(xyz,[3,1])
r = np.sqrt(np.sum(xyz*xyz,axis=0))
#rho = np.sqrt(xyz[0,:]*xyz[0,:]+xyz[1,:]*xyz[1,:])
#theta = np.where(rho>0.0,np.arctan(xyz[2,:]/rho))
theta = np.arcsin(xyz[2,:]/r)
phi = np.arctan2(xyz[1,:],xyz[0,:])
rtp = np.zeros([3,xyz.shape[1]])
rtp[0,:] = r
rtp[1,:] = theta
rtp[2,:] = phi
if(singles==1):
rtp = np.reshape(rtp,[3])
return rtp
def igrf_potential(xyz, coefstruct):
"""
Returns the IGRF potential function [nT - km] as a function of ECEF
coordinates [x,y,z] in [km] in an earth-centered earth-fixed frame.
Ref for potential function is Aiken et. al. 2021
Inputs:
xyz [3] or [3xN] set of positions [km]
coefstruct - contains gh, n, m, and a arrays
Outputs:
V [scalar] or [N]
"""
xyz = np.array(xyz)
single = 0
if(len(xyz.shape)==1):
single = 1
xyz = np.reshape(xyz,[3,1])
gh = coefstruct["gh"] #whether using a sin or cosine harmonic
n = coefstruct["n"] #
m = coefstruct["m"]
a = coefstruct["a"]
rtp = ams_xyz_rthetaphi(xyz)
theta = pi/2.0-rtp[1,:]
phi = rtp[2,:]
rref = 6371.2 #[km] - reference diameter
V = np.zeros(xyz.shape[1])
for I in range(0,a.shape[0]):
V = V + a[I]*np.float64(gh[I]==0)*rref*(rref/rtp[0,:])**(n[I]+1)*gso_cosharmonic(theta,phi,n[I],m[I])
V = V + a[I]*np.float64(gh[I]==1)*rref*(rref/rtp[0,:])**(n[I]+1)*gso_sinharmonic(theta,phi,n[I],m[I])
if(single==1):
V = V[0]
return V
def igrf_bfield(xyz,coefstruct):
"""
Takes a quick and dirty numeric derivative of the potential function
to return the B-field [nT] [x,y,z] from the IGRF-13 potential function
Inputs:
xyz [3] or [3xN] set of positions [km] ECEF
coefstruct - contains gh, n, m, and a arrays
Outputs:
B [nT] size [3] or [3xN]
"""
xyz = np.array(xyz)
xyz = np.array(xyz)
single = 0
if(len(xyz.shape)==1):
single = 1
xyz = np.reshape(xyz,[3,1])
N = xyz.shape[1]
dx = 0.1 #km
xp = np.array([dx,0,0]).reshape(3,1)
xp = np.repeat(xp,N,axis=1)
yp = np.array([0,dx,0]).reshape(3,1)
yp = np.repeat(yp,N,axis=1)
zp = np.array([0,0,dx]).reshape(3,1)
zp = np.repeat(zp,N,axis=1)
phixp = igrf_potential(xyz+xp,coefstruct)
phixm = igrf_potential(xyz-xp,coefstruct)
phiyp = igrf_potential(xyz+yp,coefstruct)
phiym = igrf_potential(xyz-yp,coefstruct)
phizp = igrf_potential(xyz+zp,coefstruct)
phizm = igrf_potential(xyz-zp,coefstruct)
B = np.zeros([3,N])
B[0,:] = -(phixp-phixm)/2.0/dx
B[1,:] = -(phiyp-phiym)/2.0/dx
B[2,:] = -(phizp-phizm)/2.0/dx
if(single==1):
B = np.squeeze(B[:,0])
return B

View File

@ -0,0 +1,126 @@
#!/usr/bin/python3
import os,sys,math
import numpy as np
import copy
def ams_whitespacesplit(ln):
splitline = []
I1 = -1
I2 = -1
mode = 0
for I in range(0,len(ln)):
c = ln[I]
if(not c.isspace() and mode==0):
mode = 1
I1 = I
if(c.isspace() and mode==1):
I2 = I
s = ln[I1:I2]
splitline.append(s)
mode = 0
if(mode==1):
I2 = len(ln)
s = ln[I1:I2]
splitline.append(s)
mode = 0
return splitline
def convert_stringlist_to_numeric(stringlist):
nlist = np.zeros(len(stringlist),dtype=np.float64)
for I in range(0,len(stringlist)):
try:
q = float(stringlist[I])
except:
q = 0.0
nlist[I] = q
return nlist
def load_igrfdata():
datastruct = dict()
lns = []
sdir = os.path.split(__file__)[0]
fname = "{}/igrf13_data.txt".format(sdir)
fp = open(fname,"r")
ln = " "
mode = 0
N = 0
gharray = []
narray = []
marray = []
amplitudetable = []
while(ln!=""):
ln = fp.readline()
if(ln.find("g/h n m")>=0 and mode==0):
mode = 1
#read date line
dateline = ams_whitespacesplit(ln)
dateline = dateline[3:len(dateline)]
dateline = convert_stringlist_to_numeric(dateline)
datastruct["year"] = dateline
elif(mode==1):
lns = ams_whitespacesplit(ln)
if(len(lns)>5):
if(lns[0]=='g'):
gh = 0
else:
gh = 1
gharray.append(gh)
lnsn = convert_stringlist_to_numeric(lns)
narray.append(lnsn[1])
marray.append(lnsn[2])
amplitudetable.append(lnsn[3:len(lnsn)])
N = N + 1
gharray = np.int32(gharray)
narray = np.int32(narray)
marray = np.int32(marray)
atable = np.zeros([len(amplitudetable),len(amplitudetable[0])],dtype=np.float64)
for I in range(0,atable.shape[0]):
atable[I,:] = amplitudetable[I][:]
datastruct["gh"] = gharray
datastruct["n"] = narray
datastruct["m"] = marray
datastruct["a"] = atable
fp.close()
return datastruct
def igrf_getcomponents(year,igrfdatastruct):
acomp = None
a = igrfdatastruct["a"]
if(year<1900):
acomp = a[:,0]
elif(year>=2020):
ac0 = a[:,a.shape[1]-2]
ac1 = a[:,a.shape[1]-1]
acomp = ac0 + ac1*(year-2020)
else:
I0 = int(np.floor((year-1900)/5.0))
I1 = I0 + 1
ac0 = a[:,I0]
ac1 = a[:,I1]
acomp = (ac1-ac0)/5.0*(year-(1900+5*I0)) + ac0
return acomp
def igrf_getcompstruct(year, igrfdatastruct):
acomp = igrf_getcomponents(year, igrfdatastruct);
compstruct = copy.deepcopy(igrfdatastruct)
compstruct["a"] = acomp
return compstruct

View File

@ -0,0 +1,115 @@
import os,sys,math
import numpy as np
factorial = math.factorial
comb = math.comb
perm = math.perm
#print (math.comb(n, k))
from .amspolyfuns import poly_pow
from .amspolyfuns import poly_derivative
from .amspolyfuns import polyval
from .amslegendre import *
#import scipy as sp
#import scipy.interpolate as interp
#scipy.interpolate.LinearNDInterpolator
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.LinearNDInterpolator.html#scipy.interpolate.LinearNDInterpolator
def sphericalharmonic_polysin(L,M):
"""
Returns sin(theta) power and normed cosine polynomial for spherical harmonic
Return: [spower, polynomial]
Y^M_L(theta,phi) = sin(theta)^spower * poly(cos(theta)) * exp(i*M*phi)
"""
L = int(L)
M = int(M)
Ma = abs(M)
polysin = [0, [0.0]]
if(L<0):
return polysin
if(abs(M)>L):
return polysin
Nrm = np.sqrt((2*L+1)/(4*np.pi) * math.factorial(L-Ma)/math.factorial(L+Ma))*((-1)**Ma)
p = alegendre_polypart(L,Ma)
p = p*Nrm
polysin = [Ma, p]
return polysin
def sphericalharmonic_eval(theta, phi, L, M):
"""
Returns the values of the spherical harmonic Y^M_L(theta,phi)
Y is normalized such that <Y^M_L, Y^M_L> over the unit sphere = 1
Integral(conj(Y^M1_L1)*Y^M2_L2 * sin(theta)*dtheta*dphi) = del(L1,L2)del(M1,M2)
"""
L = int(L)
M = int(M)
Ma = abs(M)
theta = np.array(theta)
phi = np.array(phi)
if(theta.shape != phi.shape):
print("sphericalharmonic_eval: error: theta and phi must have the same shape.")
vals = np.array([])
return vals
vals = np.zeros(theta.shape)
if(L<0):
return vals
if(abs(M)>L):
return vals
[spower, poly] = sphericalharmonic_polysin(L,M)
vals = polyval(np.cos(theta),poly)
vals = vals*(np.sin(theta)**Ma)
vals = vals*np.exp(1j * phi * M)
return vals
def gso_cosharmonic(theta,phi,n,m):
"""
Returns grahm-schmidt semi-normalized cosine spherical harmonics
y = P^n_m(cos(theta))*cos(m*phi)
P^n_m(cos(theta)) is the graham-schmidt semi-normalized
associated legendre function described in
Winch et. al. 2005
"""
theta = np.array(theta)
phi = np.array(phi)
n = int(n)
m = int(m)
alegendre = gso_cosinealegendre(theta,m,n)
y = alegendre*np.cos(m*phi)
return y
def gso_sinharmonic(theta,phi,n,m):
"""
Returns grahm-schmidt semi-normalized sine spherical harmonics
y = P^n_m(cos(theta))*sin(m*phi)
P^n_m(cos(theta)) is the graham-schmidt semi-normalized
associated legendre function described in
Winch et. al. 2005
"""
theta = np.array(theta)
phi = np.array(phi)
n = int(n)
m = int(m)
alegendre = gso_cosinealegendre(theta,m,n)
y = alegendre*np.sin(m*phi)
return y

199
amspyigrf13/igrf13_data.txt Normal file
View File

@ -0,0 +1,199 @@
# 13th Generation International Geomagnetic Reference Field Schmidt semi-normalised spherical harmonic coefficients, degree n=1,13
# in units nanoTesla for IGRF and definitive DGRF main-field models (degree n=1,8 nanoTesla/year for secular variation (SV))
c/s deg ord IGRF IGRF IGRF IGRF IGRF IGRF IGRF IGRF IGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF DGRF IGRF SV
g/h n m 1900.0 1905.0 1910.0 1915.0 1920.0 1925.0 1930.0 1935.0 1940.0 1945.0 1950.0 1955.0 1960.0 1965.0 1970.0 1975.0 1980.0 1985.0 1990.0 1995.0 2000.0 2005.0 2010.0 2015.0 2020.0 2020-25
g 1 0 -31543 -31464 -31354 -31212 -31060 -30926 -30805 -30715 -30654 -30594 -30554 -30500 -30421 -30334 -30220 -30100 -29992 -29873 -29775 -29692 -29619.4 -29554.63 -29496.57 -29441.46 -29404.8 5.7
g 1 1 -2298 -2298 -2297 -2306 -2317 -2318 -2316 -2306 -2292 -2285 -2250 -2215 -2169 -2119 -2068 -2013 -1956 -1905 -1848 -1784 -1728.2 -1669.05 -1586.42 -1501.77 -1450.9 7.4
h 1 1 5922 5909 5898 5875 5845 5817 5808 5812 5821 5810 5815 5820 5791 5776 5737 5675 5604 5500 5406 5306 5186.1 5077.99 4944.26 4795.99 4652.5 -25.9
g 2 0 -677 -728 -769 -802 -839 -893 -951 -1018 -1106 -1244 -1341 -1440 -1555 -1662 -1781 -1902 -1997 -2072 -2131 -2200 -2267.7 -2337.24 -2396.06 -2445.88 -2499.6 -11.0
g 2 1 2905 2928 2948 2956 2959 2969 2980 2984 2981 2990 2998 3003 3002 2997 3000 3010 3027 3044 3059 3070 3068.4 3047.69 3026.34 3012.20 2982.0 -7.0
h 2 1 -1061 -1086 -1128 -1191 -1259 -1334 -1424 -1520 -1614 -1702 -1810 -1898 -1967 -2016 -2047 -2067 -2129 -2197 -2279 -2366 -2481.6 -2594.50 -2708.54 -2845.41 -2991.6 -30.2
g 2 2 924 1041 1176 1309 1407 1471 1517 1550 1566 1578 1576 1581 1590 1594 1611 1632 1663 1687 1686 1681 1670.9 1657.76 1668.17 1676.35 1677.0 -2.1
h 2 2 1121 1065 1000 917 823 728 644 586 528 477 381 291 206 114 25 -68 -200 -306 -373 -413 -458.0 -515.43 -575.73 -642.17 -734.6 -22.4
g 3 0 1022 1037 1058 1084 1111 1140 1172 1206 1240 1282 1297 1302 1302 1297 1287 1276 1281 1296 1314 1335 1339.6 1336.30 1339.85 1350.33 1363.2 2.2
g 3 1 -1469 -1494 -1524 -1559 -1600 -1645 -1692 -1740 -1790 -1834 -1889 -1944 -1992 -2038 -2091 -2144 -2180 -2208 -2239 -2267 -2288.0 -2305.83 -2326.54 -2352.26 -2381.2 -5.9
h 3 1 -330 -357 -389 -421 -445 -462 -480 -494 -499 -499 -476 -462 -414 -404 -366 -333 -336 -310 -284 -262 -227.6 -198.86 -160.40 -115.29 -82.1 6.0
g 3 2 1256 1239 1223 1212 1205 1202 1205 1215 1232 1255 1274 1288 1289 1292 1278 1260 1251 1247 1248 1249 1252.1 1246.39 1232.10 1225.85 1236.2 3.1
h 3 2 3 34 62 84 103 119 133 146 163 186 206 216 224 240 251 262 271 284 293 302 293.4 269.72 251.75 245.04 241.9 -1.1
g 3 3 572 635 705 778 839 881 907 918 916 913 896 882 878 856 838 830 833 829 802 759 714.5 672.51 633.73 581.69 525.7 -12.0
h 3 3 523 480 425 360 293 229 166 101 43 -11 -46 -83 -130 -165 -196 -223 -252 -297 -352 -427 -491.1 -524.72 -537.03 -538.70 -543.4 0.5
g 4 0 876 880 884 887 889 891 896 903 914 944 954 958 957 957 952 946 938 936 939 940 932.3 920.55 912.66 907.42 903.0 -1.2
g 4 1 628 643 660 678 695 711 727 744 762 776 792 796 800 804 800 791 782 780 780 780 786.8 797.96 808.97 813.68 809.5 -1.6
h 4 1 195 203 211 218 220 216 205 188 169 144 136 133 135 148 167 191 212 232 247 262 272.6 282.07 286.48 283.54 281.9 -0.1
g 4 2 660 653 644 631 616 601 584 565 550 544 528 510 504 479 461 438 398 361 325 290 250.0 210.65 166.58 120.49 86.3 -5.9
h 4 2 -69 -77 -90 -109 -134 -163 -195 -226 -252 -276 -278 -274 -278 -269 -266 -265 -257 -249 -240 -236 -231.9 -225.23 -211.03 -188.43 -158.4 6.5
g 4 3 -361 -380 -400 -416 -424 -426 -422 -415 -405 -421 -408 -397 -394 -390 -395 -405 -419 -424 -423 -418 -403.0 -379.86 -356.83 -334.85 -309.4 5.2
h 4 3 -210 -201 -189 -173 -153 -130 -109 -90 -72 -55 -37 -23 3 13 26 39 53 69 84 97 119.8 145.15 164.46 180.95 199.7 3.6
g 4 4 134 146 160 178 199 217 234 249 265 304 303 290 269 252 234 216 199 170 141 122 111.3 100.00 89.40 70.38 48.0 -5.1
h 4 4 -75 -65 -55 -51 -57 -70 -90 -114 -141 -178 -210 -230 -255 -269 -279 -288 -297 -297 -299 -306 -303.8 -305.36 -309.72 -329.23 -349.7 -5.0
g 5 0 -184 -192 -201 -211 -221 -230 -237 -241 -241 -253 -240 -229 -222 -219 -216 -218 -218 -214 -214 -214 -218.8 -227.00 -230.87 -232.91 -234.3 -0.3
g 5 1 328 328 327 327 326 326 327 329 334 346 349 360 362 358 359 356 357 355 353 352 351.4 354.41 357.29 360.14 363.2 0.5
h 5 1 -210 -193 -172 -148 -122 -96 -72 -51 -33 -12 3 15 16 19 26 31 46 47 46 46 43.8 42.72 44.58 46.98 47.7 0.0
g 5 2 264 259 253 245 236 226 218 211 208 194 211 230 242 254 262 264 261 253 245 235 222.3 208.95 200.26 192.35 187.8 -0.6
h 5 2 53 56 57 58 58 58 60 64 71 95 103 110 125 128 139 148 150 150 154 165 171.9 180.25 189.01 196.98 208.3 2.5
g 5 3 5 -1 -9 -16 -23 -28 -32 -33 -33 -20 -20 -23 -26 -31 -42 -59 -74 -93 -109 -118 -130.4 -136.54 -141.05 -140.94 -140.7 0.2
h 5 3 -33 -32 -33 -34 -38 -44 -53 -64 -75 -67 -87 -98 -117 -126 -139 -152 -151 -154 -153 -143 -133.1 -123.45 -118.06 -119.14 -121.2 -0.6
g 5 4 -86 -93 -102 -111 -119 -125 -131 -136 -141 -142 -147 -152 -156 -157 -160 -159 -162 -164 -165 -166 -168.6 -168.05 -163.17 -157.40 -151.2 1.3
h 5 4 -124 -125 -126 -126 -125 -122 -118 -115 -113 -119 -122 -121 -114 -97 -91 -83 -78 -75 -69 -55 -39.3 -19.57 -0.01 15.98 32.3 3.0
g 5 5 -16 -26 -38 -51 -62 -69 -74 -76 -76 -82 -76 -69 -63 -62 -56 -49 -48 -46 -36 -17 -12.9 -13.55 -8.03 4.30 13.5 0.9
h 5 5 3 11 21 32 43 51 58 64 69 82 80 78 81 81 83 88 92 95 97 107 106.3 103.85 101.04 100.12 98.9 0.3
g 6 0 63 62 62 61 61 61 60 59 57 59 54 47 46 45 43 45 48 53 61 68 72.3 73.60 72.78 69.55 66.0 -0.5
g 6 1 61 60 58 57 55 54 53 53 54 57 57 57 58 61 64 66 66 65 65 67 68.2 69.56 68.69 67.57 65.5 -0.3
h 6 1 -9 -7 -5 -2 0 3 4 4 4 6 -1 -9 -10 -11 -12 -13 -15 -16 -16 -17 -17.4 -20.33 -20.90 -20.61 -19.1 0.0
g 6 2 -11 -11 -11 -10 -10 -9 -9 -8 -7 6 4 3 1 8 15 28 42 51 59 68 74.2 76.74 75.92 72.79 72.9 0.4
h 6 2 83 86 89 93 96 99 102 104 105 100 99 96 99 100 100 99 93 88 82 72 63.7 54.75 44.18 33.30 25.1 -1.6
g 6 3 -217 -221 -224 -228 -233 -238 -242 -246 -249 -246 -247 -247 -237 -228 -212 -198 -192 -185 -178 -170 -160.9 -151.34 -141.40 -129.85 -121.5 1.3
h 6 3 2 4 5 8 11 14 19 25 33 16 33 48 60 68 72 75 71 69 69 67 65.1 63.63 61.54 58.74 52.8 -1.3
g 6 4 -58 -57 -54 -51 -46 -40 -32 -25 -18 -25 -16 -8 -1 4 2 1 4 4 3 -1 -5.9 -14.58 -22.83 -28.93 -36.2 -1.4
h 6 4 -35 -32 -29 -26 -22 -18 -16 -15 -15 -9 -12 -16 -20 -32 -37 -41 -43 -48 -52 -58 -61.2 -63.53 -66.26 -66.64 -64.5 0.8
g 6 5 59 57 54 49 44 39 32 25 18 21 12 7 -2 1 3 6 14 16 18 19 16.9 14.58 13.10 13.14 13.5 0.0
h 6 5 36 32 28 23 18 13 8 4 0 -16 -12 -12 -11 -8 -6 -4 -2 -1 1 1 0.7 0.24 3.02 7.35 8.9 0.0
g 6 6 -90 -92 -95 -98 -101 -103 -104 -106 -107 -104 -105 -107 -113 -111 -112 -111 -108 -102 -96 -93 -90.4 -86.36 -78.09 -70.85 -64.7 0.9
h 6 6 -69 -67 -65 -62 -57 -52 -46 -40 -33 -39 -30 -24 -17 -7 1 11 17 21 24 36 43.8 50.94 55.40 62.41 68.1 1.0
g 7 0 70 70 71 72 73 73 74 74 74 70 65 65 67 75 72 71 72 74 77 77 79.0 79.88 80.44 81.29 80.6 -0.1
g 7 1 -55 -54 -54 -54 -54 -54 -54 -53 -53 -40 -55 -56 -56 -57 -57 -56 -59 -62 -64 -72 -74.0 -74.46 -75.00 -75.99 -76.7 -0.2
h 7 1 -45 -46 -47 -48 -49 -50 -51 -52 -52 -45 -35 -50 -55 -61 -70 -77 -82 -83 -80 -69 -64.6 -61.14 -57.80 -54.27 -51.5 0.6
g 7 2 0 0 1 2 2 3 4 4 4 0 2 2 5 4 1 1 2 3 2 1 0.0 -1.65 -4.55 -6.79 -8.2 0.0
h 7 2 -13 -14 -14 -14 -14 -14 -15 -17 -18 -18 -17 -24 -28 -27 -27 -26 -27 -27 -26 -25 -24.2 -22.57 -21.20 -19.53 -16.9 0.6
g 7 3 34 33 32 31 29 27 25 23 20 0 1 10 15 13 14 16 21 24 26 28 33.3 38.73 45.24 51.82 56.5 0.7
h 7 3 -10 -11 -12 -12 -13 -14 -14 -14 -14 2 0 -4 -6 -2 -4 -5 -5 -2 0 4 6.2 6.82 6.54 5.59 2.2 -0.8
g 7 4 -41 -41 -40 -38 -37 -35 -34 -33 -31 -29 -40 -32 -32 -26 -22 -14 -12 -6 -1 5 9.1 12.30 14.00 15.07 15.8 0.1
h 7 4 -1 0 1 2 4 5 6 7 7 6 10 8 7 6 8 10 16 20 21 24 24.0 25.35 24.96 24.45 23.5 -0.2
g 7 5 -21 -20 -19 -18 -16 -14 -12 -11 -9 -10 -7 -11 -7 -6 -2 0 1 4 5 4 6.9 9.37 10.46 9.32 6.4 -0.5
h 7 5 28 28 28 28 28 29 29 29 29 28 36 28 23 26 23 22 18 17 17 17 14.8 10.93 7.03 3.27 -2.2 -1.1
g 7 6 18 18 18 19 19 19 18 18 17 15 5 9 17 13 13 12 11 10 9 8 7.3 5.42 1.64 -2.88 -7.2 -0.8
h 7 6 -12 -12 -13 -15 -16 -17 -18 -19 -20 -17 -18 -20 -18 -23 -23 -23 -23 -23 -23 -24 -25.4 -26.32 -27.61 -27.50 -27.2 0.1
g 7 7 6 6 6 6 6 6 6 6 5 29 19 18 8 1 -2 -5 -2 0 0 -2 -1.2 1.94 4.92 6.61 9.8 0.8
h 7 7 -22 -22 -22 -22 -22 -21 -20 -19 -19 -22 -16 -18 -17 -12 -11 -12 -10 -7 -4 -6 -5.8 -4.64 -3.28 -2.32 -1.8 0.3
g 8 0 11 11 11 11 11 11 11 11 11 13 22 11 15 13 14 14 18 21 23 25 24.4 24.80 24.41 23.98 23.7 0.0
g 8 1 8 8 8 8 7 7 7 7 7 7 15 9 6 5 6 6 6 6 5 6 6.6 7.62 8.21 8.89 9.7 0.1
h 8 1 8 8 8 8 8 8 8 8 8 12 5 10 11 7 7 6 7 8 10 11 11.9 11.20 10.84 10.04 8.4 -0.2
g 8 2 -4 -4 -4 -4 -3 -3 -3 -3 -3 -8 -4 -6 -4 -4 -2 -1 0 0 -1 -6 -9.2 -11.73 -14.50 -16.78 -17.6 -0.1
h 8 2 -14 -15 -15 -15 -15 -15 -15 -15 -14 -21 -22 -15 -14 -12 -15 -16 -18 -19 -19 -21 -21.5 -20.88 -20.03 -18.26 -15.3 0.6
g 8 3 -9 -9 -9 -9 -9 -9 -9 -9 -10 -5 -1 -14 -11 -14 -13 -12 -11 -11 -10 -9 -7.9 -6.88 -5.59 -3.16 -0.5 0.4
h 8 3 7 7 6 6 6 6 5 5 5 -12 0 5 7 9 6 4 4 5 6 8 8.5 9.83 11.83 13.18 12.8 -0.2
g 8 4 1 1 1 2 2 2 2 1 1 9 11 6 2 0 -3 -8 -7 -9 -12 -14 -16.6 -18.11 -19.34 -20.56 -21.1 -0.1
h 8 4 -13 -13 -13 -13 -14 -14 -14 -15 -15 -7 -21 -23 -18 -16 -17 -19 -22 -23 -22 -23 -21.5 -19.71 -17.41 -14.60 -11.7 0.5
g 8 5 2 2 2 3 4 4 5 6 6 7 15 10 10 8 5 4 4 4 3 9 9.1 10.17 11.61 13.33 15.3 0.4
h 8 5 5 5 5 5 5 5 5 5 5 2 -8 3 4 4 6 6 9 11 12 15 15.5 16.22 16.71 16.16 14.9 -0.3
g 8 6 -9 -8 -8 -8 -7 -7 -6 -6 -5 -10 -13 -7 -5 -1 0 0 3 4 4 6 7.0 9.36 10.85 11.76 13.7 0.3
h 8 6 16 16 16 16 17 17 18 18 19 18 17 23 23 24 21 18 16 14 12 11 8.9 7.61 6.96 5.69 3.6 -0.4
g 8 7 5 5 5 6 6 7 8 8 9 7 5 6 10 11 11 10 6 4 2 -5 -7.9 -11.25 -14.05 -15.98 -16.5 -0.1
h 8 7 -5 -5 -5 -5 -5 -5 -5 -5 -5 3 -4 -4 1 -3 -6 -10 -13 -15 -16 -16 -14.9 -12.76 -10.74 -9.10 -6.9 0.5
g 8 8 8 8 8 8 8 8 8 7 7 2 -1 9 8 4 3 1 -1 -4 -6 -7 -7.0 -4.87 -3.54 -2.02 -0.3 0.4
h 8 8 -18 -18 -18 -18 -19 -19 -19 -19 -19 -11 -17 -13 -20 -17 -16 -17 -15 -11 -10 -4 -2.1 -0.06 1.64 2.26 2.8 0.0
g 9 0 8 8 8 8 8 8 8 8 8 5 3 4 4 8 8 7 5 5 4 4 5.0 5.58 5.50 5.33 5.0 0.0
g 9 1 10 10 10 10 10 10 10 10 10 -21 -7 9 6 10 10 10 10 10 9 9 9.4 9.76 9.45 8.83 8.4 0.0
h 9 1 -20 -20 -20 -20 -20 -20 -20 -20 -21 -27 -24 -11 -18 -22 -21 -21 -21 -21 -20 -20 -19.7 -20.11 -20.54 -21.77 -23.4 0.0
g 9 2 1 1 1 1 1 1 1 1 1 1 -1 -4 0 2 2 2 1 1 1 3 3.0 3.58 3.45 3.02 2.9 0.0
h 9 2 14 14 14 14 14 14 14 15 15 17 19 12 12 15 16 16 16 15 15 15 13.4 12.69 11.51 10.76 11.0 0.0
g 9 3 -11 -11 -11 -11 -11 -11 -12 -12 -12 -11 -25 -5 -9 -13 -12 -12 -12 -12 -12 -10 -8.4 -6.94 -5.27 -3.22 -1.5 0.0
h 9 3 5 5 5 5 5 5 5 5 5 29 12 7 2 7 6 7 9 9 11 12 12.5 12.67 12.75 11.74 9.8 0.0
g 9 4 12 12 12 12 12 12 12 11 11 3 10 2 1 10 10 10 9 9 9 8 6.3 5.01 3.13 0.67 -1.1 0.0
h 9 4 -3 -3 -3 -3 -3 -3 -3 -3 -3 -9 2 6 0 -4 -4 -4 -5 -6 -7 -6 -6.2 -6.72 -7.14 -6.74 -5.1 0.0
g 9 5 1 1 1 1 1 1 1 1 1 16 5 4 4 -1 -1 -1 -3 -3 -4 -8 -8.9 -10.76 -12.38 -13.20 -13.2 0.0
h 9 5 -2 -2 -2 -2 -2 -2 -2 -3 -3 4 2 -2 -3 -5 -5 -5 -6 -6 -7 -8 -8.4 -8.16 -7.42 -6.88 -6.3 0.0
g 9 6 -2 -2 -2 -2 -2 -2 -2 -2 -2 -3 -5 1 -1 -1 0 -1 -1 -1 -2 -1 -1.5 -1.25 -0.76 -0.10 1.1 0.0
h 9 6 8 8 8 8 9 9 9 9 9 9 8 10 9 10 10 10 9 9 9 8 8.4 8.10 7.97 7.79 7.8 0.0
g 9 7 2 2 2 2 2 2 3 3 3 -4 -2 2 -2 5 3 4 7 7 7 10 9.3 8.76 8.43 8.68 8.8 0.0
h 9 7 10 10 10 10 10 10 10 11 11 6 8 7 8 10 11 11 10 9 8 5 3.8 2.92 2.14 1.04 0.4 0.0
g 9 8 -1 0 0 0 0 0 0 0 1 -3 3 2 3 1 1 1 2 1 1 -2 -4.3 -6.66 -8.42 -9.06 -9.3 0.0
h 9 8 -2 -2 -2 -2 -2 -2 -2 -2 -2 1 -11 -6 0 -4 -2 -3 -6 -7 -7 -8 -8.2 -7.73 -6.08 -3.89 -1.4 0.0
g 9 9 -1 -1 -1 -1 -1 -1 -2 -2 -2 -4 8 5 -1 -2 -1 -2 -5 -5 -6 -8 -8.2 -9.22 -10.08 -10.54 -11.9 0.0
h 9 9 2 2 2 2 2 2 2 2 2 8 -7 5 5 1 1 1 2 2 2 3 4.8 6.01 7.01 8.44 9.6 0.0
g 10 0 -3 -3 -3 -3 -3 -3 -3 -3 -3 -3 -8 -3 1 -2 -3 -3 -4 -4 -3 -3 -2.6 -2.17 -1.94 -2.01 -1.9 0.0
g 10 1 -4 -4 -4 -4 -4 -4 -4 -4 -4 11 4 -5 -3 -3 -3 -3 -4 -4 -4 -6 -6.0 -6.12 -6.24 -6.26 -6.2 0.0
h 10 1 2 2 2 2 2 2 2 2 2 5 13 -4 4 2 1 1 1 1 2 1 1.7 2.19 2.73 3.28 3.4 0.0
g 10 2 2 2 2 2 2 2 2 2 2 1 -1 -1 4 2 2 2 2 3 2 2 1.7 1.42 0.89 0.17 -0.1 0.0
h 10 2 1 1 1 1 1 1 1 1 1 1 -2 0 1 1 1 1 0 0 1 0 0.0 0.10 -0.10 -0.40 -0.2 0.0
g 10 3 -5 -5 -5 -5 -5 -5 -5 -5 -5 2 13 2 0 -5 -5 -5 -5 -5 -5 -4 -3.1 -2.35 -1.07 0.55 1.7 0.0
h 10 3 2 2 2 2 2 2 2 2 2 -20 -10 -8 0 2 3 3 3 3 3 4 4.0 4.46 4.71 4.55 3.6 0.0
g 10 4 -2 -2 -2 -2 -2 -2 -2 -2 -2 -5 -4 -3 -1 -2 -1 -2 -2 -2 -2 -1 -0.5 -0.15 -0.16 -0.55 -0.9 0.0
h 10 4 6 6 6 6 6 6 6 6 6 -1 2 -2 2 6 4 4 6 6 6 5 4.9 4.76 4.44 4.40 4.8 0.0
g 10 5 6 6 6 6 6 6 6 6 6 -1 4 7 4 4 6 5 5 5 4 4 3.7 3.06 2.45 1.70 0.7 0.0
h 10 5 -4 -4 -4 -4 -4 -4 -4 -4 -4 -6 -3 -4 -5 -4 -4 -4 -4 -4 -4 -5 -5.9 -6.58 -7.22 -7.92 -8.6 0.0
g 10 6 4 4 4 4 4 4 4 4 4 8 12 4 6 4 4 4 3 3 3 2 1.0 0.29 -0.33 -0.67 -0.9 0.0
h 10 6 0 0 0 0 0 0 0 0 0 6 6 1 1 0 0 -1 0 0 0 -1 -1.2 -1.01 -0.96 -0.61 -0.1 0.0
g 10 7 0 0 0 0 0 0 0 0 0 -1 3 -2 1 0 1 1 1 1 1 2 2.0 2.06 2.13 2.13 1.9 0.0
h 10 7 -2 -2 -2 -2 -2 -2 -2 -1 -1 -4 -3 -3 -1 -2 -1 -1 -1 -1 -2 -2 -2.9 -3.47 -3.95 -4.16 -4.3 0.0
g 10 8 2 2 2 1 1 1 1 2 2 -3 2 6 -1 2 0 0 2 2 3 5 4.2 3.77 3.09 2.33 1.4 0.0
h 10 8 4 4 4 4 4 4 4 4 4 -2 6 7 6 3 3 3 4 4 3 1 0.2 -0.86 -1.99 -2.85 -3.4 0.0
g 10 9 2 2 2 2 3 3 3 3 3 5 10 -2 2 2 3 3 3 3 3 1 0.3 -0.21 -1.03 -1.80 -2.4 0.0
h 10 9 0 0 0 0 0 0 0 0 0 0 11 -1 0 0 1 1 0 0 -1 -2 -2.2 -2.31 -1.97 -1.12 -0.1 0.0
g 10 10 0 0 0 0 0 0 0 0 0 -2 3 0 0 0 -1 -1 0 0 0 0 -1.1 -2.09 -2.80 -3.59 -3.8 0.0
h 10 10 -6 -6 -6 -6 -6 -6 -6 -6 -6 -2 8 -3 -7 -6 -4 -5 -6 -6 -6 -7 -7.4 -7.93 -8.31 -8.72 -8.8 0.0
g 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2.7 2.95 3.05 3.00 3.0 0.0
g 11 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1.7 -1.60 -1.48 -1.40 -1.4 0.0
h 11 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0.26 0.13 0.00 0.0 0.0
g 11 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1.9 -1.88 -2.03 -2.30 -2.5 0.0
h 11 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.3 1.44 1.67 2.11 2.5 0.0
g 11 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.5 1.44 1.65 2.08 2.3 0.0
h 11 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.9 -0.77 -0.66 -0.60 -0.6 0.0
g 11 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.1 -0.31 -0.51 -0.79 -0.9 0.0
h 11 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2.6 -2.27 -1.76 -1.05 -0.4 0.0
g 11 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0.29 0.54 0.58 0.3 0.0
h 11 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9 0.90 0.85 0.76 0.6 0.0
g 11 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.7 -0.79 -0.79 -0.70 -0.7 0.0
h 11 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.7 -0.58 -0.39 -0.20 -0.2 0.0
g 11 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0.53 0.37 0.14 -0.1 0.0
h 11 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2.8 -2.69 -2.51 -2.12 -1.7 0.0
g 11 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.7 1.80 1.79 1.70 1.4 0.0
h 11 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.9 -1.08 -1.27 -1.44 -1.6 0.0
g 11 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0.16 0.12 -0.22 -0.6 0.0
h 11 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1.2 -1.58 -2.11 -2.57 -3.0 0.0
g 11 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.2 0.96 0.75 0.44 0.2 0.0
h 11 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1.9 -1.90 -1.94 -2.01 -2.0 0.0
g 11 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4.0 3.99 3.75 3.49 3.1 0.0
h 11 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.9 -1.39 -1.86 -2.34 -2.6 0.0
g 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2.2 -2.15 -2.12 -2.09 -2.0 0.0
g 12 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.3 -0.29 -0.21 -0.16 -0.1 0.0
h 12 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.55 -0.87 -1.08 -1.2 0.0
g 12 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0.21 0.30 0.46 0.5 0.0
h 12 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.23 0.27 0.37 0.5 0.0
g 12 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9 0.89 1.04 1.23 1.3 0.0
h 12 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2.5 2.38 2.13 1.75 1.4 0.0
g 12 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2 -0.38 -0.63 -0.89 -1.2 0.0
h 12 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2.6 -2.63 -2.49 -2.19 -1.8 0.0
g 12 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9 0.96 0.95 0.85 0.7 0.0
h 12 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0.61 0.49 0.27 0.1 0.0
g 12 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.5 -0.30 -0.11 0.10 0.3 0.0
h 12 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.40 0.59 0.72 0.8 0.0
g 12 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.46 0.52 0.54 0.5 0.0
h 12 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0 0.01 0.00 -0.09 -0.2 0.0
g 12 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.3 -0.35 -0.39 -0.37 -0.3 0.0
h 12 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0 0.02 0.13 0.29 0.6 0.0
g 12 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.36 -0.37 -0.43 -0.5 0.0
h 12 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.28 0.27 0.23 0.2 0.0
g 12 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.1 0.08 0.21 0.22 0.1 0.0
h 12 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.9 -0.87 -0.86 -0.89 -0.9 0.0
g 12 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2 -0.49 -0.77 -0.94 -1.1 0.0
h 12 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.34 -0.23 -0.16 0.0 0.0
g 12 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.08 0.04 -0.03 -0.3 0.0
h 12 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.8 0.88 0.87 0.72 0.5 0.0
g 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2 -0.16 -0.09 -0.02 0.1 0.0
g 13 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.9 -0.88 -0.89 -0.92 -0.9 0.0
h 13 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.9 -0.76 -0.87 -0.88 -0.9 0.0
g 13 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.30 0.31 0.42 0.5 0.0
h 13 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0.33 0.30 0.49 0.6 0.0
g 13 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0.28 0.42 0.63 0.7 0.0
h 13 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.8 1.72 1.66 1.56 1.4 0.0
g 13 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.43 -0.45 -0.42 -0.3 0.0
h 13 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.54 -0.59 -0.50 -0.4 0.0
g 13 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.3 1.18 1.08 0.96 0.8 0.0
h 13 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1.0 -1.07 -1.14 -1.24 -1.3 0.0
g 13 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.37 -0.31 -0.19 0.0 0.0
h 13 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.1 -0.04 -0.07 -0.10 -0.1 0.0
g 13 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0.75 0.78 0.81 0.8 0.0
h 13 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0.63 0.54 0.42 0.3 0.0
g 13 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.4 -0.26 -0.18 -0.13 0.0 0.0
h 13 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.21 0.10 -0.04 -0.1 0.0
g 13 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.35 0.38 0.38 0.4 0.0
h 13 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0.53 0.49 0.48 0.5 0.0
g 13 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.1 -0.05 0.02 0.08 0.1 0.0
h 13 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.38 0.44 0.48 0.5 0.0
g 13 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0.41 0.42 0.46 0.5 0.0
h 13 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2 -0.22 -0.25 -0.30 -0.4 0.0
g 13 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0 -0.10 -0.26 -0.35 -0.5 0.0
h 13 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.5 -0.57 -0.53 -0.43 -0.4 0.0
g 13 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 -0.18 -0.26 -0.36 -0.4 0.0
h 13 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.9 -0.82 -0.79 -0.71 -0.6 0.0

File diff suppressed because one or more lines are too long

469
scratch/c_legendrecoefs.c Normal file
View File

@ -0,0 +1,469 @@
static const int amslegendre_ndegree = 20;
static const int amslegendre_maxporder = 20;
static const float amslegendrecoefsf[] = {
1.0000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.0000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1.0000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.50000000,0,1.5000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.7320508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.86602540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-1.5000000,0,2.5000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.61237244,0,3.0618622,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.9364917,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.79056942,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.37500000,0,-3.7500000,0,4.3750000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.3717082,0,5.5339859,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.55901699,0,3.9131190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.0916501,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.73950997,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.8750000,0,-8.7500000,0,7.8750000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.48412292,0,-6.7777209,0,10.166581,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.5617377,0,7.6852131,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.52291252,0,4.7062126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.2185299,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.70156076,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.31250000,0,6.5625000,0,-19.687500,0,14.437500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.8641098,0,-17.184659,0,18.903125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.45285552,0,-8.1513994,0,14.944232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.7171331,0,9.9628215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.49607837,0,5.4568621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.3268138,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.67169329,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.1875000,0,19.687500,0,-43.312500,0,26.812500,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.41339864,0,11.161763,0,-40.926466,0,35.469604,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.0378472,0,-22.277546,0,28.960810,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.42961647,0,-9.4515624,0,20.478385,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.8497533,0,12.348931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.47495888,0,6.1744654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.4218246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.64725985,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.27343750,0,-9.8437500,0,54.140625,0,-93.843750,0,50.273438,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.2812500,0,36.093750,0,-93.843750,0,67.031250,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.39218439,0,12.942085,0,-56.082367,0,56.082367,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.1861210,0,-27.613049,0,41.419573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.41132646,0,-10.694488,0,26.736220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.9661173,0,14.830586,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.45768183,0,6.8652274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.5068266,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.62670665,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.4609375,0,-36.093750,0,140.76562,0,-201.09375,0,94.960938,0,0,0,0,0,0,0,0,0,0,0,
0.36685490,0,-16.141616,0,104.92050,0,-209.84100,0,127.40347,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.4414040,0,44.738252,0,-134.21476,0,108.65004,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.37548796,0,14.644031,0,-73.220153,0,82.982840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.3162199,0,-33.162199,0,56.375738,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.39636409,0,-11.890923,0,33.690948,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.0702230,0,17.397931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.44314853,0,7.5335249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.5839777,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.60904939,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.24609375,0,13.535156,0,-117.30469,0,351.91406,0,-427.32422,0,180.42578,0,0,0,0,0,0,0,0,0,0,
0,3.6501602,0,-63.269443,0,284.71250,0,-460.96309,0,243.28607,0,0,0,0,0,0,0,0,0,0,0,
0.35123683,0,-18.264315,0,136.98236,0,-310.49336,0,210.69192,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.5819269,0,53.728903,0,-182.67827,0,165.28034,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.36182926,0,16.282316,0,-92.266460,0,116.87085,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.4326137,0,-38.902955,0,73.915615,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.38377788,0,-13.048448,0,41.320085,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.1647135,0,20.043185,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.43066296,0,8.1825962,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.6547848,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.59362792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.7070312,0,58.652344,0,-351.91406,0,854.64844,0,-902.12891,0,344.44922,0,0,0,0,0,0,0,0,0,
-0.33321251,0,21.658813,0,-216.58813,0,736.39965,0,-999.39953,0,466.38645,0,0,0,0,0,0,0,0,0,0,
0,3.7992072,0,-75.984144,0,387.51913,0,-701.22510,0,409.04797,0,0,0,0,0,0,0,0,0,0,0,
0.33846028,0,-20.307617,0,172.61474,0,-437.29068,0,327.96801,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.7076466,0,63.029992,0,-239.51397,0,239.51397,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.35033967,0,17.867323,0,-113.15971,0,158.42360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.5382572,0,-44.817925,0,94.117642,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.37296506,0,-14.172672,0,49.604353,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.2514340,0,22.760038,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.41975833,0,8.8149248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.7203449,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.57997947,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.22558594,0,-17.595703,0,219.94629,0,-997.08984,0,2029.7900,0,-1894.4707,0,660.19434,0,0,0,0,0,0,0,0,
0,-3.9846421,0,99.616053,0,-677.38916,0,1838.6277,0,-2145.0657,0,897.02746,0,0,0,0,0,0,0,0,0,
-0.32109161,0,24.081871,0,-272.92787,0,1037.1259,0,-1555.6889,0,795.12986,0,0,0,0,0,0,0,0,0,0,
0,3.9325530,0,-89.137869,0,508.08585,0,-1016.1717,0,649.22081,0,0,0,0,0,0,0,0,0,0,0,
0.32771275,0,-22.284467,0,211.70244,0,-592.76683,0,486.91561,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.8217546,0,72.613337,0,-304.97602,0,334.02135,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.34046896,0,19.406731,0,-135.84712,0,208.29891,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.6352137,0,-50.892992,0,117.05388,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.36352137,0,-15.267898,0,58.526941,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.3317284,0,25.543251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.41010742,0,9.4324706,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.7814838,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.56776801,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.9326172,0,-87.978516,0,747.81738,0,-2706.3867,0,4736.1768,0,-3961.1660,0,1269.6045,0,0,0,0,0,0,0,
0.30742181,0,-27.667963,0,391.96281,0,-1985.9449,0,4468.3761,0,-4567.6733,0,1730.1793,0,0,0,0,0,0,0,0,
0,-4.1244964,0,116.86073,0,-888.14156,0,2664.4247,0,-3404.5427,0,1547.5194,0,0,0,0,0,0,0,0,0,
-0.31089562,0,26.426127,0,-334.73095,0,1405.8700,0,-2309.6435,0,1283.1353,0,0,0,0,0,0,0,0,0,0,
0,4.0535829,0,-102.69077,0,646.95183,0,-1417.1326,0,984.11985,0,0,0,0,0,0,0,0,0,0,0,
0.31847955,0,-24.204446,0,254.14668,0,-779.38316,0,695.87782,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.9264796,0,82.456072,0,-379.29793,0,451.54515,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.33184809,0,20.906430,0,-160.28263,0,267.13772,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.7249856,0,-57.116446,0,142.79112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.35516344,0,-16.337518,0,68.072993,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.4066081,0,28.388401,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.40147261,0,10.036815,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.8388401,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.55674234,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.20947266,0,21.994629,0,-373.90869,0,2368.0884,0,-7104.2651,0,10893.207,0,-8252.4292,0,2448.5229,0,0,0,0,0,0,
0,4.2929120,0,-145.95901,0,1386.6106,0,-5546.4423,0,10630.681,0,-9664.2555,0,3345.3192,0,0,0,0,0,0,0,
0.29765989,0,-30.361309,0,480.72072,0,-2692.0360,0,6633.9460,0,-7371.0511,0,3015.4300,0,0,0,0,0,0,0,0,
0,-4.2514336,0,134.62873,0,-1130.8813,0,3715.7530,0,-5160.7680,0,2533.4679,0,0,0,0,0,0,0,0,0,
-0.30213623,0,28.702942,0,-401.84119,0,1848.4695,0,-3300.8383,0,1980.5030,0,0,0,0,0,0,0,0,0,0,
0,4.1646605,0,-116.61049,0,804.61241,0,-1915.7438,0,1436.8079,0,0,0,0,0,0,0,0,0,0,0,
0.31041547,0,-26.074899,0,299.86134,0,-999.53781,0,963.84003,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.0234443,0,92.539219,0,-462.69610,0,594.89498,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.32421838,0,22.371068,0,-186.42557,0,335.56603,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.8087036,0,-63.478394,0,171.39166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.34768548,0,-17.384274,0,78.229233,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.4768548,0,31.291693,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.39367628,0,10.629260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.8929181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.54671013,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.1420898,0,124.63623,0,-1420.8530,0,7104.2651,0,-18155.344,0,24757.288,0,-17139.661,0,4733.8110,0,0,0,0,0,
-0.28683225,0,34.133037,0,-648.52771,0,4539.6940,0,-14916.137,0,24860.229,0,-20340.187,0,6482.0377,0,0,0,0,0,0,
0,4.4250324,0,-168.15123,0,1765.5879,0,-7734.9566,0,16114.493,0,-15821.502,0,5882.3534,0,0,0,0,0,0,0,
0.28927342,0,-32.977170,0,577.10047,0,-3539.5495,0,9480.9362,0,-11377.123,0,4999.0391,0,0,0,0,0,0,0,0,
0,-4.3679328,0,152.87765,0,-1406.4744,0,5023.1227,0,-7534.6841,0,3972.8334,0,0,0,0,0,0,0,0,0,
-0.29448597,0,30.921027,0,-474.12241,0,2370.6121,0,-4571.8947,0,2946.3321,0,0,0,0,0,0,0,0,0,0,
0,4.2675071,0,-130.87022,0,981.52664,0,-2523.9257,0,2033.1623,0,0,0,0,0,0,0,0,0,0,0,
0.30327853,0,-27.901624,0,348.77031,0,-1255.5731,0,1300.4150,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.1138701,0,102.84675,0,-555.37246,0,766.94292,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.31739197,0,23.804398,0,-214.23958,0,414.19652,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.8872418,0,-69.970353,0,202.91402,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.34093366,0,-18.410418,0,88.983686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.5430866,0,34.249837,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.38658244,0,11.210891,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.9441241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.53752107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.19638062,0,-26.707764,0,592.02209,0,-4972.9856,0,20424.762,0,-45388.361,0,55703.897,0,-35503.583,0,9171.7589,0,0,0,0,
0,-4.5803437,0,203.06190,0,-2558.5800,0,14011.271,0,-38920.198,0,57318.837,0,-42621.699,0,12583.549,0,0,0,0,0,
-0.27875084,0,37.073862,0,-778.55109,0,5968.8917,0,-21317.470,0,38371.447,0,-33720.362,0,11487.156,0,0,0,0,0,0,
0,4.5462886,0,-190.94412,0,2195.8574,0,-10456.464,0,23527.044,0,-24810.337,0,9860.5185,0,0,0,0,0,0,0,
0.28194885,0,-35.525555,0,680.90647,0,-4539.3765,0,13131.768,0,-16925.389,0,7949.8042,0,0,0,0,0,0,0,0,
0,-4.4757992,0,171.57230,0,-1715.7230,0,6617.7889,0,-10661.993,0,6009.4871,0,0,0,0,0,0,0,0,0,
-0.28771527,0,33.087256,0,-551.45427,0,2977.8531,0,-6168.4099,0,4249.3491,0,0,0,0,0,0,0,0,0,0,
0,4.3634182,0,-145.44727,0,1178.1229,0,-3253.8632,0,2801.9378,0,0,0,0,0,0,0,0,0,0,0,
0.29689300,0,-29.689300,0,400.80555,0,-1549.7815,0,1715.8295,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.1987011,0,113.36493,0,-657.51659,0,970.61973,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.31122843,0,25.209503,0,-243.69186,0,503.62985,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.9612912,0,-76.584963,0,237.41339,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.33479021,0,-19.417832,0,100.32547,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.6058009,0,37.259943,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.38008479,0,11.782629,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.9927906,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.52905564,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.3384705,0,-169.14917,0,2486.4928,0,-16339.810,0,56735.451,0,-111407.79,0,124262.54,0,-73374.071,0,17804.003,0,0,0,
0.26989934,0,-41.024700,0,1005.1051,0,-9246.9673,0,41281.104,0,-99074.650,0,130598.40,0,-88979.131,0,24469.261,0,0,0,0,
0,-4.7058558,0,230.58693,0,-3182.0997,0,18941.070,0,-56823.209,0,89883.985,0,-71446.244,0,22454.534,0,0,0,0,0,
-0.27169271,0,39.938828,0,-918.59305,0,7654.9421,0,-29526.205,0,57083.997,0,-53624.361,0,19446.197,0,0,0,0,0,0,
0,4.6585596,0,-214.29374,0,2678.6717,0,-13776.026,0,33292.063,0,-37529.235,0,15877.753,0,0,0,0,0,0,0,
0.27546640,0,-38.014363,0,791.96590,0,-5702.1545,0,17717.409,0,-24410.652,0,12205.326,0,0,0,0,0,0,0,0,
0,-4.5763916,0,190.68298,0,-2059.3762,0,8531.7014,0,-14693.486,0,8816.0915,0,0,0,0,0,0,0,0,0,
-0.28165743,0,35.207179,0,-633.72922,0,3675.6295,0,-8138.8938,0,5968.5221,0,0,0,0,0,0,0,0,0,0,
0,4.4533950,0,-160.32222,0,1394.8033,0,-4117.9907,0,3774.8248,0,0,0,0,0,0,0,0,0,0,0,
0.29112754,0,-31.441774,0,455.90573,0,-1884.4103,0,2220.9122,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.2786835,0,124.08182,0,-769.30730,0,1208.9115,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.30562025,0,26.588962,0,-274.75261,0,604.45573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.0314080,0,-83.315765,0,274.94203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.32916308,0,-20.408111,0,112.24461,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.6654050,0,40.319455,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.37409883,0,12.345261,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.0391933,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.52121734,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.18547058,0,31.715469,0,-888.03314,0,9531.5557,0,-51061.906,0,153185.72,0,-269235.50,0,275152.77,0,-151334.02,0,34618.894,0,0,
0,4.8506851,0,-271.63837,0,4373.3777,0,-31238.412,0,117144.05,0,-247067.44,0,294580.41,0,-185164.83,0,47652.714,0,0,0,
0.26306534,0,-44.194976,0,1185.8985,0,-11858.985,0,57177.251,0,-147390.25,0,207686.26,0,-150629.59,0,43933.631,0,0,0,0,
0,-4.8220673,0,258.78428,0,-3881.7641,0,24954.198,0,-80407.972,0,135962.57,0,-115045.25,0,38348.417,0,0,0,0,0,
-0.26544607,0,42.736817,0,-1068.4204,0,9615.7837,0,-39836.818,0,82329.425,0,-82329.425,0,31665.163,0,0,0,0,0,0,
0,4.7632594,0,-238.16297,0,3215.2001,0,-17760.153,0,45880.395,0,-55056.474,0,24704.828,0,0,0,0,0,0,0,
0.26966646,0,-40.449969,0,910.12430,0,-7038.2946,0,23377.193,0,-34286.549,0,18182.261,0,0,0,0,0,0,0,0,
0,-4.6707601,0,210.18420,0,-2438.1368,0,10797.463,0,-19795.348,0,12597.040,0,0,0,0,0,0,0,0,0,
-0.27618783,0,37.285358,0,-720.85025,0,4469.2715,0,-10534.711,0,8193.6645,0,0,0,0,0,0,0,0,0,0,
0,4.5382292,0,-175.47820,0,1631.9472,0,-5128.9770,0,4986.5054,0,0,0,0,0,0,0,0,0,0,0,
0.28588157,0,-33.162262,0,514.01506,0,-2261.6663,0,2827.0828,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.3544183,0,134.98697,0,-890.91399,0,1484.8566,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.30048341,0,27.944957,0,-307.39453,0,717.25390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.0980474,0,-90.157042,0,315.54965,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.32397909,0,-21.382620,0,124.73195,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.7222364,0,43.426091,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.36855632,0,12.899471,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.0835634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.51392723,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.5239410,0,222.00829,0,-4084.9525,0,34041.270,0,-153185.72,0,403853.25,0,-642023.12,0,605336.09,0,-311570.04,0,67415.741,0,
-0.25565355,0,48.318522,0,-1481.7680,0,17287.293,0,-100019.34,0,322284.54,0,-605504.28,0,658735.43,0,-384262.33,0,92926.185,0,0,
0,4.9704732,0,-304.85569,0,5334.9745,0,-41155.518,0,165765.28,0,-373725.36,0,474343.72,0,-316229.15,0,86032.930,0,0,0,
0.25701705,0,-47.291137,0,1379.3248,0,-14896.708,0,77143.667,0,-212573.66,0,318860.49,0,-245277.30,0,75627.168,0,0,0,0,
0,-4.9304419,0,287.60911,0,-4659.2675,0,32171.133,0,-110811.68,0,199461.03,0,-179003.48,0,63077.418,0,0,0,0,0,
-0.25985710,0,45.474993,0,-1227.8248,0,11868.973,0,-52562.595,0,115637.71,0,-122646.06,0,49867.078,0,0,0,0,0,0,
0,4.8614812,0,-262.51999,0,3806.5398,0,-22476.711,0,61810.956,0,-78668.489,0,37317.104,0,0,0,0,0,0,0,
0.26442972,0,-42.837614,0,1035.2423,0,-8558.0034,0,30258.655,0,-47069.019,0,26387.177,0,0,0,0,0,0,0,0,
0,-4.7597349,0,230.05386,0,-2852.6678,0,13448.291,0,-26149.455,0,17591.451,0,0,0,0,0,0,0,0,0,
-0.27121107,0,39.325605,0,-812.72917,0,5364.0125,0,-13410.031,0,11026.026,0,0,0,0,0,0,0,0,0,0,
0,4.6185581,0,-190.90040,0,1889.9140,0,-6299.7132,0,6474.7052,0,0,0,0,0,0,0,0,0,0,0,
0.28107649,0,-34.853485,0,575.08251,0,-2683.7184,0,3546.3421,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.4263970,0,146.07110,0,-1022.4977,0,1801.5436,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.29575109,0,29.279358,0,-341.59251,0,842.59486,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.1615868,0,-97.103691,0,359.28366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.31917913,0,-22.342539,0,137.77899,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.7765784,0,46.577801,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.36340143,0,13.445853,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.1260973,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.50711995,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.17619705,0,-37.001381,0,1276.5476,0,-17020.635,0,114889.29,0,-444238.58,0,1043287.6,0,-1513340.2,0,1324172.7,0,-640449.54,0,131460.69,
0,-5.1066757,0,352.36062,0,-7047.2125,0,63424.912,0,-306553.74,0,863924.19,0,-1462025.5,0,1462025.5,0,-795513.90,0,181432.99,0,
-0.24977567,0,51.703565,0,-1723.4522,0,21715.497,0,-134946.30,0,464815.05,0,-929630.09,0,1072650.1,0,-661467.56,0,168609.38,0,0,
0,5.0821831,0,-338.81221,0,6403.5507,0,-53057.992,0,228444.13,0,-548265.92,0,738050.27,0,-520149.72,0,149160.58,0,0,0,
0.25160556,0,-50.321111,0,1585.1150,0,-18387.334,0,101787.03,0,-298575.28,0,475006.13,0,-386268.72,0,125537.33,0,0,0,0,
0,-5.0321111,0,317.02300,0,-5516.2002,0,40714.811,0,-149287.64,0,285003.68,0,-270388.11,0,100429.87,0,0,0,0,0,
-0.25481085,0,48.159251,0,-1396.6183,0,14431.722,0,-68035.262,0,158748.94,0,-177991.24,0,76281.961,0,0,0,0,0,0,
0,4.9540892,0,-287.33717,0,4453.7262,0,-27994.850,0,81651.647,0,-109858.58,0,54929.290,0,0,0,0,0,0,0,
0.25966483,0,-45.181680,0,1167.1934,0,-10271.302,0,38517.382,0,-63339.695,0,37428.002,0,0,0,0,0,0,0,0,
0,-4.8439846,0,250.27254,0,-3303.5975,0,16517.987,0,-33953.641,0,24076.218,0,0,0,0,0,0,0,0,0,
-0.26665257,0,41.331149,0,-909.28528,0,6364.9970,0,-16821.778,0,14578.874,0,0,0,0,0,0,0,0,0,0,
0,4.6949030,0,-206.57573,0,2169.0452,0,-7643.3022,0,8280.2440,0,0,0,0,0,0,0,0,0,0,0,
0.27664982,0,-36.517776,0,639.06107,0,-3152.7013,0,4391.2625,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.4950274,0,157.32596,0,-1164.2121,0,2162.1082,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.29136935,0,30.593782,0,-377.32331,0,981.04061,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.2223431,0,-104.15113,0,406.18940,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.31471487,0,-23.288900,0,151.37785,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.8286716,0,49.772731,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.35858795,0,13.984930,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.1669631,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.50074083,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
static const double amslegendrecoefs[] = {
1.0000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.0000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1.0000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.50000000,0,1.5000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.7320508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.86602540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-1.5000000,0,2.5000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.61237244,0,3.0618622,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.9364917,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.79056942,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.37500000,0,-3.7500000,0,4.3750000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.3717082,0,5.5339859,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.55901699,0,3.9131190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.0916501,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.73950997,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1.8750000,0,-8.7500000,0,7.8750000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.48412292,0,-6.7777209,0,10.166581,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.5617377,0,7.6852131,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.52291252,0,4.7062126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.2185299,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.70156076,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.31250000,0,6.5625000,0,-19.687500,0,14.437500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.8641098,0,-17.184659,0,18.903125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.45285552,0,-8.1513994,0,14.944232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.7171331,0,9.9628215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.49607837,0,5.4568621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.3268138,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.67169329,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.1875000,0,19.687500,0,-43.312500,0,26.812500,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.41339864,0,11.161763,0,-40.926466,0,35.469604,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.0378472,0,-22.277546,0,28.960810,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.42961647,0,-9.4515624,0,20.478385,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.8497533,0,12.348931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.47495888,0,6.1744654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.4218246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.64725985,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.27343750,0,-9.8437500,0,54.140625,0,-93.843750,0,50.273438,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.2812500,0,36.093750,0,-93.843750,0,67.031250,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.39218439,0,12.942085,0,-56.082367,0,56.082367,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.1861210,0,-27.613049,0,41.419573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.41132646,0,-10.694488,0,26.736220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.9661173,0,14.830586,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.45768183,0,6.8652274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.5068266,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.62670665,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.4609375,0,-36.093750,0,140.76562,0,-201.09375,0,94.960938,0,0,0,0,0,0,0,0,0,0,0,
0.36685490,0,-16.141616,0,104.92050,0,-209.84100,0,127.40347,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.4414040,0,44.738252,0,-134.21476,0,108.65004,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.37548796,0,14.644031,0,-73.220153,0,82.982840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.3162199,0,-33.162199,0,56.375738,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.39636409,0,-11.890923,0,33.690948,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.0702230,0,17.397931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.44314853,0,7.5335249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.5839777,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.60904939,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.24609375,0,13.535156,0,-117.30469,0,351.91406,0,-427.32422,0,180.42578,0,0,0,0,0,0,0,0,0,0,
0,3.6501602,0,-63.269443,0,284.71250,0,-460.96309,0,243.28607,0,0,0,0,0,0,0,0,0,0,0,
0.35123683,0,-18.264315,0,136.98236,0,-310.49336,0,210.69192,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.5819269,0,53.728903,0,-182.67827,0,165.28034,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.36182926,0,16.282316,0,-92.266460,0,116.87085,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.4326137,0,-38.902955,0,73.915615,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.38377788,0,-13.048448,0,41.320085,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.1647135,0,20.043185,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.43066296,0,8.1825962,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.6547848,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.59362792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-2.7070312,0,58.652344,0,-351.91406,0,854.64844,0,-902.12891,0,344.44922,0,0,0,0,0,0,0,0,0,
-0.33321251,0,21.658813,0,-216.58813,0,736.39965,0,-999.39953,0,466.38645,0,0,0,0,0,0,0,0,0,0,
0,3.7992072,0,-75.984144,0,387.51913,0,-701.22510,0,409.04797,0,0,0,0,0,0,0,0,0,0,0,
0.33846028,0,-20.307617,0,172.61474,0,-437.29068,0,327.96801,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.7076466,0,63.029992,0,-239.51397,0,239.51397,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.35033967,0,17.867323,0,-113.15971,0,158.42360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.5382572,0,-44.817925,0,94.117642,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.37296506,0,-14.172672,0,49.604353,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.2514340,0,22.760038,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.41975833,0,8.8149248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.7203449,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.57997947,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.22558594,0,-17.595703,0,219.94629,0,-997.08984,0,2029.7900,0,-1894.4707,0,660.19434,0,0,0,0,0,0,0,0,
0,-3.9846421,0,99.616053,0,-677.38916,0,1838.6277,0,-2145.0657,0,897.02746,0,0,0,0,0,0,0,0,0,
-0.32109161,0,24.081871,0,-272.92787,0,1037.1259,0,-1555.6889,0,795.12986,0,0,0,0,0,0,0,0,0,0,
0,3.9325530,0,-89.137869,0,508.08585,0,-1016.1717,0,649.22081,0,0,0,0,0,0,0,0,0,0,0,
0.32771275,0,-22.284467,0,211.70244,0,-592.76683,0,486.91561,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.8217546,0,72.613337,0,-304.97602,0,334.02135,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.34046896,0,19.406731,0,-135.84712,0,208.29891,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.6352137,0,-50.892992,0,117.05388,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.36352137,0,-15.267898,0,58.526941,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.3317284,0,25.543251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.41010742,0,9.4324706,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.7814838,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.56776801,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.9326172,0,-87.978516,0,747.81738,0,-2706.3867,0,4736.1768,0,-3961.1660,0,1269.6045,0,0,0,0,0,0,0,
0.30742181,0,-27.667963,0,391.96281,0,-1985.9449,0,4468.3761,0,-4567.6733,0,1730.1793,0,0,0,0,0,0,0,0,
0,-4.1244964,0,116.86073,0,-888.14156,0,2664.4247,0,-3404.5427,0,1547.5194,0,0,0,0,0,0,0,0,0,
-0.31089562,0,26.426127,0,-334.73095,0,1405.8700,0,-2309.6435,0,1283.1353,0,0,0,0,0,0,0,0,0,0,
0,4.0535829,0,-102.69077,0,646.95183,0,-1417.1326,0,984.11985,0,0,0,0,0,0,0,0,0,0,0,
0.31847955,0,-24.204446,0,254.14668,0,-779.38316,0,695.87782,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.9264796,0,82.456072,0,-379.29793,0,451.54515,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.33184809,0,20.906430,0,-160.28263,0,267.13772,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.7249856,0,-57.116446,0,142.79112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.35516344,0,-16.337518,0,68.072993,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.4066081,0,28.388401,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.40147261,0,10.036815,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.8388401,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.55674234,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.20947266,0,21.994629,0,-373.90869,0,2368.0884,0,-7104.2651,0,10893.207,0,-8252.4292,0,2448.5229,0,0,0,0,0,0,
0,4.2929120,0,-145.95901,0,1386.6106,0,-5546.4423,0,10630.681,0,-9664.2555,0,3345.3192,0,0,0,0,0,0,0,
0.29765989,0,-30.361309,0,480.72072,0,-2692.0360,0,6633.9460,0,-7371.0511,0,3015.4300,0,0,0,0,0,0,0,0,
0,-4.2514336,0,134.62873,0,-1130.8813,0,3715.7530,0,-5160.7680,0,2533.4679,0,0,0,0,0,0,0,0,0,
-0.30213623,0,28.702942,0,-401.84119,0,1848.4695,0,-3300.8383,0,1980.5030,0,0,0,0,0,0,0,0,0,0,
0,4.1646605,0,-116.61049,0,804.61241,0,-1915.7438,0,1436.8079,0,0,0,0,0,0,0,0,0,0,0,
0.31041547,0,-26.074899,0,299.86134,0,-999.53781,0,963.84003,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.0234443,0,92.539219,0,-462.69610,0,594.89498,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.32421838,0,22.371068,0,-186.42557,0,335.56603,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.8087036,0,-63.478394,0,171.39166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.34768548,0,-17.384274,0,78.229233,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.4768548,0,31.291693,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.39367628,0,10.629260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.8929181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.54671013,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.1420898,0,124.63623,0,-1420.8530,0,7104.2651,0,-18155.344,0,24757.288,0,-17139.661,0,4733.8110,0,0,0,0,0,
-0.28683225,0,34.133037,0,-648.52771,0,4539.6940,0,-14916.137,0,24860.229,0,-20340.187,0,6482.0377,0,0,0,0,0,0,
0,4.4250324,0,-168.15123,0,1765.5879,0,-7734.9566,0,16114.493,0,-15821.502,0,5882.3534,0,0,0,0,0,0,0,
0.28927342,0,-32.977170,0,577.10047,0,-3539.5495,0,9480.9362,0,-11377.123,0,4999.0391,0,0,0,0,0,0,0,0,
0,-4.3679328,0,152.87765,0,-1406.4744,0,5023.1227,0,-7534.6841,0,3972.8334,0,0,0,0,0,0,0,0,0,
-0.29448597,0,30.921027,0,-474.12241,0,2370.6121,0,-4571.8947,0,2946.3321,0,0,0,0,0,0,0,0,0,0,
0,4.2675071,0,-130.87022,0,981.52664,0,-2523.9257,0,2033.1623,0,0,0,0,0,0,0,0,0,0,0,
0.30327853,0,-27.901624,0,348.77031,0,-1255.5731,0,1300.4150,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.1138701,0,102.84675,0,-555.37246,0,766.94292,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.31739197,0,23.804398,0,-214.23958,0,414.19652,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.8872418,0,-69.970353,0,202.91402,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.34093366,0,-18.410418,0,88.983686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.5430866,0,34.249837,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.38658244,0,11.210891,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.9441241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.53752107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.19638062,0,-26.707764,0,592.02209,0,-4972.9856,0,20424.762,0,-45388.361,0,55703.897,0,-35503.583,0,9171.7589,0,0,0,0,
0,-4.5803437,0,203.06190,0,-2558.5800,0,14011.271,0,-38920.198,0,57318.837,0,-42621.699,0,12583.549,0,0,0,0,0,
-0.27875084,0,37.073862,0,-778.55109,0,5968.8917,0,-21317.470,0,38371.447,0,-33720.362,0,11487.156,0,0,0,0,0,0,
0,4.5462886,0,-190.94412,0,2195.8574,0,-10456.464,0,23527.044,0,-24810.337,0,9860.5185,0,0,0,0,0,0,0,
0.28194885,0,-35.525555,0,680.90647,0,-4539.3765,0,13131.768,0,-16925.389,0,7949.8042,0,0,0,0,0,0,0,0,
0,-4.4757992,0,171.57230,0,-1715.7230,0,6617.7889,0,-10661.993,0,6009.4871,0,0,0,0,0,0,0,0,0,
-0.28771527,0,33.087256,0,-551.45427,0,2977.8531,0,-6168.4099,0,4249.3491,0,0,0,0,0,0,0,0,0,0,
0,4.3634182,0,-145.44727,0,1178.1229,0,-3253.8632,0,2801.9378,0,0,0,0,0,0,0,0,0,0,0,
0.29689300,0,-29.689300,0,400.80555,0,-1549.7815,0,1715.8295,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.1987011,0,113.36493,0,-657.51659,0,970.61973,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.31122843,0,25.209503,0,-243.69186,0,503.62985,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.9612912,0,-76.584963,0,237.41339,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.33479021,0,-19.417832,0,100.32547,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.6058009,0,37.259943,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.38008479,0,11.782629,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2.9927906,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.52905564,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.3384705,0,-169.14917,0,2486.4928,0,-16339.810,0,56735.451,0,-111407.79,0,124262.54,0,-73374.071,0,17804.003,0,0,0,
0.26989934,0,-41.024700,0,1005.1051,0,-9246.9673,0,41281.104,0,-99074.650,0,130598.40,0,-88979.131,0,24469.261,0,0,0,0,
0,-4.7058558,0,230.58693,0,-3182.0997,0,18941.070,0,-56823.209,0,89883.985,0,-71446.244,0,22454.534,0,0,0,0,0,
-0.27169271,0,39.938828,0,-918.59305,0,7654.9421,0,-29526.205,0,57083.997,0,-53624.361,0,19446.197,0,0,0,0,0,0,
0,4.6585596,0,-214.29374,0,2678.6717,0,-13776.026,0,33292.063,0,-37529.235,0,15877.753,0,0,0,0,0,0,0,
0.27546640,0,-38.014363,0,791.96590,0,-5702.1545,0,17717.409,0,-24410.652,0,12205.326,0,0,0,0,0,0,0,0,
0,-4.5763916,0,190.68298,0,-2059.3762,0,8531.7014,0,-14693.486,0,8816.0915,0,0,0,0,0,0,0,0,0,
-0.28165743,0,35.207179,0,-633.72922,0,3675.6295,0,-8138.8938,0,5968.5221,0,0,0,0,0,0,0,0,0,0,
0,4.4533950,0,-160.32222,0,1394.8033,0,-4117.9907,0,3774.8248,0,0,0,0,0,0,0,0,0,0,0,
0.29112754,0,-31.441774,0,455.90573,0,-1884.4103,0,2220.9122,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.2786835,0,124.08182,0,-769.30730,0,1208.9115,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.30562025,0,26.588962,0,-274.75261,0,604.45573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.0314080,0,-83.315765,0,274.94203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.32916308,0,-20.408111,0,112.24461,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.6654050,0,40.319455,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.37409883,0,12.345261,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.0391933,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.52121734,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.18547058,0,31.715469,0,-888.03314,0,9531.5557,0,-51061.906,0,153185.72,0,-269235.50,0,275152.77,0,-151334.02,0,34618.894,0,0,
0,4.8506851,0,-271.63837,0,4373.3777,0,-31238.412,0,117144.05,0,-247067.44,0,294580.41,0,-185164.83,0,47652.714,0,0,0,
0.26306534,0,-44.194976,0,1185.8985,0,-11858.985,0,57177.251,0,-147390.25,0,207686.26,0,-150629.59,0,43933.631,0,0,0,0,
0,-4.8220673,0,258.78428,0,-3881.7641,0,24954.198,0,-80407.972,0,135962.57,0,-115045.25,0,38348.417,0,0,0,0,0,
-0.26544607,0,42.736817,0,-1068.4204,0,9615.7837,0,-39836.818,0,82329.425,0,-82329.425,0,31665.163,0,0,0,0,0,0,
0,4.7632594,0,-238.16297,0,3215.2001,0,-17760.153,0,45880.395,0,-55056.474,0,24704.828,0,0,0,0,0,0,0,
0.26966646,0,-40.449969,0,910.12430,0,-7038.2946,0,23377.193,0,-34286.549,0,18182.261,0,0,0,0,0,0,0,0,
0,-4.6707601,0,210.18420,0,-2438.1368,0,10797.463,0,-19795.348,0,12597.040,0,0,0,0,0,0,0,0,0,
-0.27618783,0,37.285358,0,-720.85025,0,4469.2715,0,-10534.711,0,8193.6645,0,0,0,0,0,0,0,0,0,0,
0,4.5382292,0,-175.47820,0,1631.9472,0,-5128.9770,0,4986.5054,0,0,0,0,0,0,0,0,0,0,0,
0.28588157,0,-33.162262,0,514.01506,0,-2261.6663,0,2827.0828,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.3544183,0,134.98697,0,-890.91399,0,1484.8566,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.30048341,0,27.944957,0,-307.39453,0,717.25390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.0980474,0,-90.157042,0,315.54965,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.32397909,0,-21.382620,0,124.73195,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.7222364,0,43.426091,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.36855632,0,12.899471,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.0835634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.51392723,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.5239410,0,222.00829,0,-4084.9525,0,34041.270,0,-153185.72,0,403853.25,0,-642023.12,0,605336.09,0,-311570.04,0,67415.741,0,
-0.25565355,0,48.318522,0,-1481.7680,0,17287.293,0,-100019.34,0,322284.54,0,-605504.28,0,658735.43,0,-384262.33,0,92926.185,0,0,
0,4.9704732,0,-304.85569,0,5334.9745,0,-41155.518,0,165765.28,0,-373725.36,0,474343.72,0,-316229.15,0,86032.930,0,0,0,
0.25701705,0,-47.291137,0,1379.3248,0,-14896.708,0,77143.667,0,-212573.66,0,318860.49,0,-245277.30,0,75627.168,0,0,0,0,
0,-4.9304419,0,287.60911,0,-4659.2675,0,32171.133,0,-110811.68,0,199461.03,0,-179003.48,0,63077.418,0,0,0,0,0,
-0.25985710,0,45.474993,0,-1227.8248,0,11868.973,0,-52562.595,0,115637.71,0,-122646.06,0,49867.078,0,0,0,0,0,0,
0,4.8614812,0,-262.51999,0,3806.5398,0,-22476.711,0,61810.956,0,-78668.489,0,37317.104,0,0,0,0,0,0,0,
0.26442972,0,-42.837614,0,1035.2423,0,-8558.0034,0,30258.655,0,-47069.019,0,26387.177,0,0,0,0,0,0,0,0,
0,-4.7597349,0,230.05386,0,-2852.6678,0,13448.291,0,-26149.455,0,17591.451,0,0,0,0,0,0,0,0,0,
-0.27121107,0,39.325605,0,-812.72917,0,5364.0125,0,-13410.031,0,11026.026,0,0,0,0,0,0,0,0,0,0,
0,4.6185581,0,-190.90040,0,1889.9140,0,-6299.7132,0,6474.7052,0,0,0,0,0,0,0,0,0,0,0,
0.28107649,0,-34.853485,0,575.08251,0,-2683.7184,0,3546.3421,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.4263970,0,146.07110,0,-1022.4977,0,1801.5436,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.29575109,0,29.279358,0,-341.59251,0,842.59486,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.1615868,0,-97.103691,0,359.28366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.31917913,0,-22.342539,0,137.77899,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.7765784,0,46.577801,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.36340143,0,13.445853,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.1260973,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.50711995,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.17619705,0,-37.001381,0,1276.5476,0,-17020.635,0,114889.29,0,-444238.58,0,1043287.6,0,-1513340.2,0,1324172.7,0,-640449.54,0,131460.69,
0,-5.1066757,0,352.36062,0,-7047.2125,0,63424.912,0,-306553.74,0,863924.19,0,-1462025.5,0,1462025.5,0,-795513.90,0,181432.99,0,
-0.24977567,0,51.703565,0,-1723.4522,0,21715.497,0,-134946.30,0,464815.05,0,-929630.09,0,1072650.1,0,-661467.56,0,168609.38,0,0,
0,5.0821831,0,-338.81221,0,6403.5507,0,-53057.992,0,228444.13,0,-548265.92,0,738050.27,0,-520149.72,0,149160.58,0,0,0,
0.25160556,0,-50.321111,0,1585.1150,0,-18387.334,0,101787.03,0,-298575.28,0,475006.13,0,-386268.72,0,125537.33,0,0,0,0,
0,-5.0321111,0,317.02300,0,-5516.2002,0,40714.811,0,-149287.64,0,285003.68,0,-270388.11,0,100429.87,0,0,0,0,0,
-0.25481085,0,48.159251,0,-1396.6183,0,14431.722,0,-68035.262,0,158748.94,0,-177991.24,0,76281.961,0,0,0,0,0,0,
0,4.9540892,0,-287.33717,0,4453.7262,0,-27994.850,0,81651.647,0,-109858.58,0,54929.290,0,0,0,0,0,0,0,
0.25966483,0,-45.181680,0,1167.1934,0,-10271.302,0,38517.382,0,-63339.695,0,37428.002,0,0,0,0,0,0,0,0,
0,-4.8439846,0,250.27254,0,-3303.5975,0,16517.987,0,-33953.641,0,24076.218,0,0,0,0,0,0,0,0,0,
-0.26665257,0,41.331149,0,-909.28528,0,6364.9970,0,-16821.778,0,14578.874,0,0,0,0,0,0,0,0,0,0,
0,4.6949030,0,-206.57573,0,2169.0452,0,-7643.3022,0,8280.2440,0,0,0,0,0,0,0,0,0,0,0,
0.27664982,0,-36.517776,0,639.06107,0,-3152.7013,0,4391.2625,0,0,0,0,0,0,0,0,0,0,0,0,
0,-4.4950274,0,157.32596,0,-1164.2121,0,2162.1082,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.29136935,0,30.593782,0,-377.32331,0,981.04061,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,4.2223431,0,-104.15113,0,406.18940,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.31471487,0,-23.288900,0,151.37785,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-3.8286716,0,49.772731,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0.35858795,0,13.984930,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,3.1669631,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0.50074083,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

267
scratch/c_legendrefn.c Normal file
View File

@ -0,0 +1,267 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "c_legendrecoefs.c"
static const float amsleg_pif = 3.14159265359;
static const double amsleg_pi = 3.14159265359;
float amsleg_polyvalf(float x, const float *coefs, int polyorder)
{
float ret = 0.0f;
float xv = 1.0f;
int I;
for(I=0;I<=polyorder;I++)
{
//printf("debug: %d %1.6g\n",I,coefs[I]);
ret = ret + coefs[I]*xv;
xv = xv * x;
}
return ret;
}
double amsleg_polyval(double x, const double *coefs, int polyorder)
{
double ret = 0.0;
double xv = 1.0;
int I;
for(I=0;I<=polyorder;I++)
{
ret = ret + coefs[I]*xv;
xv = xv * x;
}
return ret;
}
//Schmidt Quasi-Normalized Legendre Function P^n_m(x)
//for degree n, and order m, m<=n
//n from 0 to 20
//m from 0 to n
float amsleg_legendref(float x, int n, int m)
{
float ret = 0.0f;
int I, mo2, mr, ind;
float mpart = 1.0f;
float ppart = 0.0f;
const float *coefptr = NULL;
if(x<-1.0f) x=-1.0f;
if(x>1.0f) x = 1.0f;
if(m<0)
{
m = -m;
}
if(m>n || n<0 || n>20)
{
ret = 0.0f;
return ret;
}
if(m>0)
{
mo2 = m/2;
mr = (m%2==1);
for(I=0;I<mo2;I++)
{
mpart = mpart*(1.0f-x*x);
}
if(mr==1)
{
mpart = mpart*sqrt(1.0f-x*x);
}
}
ind = n*(n+1)/2 + m;
//printf("debug: ind=%d\n",ind);
coefptr = &(amslegendrecoefsf[ind*(amslegendre_maxporder+1)]);
// printf("debug ");
// for(I=0;I<amslegendre_maxporder+1;I++)
// {
// printf("%1.6g,",coefptr[I]);
// }
// printf("\n");
ppart = amsleg_polyvalf(x,coefptr,amslegendre_maxporder);
ret = ppart*mpart;
return ret;
}
//Schmidt Quasi-Normalized Legendre Function P^n_m(x)
//for degree n, and order m, m<=n
//n from 0 to 20
//m from 0 to n
double amsleg_legendre(double x, int n, int m)
{
double ret = 0.0;
int I, mo2, mr, ind;
double mpart = 1.0;
double ppart = 0.0;
const double *coefptr = NULL;
if(x<-1.0f) x=-1.0f;
if(x>1.0f) x = 1.0f;
if(m<0)
{
m = -m;
}
if(m>n || n<0 || n>20)
{
ret = 0.0f;
return ret;
}
if(m>0)
{
mo2 = m/2;
mr = (m%2==1);
for(I=0;I<mo2;I++)
{
mpart = mpart*(1.0f-x*x);
}
if(mr==1)
{
mpart = mpart*sqrt(1.0f-x*x);
}
}
ind = n*(n+1)/2 + m;
coefptr = &(amslegendrecoefs[ind*(amslegendre_maxporder+1)]);
ppart = amsleg_polyval(x,coefptr,amslegendre_maxporder);
ret = ppart*mpart;
return ret;
}
float amsleg_rsphcosf(float theta,float phi,int n,int m)
{
float ret = 0.0f;
float p;
ret = amsleg_legendref(cosf(theta),n,m)*cosf(m*phi);
return ret;
}
float amsleg_rsphsinf(float theta,float phi,int n,int m)
{
float ret = 0.0f;
float p;
ret = amsleg_legendref(cosf(theta),n,m)*sinf(m*phi);
return ret;
}
float amsleg_dotprodf(int n1, int m1, int sc1, int n2, int m2, int sc2)
{
float ret = 0.0f;
float p1,p2;
int Ntheta = 360;
int Nphi = 720;
int I,J;
float dtheta,dphi,theta,phi;
float domega = 0.0f;
dtheta = amsleg_pif/(Ntheta);
dphi = 2.0f*amsleg_pif/(Nphi);
for(I=0;I<Ntheta;I++)
{
for(J=0;J<Nphi;J++)
{
theta = dtheta*I;
phi = dphi*J;
domega = dtheta*dphi*sin(theta);
if(sc1==0)
p1 = amsleg_rsphcosf(theta,phi,n1,m1);
else
p1 = amsleg_rsphsinf(theta,phi,n1,m1);
if(sc2==0)
p2 = amsleg_rsphcosf(theta,phi,n2,m2);
else
p2 = amsleg_rsphsinf(theta,phi,n2,m2);
ret = ret + p1*p2*domega;
//ret = ret + domega;
}
}
return ret;
}
void amsleg_test1()
{
int n = 20;
int m = 20;
float p;
float x;
printf("Test legendre fn %d %d \n",n,m);
for(x=-1.0f; x<=1.005f; x = x + 0.01f)
{
p = amsleg_legendref(x,n,m);
printf("%1.4g\t\t%1.4g\n",x,p);
}
return;
}
void amsleg_test2()
{
int n1 = 3;
int m1 = 1;
int n2;
int m2;
float dp;
//for Schmidt quasi normalized spherical harmonics:
// 1/4pi * integral( C_mn C_MN sin(th)dthdphi ) = 1/(2n+1) del_nN del_mM
// there is a factor of 1/(2n+1)
printf("dot products with (%d,%d).\n",n1,m1);
for(n2 = 0; n2<5; n2++)
{
for(m2 = 0; m2<=n2; m2++)
{
dp = amsleg_dotprodf(n2,m2,1,n2,m2,1);
if(dp<1E-4) dp = 0;
dp = dp/4.0f/amsleg_pif;
dp = dp * (2*n2+1);
printf("(%d,%d): %1.6g\n",n2,m2,dp);
}
}
}
int main(int argc, char* argv[])
{
printf("Legendre Function Tests\n");
amsleg_test2();
return 0;
}

90
scratch/legendre.sage Normal file
View File

@ -0,0 +1,90 @@
#!/usr/bin/sage
# Schmidt Quasi-Normalized Legendre Functions for Spherical Harmonics
x = var('x');
def polypart(n,m):
pol = (x^2-1)^n
for I in range(1,n+1):
pol = diff(pol,x)
for I in range(1,m+1):
pol = diff(pol,x)
return pol
def normpart(n,m):
if(m==0):
nrm = 1/2^n/factorial(n)
else:
nrm = (1/2^n/factorial(n)) * sqrt(2*factorial(n-m)/factorial(n+m))
return nrm
NN = 20
lns = []
coefs = []
nmaxcoefs = 0
for I in range(0,NN+1):
for J in range(0,I+1):
pol = polypart(I,J)
nrm = normpart(I,J)
pol2 = expand(pol)
p2c = pol2.coefficients(sparse=False)
pol3 = nrm*pol2
p3c = pol3.coefficients(sparse=False)
for K in range(0,len(p3c)):
p3c[K] = p3c[K].n()
coefs.append(p3c)
if(nmaxcoefs<len(p3c)):
nmaxcoefs = len(p3c)
#print("{:d}\t{:d}\t{}\t\t{}".format(I,J,nrm,p2c))
s = ""
s = s + "{:d}\t{:d}\t".format(I,J)
for K in range(0,len(p3c)):
nn = p3c[K]
if(abs(nn)<1E-14):
nn = 0
s = s + "{:1.8g}\t".format(nn)
s = s + "\n"
print(s)
lns.append(s)
##C style coefficient output
fout = "c_legendrecoefs2.c"
fp = open(fout,"w+")
pref1 = "static const int amslegendre_ndegree = {:d};\n".format(NN)
pref2 = "static const int amslegendre_maxporder = {:d};\n".format(nmaxcoefs-1)
pref = pref1 + pref2 + "static const float amslegendrecoefs[] = { \n"
for I in range(0,NN+1):
for J in range(0,I+1):
ind = I*(I+1)/2+J
for K in range(0,nmaxcoefs):
if(K<len(coefs[ind])):
nn = coefs[ind][K]
if(abs(nn)<1E-14):
nn = 0
else:
nn = 0
if(ind<len(coefs)-1):
if(K<nmaxcoefs-1):
pref = pref + "{:1.8g},".format(nn)
else:
pref = pref + "{:1.8g},\n".format(nn)
else:
if(K<nmaxcoefs-1):
pref = pref + "{:1.8g},".format(nn)
else:
pref = pref + "{:1.8g}".format(nn) + "\n};\n\n"
fp.writelines(pref)
fp.close()

96
scratch/legendre.sage.py Normal file
View File

@ -0,0 +1,96 @@
# This file was *autogenerated* from the file ./legendre.sage
from sage.all_cmdline import * # import sage library
_sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_20 = Integer(20); _sage_const_1En14 = RealNumber('1E-14')#!/usr/bin/sage
# Schmidt Quasi-Normalized Legendre Functions for Spherical Harmonics
x = var('x');
def polypart(n,m):
pol = (x**_sage_const_2 -_sage_const_1 )**n
for I in range(_sage_const_1 ,n+_sage_const_1 ):
pol = diff(pol,x)
for I in range(_sage_const_1 ,m+_sage_const_1 ):
pol = diff(pol,x)
return pol
def normpart(n,m):
if(m==_sage_const_0 ):
nrm = _sage_const_1 /_sage_const_2 **n/factorial(n)
else:
nrm = (_sage_const_1 /_sage_const_2 **n/factorial(n)) * sqrt(_sage_const_2 *factorial(n-m)/factorial(n+m))
return nrm
NN = _sage_const_20
lns = []
coefs = []
nmaxcoefs = _sage_const_0
for I in range(_sage_const_0 ,NN+_sage_const_1 ):
for J in range(_sage_const_0 ,I+_sage_const_1 ):
pol = polypart(I,J)
nrm = normpart(I,J)
pol2 = expand(pol)
p2c = pol2.coefficients(sparse=False)
pol3 = nrm*pol2
p3c = pol3.coefficients(sparse=False)
for K in range(_sage_const_0 ,len(p3c)):
p3c[K] = p3c[K].n()
coefs.append(p3c)
if(nmaxcoefs<len(p3c)):
nmaxcoefs = len(p3c)
#print("{:d}\t{:d}\t{}\t\t{}".format(I,J,nrm,p2c))
s = ""
s = s + "{:d}\t{:d}\t".format(I,J)
for K in range(_sage_const_0 ,len(p3c)):
nn = p3c[K]
if(abs(nn)<_sage_const_1En14 ):
nn = _sage_const_0
s = s + "{:1.8g}\t".format(nn)
s = s + "\n"
print(s)
lns.append(s)
##C style coefficient output
fout = "c_legendrecoefs.c"
fp = open(fout,"w+")
pref1 = "static const int amslegendre_ndegree = {:d};\n".format(NN)
pref2 = "static const int amslegendre_maxporder = {:d};\n".format(nmaxcoefs-_sage_const_1 )
pref = pref1 + pref2 + "static const float amslegendrecoefs[] = { \n"
for I in range(_sage_const_0 ,NN+_sage_const_1 ):
for J in range(_sage_const_0 ,I+_sage_const_1 ):
ind = I*(I+_sage_const_1 )/_sage_const_2 +J
for K in range(_sage_const_0 ,nmaxcoefs):
if(K<len(coefs[ind])):
nn = coefs[ind][K]
if(abs(nn)<_sage_const_1En14 ):
nn = _sage_const_0
else:
nn = _sage_const_0
if(ind<len(coefs)-_sage_const_1 ):
if(K<nmaxcoefs-_sage_const_1 ):
pref = pref + "{:1.8g},".format(nn)
else:
pref = pref + "{:1.8g},\n".format(nn)
else:
if(K<nmaxcoefs-_sage_const_1 ):
pref = pref + "{:1.8g},".format(nn)
else:
pref = pref + "{:1.8g}".format(nn) + "\n};\n\n"
fp.writelines(pref)
fp.close()

View File

0
scratch/new file Normal file
View File

BIN
scratch/testcl Normal file

Binary file not shown.

5
scratch/testcl.sh Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/bash
gcc c_legendrefn.c -o testcl -lm
./testcl

210
test_ams_pythonigrf.py Normal file
View File

@ -0,0 +1,210 @@
#!/usr/bin/python3
import os,sys,math
import numpy as np
import matplotlib.pyplot as plt
from amspyigrf13 import *
pi = np.pi
def test_loading_igrfdata():
q = load_igrfdata()
print(q)
def test_getcomponents():
igrfdata = load_igrfdata()
yrs = np.linspace(1895,2035,1000)
q = []
for I in range(0,len(yrs)):
a = igrf_getcomponents(yrs[I],igrfdata)
q.append(a)
q = np.array(q)
for I in range(0,q.shape[1]):
plt.plot(yrs,q[:,I])
plt.show()
return
def test_gsosph_normalization(n1,m1,n2,m2):
Ntheta = 50
Nphi = 100
sum1 = 0.0
sum2 = 0.0
sum3 = 0.0
for I in range(0,Ntheta):
for J in range(0,Nphi):
theta = I/Ntheta*pi
phi = J/Nphi*2*pi
dtheta = pi/Ntheta
dphi = 2*pi/Nphi
dA = np.sin(theta)*dtheta*dphi
sum1 = sum1 + gso_cosharmonic(theta,phi,n1,m1)*gso_cosharmonic(theta,phi,n2,m2)*dA
sum2 = sum2 + gso_sinharmonic(theta,phi,n1,m1)*gso_sinharmonic(theta,phi,n2,m2)*dA
sum3 = sum3 + gso_cosharmonic(theta,phi,n1,m1)*gso_sinharmonic(theta,phi,n2,m2)*dA
return [sum1,sum2,sum3]
def test_norm2():
for I in range(0,5):
for J in range(0,5):
[a,b,c] = test_gsosph_normalization(I,J,I,J)
a2 = a*(2*I+1)/(4*pi)
b2 = b*(2*I+1)/(4*pi)
c2 = c*(2*I+1)/(4*pi)
print("{} {}: {} {} {}".format(I,J,a2,b2,c2))
#print("{} {}".format(I,J))
return
def test_igrf_potential():
coefstruct = load_igrfdata()
coefstruct = igrf_getcompstruct(2024,coefstruct)
xyz = [6371,0,0]
V1 = igrf_potential(xyz,coefstruct)
B1 = igrf_bfield(xyz,coefstruct)
print("Potential at {} = {} [nT-km], B = {} [nT]".format(xyz,V1,B1))
xyz = [-6371,0,0]
V1 = igrf_potential(xyz,coefstruct)
B1 = igrf_bfield(xyz,coefstruct)
print("Potential at {} = {} [nT-km], B = {} [nT]".format(xyz,V1,B1))
xyz = [6371+100,0,0]
V1 = igrf_potential(xyz,coefstruct)
B1 = igrf_bfield(xyz,coefstruct)
print("Potential at {} = {} [nT-km], B = {} [nT]".format(xyz,V1,B1))
xyz = [0,0,-6371]
V1 = igrf_potential(xyz,coefstruct)
B1 = igrf_bfield(xyz,coefstruct)
print("Potential at {} = {} [nT-km], B = {} [nT]".format(xyz,V1,B1))
xyz = [0,0,6371]
V1 = igrf_potential(xyz,coefstruct)
B1 = igrf_bfield(xyz,coefstruct)
print("Potential at {} = {} [nT-km], B = {} [nT]".format(xyz,V1,B1))
return
def mycontourf(x,y,s,N=100):
s = np.copy(s)
s[np.isinf(s)] = 0
s[np.isnan(s)] = 0
# s[s<smin] = smin
# s[s>smax] = smax
smin = np.min(s)
smax = np.max(s)
if(np.abs(smax-smin)<1E-15):
smax = smin + 1
s[1,0] = smax
lvls = np.linspace(smin,smax,N)
plt.contourf(x,y,s,cmap="jet",levels=lvls)
plt.colorbar()
return
def getuvw(xyz):
return [u,v,w]
def test_igrf_plotsurfaceB():
coefstruct = load_igrfdata()
coefstruct = igrf_getcompstruct(2020,coefstruct)
Nlats = 25
Nlons = 50
lats = np.linspace(-pi/2,pi/2,Nlats)
lons = np.linspace(-pi,pi,Nlons)
[lons2,lats2] = np.meshgrid(lons,lats)
lons2 = lons2.transpose(); lats2=lats2.transpose()
lons2 = np.array(lons2,order="F")
lats2 = np.array(lats2,order="F")
lons3 = np.reshape(lons2,[Nlons*Nlats],order="F")
lats3 = np.reshape(lats2,[Nlons*Nlats],order="F")
Re = 6378
x = np.cos(lats3)*np.cos(lons3)*Re
y = np.cos(lats3)*np.sin(lons3)*Re
z = np.sin(lats3)*Re
# xyz = np.zeros([3,Nlons*Nlats],order="F")
# xyz[0,:] = x
# xyz[1,:] = y
# xyz[2,:] = z
xyz = np.stack([x,y,z],axis=0)
B = igrf_bfield(xyz,coefstruct)
[lonlatalt,Buvw] = grs80_xyzvectors_to_uvw(xyz,B)
print(Buvw.shape)
Bmag = np.squeeze(np.sqrt(np.sum(B**2,axis=0)))
lats2 = lats2*180/pi
lons2 = lons2*180/pi
Bmag2 = np.reshape(Bmag,[Nlons,Nlats],order="F")
fig = plt.figure(1)
mycontourf(lons2,lats2,Bmag2)
ax = plt.gca()
ax.set_aspect("equal")
plt.title("IGRF-13 Surface B magnitude [nT]")
plt.xlabel("Longitude [deg]")
plt.ylabel("Latitude [deg]")
# fig = plt.figure(2).add_subplot(projection="3d")
# sc = 1/60
# plt.quiver(xyz[0,:],xyz[1,:],xyz[2,:],B[0,:]*sc,B[1,:]*sc,B[2,:]*sc,color=[0,0,0])
# ax = plt.gca()
# ax.set_aspect("equal")
print(np.max(lonlatalt[0,:]),np.min(lonlatalt[0,:]))
print(np.max(lonlatalt[1,:]),np.min(lonlatalt[1,:]))
print(np.max(lonlatalt[2,:]),np.min(lonlatalt[2,:]))
fig = plt.figure(2)
sc = 1/60
plt.quiver(lonlatalt[0,:],lonlatalt[1,:],Buvw[0,:]*sc,Buvw[1,:]*sc,color=[0,0,0])
ax = plt.gca()
ax.set_aspect("equal")
plt.title("IGRF-13 Surface B Heading")
plt.xlabel("Longitude [deg]")
plt.ylabel("Latitude [deg]")
plt.show()
return
if(__name__=="__main__"):
#test_loading_igrfdata()
#test_getcomponents()
#test_norm2()
#test_igrf_potential()
test_igrf_plotsurfaceB()
pass