def semiNormalizedSH_genericNumpy(e, a, target=None) : """ Returns the value of the sh components at the specified orientation. Version based on the generic formula, using sympy just for legendre. """ x,y,z = ead2xyz(e, a, 1) sn3d = np.zeros((order+1,order+1)) if target is None else target from sympy import factorial, sqrt, S import sympy as sp ra = math.radians(a) for l in xrange(order+1) : for m in xrange(-l,l+1) : absm = abs(m) factor = math.sqrt(2) if m else 1. sn3d[shi(l,m)] = (factor / math.sqrt( # sp.factorial(l+absm) / sp.factorial(l-absm) # clearest for the next one np.prod(xrange(l-absm+1, l+absm+1)) ) * ( sp.assoc_legendre(l,absm,z) * S(-1)**m ).evalf() * ( np.cos(m*ra) if m>=0 else np.sin(absm*ra) ) ) return sn3d
def semiNormalizedSH_cartesianRecursive(e, a, target=None) : """ Returns the value of the sh components at the specified orientation """ x,y,z = ead2xyz(e, a, 1) sn3d = np.zeros((order+1,order+1)) if target is None else target from sympy import factorial, sqrt, S import sympy as sp ra = math.radians(a) sn3d[shi(0, 0)] = 1. sn3d[shi(1,-1)] = y sn3d[shi(1, 0)] = z sn3d[shi(1,+1)] = x sn3d[shi(2,-2)] = (y*sn3d[shi(1,+1)] +x*sn3d[shi(1,-1)]) * np.sqrt(3./4) sn3d[shi(2,-1)] = z*sn3d[shi(1,-1)] * np.sqrt(3.) sn3d[shi(2, 0)] = (3*z*z -1)*sn3d[shi(0, 0)] * np.sqrt(1./4) sn3d[shi(2,+1)] = z*sn3d[shi(1,+1)] * np.sqrt(3.) sn3d[shi(2,+2)] = (x*sn3d[shi(1,+1)] -y*sn3d[shi(1,-1)]) * np.sqrt(3./4) sn3d[shi(3,+3)] = (x*sn3d[shi(2,+2)] -y*sn3d[shi(2,-2)]) * np.sqrt(5./6) sn3d[shi(3,+2)] = z*sn3d[shi(2,+2)] * np.sqrt(5.) sn3d[shi(3,+1)] = (5*z*z -1)*sn3d[shi(1,+1)] * np.sqrt(3./8) sn3d[shi(3, 0)] = (5*z*z -3)*sn3d[shi(1, 0)] * np.sqrt(1./4) sn3d[shi(3,-1)] = (5*z*z -1)*sn3d[shi(1,-1)] * np.sqrt(3./8) sn3d[shi(3,-2)] = z*sn3d[shi(2,-2)] * np.sqrt(5.) sn3d[shi(3,-3)] = (y*sn3d[shi(2,+2)] +x*sn3d[shi(2,-2)]) * np.sqrt(5./6) sn3d[shi(4,+4)] = (x*sn3d[shi(3,+3)] -y*sn3d[shi(3,-3)]) * np.sqrt(7./8) sn3d[shi(4,+3)] = z*sn3d[shi(3,+3)] * np.sqrt(7.) sn3d[shi(4,+2)] = (7*z*z-1)*sn3d[shi(2,+2)] * np.sqrt(5./3/4) sn3d[shi(4,+1)] = (7*z*z-3)*sn3d[shi(2,+1)] * np.sqrt(5./3/8) sn3d[shi(4, 0)] = (3+z*z*(-30+z*z*35)) * np.sqrt(1./64) # Recursion? sn3d[shi(4,-1)] = (7*z*z-3)*sn3d[shi(2,-1)] * np.sqrt(5./3/8) sn3d[shi(4,-2)] = (7*z*z-1)*sn3d[shi(2,-2)] * np.sqrt(5./3/4) sn3d[shi(4,-3)] = z*sn3d[shi(3,-3)] * np.sqrt(7.) sn3d[shi(4,-4)] = (y*sn3d[shi(3,+3)] +x*sn3d[shi(3,-3)]) * np.sqrt(7./8) sn3d[shi(5,+5)] = (x*sn3d[shi(4,+4)] -y*sn3d[shi(4,-4)]) * np.sqrt(9./10) sn3d[shi(5,+4)] = z*sn3d[shi(4,+4)] * np.sqrt(9.) sn3d[shi(5,+3)] = (9*z*z-1)*sn3d[shi(3,+3)] * np.sqrt(7./8/2) sn3d[shi(5,+2)] = (9*z*z-3)*sn3d[shi(3,+2)] * np.sqrt(7./9/4) sn3d[shi(5,+1)] = x*(21*z**4 -14*z**2 + 1) * np.sqrt(3.*5/64) sn3d[shi(5, 0)] = z*(63*z**4 -70*z**2 + 15) * np.sqrt(1./64) sn3d[shi(5,-1)] = y*(21*z**4 -14*z**2 + 1) * np.sqrt(3.*5/64) sn3d[shi(5,-2)] = 2*x*y*z*(3*z*z -1) * np.sqrt(105./16) sn3d[shi(5,-3)] = y*(9*z*z-1)*(3*x*x-y*y) * np.sqrt(35./8/16) sn3d[shi(5,-4)] = z*sn3d[shi(4,-4)] * np.sqrt(9.) sn3d[shi(5,-5)] = (x*sn3d[shi(4,-4)] +y*sn3d[shi(4,+4)]) * np.sqrt(9./10) return sn3d
def semiNormalizedSH_cartesian(e, a, target=None) : """ Returns the value of the sh components at the specified orientation """ x,y,z = ead2xyz(e, a, 1) sn3d = np.zeros((order+1,order+1)) if target is None else target from sympy import factorial, sqrt, S import sympy as sp ra = math.radians(a) # Synthetic version sn3d[shi(0, 0)] = 1. sn3d[shi(1,+1)] = x sn3d[shi(1, 0)] = z sn3d[shi(1,-1)] = y sn3d[shi(2,-2)] = (x*y)*2 * np.sqrt(3./4) sn3d[shi(2,-1)] = (y*z)*2 * np.sqrt(3./4) sn3d[shi(2, 0)] = (3*z*z -1)/2 sn3d[shi(2,+1)] = (x*z)*2 * np.sqrt(3./4) sn3d[shi(2,+2)] = (x*x - y*y) * np.sqrt(3./4) sn3d[shi(3,+3)] = x*(x*x-3*y*y) * np.sqrt(5./8) sn3d[shi(3,+2)] = z*(x*x-y*y) * np.sqrt(15./4) sn3d[shi(3,+1)] = x*(5*z*z -1) * np.sqrt(3./8) sn3d[shi(3, 0)] = z*(5*z*z -3) * np.sqrt(1./4) sn3d[shi(3,-1)] = y*(5*z*z -1) * np.sqrt(3./8) sn3d[shi(3,-2)] = z*x*y*2 * np.sqrt(15./4) sn3d[shi(3,-3)] = y*(3*x*x-y*y) * np.sqrt(5./8) # sn3d[shi(4,+4)] = (x*x*(x*x-3*y*y)-y*y*(3*x*x-y*y)) * np.sqrt(35./64) # reference sn3d[shi(4,+4)] = (x**4 -6*x*x*y*y +y**4) * np.sqrt(35./64) sn3d[shi(4,+3)] = z*x*(x*x -3*y*y) * np.sqrt(35./8) sn3d[shi(4,+2)] = (x*x-y*y)*(7*z*z -1) * np.sqrt(5./16) sn3d[shi(4,+1)] = z*x*(7*z*z -3) * np.sqrt(5./8) sn3d[shi(4, 0)] = (3+z*z*(-30+z*z*35)) * np.sqrt(1./64) sn3d[shi(4,-1)] = z*y*(7*z*z -3) * np.sqrt(5./8) sn3d[shi(4,-2)] = 2*x*y*(7*z*z -1) * np.sqrt(5./16) sn3d[shi(4,-3)] = z*y*(3*x*x -y*y) * np.sqrt(35./8) sn3d[shi(4,-4)] = 4*x*y*(x*x -y*y) * np.sqrt(35./64) sn3d[shi(5,+5)] = x*(x**4 -10*x*x*y*y +5*y**4) * np.sqrt(9.*7./64/2) sn3d[shi(5,+4)] = z*(x**4 -6*x*x*y*y +y**4) * np.sqrt(35*9./64) sn3d[shi(5,+3)] = x*(x*x-3*y*y)*(9*z*z-1) * np.sqrt(5.*7./128) sn3d[shi(5,+2)] = 3*z*(x*x-y*y)*(3*z*z-1) * np.sqrt(7.*5/3/16) sn3d[shi(5,+1)] = x*(21*z**4 -14*z**2 + 1) * np.sqrt(3.*5/64) sn3d[shi(5, 0)] = z*(63*z**4 -70*z**2 + 15) * np.sqrt(1./64) sn3d[shi(5,-1)] = y*(21*z**4 -14*z**2 + 1) * np.sqrt(3.*5/64) sn3d[shi(5,-2)] = 2*x*y*z*(3*z*z -1) * np.sqrt(105./16) sn3d[shi(5,-3)] = y*(9*z*z-1)*(3*x*x-y*y) * np.sqrt(35./8/16) sn3d[shi(5,-4)] = 4*x*y*z*(x*x -y*y) * np.sqrt(9.*35./64) sn3d[shi(5,-5)] = y*( 5*x**4 -10*x*x*y*y +y**4 ) * np.sqrt(9.*7/64/2) assert abs(sn3d[shi(5,+5)] - 3*14**(1./2)*(-z**2 + 1)**(1./2)*(z**4 - 2*z**2 + 1)*np.cos(5*ra)/16) < 1e-7 assert abs(sn3d[shi(5,+4)] - 3*35**(1./2)*z*(z**4 - 2*z**2 + 1)*np.cos(4*ra)/8 ) < 1e-7 assert abs(sn3d[shi(5,+3)] - 70**(1./2)*(-z**2 + 1)**(1./2)*(-9*z**4 + 10*z**2 - 1)*np.cos(3*ra)/16 ) < 1e-7 assert abs(sn3d[shi(5,+2)] - 105**(1./2)*z*(-3*z**4 + 4*z**2 - 1)*np.cos(2*ra)/4 ) < 1e-7 assert abs(sn3d[shi(5,+1)] - 15**(1./2)*(-z**2 + 1)**(1./2)*(21*z**4 - 14*z**2 + 1)*np.cos(ra)/8 ) < 1e-7 assert abs(sn3d[shi(5, 0)] - z*(63*z**4 - 70*z**2 + 15)/8 )< 1e-7 assert abs(sn3d[shi(5,-1)] - 15**(1./2)*(-z**2 + 1)**(1./2)*(21*z**4 - 14*z**2 + 1)*np.sin(ra)/8 ) < 1e-7 assert abs(sn3d[shi(5,-5)] - 3*14**(1./2)*(-z**2 + 1)**(1./2)*(z**4 - 2*z**2 + 1)*np.sin(5*ra)/16 ) < 1e-7 assert abs(sn3d[shi(5,-4)] - 3*35**(1./2)*z*(z**4 - 2*z**2 + 1)*np.sin(4*ra)/8 ) < 1e-7 assert abs(sn3d[shi(5,-3)] - 70**(1./2)*(-z**2 + 1)**(1./2)*(-9*z**4 + 10*z**2 - 1)*np.sin(3*ra)/16 ) < 1e-7 assert abs(sn3d[shi(5,-2)] - 105**(1./2)*z*(-3*z**4 + 4*z**2 - 1)*np.sin(2*ra)/4 ) < 1e-7 assert abs(sn3d[shi(5,-1)] - 15**(1./2)*(-z**2 + 1)**(1./2)*(21*z**4 - 14*z**2 + 1)*np.sin(ra)/8 ) < 1e-7 return sn3d
def semiNormalizedSH_sympyGeneratedExpressions(e, a, target=None) : """ Returns the value of the sh components at the specified orientation Version based on sympy expansion of the generic formula for each l,m. being a function of z (sin(elevation) and azimuth """ x,y,z = ead2xyz(e, a, 1) sn3d = np.zeros((order+1,order+1)) if target is None else target ra = math.radians(a) # sympy generated from generic formula sn3d[shi(0, 0)] = 1 sn3d[shi(1,-1)] = (-z**2 + 1)**(1./2)*np.sin(ra) sn3d[shi(1, 0)] = z sn3d[shi(1,+1)] = (-z**2 + 1)**(1./2)*np.cos(ra) sn3d[shi(2,-2)] = 3**(1./2)*(-z**2 + 1)*np.sin(2*ra)/2 sn3d[shi(2,-1)] = 3**(1./2)*z*(-z**2 + 1)**(1./2)*np.sin(ra) sn3d[shi(2, 0)] = 3*z**2/2 - 1./2 sn3d[shi(2,+1)] = 3**(1./2)*z*(-z**2 + 1)**(1./2)*np.cos(ra) sn3d[shi(2,+2)] = 3**(1./2)*(-z**2 + 1)*np.cos(2*ra)/2 sn3d[shi(3,-3)] = 10**(1./2)*(-z**2 + 1)**(3./2)*np.sin(3*ra)/4 sn3d[shi(3,-2)] = 15**(1./2)*z*(-z**2 + 1)*np.sin(2*ra)/2 sn3d[shi(3,-1)] = 6**(1./2)*(-z**2 + 1)**(1./2)*(5*z**2 - 1)*np.sin(ra)/4 sn3d[shi(3, 0)] = z*(5*z**2 - 3)/2 sn3d[shi(3,+1)] = 6**(1./2)*(-z**2 + 1)**(1./2)*(5*z**2 - 1)*np.cos(ra)/4 sn3d[shi(3,+2)] = 15**(1./2)*z*(-z**2 + 1)*np.cos(2*ra)/2 sn3d[shi(3,+3)] = 10**(1./2)*(-z**2 + 1)**(3./2)*np.cos(3*ra)/4 sn3d[shi(4,-4)] = 35**(1./2)*(z**4 - 2*z**2 + 1)*np.sin(4*ra)/8 sn3d[shi(4,-3)] = 70**(1./2)*z*(-z**2 + 1)**(3./2)*np.sin(3*ra)/4 sn3d[shi(4,-2)] = 5**(1./2)*(-7*z**4 + 8*z**2 - 1)*np.sin(2*ra)/4 sn3d[shi(4,-1)] = 10**(1./2)*z*(-z**2 + 1)**(1./2)*(7*z**2 - 3)*np.sin(ra)/4 sn3d[shi(4, 0)] = 35*z**4/8 - 15*z**2/4 + 3./8 sn3d[shi(4,+1)] = 10**(1./2)*z*(-z**2 + 1)**(1./2)*(7*z**2 - 3)*np.cos(ra)/4 sn3d[shi(4,+2)] = 5**(1./2)*(-7*z**4 + 8*z**2 - 1)*np.cos(2*ra)/4 sn3d[shi(4,+3)] = 70**(1./2)*z*(-z**2 + 1)**(3./2)*np.cos(3*ra)/4 sn3d[shi(4,+4)] = 35**(1./2)*(z**4 - 2*z**2 + 1)*np.cos(4*ra)/8 sn3d[shi(5,-5)] = 3*14**(1./2)*(-z**2 + 1)**(1./2)*(z**4 - 2*z**2 + 1)*np.sin(5*ra)/16 sn3d[shi(5,-4)] = 3*35**(1./2)*z*(z**4 - 2*z**2 + 1)*np.sin(4*ra)/8 sn3d[shi(5,-3)] = 70**(1./2)*(-z**2 + 1)**(1./2)*(-9*z**4 + 10*z**2 - 1)*np.sin(3*ra)/16 sn3d[shi(5,-2)] = 105**(1./2)*z*(-3*z**4 + 4*z**2 - 1)*np.sin(2*ra)/4 sn3d[shi(5,-1)] = 15**(1./2)*(-z**2 + 1)**(1./2)*(21*z**4 - 14*z**2 + 1)*np.sin(ra)/8 sn3d[shi(5, 0)] = z*(63*z**4 - 70*z**2 + 15)/8 sn3d[shi(5,+1)] = 15**(1./2)*(-z**2 + 1)**(1./2)*(21*z**4 - 14*z**2 + 1)*np.cos(ra)/8 sn3d[shi(5,+2)] = 105**(1./2)*z*(-3*z**4 + 4*z**2 - 1)*np.cos(2*ra)/4 sn3d[shi(5,+3)] = 70**(1./2)*(-z**2 + 1)**(1./2)*(-9*z**4 + 10*z**2 - 1)*np.cos(3*ra)/16 sn3d[shi(5,+4)] = 3*35**(1./2)*z*(z**4 - 2*z**2 + 1)*np.cos(4*ra)/8 sn3d[shi(5,+5)] = 3*14**(1./2)*(-z**2 + 1)**(1./2)*(z**4 - 2*z**2 + 1)*np.cos(5*ra)/16 """ sn3d[shi(6,-6)] = 462**(1./2)*(-z**6 + 3*z**4 - 3*z**2 + 1)*np.sin(6*ra)/32 sn3d[shi(6,-5)] = 3*154**(1./2)*z*(-z**2 + 1)**(1./2)*(z**4 - 2*z**2 + 1)*np.sin(5*ra)/16 sn3d[shi(6,-4)] = 3*7**(1./2)*(11*z**6 - 23*z**4 + 13*z**2 - 1)*np.sin(4*ra)/16 sn3d[shi(6,-3)] = 210**(1./2)*z*(-z**2 + 1)**(1./2)*(-11*z**4 + 14*z**2 - 3)*np.sin(3*ra)/16 sn3d[shi(6,-2)] = 210**(1./2)*(-33*z**6 + 51*z**4 - 19*z**2 + 1)*np.sin(2*ra)/32 sn3d[shi(6,-1)] = 21**(1./2)*z*(-z**2 + 1)**(1./2)*(33*z**4 - 30*z**2 + 5)*np.sin(ra)/8 sn3d[shi(6, 0)] = 231*z**6/16 - 315*z**4/16 + 105*z**2/16 - 5./16 sn3d[shi(6,+1)] = 21**(1./2)*z*(-z**2 + 1)**(1./2)*(33*z**4 - 30*z**2 + 5)*np.cos(ra)/8 sn3d[shi(6,+2)] = 210**(1./2)*(-33*z**6 + 51*z**4 - 19*z**2 + 1)*np.cos(2*ra)/32 sn3d[shi(6,+3)] = 210**(1./2)*z*(-z**2 + 1)**(1./2)*(-11*z**4 + 14*z**2 - 3)*np.cos(3*ra)/16 sn3d[shi(6,+4)] = 3*7**(1./2)*(11*z**6 - 23*z**4 + 13*z**2 - 1)*np.cos(4*ra)/16 sn3d[shi(6,+5)] = 3*154**(1./2)*z*(-z**2 + 1)**(1./2)*(z**4 - 2*z**2 + 1)*np.cos(5*ra)/16 sn3d[shi(6,+6)] = 462**(1./2)*(-z**6 + 3*z**4 - 3*z**2 + 1)*np.cos(6*ra)/32 """ return sn3d
def evalEA(self, e, a, target=None) : x,y,z = ead2xyz(e, a, 1) return self.evalXYZ(x,y,z, target)