feectools 0.1.5__tar.gz → 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. {feectools-0.1.5/feectools.egg-info → feectools-0.1.7}/PKG-INFO +2 -1
  2. {feectools-0.1.5 → feectools-0.1.7}/feectools/api/fem_bilinear_form.py +30 -30
  3. {feectools-0.1.5 → feectools-0.1.7}/feectools/api/fem_common.py +3 -3
  4. {feectools-0.1.5 → feectools-0.1.7}/feectools/api/fem_sum_form.py +2 -2
  5. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/bsplines.py +92 -86
  6. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/bsplines_kernels.py +10 -6
  7. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/tests/test_bsplines.py +34 -34
  8. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/tests/test_bsplines_kernel.py +8 -8
  9. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/tests/test_bsplines_pyccel.py +180 -180
  10. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/blocking_data_exchanger.py +16 -15
  11. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/cart.py +39 -34
  12. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/nonblocking_data_exchanger.py +31 -14
  13. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/partition.py +12 -12
  14. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/petsc.py +4 -4
  15. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/tests/test_cart_1d.py +4 -4
  16. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/tests/test_cart_2d.py +3 -3
  17. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/tests/test_cart_3d.py +3 -3
  18. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/tests/test_multicart_2d.py +7 -7
  19. {feectools-0.1.5 → feectools-0.1.7}/feectools/feec/derivatives.py +6 -6
  20. {feectools-0.1.5 → feectools-0.1.7}/feectools/feec/global_geometric_projectors.py +84 -72
  21. {feectools-0.1.5 → feectools-0.1.7}/feectools/feec/hodge.py +0 -1
  22. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/grid.py +1 -1
  23. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/partitioning.py +2 -2
  24. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/projectors.py +6 -6
  25. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/splines.py +31 -11
  26. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tensor.py +30 -29
  27. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/analytical_profiles_1d.py +4 -4
  28. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/test_spline_histopolation.py +14 -14
  29. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/test_spline_interpolation.py +11 -11
  30. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/test_splines.py +14 -14
  31. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/test_splines_par.py +3 -3
  32. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/test_vector_spaces.py +6 -6
  33. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/utilities.py +3 -3
  34. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/vector.py +2 -2
  35. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/basic.py +14 -13
  36. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/block.py +25 -13
  37. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/direct_solvers.py +30 -11
  38. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/fft.py +5 -5
  39. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kron.py +42 -29
  40. feectools-0.1.7/feectools/linalg/memory.py +41 -0
  41. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/solvers.py +6 -6
  42. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/stencil.py +217 -130
  43. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_block.py +117 -117
  44. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_fft.py +7 -7
  45. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_kron_stencil_matrix.py +3 -3
  46. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_linalg.py +133 -78
  47. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_matrix_free.py +14 -14
  48. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_solvers.py +15 -15
  49. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_stencil_interface_matrix.py +9 -8
  50. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_stencil_vector.py +57 -57
  51. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/test_stencil_vector_space.py +3 -3
  52. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/topetsc.py +49 -49
  53. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/utilities.py +23 -11
  54. {feectools-0.1.5 → feectools-0.1.7}/feectools/utilities/quadratures.py +11 -10
  55. {feectools-0.1.5 → feectools-0.1.7}/feectools/utilities/utils.py +14 -14
  56. {feectools-0.1.5 → feectools-0.1.7/feectools.egg-info}/PKG-INFO +2 -1
  57. {feectools-0.1.5 → feectools-0.1.7}/feectools.egg-info/SOURCES.txt +1 -0
  58. {feectools-0.1.5 → feectools-0.1.7}/feectools.egg-info/requires.txt +1 -0
  59. {feectools-0.1.5 → feectools-0.1.7}/pyproject.toml +2 -1
  60. {feectools-0.1.5 → feectools-0.1.7}/AUTHORS +0 -0
  61. {feectools-0.1.5 → feectools-0.1.7}/LICENSE +0 -0
  62. {feectools-0.1.5 → feectools-0.1.7}/README.md +0 -0
  63. {feectools-0.1.5 → feectools-0.1.7}/feectools/__init__.py +0 -0
  64. {feectools-0.1.5 → feectools-0.1.7}/feectools/accelerate/__init__.py +0 -0
  65. {feectools-0.1.5 → feectools-0.1.7}/feectools/accelerate/accelerate.py +0 -0
  66. {feectools-0.1.5 → feectools-0.1.7}/feectools/accelerate/compile_psydac.mk +0 -0
  67. {feectools-0.1.5 → feectools-0.1.7}/feectools/api/__init__.py +0 -0
  68. {feectools-0.1.5 → feectools-0.1.7}/feectools/api/essential_bc.py +0 -0
  69. {feectools-0.1.5 → feectools-0.1.7}/feectools/api/settings.py +0 -0
  70. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/__init__.py +0 -0
  71. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/field_evaluation_kernels.py +0 -0
  72. {feectools-0.1.5 → feectools-0.1.7}/feectools/core/tests/__init__.py +0 -0
  73. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/__init__.py +0 -0
  74. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/basic.py +0 -0
  75. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/interface_data_exchanger.py +0 -0
  76. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/mpi.py +0 -0
  77. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/tests/__init__.py +0 -0
  78. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/tests/test_partition.py +0 -0
  79. {feectools-0.1.5 → feectools-0.1.7}/feectools/ddm/utilities.py +0 -0
  80. {feectools-0.1.5 → feectools-0.1.7}/feectools/feec/__init__.py +0 -0
  81. {feectools-0.1.5 → feectools-0.1.7}/feectools/feec/dof_kernels.py +0 -0
  82. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/__init__.py +0 -0
  83. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/basic.py +0 -0
  84. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/lst_preconditioner.py +0 -0
  85. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/__init__.py +0 -0
  86. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/analytical_profiles_base.py +0 -0
  87. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/splines_error_bounds.py +0 -0
  88. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/test_dirichlet_projectors.py +0 -0
  89. {feectools-0.1.5 → feectools-0.1.7}/feectools/fem/tests/test_tensor.py +0 -0
  90. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/__init__.py +0 -0
  91. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kernels/__init__.py +0 -0
  92. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kernels/axpy_kernels.py +0 -0
  93. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kernels/inner_kernels.py +0 -0
  94. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kernels/matvec_kernels.py +0 -0
  95. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kernels/stencil2IJV_kernels.py +0 -0
  96. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kernels/stencil2coo_kernels.py +0 -0
  97. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/kernels/transpose_kernels.py +0 -0
  98. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/sparse.py +0 -0
  99. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/stencil_dot_kernels.py +0 -0
  100. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/stencil_transpose_kernels.py +0 -0
  101. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/__init__.py +0 -0
  102. {feectools-0.1.5 → feectools-0.1.7}/feectools/linalg/tests/utilities.py +0 -0
  103. {feectools-0.1.5 → feectools-0.1.7}/feectools/utilities/__init__.py +0 -0
  104. {feectools-0.1.5 → feectools-0.1.7}/feectools/version.py +0 -0
  105. {feectools-0.1.5 → feectools-0.1.7}/feectools.egg-info/dependency_links.txt +0 -0
  106. {feectools-0.1.5 → feectools-0.1.7}/feectools.egg-info/entry_points.txt +0 -0
  107. {feectools-0.1.5 → feectools-0.1.7}/feectools.egg-info/top_level.txt +0 -0
  108. {feectools-0.1.5 → feectools-0.1.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: feectools
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: Slimmed-down fork of Psydac (https://github.com/pyccel/psydac) with less functionality and fewer dependencies.
5
5
  Author-email: Psydac development team <psydac@googlegroups.com>
6
6
  Maintainer-email: Stefan Possanner <stefan.possanner@ipp.mpg.de>, Max Lindqvist <max.lindqvist@ipp.mpg.de>, Yaman Güçlü <yaman.guclu@gmail.com>, Martin Campos Pinto <martin.campos-pinto@ipp.mpg.de>, Ahmed Ratnani <ratnaniahmed@gmail.com>
@@ -42,6 +42,7 @@ Requires-Dist: matplotlib
42
42
  Requires-Dist: pyyaml>=5.1
43
43
  Requires-Dist: packaging
44
44
  Requires-Dist: pyevtk
45
+ Requires-Dist: cunumpy
45
46
  Requires-Dist: pyccel>=2.1.0
46
47
  Requires-Dist: h5py
47
48
  Requires-Dist: tblib
@@ -2,7 +2,7 @@ import sys
2
2
  import os
3
3
  import importlib
4
4
 
5
- import numpy as np
5
+ import cunumpy as xp
6
6
 
7
7
  from sympy import ImmutableDenseMatrix, Matrix, Symbol, sympify
8
8
  from sympy.tensor.indexed import Indexed, IndexedBase
@@ -465,8 +465,8 @@ class DiscreteBilinearForm:
465
465
 
466
466
  expr = self.kernel_expr.expr
467
467
  target = self.kernel_expr.target
468
- test_degree = np.array(self.test_basis.space.degree)
469
- trial_degree = np.array(self.trial_basis.space.degree)
468
+ test_degree = xp.array(self.test_basis.space.degree)
469
+ trial_degree = xp.array(self.trial_basis.space.degree)
470
470
  test_space = self.spaces[1].coeff_space
471
471
  trial_space = self.spaces[0].coeff_space
472
472
  test_fem_space = self.spaces[1]
@@ -476,20 +476,20 @@ class DiscreteBilinearForm:
476
476
  is_conformal = True
477
477
 
478
478
  if isinstance(expr, (ImmutableDenseMatrix, Matrix)):
479
- if not isinstance(test_degree[0],(list, tuple, np.ndarray)):
479
+ if not isinstance(test_degree[0],(list, tuple, xp.ndarray)):
480
480
  test_degree = [test_degree]
481
481
 
482
- if not isinstance(trial_degree[0],(list, tuple, np.ndarray)):
482
+ if not isinstance(trial_degree[0],(list, tuple, xp.ndarray)):
483
483
  trial_degree = [trial_degree]
484
484
 
485
- pads = np.empty((len(test_degree),len(trial_degree),len(test_degree[0])), dtype=int)
485
+ pads = xp.empty((len(test_degree),len(trial_degree),len(test_degree[0])), dtype=int)
486
486
  for i in range(len(test_degree)):
487
487
  for j in range(len(trial_degree)):
488
488
  td = test_degree[i]
489
489
  trd = trial_degree[j]
490
- pads[i,j][:] = np.array([td, trd]).max(axis=0)
490
+ pads[i,j][:] = xp.array([td, trd]).max(axis=0)
491
491
  else:
492
- pads = np.maximum(test_degree, trial_degree)
492
+ pads = xp.maximum(test_degree, trial_degree)
493
493
 
494
494
  if self._matrix is None and (is_broken or isinstance(expr, (ImmutableDenseMatrix, Matrix))):
495
495
  self._matrix = BlockLinearOperator(trial_space, test_space)
@@ -714,8 +714,8 @@ class DiscreteBilinearForm:
714
714
  bs, d, s, p, mult = construct_test_space_arguments(basis_v)
715
715
  basis += bs
716
716
  spans += s
717
- degrees += [np.int64(a) for a in d]
718
- pads += [np.int64(a) for a in p]
717
+ degrees += [xp.int64(a) for a in d]
718
+ pads += [xp.int64(a) for a in p]
719
719
  if v.space.is_multipatch or v.space.is_vector_valued:
720
720
  coeffs += (e._data for e in v.coeffs)
721
721
  else:
@@ -1382,12 +1382,12 @@ class DiscreteBilinearForm:
1382
1382
  I_1 = f'int(floor(i_1/{test_mult[0]})*{trial_mult[0]})' if max(test_mult[0], trial_mult[0]) > 1 else 'i_1'
1383
1383
  I_2 = f'int(floor(i_2/{test_mult[1]})*{trial_mult[1]})' if max(test_mult[1], trial_mult[1]) > 1 else 'i_2'
1384
1384
  I_3 = f'int(floor(i_3/{test_mult[2]})*{trial_mult[2]})' if max(test_mult[2], trial_mult[2]) > 1 else 'i_3'
1385
- #MAX_P1 = max(int( ( MAX_P1 + np.floor(MAX_P1 / test_mult[0]) * trial_mult[0] ) / 2 ), MAX_P1) if max(test_mult[0], trial_mult[0]) > 1 else MAX_P1
1386
- #MAX_P2 = max(int( ( MAX_P2 + np.floor(MAX_P2 / test_mult[1]) * trial_mult[1] ) / 2 ), MAX_P2) if max(test_mult[1], trial_mult[1]) > 1 else MAX_P2
1387
- #MAX_P3 = max(int( ( MAX_P3 + np.floor(MAX_P3 / test_mult[2]) * trial_mult[2] ) / 2 ), MAX_P3) if max(test_mult[2], trial_mult[2]) > 1 else MAX_P3
1388
- n_cols_x1 = max( int(MAX_P1 + 1 + np.floor(MAX_P1 / test_mult[0]) * trial_mult[0]), 2*MAX_P1+1 )
1389
- n_cols_x2 = max( int(MAX_P2 + 1 + np.floor(MAX_P2 / test_mult[1]) * trial_mult[1]), 2*MAX_P2+1 )
1390
- n_cols_x3 = max( int(MAX_P3 + 1 + np.floor(MAX_P3 / test_mult[2]) * trial_mult[2]), 2*MAX_P3+1 )
1385
+ #MAX_P1 = max(int( ( MAX_P1 + xp.floor(MAX_P1 / test_mult[0]) * trial_mult[0] ) / 2 ), MAX_P1) if max(test_mult[0], trial_mult[0]) > 1 else MAX_P1
1386
+ #MAX_P2 = max(int( ( MAX_P2 + xp.floor(MAX_P2 / test_mult[1]) * trial_mult[1] ) / 2 ), MAX_P2) if max(test_mult[1], trial_mult[1]) > 1 else MAX_P2
1387
+ #MAX_P3 = max(int( ( MAX_P3 + xp.floor(MAX_P3 / test_mult[2]) * trial_mult[2] ) / 2 ), MAX_P3) if max(test_mult[2], trial_mult[2]) > 1 else MAX_P3
1388
+ n_cols_x1 = max( int(MAX_P1 + 1 + xp.floor(MAX_P1 / test_mult[0]) * trial_mult[0]), 2*MAX_P1+1 )
1389
+ n_cols_x2 = max( int(MAX_P2 + 1 + xp.floor(MAX_P2 / test_mult[1]) * trial_mult[1]), 2*MAX_P2+1 )
1390
+ n_cols_x3 = max( int(MAX_P3 + 1 + xp.floor(MAX_P3 / test_mult[2]) * trial_mult[2]), 2*MAX_P3+1 )
1391
1391
  MAX_P1 = n_cols_x1 - MAX_P1 - 1
1392
1392
  MAX_P2 = n_cols_x2 - MAX_P2 - 1
1393
1393
  MAX_P3 = n_cols_x3 - MAX_P3 - 1
@@ -2024,9 +2024,9 @@ class DiscreteBilinearForm:
2024
2024
 
2025
2025
  # keys_2[(u[0], v[1])][3] = (1,2) means that the fourth sub-expression corresponding to the trial-test-function-component-product
2026
2026
  # u[0] * v[1] involves a first derivative in x2 direction of the trial function and a second derivative in x2 direction of the test function
2027
- keys_1[block] = np.array([(alpha_1, beta_1) for alpha_1, beta_1 in zip(x1_trial_keys[block], x1_test_keys[block])])
2028
- keys_2[block] = np.array([(alpha_2, beta_2) for alpha_2, beta_2 in zip(x2_trial_keys[block], x2_test_keys[block])])
2029
- keys_3[block] = np.array([(alpha_3, beta_3) for alpha_3, beta_3 in zip(x3_trial_keys[block], x3_test_keys[block])])
2027
+ keys_1[block] = xp.array([(alpha_1, beta_1) for alpha_1, beta_1 in zip(x1_trial_keys[block], x1_test_keys[block])])
2028
+ keys_2[block] = xp.array([(alpha_2, beta_2) for alpha_2, beta_2 in zip(x2_trial_keys[block], x2_test_keys[block])])
2029
+ keys_3[block] = xp.array([(alpha_3, beta_3) for alpha_3, beta_3 in zip(x3_trial_keys[block], x3_test_keys[block])])
2030
2030
 
2031
2031
  # Those are the function values in each direction of a particular component of the trial/test function
2032
2032
  global_basis_u_1, global_basis_u_2, global_basis_u_3 = global_basis_u[u_i]
@@ -2056,9 +2056,9 @@ class DiscreteBilinearForm:
2056
2056
  # of non-zero product.
2057
2057
  # Hence, we assign zeros for each element, each quadrature point on the element, each test and trial function combination,
2058
2058
  # and each (or even more than required) appearing partial derivative combination of these functions - in each direction
2059
- test_trial_1 = np.zeros((n_element_1, k1, test_v_p1 + 1, trial_u_p1 + 1, max_block_trial_x1_derivative+1, max_block_test_x1_derivative+1), dtype='float64')
2060
- test_trial_2 = np.zeros((n_element_2, k2, test_v_p2 + 1, trial_u_p2 + 1, max_block_trial_x2_derivative+1, max_block_test_x2_derivative+1), dtype='float64')
2061
- test_trial_3 = np.zeros((n_element_3, k3, test_v_p3 + 1, trial_u_p3 + 1, max_block_trial_x3_derivative+1, max_block_test_x3_derivative+1), dtype='float64')
2059
+ test_trial_1 = xp.zeros((n_element_1, k1, test_v_p1 + 1, trial_u_p1 + 1, max_block_trial_x1_derivative+1, max_block_test_x1_derivative+1), dtype='float64')
2060
+ test_trial_2 = xp.zeros((n_element_2, k2, test_v_p2 + 1, trial_u_p2 + 1, max_block_trial_x2_derivative+1, max_block_test_x2_derivative+1), dtype='float64')
2061
+ test_trial_3 = xp.zeros((n_element_3, k3, test_v_p3 + 1, trial_u_p3 + 1, max_block_trial_x3_derivative+1, max_block_test_x3_derivative+1), dtype='float64')
2062
2062
 
2063
2063
  # And that's how we fill the test_trial arrays
2064
2064
  if self._pyccelize_test_trial_computation and assembly_backend['name'] == 'pyccel':
@@ -2068,7 +2068,7 @@ class DiscreteBilinearForm:
2068
2068
  [max_block_trial_x1_derivative, max_block_trial_x2_derivative, max_block_trial_x3_derivative], [max_block_test_x1_derivative, max_block_test_x2_derivative, max_block_test_x3_derivative],
2069
2069
  [test_trial_1, test_trial_2, test_trial_3]):
2070
2070
 
2071
- args = tuple(np.int64(a) if isinstance(a, int) else a for a in args)
2071
+ args = tuple(xp.int64(a) if isinstance(a, int) else a for a in args)
2072
2072
 
2073
2073
  test_trial_func(*args)
2074
2074
  else:
@@ -2118,13 +2118,13 @@ class DiscreteBilinearForm:
2118
2118
  # to store local information correctly. 2*degree+1 in the simplest case.
2119
2119
  n_funs_x2 = n_element_2 + test_v_p2 + (test_mult[1]-1)*(n_element_2-1)
2120
2120
  n_funs_x3 = n_element_3 + test_v_p3 + (test_mult[2]-1)*(n_element_3-1)
2121
- n_cols_x2 = max( int(max_p_2 + 1 + np.floor(max_p_2 / test_mult[1]) * trial_mult[1]), 2*max_p_2+1 )
2122
- n_cols_x3 = max( int(max_p_3 + 1 + np.floor(max_p_3 / test_mult[2]) * trial_mult[2]), 2*max_p_3+1 )
2121
+ n_cols_x2 = max( int(max_p_2 + 1 + xp.floor(max_p_2 / test_mult[1]) * trial_mult[1]), 2*max_p_2+1 )
2122
+ n_cols_x3 = max( int(max_p_3 + 1 + xp.floor(max_p_3 / test_mult[2]) * trial_mult[2]), 2*max_p_3+1 )
2123
2123
 
2124
- a3[block] = np.zeros((n_expr, n_funs_x3, n_cols_x3), dtype='float64')
2125
- a2[block] = np.zeros((n_expr, n_funs_x2, n_funs_x3, n_cols_x2, n_cols_x3), dtype='float64')
2124
+ a3[block] = xp.zeros((n_expr, n_funs_x3, n_cols_x3), dtype='float64')
2125
+ a2[block] = xp.zeros((n_expr, n_funs_x2, n_funs_x3, n_cols_x2, n_cols_x3), dtype='float64')
2126
2126
 
2127
- coupling_terms[block] = np.zeros((n_element_2, k2, n_element_3, k3, n_expr), dtype='float64')
2127
+ coupling_terms[block] = xp.zeros((n_element_2, k2, n_element_3, k3, n_expr), dtype='float64')
2128
2128
 
2129
2129
  # We gather the socalled new args - all other args are being obtained in a similar way using the old assembly implementation
2130
2130
  new_args = (*list(test_trial_1s.values()),
@@ -2158,8 +2158,8 @@ class DiscreteBilinearForm:
2158
2158
 
2159
2159
  threads_args = ()
2160
2160
 
2161
- args = tuple(np.int64(a) if isinstance(a, int) else a for a in args)
2162
- threads_args = tuple(np.int64(a) if isinstance(a, int) else a for a in threads_args)
2161
+ args = tuple(xp.int64(a) if isinstance(a, int) else a for a in args)
2162
+ threads_args = tuple(xp.int64(a) if isinstance(a, int) else a for a in threads_args)
2163
2163
 
2164
2164
  #---------- We now generate the assembly file ----------
2165
2165
 
@@ -2,7 +2,7 @@ from typing import Iterable
2
2
 
3
3
  from sympy import Expr, ImmutableDenseMatrix, Matrix
4
4
 
5
- import numpy as np
5
+ import cunumpy as xp
6
6
 
7
7
  from sympde.expr.basic import BasicForm
8
8
  from sympde.expr.evaluation import KernelExpression
@@ -215,8 +215,8 @@ def collect_spaces(space, *args):
215
215
 
216
216
  #==============================================================================
217
217
  def compute_diag_len(p, md, mc):
218
- n = ((np.ceil((p+1)/mc)-1)*md).astype('int')
219
- n = n-np.minimum(0, n-p)+p+1
218
+ n = ((xp.ceil((p+1)/mc)-1)*md).astype('int')
219
+ n = n-xp.minimum(0, n-p)+p+1
220
220
  return n.astype('int')
221
221
 
222
222
  #==============================================================================
@@ -1,4 +1,4 @@
1
- import numpy as np
1
+ import cunumpy as xp
2
2
 
3
3
  from sympde.expr.expr import (
4
4
  BilinearForm as sym_BilinearForm,
@@ -119,5 +119,5 @@ class DiscreteSumForm(BasicDiscrete):
119
119
  return self._operator
120
120
  else:
121
121
  M = [form.assemble(**kwargs) for form in self.forms]
122
- M = np.sum(M)
122
+ M = sum(M)
123
123
  return M
@@ -15,7 +15,8 @@ References:
15
15
  - [2] SELALIB, Semi-Lagrangian Library. http://selalib.gforge.inria.fr
16
16
 
17
17
  """
18
- import numpy as np
18
+ import cunumpy as xp
19
+ from cunumpy.xp import array_backend
19
20
 
20
21
  from feectools.core.bsplines_kernels import (find_span_p,
21
22
  find_spans_p,
@@ -82,7 +83,7 @@ def find_span(knots, degree, x):
82
83
  Knot span index.
83
84
  """
84
85
  x = float(x)
85
- knots = np.ascontiguousarray(knots, dtype=float)
86
+ knots = xp.ascontiguousarray(knots, dtype=float)
86
87
  return find_span_p(knots, degree, x)
87
88
 
88
89
  #==============================================================================
@@ -114,12 +115,12 @@ def find_spans(knots, degree, x, out=None):
114
115
  spans : array of ints
115
116
  Knots span indexes.
116
117
  """
117
- knots = np.ascontiguousarray(knots, dtype=float)
118
- x = np.ascontiguousarray(x, dtype=float)
118
+ knots = xp.ascontiguousarray(knots, dtype=float)
119
+ x = xp.ascontiguousarray(x, dtype=float)
119
120
  if out is None:
120
- out = np.zeros_like(x, dtype=int)
121
+ out = xp.zeros_like(x, dtype=int)
121
122
  else:
122
- assert out.shape == x.shape and out.dtype == np.dtype('int')
123
+ assert out.shape == x.shape and out.dtype == xp.dtype('int')
123
124
 
124
125
  find_spans_p(knots, degree, x, out)
125
126
  return out
@@ -153,13 +154,13 @@ def basis_funs(knots, degree, x, span, out=None):
153
154
  1D array containing the values of ``degree + 1`` non-zero
154
155
  Bsplines at location ``x``.
155
156
  """
156
- knots = np.ascontiguousarray(knots, dtype=float)
157
+ knots = xp.ascontiguousarray(knots, dtype=float)
157
158
  # Get native float
158
159
  x = float(x)
159
160
  if out is None:
160
- out = np.zeros(degree + 1, dtype=float)
161
+ out = xp.zeros(degree + 1, dtype=float)
161
162
  else:
162
- assert out.shape == (degree + 1,) and out.dtype == np.dtype('float')
163
+ assert out.shape == (degree + 1,) and out.dtype == xp.dtype('float')
163
164
  basis_funs_p(knots, degree, x, span, out)
164
165
  return out
165
166
 
@@ -191,12 +192,12 @@ def basis_funs_array(knots, degree, span, x, out=None):
191
192
  2D array of shape ``(len(x), degree + 1)`` containing the values of ``degree + 1`` non-zero
192
193
  Bsplines at each location in ``x``.
193
194
  """
194
- knots = np.ascontiguousarray(knots, dtype=float)
195
- x = np.ascontiguousarray(x, dtype=float)
195
+ knots = xp.ascontiguousarray(knots, dtype=float)
196
+ x = xp.ascontiguousarray(x, dtype=float)
196
197
  if out is None:
197
- out = np.zeros(x.shape + (degree + 1,), dtype=float)
198
+ out = xp.zeros(x.shape + (degree + 1,), dtype=float)
198
199
  else:
199
- assert out.shape == x.shape + (degree + 1,) and out.dtype == np.dtype('float')
200
+ assert out.shape == x.shape + (degree + 1,) and out.dtype == xp.dtype('float')
200
201
  basis_funs_array_p(knots, degree, x, span, out)
201
202
  return out
202
203
 
@@ -238,13 +239,13 @@ def basis_funs_1st_der(knots, degree, x, span, out=None):
238
239
  ----------
239
240
  .. [2] SELALIB, Semi-Lagrangian Library. http://selalib.gforge.inria.fr
240
241
  """
241
- knots = np.ascontiguousarray(knots, dtype=float)
242
+ knots = xp.ascontiguousarray(knots, dtype=float)
242
243
  # Get native float to work on windows
243
244
  x = float(x)
244
245
  if out is None:
245
- out = np.zeros(degree + 1, dtype=float)
246
+ out = xp.zeros(degree + 1, dtype=float)
246
247
  else:
247
- assert out.shape == (degree + 1,) and out.dtype == np.dtype('float')
248
+ assert out.shape == (degree + 1,) and out.dtype == xp.dtype('float')
248
249
 
249
250
  basis_funs_1st_der_p(knots, degree, x, span, out)
250
251
  return out
@@ -289,13 +290,13 @@ def basis_funs_all_ders(knots, degree, x, span, n, normalization='B', out=None):
289
290
  ders[i,j] = (d/dx)^i B_k(x) with k=(span-degree+j),
290
291
  for 0 <= i <= n and 0 <= j <= degree+1.
291
292
  """
292
- knots = np.ascontiguousarray(knots, dtype=float)
293
+ knots = xp.ascontiguousarray(knots, dtype=float)
293
294
  # Get native float to work on windows
294
295
  x = float(x)
295
296
  if out is None:
296
- out = np.zeros((n + 1, degree + 1), dtype=float)
297
+ out = xp.zeros((n + 1, degree + 1), dtype=float)
297
298
  else:
298
- assert out.shape == (n + 1, degree + 1) and out.dtype == np.dtype('float')
299
+ assert out.shape == (n + 1, degree + 1) and out.dtype == xp.dtype('float')
299
300
 
300
301
  basis_funs_all_ders_p(knots, degree, x, span, n, normalization == 'M', out)
301
302
  return out
@@ -342,18 +343,18 @@ def collocation_matrix(knots, degree, periodic, normalization, xgrid, out=None,
342
343
  values of each B-spline basis function :math:`B_j` at all locations :math:`x_i`.
343
344
  """
344
345
  if xgrid.size == 1:
345
- return np.ones((1, 1), dtype=float)
346
+ return xp.ones((1, 1), dtype=float)
346
347
 
347
- knots = np.ascontiguousarray(knots, dtype=float)
348
- xgrid = np.ascontiguousarray(xgrid, dtype=float)
348
+ knots = xp.ascontiguousarray(knots, dtype=float)
349
+ xgrid = xp.ascontiguousarray(xgrid, dtype=float)
349
350
  if out is None:
350
351
  nb = len(knots) - degree - 1
351
352
  if periodic:
352
353
  nb -= degree + 1 - multiplicity
353
354
 
354
- out = np.zeros((xgrid.shape[0], nb), dtype=float)
355
+ out = xp.zeros((int(xgrid.shape[0]), int(nb)), dtype=float)
355
356
  else:
356
- assert out.shape == ((xgrid.shape[0], nb)) and out.dtype == np.dtype('float')
357
+ assert out.shape == ((int(xgrid.shape[0]), int(nb))) and out.dtype == xp.dtype('float')
357
358
 
358
359
  bool_normalization = normalization == "M"
359
360
  multiplicity = int(multiplicity)
@@ -407,11 +408,11 @@ def histopolation_matrix(knots, degree, periodic, normalization, xgrid, multipli
407
408
  two successive grid points.
408
409
  """
409
410
  # Check that knots are ordered (but allow repeated knots)
410
- if not np.all(np.diff(knots) >= 0):
411
+ if not xp.all(xp.diff(knots) >= 0):
411
412
  raise ValueError("Cannot accept knot sequence: {}".format(knots))
412
413
 
413
414
  # Check that spline degree is non-negative integer
414
- if not isinstance(degree, (int, np.integer)):
415
+ if not isinstance(degree, (int, xp.integer)):
415
416
  raise TypeError("Degree {} must be integer, got type {} instead".format(degree, type(degree)))
416
417
  if degree < 0:
417
418
  raise ValueError("Cannot accept negative degree: {}".format(degree))
@@ -425,26 +426,26 @@ def histopolation_matrix(knots, degree, periodic, normalization, xgrid, multipli
425
426
  raise ValueError("Cannot accept 'normalization' parameter: {}".format(normalization))
426
427
 
427
428
  # Check that grid points are ordered, and do not allow repetitions
428
- if not np.all(np.diff(xgrid) > 0):
429
+ if not xp.all(xp.diff(xgrid) > 0):
429
430
  raise ValueError("Grid points must be ordered, with no repetitions: {}".format(xgrid))
430
431
 
431
- knots = np.ascontiguousarray(knots, dtype=float)
432
- xgrid = np.ascontiguousarray(xgrid, dtype=float)
432
+ knots = xp.ascontiguousarray(knots, dtype=float)
433
+ xgrid = xp.ascontiguousarray(xgrid, dtype=float)
433
434
  elevated_knots = elevate_knots(knots, degree, periodic, multiplicity=multiplicity)
434
435
 
435
436
  normalization = normalization == "M"
436
437
 
437
438
  if out is None:
438
439
  if periodic:
439
- out = np.zeros((len(xgrid), len(knots) - 2 * degree - 2 + multiplicity), dtype=float)
440
+ out = xp.zeros((len(xgrid), len(knots) - 2 * int(degree) - 2 + int(multiplicity)), dtype=float)
440
441
  else:
441
- out = np.zeros((len(xgrid) - 1, len(elevated_knots) - (degree + 1) - 1 - 1), dtype=float)
442
+ out = xp.zeros((len(xgrid) - 1, len(elevated_knots) - (int(degree) + 1) - 1 - 1), dtype=float)
442
443
  else:
443
444
  if periodic:
444
445
  assert out.shape == (len(xgrid), len(knots) - 2 * degree - 2 + multiplicity)
445
446
  else:
446
447
  assert out.shape == (len(xgrid) - 1, len(elevated_knots) - (degree + 1) - 1 - 1)
447
- assert out.dtype == np.dtype('float')
448
+ assert out.dtype == xp.dtype('float')
448
449
  multiplicity = int(multiplicity)
449
450
  histopolation_matrix_p(knots, degree, periodic, normalization, xgrid, check_boundary, elevated_knots, out, multiplicity = multiplicity)
450
451
  return out
@@ -475,11 +476,11 @@ def breakpoints(knots, degree, tol=1e-15, out=None):
475
476
  breaks : numpy.ndarray (1D)
476
477
  Abscissas of all breakpoints.
477
478
  """
478
- knots = np.ascontiguousarray(knots, dtype=float)
479
+ knots = xp.ascontiguousarray(knots, dtype=float)
479
480
  if out is None:
480
- out = np.zeros(len(knots), dtype=float)
481
+ out = xp.zeros(len(knots), dtype=float)
481
482
  else:
482
- assert out.shape == knots.shape and out.dtype == np.dtype('float')
483
+ assert out.shape == knots.shape and out.dtype == xp.dtype('float')
483
484
  i_final = breakpoints_p(knots, degree, out, tol)
484
485
  return out[:i_final]
485
486
 
@@ -513,10 +514,10 @@ def greville(knots, degree, periodic, out=None, multiplicity=1):
513
514
  Abscissas of all Greville points.
514
515
 
515
516
  """
516
- knots = np.ascontiguousarray(knots, dtype=float)
517
+ knots = xp.ascontiguousarray(knots, dtype=float)
517
518
  if out is None:
518
519
  n = len(knots) - 2 * degree - 2 + multiplicity if periodic else len(knots) - degree - 1
519
- out = np.zeros(n)
520
+ out = xp.zeros(int(n))
520
521
  multiplicity = int(multiplicity)
521
522
  greville_p(knots, degree, periodic, out, multiplicity)
522
523
  return out
@@ -546,11 +547,11 @@ def elements_spans(knots, degree, out=None):
546
547
 
547
548
  Examples
548
549
  --------
549
- >>> import numpy as np
550
+ >>> import cunumpy as xp
550
551
  >>> from feectools.core.bsplines import make_knots, elements_spans
551
552
 
552
553
  >>> p = 3 ; n = 8
553
- >>> grid = np.arange( n-p+1 )
554
+ >>> grid = xp.arange( n-p+1 )
554
555
  >>> knots = make_knots( breaks=grid, degree=p, periodic=False )
555
556
  >>> spans = elements_spans( knots=knots, degree=p )
556
557
  >>> spans
@@ -562,14 +563,14 @@ def elements_spans(knots, degree, out=None):
562
563
  2) This function could be written in two lines:
563
564
 
564
565
  breaks = breakpoints( knots, degree )
565
- spans = np.searchsorted( knots, breaks[:-1], side='right' ) - 1
566
+ spans = xp.searchsorted( knots, breaks[:-1], side='right' ) - 1
566
567
 
567
568
  """
568
- knots = np.ascontiguousarray(knots, dtype=float)
569
+ knots = xp.ascontiguousarray(knots, dtype=float)
569
570
  if out is None:
570
- out = np.zeros(len(knots), dtype=np.int64)
571
+ out = xp.zeros(len(knots), dtype=xp.int64)
571
572
  else:
572
- assert out.shape == knots.shape and out.dtype == np.dtype('int64')
573
+ assert out.shape == knots.shape and out.dtype == xp.dtype('int64')
573
574
  i_final = elements_spans_p(knots, degree, out)
574
575
  return out[:i_final]
575
576
 
@@ -616,7 +617,7 @@ def make_knots(breaks, degree, periodic, multiplicity=1, out=None):
616
617
 
617
618
  # Consistency checks
618
619
  assert len(breaks) > 1
619
- assert all( np.diff(breaks) > 0 )
620
+ assert all( xp.diff(breaks) > 0 )
620
621
  assert degree >= 0
621
622
  assert 1 <= multiplicity and multiplicity <= degree + 1
622
623
  # Cast potential numpy.int64 into python native int
@@ -625,12 +626,12 @@ def make_knots(breaks, degree, periodic, multiplicity=1, out=None):
625
626
  if periodic:
626
627
  assert len(breaks) > degree
627
628
 
628
- breaks = np.ascontiguousarray(breaks, dtype=float)
629
+ breaks = xp.ascontiguousarray(breaks, dtype=float)
629
630
  if out is None:
630
- out = np.zeros(multiplicity * len(breaks[1:-1]) + 2 + 2 * degree)
631
+ out = xp.zeros(multiplicity * len(breaks[1:-1]) + 2 + 2 * degree)
631
632
  else:
632
633
  assert out.shape == (multiplicity * len(breaks[1:-1]) + 2 + 2 * degree,) \
633
- and out.dtype == np.dtype('float')
634
+ and out.dtype == xp.dtype('float')
634
635
  make_knots_p(breaks, degree, periodic, out, multiplicity)
635
636
 
636
637
  return out
@@ -675,25 +676,25 @@ def elevate_knots(knots, degree, periodic, multiplicity=1, tol=1e-15, out=None):
675
676
  Knots sequence of spline space of degree p+1.
676
677
  """
677
678
  multiplicity = int(multiplicity)
678
- knots = np.ascontiguousarray(knots, dtype=float)
679
+ knots = xp.ascontiguousarray(knots, dtype=float)
679
680
  if out is None:
680
681
  if periodic:
681
- out = np.zeros(knots.shape[0] + 2, dtype=float)
682
+ out = xp.zeros(knots.shape[0] + 2, dtype=float)
682
683
  else:
683
684
  shape = 2*(degree + 2)
684
685
  if len(knots) - 2 * (degree + 1) > 0:
685
- uniques = (np.diff(knots[degree + 1:-degree - 1]) > tol).nonzero()
686
+ uniques = (xp.diff(knots[degree + 1:-degree - 1]) > tol).nonzero()
686
687
  shape += multiplicity * (1 + uniques[0].shape[0])
687
- out = np.zeros(shape, dtype=float)
688
+ out = xp.zeros(shape, dtype=float)
688
689
  else:
689
690
  if periodic:
690
- assert out.shape == (knots.shape[0] + 2,) and out.dtype == np.dtype('float')
691
+ assert out.shape == (knots.shape[0] + 2,) and out.dtype == xp.dtype('float')
691
692
  else:
692
693
  shape = 2*(degree + 2)
693
694
  if len(knots) - 2 * (degree + 1) > 0:
694
- uniques = (np.diff(knots[degree + 1:-degree - 1]) > tol).nonzero()
695
+ uniques = (xp.diff(knots[degree + 1:-degree - 1]) > tol).nonzero()
695
696
  shape += multiplicity * (1 + uniques[0].shape[0])
696
- assert out.shape == shape and out.dtype == np.dtype('float')
697
+ assert out.shape == shape and out.dtype == xp.dtype('float')
697
698
 
698
699
  elevate_knots_p(knots, degree, periodic, out, multiplicity, tol)
699
700
  return out
@@ -750,13 +751,18 @@ def quadrature_grid(breaks, quad_rule_x, quad_rule_w):
750
751
  assert min(quad_rule_x) >= -1
751
752
  assert max(quad_rule_x) <= +1
752
753
 
753
- breaks = np.ascontiguousarray(breaks, dtype=float)
754
+ breaks = xp.ascontiguousarray(breaks, dtype=float)
754
755
 
755
- quad_rule_x = np.ascontiguousarray( quad_rule_x, dtype=float )
756
- quad_rule_w = np.ascontiguousarray( quad_rule_w, dtype=float )
756
+ if array_backend.backend == "cupy":
757
+ quad_rule_x = xp.ascontiguousarray(xp.array(quad_rule_x), dtype=float)
758
+ quad_rule_w = xp.ascontiguousarray( xp.array(quad_rule_w), dtype=float )
759
+ else:
760
+ quad_rule_x = xp.ascontiguousarray(quad_rule_x, dtype=float)
761
+ quad_rule_w = xp.ascontiguousarray( quad_rule_w, dtype=float )
762
+
757
763
 
758
- out1 = np.zeros((len(breaks) - 1, len(quad_rule_x)))
759
- out2 = np.zeros_like(out1)
764
+ out1 = xp.zeros((len(breaks) - 1, len(quad_rule_x)))
765
+ out2 = xp.zeros_like(out1)
760
766
 
761
767
  quadrature_grid_p(breaks, quad_rule_x, quad_rule_w, out1, out2)
762
768
 
@@ -805,10 +811,10 @@ def basis_ders_on_quad_grid(knots, degree, quad_grid, nders, normalization, offs
805
811
 
806
812
  Examples
807
813
  --------
808
- >>> knots = np.array([0.0, 0.0, 0.25, 0.5, 0.75, 1., 1.])
814
+ >>> knots = xp.array([0.0, 0.0, 0.25, 0.5, 0.75, 1., 1.])
809
815
  >>> degree = 2
810
816
  >>> bk = breakpoints(knots, degree)
811
- >>> grid = np.array([np.linspace(bk[i], bk[i+1], 4, endpoint=False) for i in range(len(bk) - 1)])
817
+ >>> grid = xp.array([xp.linspace(bk[i], bk[i+1], 4, endpoint=False) for i in range(len(bk) - 1)])
812
818
  >>> basis_ders_on_quad_grid(knots, degree, grid, 0, "B")
813
819
  array([[[[0.5, 0.28125, 0.125, 0.03125]],
814
820
  [[0.5, 0.6875 , 0.75 , 0.6875 ]],
@@ -819,12 +825,12 @@ def basis_ders_on_quad_grid(knots, degree, quad_grid, nders, normalization, offs
819
825
  """
820
826
  offset = int(offset)
821
827
  ne, nq = quad_grid.shape
822
- knots = np.ascontiguousarray(knots, dtype=float)
823
- quad_grid = np.ascontiguousarray(quad_grid, dtype=float)
828
+ knots = xp.ascontiguousarray(knots, dtype=float)
829
+ quad_grid = xp.ascontiguousarray(quad_grid, dtype=float)
824
830
  if out is None:
825
- out = np.zeros((ne, degree + 1, nders + 1, nq), dtype=float)
831
+ out = xp.zeros((ne, degree + 1, nders + 1, nq), dtype=float)
826
832
  else:
827
- assert out.shape == (ne, degree + 1, nders + 1, nq) and out.dtype == np.dtype('float')
833
+ assert out.shape == (ne, degree + 1, nders + 1, nq) and out.dtype == xp.dtype('float')
828
834
  basis_ders_on_quad_grid_p(knots, degree, quad_grid, nders, normalization == 'M', offset, out)
829
835
  return out
830
836
 
@@ -863,11 +869,11 @@ def basis_integrals(knots, degree, out=None):
863
869
  to (len(knots)-degree-1). In the periodic case the last (degree) values in
864
870
  the array are redundant, as they are a copy of the first (degree) values.
865
871
  """
866
- knots = np.ascontiguousarray(knots, dtype=float)
872
+ knots = xp.ascontiguousarray(knots, dtype=float)
867
873
  if out is None:
868
- out = np.zeros(len(knots) - degree - 1, dtype=float)
874
+ out = xp.zeros(len(knots) - degree - 1, dtype=float)
869
875
  else:
870
- assert out.shape is (len(knots) - degree - 1,) and out.dtype == np.dtype('float')
876
+ assert out.shape is (len(knots) - degree - 1,) and out.dtype == xp.dtype('float')
871
877
  basis_integrals_p(knots, degree, out)
872
878
  return out
873
879
 
@@ -905,12 +911,12 @@ def cell_index(breaks, i_grid, tol=1e-15, out=None):
905
911
  ``cell_index[i]`` is the index of the cell in which
906
912
  ``i_grid[i]`` belong.
907
913
  """
908
- breaks = np.ascontiguousarray(breaks, dtype=float)
909
- i_grid = np.ascontiguousarray(i_grid, dtype=float)
914
+ breaks = xp.ascontiguousarray(breaks, dtype=float)
915
+ i_grid = xp.ascontiguousarray(i_grid, dtype=float)
910
916
  if out is None:
911
- out = np.zeros_like(i_grid, dtype=np.int64)
917
+ out = xp.zeros_like(i_grid, dtype=xp.int64)
912
918
  else:
913
- assert out.shape == i_grid.shape and out.dtype == np.dtype('int64')
919
+ assert out.shape == i_grid.shape and out.dtype == xp.dtype('int64')
914
920
  status = cell_index_p(breaks, i_grid, tol, out)
915
921
  if status == -1:
916
922
  raise ValueError("Encountered a point that was outside of the domain")
@@ -961,13 +967,13 @@ def basis_ders_on_irregular_grid(knots, degree, i_grid, cell_index, nders, norma
961
967
  . il: local basis function (0 <= il <= degree)
962
968
  . id: derivative (0 <= id <= nders )
963
969
  """
964
- knots = np.ascontiguousarray(knots, dtype=float)
965
- i_grid = np.ascontiguousarray(i_grid, dtype=float)
970
+ knots = xp.ascontiguousarray(knots, dtype=float)
971
+ i_grid = xp.ascontiguousarray(i_grid, dtype=float)
966
972
  if out is None:
967
973
  nx = i_grid.shape[0]
968
- out = np.zeros((nx, degree + 1, nders + 1), dtype=float)
974
+ out = xp.zeros((nx, degree + 1, nders + 1), dtype=float)
969
975
  else:
970
- assert out.shape == (nx, degree + 1, nders + 1) and out.dtype == np.dtype('float')
976
+ assert out.shape == (nx, degree + 1, nders + 1) and out.dtype == xp.dtype('float')
971
977
  basis_ders_on_irregular_grid_p(knots, degree, i_grid, cell_index, nders, normalization == 'M', out)
972
978
  return out
973
979
 
@@ -994,7 +1000,7 @@ def _refinement_matrix_one_stage(t, p, knots):
994
1000
 
995
1001
  Returns
996
1002
  -------
997
- mat : np.array[:,:]
1003
+ mat : xp.array[:,:]
998
1004
  h-refinement matrix.
999
1005
 
1000
1006
  new_knots : array_like
@@ -1017,7 +1023,7 @@ def _refinement_matrix_one_stage(t, p, knots):
1017
1023
 
1018
1024
  n = len(knots) - p - 1
1019
1025
 
1020
- mat = np.zeros((n+1,n))
1026
+ mat = xp.zeros((n+1,n))
1021
1027
 
1022
1028
  left = find_span( knots, p, t )
1023
1029
 
@@ -1037,7 +1043,7 @@ def _refinement_matrix_one_stage(t, p, knots):
1037
1043
  # ...
1038
1044
 
1039
1045
  # ...
1040
- new_knots = np.zeros(n+1+p+1)
1046
+ new_knots = xp.zeros(n+1+p+1)
1041
1047
 
1042
1048
  new_knots[:left+1] = knots[:left+1]
1043
1049
  new_knots[left+1] = t
@@ -1058,7 +1064,7 @@ def hrefinement_matrix(ts, p, knots):
1058
1064
 
1059
1065
  Parameters
1060
1066
  ----------
1061
- ts: np.array
1067
+ ts: xp.array
1062
1068
  array containing the knots to be inserted
1063
1069
 
1064
1070
  p: int
@@ -1069,18 +1075,18 @@ def hrefinement_matrix(ts, p, knots):
1069
1075
 
1070
1076
  Returns
1071
1077
  -------
1072
- mat : np.array[:,:]
1078
+ mat : xp.array[:,:]
1073
1079
  h-refinement matrix
1074
1080
 
1075
1081
  Examples
1076
1082
  --------
1077
- >>> import numpy as np
1083
+ >>> import cunumpy as xp
1078
1084
  >>> from feectools.core.bsplines import make_knots
1079
1085
  >>> from feectools.core.bsplines import hrefinement_matrix
1080
- >>> grid = np.linspace(0.,1.,5)
1086
+ >>> grid = xp.linspace(0.,1.,5)
1081
1087
  >>> degree = 2
1082
1088
  >>> knots = make_knots(grid, degree, periodic=False)
1083
- >>> ts = np.array([0.1, 0.2, 0.4, 0.5, 0.7, 0.8])
1089
+ >>> ts = xp.array([0.1, 0.2, 0.4, 0.5, 0.7, 0.8])
1084
1090
  >>> hrefinement_matrix(ts, p, knots)
1085
1091
  array([[1. , 0. , 0. , 0. , 0. , 0. ],
1086
1092
  [0.6 , 0.4 , 0. , 0. , 0. , 0. ],
@@ -1098,11 +1104,11 @@ def hrefinement_matrix(ts, p, knots):
1098
1104
 
1099
1105
  m = len(ts)
1100
1106
  n = len(knots) - p - 1
1101
- out = np.eye(n)
1107
+ out = xp.eye(n)
1102
1108
 
1103
1109
  for i in range(m):
1104
1110
  t = ts[i]
1105
1111
  mat, knots = _refinement_matrix_one_stage(t, p, knots)
1106
- out = np.matmul(mat, out)
1112
+ out = xp.matmul(mat, out)
1107
1113
 
1108
1114
  return out