1919from ..tools .cache import CachedAttribute
2020from ..tools .cache import CachedMethod
2121from ..tools .cache import CachedClass
22- from ..tools import jacobi
2322from ..tools import clenshaw
2423from ..tools .array import reshape_vector , axindex , axslice
2524from ..tools .dispatch import MultiClass , SkipDispatchException
2625from ..tools .general import unify
2726
28- from .spaces import ParityInterval , Disk
2927from .coords import Coordinate , CartesianCoordinates , S2Coordinates , SphericalCoordinates , PolarCoordinates , AzimuthalCoordinate
3028from .domain import Domain
3129from .field import Operand , LockedField
@@ -435,23 +433,19 @@ def __init__(self, coord, size, bounds, a, b, a0=None, b0=None, dealias=1, libra
435433 self .b0 = float (b0 )
436434 self .library = library
437435 self .grid_params = (coord , bounds , a0 , b0 )
438- self .constant_mode_value = 1 / np .sqrt (jacobi .mass (self .a , self .b ))
436+ self .constant_mode_value = ( 1 / np .sqrt (dedalus_sphere . jacobi .mass (self .a , self .b ))). astype ( np . float64 )
439437
440438 def _native_grid (self , scale ):
441439 """Native flat global grid."""
442440 N , = self .grid_shape ((scale ,))
443- return jacobi .build_grid (N , a = self .a0 , b = self .b0 )
441+ grid , weights = dedalus_sphere .jacobi .quadrature (N , self .a0 , self .b0 )
442+ return grid .astype (np .float64 )
444443
445444 @CachedMethod
446445 def transform_plan (self , grid_size ):
447446 """Build transform plan."""
448447 return self .transforms [self .library ](grid_size , self .size , self .a , self .b , self .a0 , self .b0 )
449448
450- # def weights(self, scales):
451- # """Gauss-Jacobi weights."""
452- # N = self.grid_shape(scales)[0]
453- # return jacobi.build_weights(N, a=self.a, b=self.b)
454-
455449 # def __str__(self):
456450 # space = self.space
457451 # cls = self.__class__
@@ -513,14 +507,30 @@ def Jacobi_matrix(self, size):
513507 size = self .size
514508 return dedalus_sphere .jacobi .operator ('Z' )(size , self .a , self .b ).square
515509
510+ @staticmethod
511+ def conversion_matrix (N , a0 , b0 , a1 , b1 ):
512+ if not float (a1 - a0 ).is_integer ():
513+ raise ValueError ("a0 and a1 must be integer-separated" )
514+ if not float (b1 - b0 ).is_integer ():
515+ raise ValueError ("b0 and b1 must be integer-separated" )
516+ if a0 > a1 :
517+ raise ValueError ("a0 must be less than or equal to a1" )
518+ if b0 > b1 :
519+ raise ValueError ("b0 must be less than or equal to b1" )
520+ A = dedalus_sphere .jacobi .operator ('A' )(+ 1 )
521+ B = dedalus_sphere .jacobi .operator ('B' )(+ 1 )
522+ da , db = int (a1 - a0 ), int (b1 - b0 )
523+ conv = A ** da @ B ** db
524+ return conv (N , a0 , b0 ).astype (np .float64 )
525+
516526 def ncc_matrix (self , arg_basis , coeffs , cutoff = 1e-6 ):
517527 """Build NCC matrix via Clenshaw algorithm."""
518528 if arg_basis is None :
519529 return super ().ncc_matrix (arg_basis , coeffs )
520530 # Kronecker Clenshaw on argument Jacobi matrix
521531 elif isinstance (arg_basis , Jacobi ):
522532 N = self .size
523- J = jacobi .jacobi_matrix ( N , arg_basis .a , arg_basis .b )
533+ J = dedalus_sphere . jacobi .operator ( 'Z' )( N , arg_basis .a , arg_basis .b ). square . astype ( np . float64 )
524534 A , B = clenshaw .jacobi_recursion (N , self .a , self .b , J )
525535 f0 = self .const * sparse .identity (N )
526536 total = clenshaw .kronecker_clenshaw (coeffs , A , B , f0 , cutoff = cutoff )
@@ -552,7 +562,7 @@ def multiplication_matrix(self, subproblem, arg_basis, coeffs, ncc_comp, arg_com
552562 A , B = clenshaw .jacobi_recursion (Nmat , a_ncc , b_ncc , J )
553563 f0 = dedalus_sphere .jacobi .polynomials (1 , a_ncc , b_ncc , 1 )[0 ].astype (np .float64 ) * sparse .identity (Nmat )
554564 matrix = clenshaw .matrix_clenshaw (coeffs .ravel (), A , B , f0 , cutoff = cutoff )
555- convert = jacobi .conversion_matrix (Nmat , arg_basis .a , arg_basis .b , out_basis .a , out_basis .b )
565+ convert = Jacobi .conversion_matrix (Nmat , arg_basis .a , arg_basis .b , out_basis .a , out_basis .b )
556566 matrix = convert @ matrix
557567 return matrix [:N , :N ]
558568
@@ -604,7 +614,7 @@ def _full_matrix(input_basis, output_basis):
604614 N = input_basis .size
605615 a0 , b0 = input_basis .a , input_basis .b
606616 a1 , b1 = output_basis .a , output_basis .b
607- matrix = jacobi .conversion_matrix (N , a0 , b0 , a1 , b1 )
617+ matrix = Jacobi .conversion_matrix (N , a0 , b0 , a1 , b1 )
608618 return matrix .tocsr ()
609619
610620
@@ -643,8 +653,9 @@ def _output_basis(input_basis):
643653 def _full_matrix (input_basis , output_basis ):
644654 N = input_basis .size
645655 a , b = input_basis .a , input_basis .b
646- matrix = jacobi .differentiation_matrix (N , a , b ) / input_basis .COV .stretch
647- return matrix .tocsr ()
656+ native_matrix = dedalus_sphere .jacobi .operator ('D' )(+ 1 )(N , a , b ).square .astype (np .float64 )
657+ problem_matrix = native_matrix / input_basis .COV .stretch
658+ return problem_matrix .tocsr ()
648659
649660
650661class InterpolateJacobi (operators .Interpolate , operators .SpectralOperator1D ):
@@ -666,9 +677,9 @@ def _full_matrix(input_basis, output_basis, position):
666677 N = input_basis .size
667678 a , b = input_basis .a , input_basis .b
668679 x = input_basis .COV .native_coord (position )
669- interp_vector = jacobi . build_polynomials ( N , a , b , x )
670- # Return with shape (1, N)
671- return interp_vector [ None , :]
680+ x = np . array ([ x ] )
681+ matrix = dedalus_sphere . jacobi . polynomials ( N , a , b , x ). T
682+ return matrix . astype ( np . float64 )
672683
673684
674685class IntegrateJacobi (operators .Integrate , operators .SpectralOperator1D ):
@@ -688,7 +699,7 @@ def _full_matrix(input_basis, output_basis):
688699 # Build native integration vector
689700 N = input_basis .size
690701 a , b = input_basis .a , input_basis .b
691- integ_vector = jacobi .integration_vector (N , a , b )
702+ integ_vector = dedalus_sphere . jacobi .polynomial_integrals (N , a , b ). astype ( np . float64 )
692703 # Rescale and return with shape (1, N)
693704 return integ_vector [None , :] * input_basis .COV .stretch
694705
@@ -710,7 +721,7 @@ def _full_matrix(input_basis, output_basis):
710721 # Build native integration vector
711722 N = input_basis .size
712723 a , b = input_basis .a , input_basis .b
713- integ_vector = jacobi .integration_vector (N , a , b )
724+ integ_vector = dedalus_sphere . jacobi .polynomial_integrals (N , a , b ). astype ( np . float64 )
714725 ave_vector = integ_vector / 2
715726 # Rescale and return with shape (1, N)
716727 return ave_vector [None , :]
0 commit comments