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