Source code for hpfracc.core.fractional_implementations

"""
Fractional derivative and integral implementations.

This module provides concrete implementations of fractional derivatives
and integrals that can be registered with the factory.

Performance Note (v2.1.0):
- All implementations automatically benefit from intelligent backend selection
- Backend selection happens in the underlying optimized algorithms
- Small data (< 1K elements): Uses NumPy/Numba for minimal overhead
- Large data (> 100K elements): Uses GPU when available for acceleration
- Zero code changes required - optimization is automatic

Engine path (RL / Caputo / Grünwald–Letnikov):

- Canonical numerical engines live in ``hpfracc.algorithms.derivatives``.
- Classes in this module (for example ``CaputoDerivative``) are thin ``BaseFractionalDerivative``
  adapters that delegate to those engines via ``_engine``; there is no second implementation.
"""

import logging
import numpy as np
from typing import Union, Callable, Tuple, List, Dict, Any
from .derivatives import BaseFractionalDerivative
from .definitions import FractionalOrder, DefinitionType


[docs] class _AlphaCompatibilityWrapper: """Wrapper that makes alpha behave like both a float and FractionalOrder."""
[docs] def __init__(self, fractional_order: FractionalOrder): self._fractional_order = fractional_order
def __eq__(self, other): """Allow comparison with floats.""" if isinstance(other, (int, float)): return self._fractional_order.alpha == other return self._fractional_order == other def __getattr__(self, name): """Delegate attribute access to the FractionalOrder object.""" return getattr(self._fractional_order, name) def __repr__(self): return repr(self._fractional_order) def __float__(self): """Allow conversion to float.""" return float(self._fractional_order.alpha) def __int__(self): """Allow conversion to int.""" return int(self._fractional_order.alpha) def __class__(self): """Support isinstance checks by returning the wrapped class.""" return type(self._fractional_order)
[docs] class RiemannLiouvilleDerivative(BaseFractionalDerivative): """ Riemann-Liouville fractional derivative — adapter over the canonical engine :class:`hpfracc.algorithms.derivatives.RiemannLiouville`. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) from ..algorithms.derivatives import RiemannLiouville self._engine = RiemannLiouville(order) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], h: Union[float, None] = None, **kwargs) -> Union[float, np.ndarray]: """Compute the Riemann-Liouville fractional derivative.""" # Check for empty arrays if hasattr(x, '__len__') and len(x) == 0: raise ValueError("zero-size array") # Check for single-point arrays if hasattr(x, '__len__') and len(x) == 1: raise ValueError("Time array must have at least 2 points for numerical computation") if h is not None: kwargs['h'] = h return self._engine.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the derivative numerically from function values.""" return self._engine.compute(f_values, x_values, **kwargs)
[docs] class CaputoDerivative(BaseFractionalDerivative): """ Caputo fractional derivative — adapter over the canonical engine :class:`hpfracc.algorithms.derivatives.Caputo` (single implementation path). """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) from ..algorithms.derivatives import Caputo self._engine = Caputo(order) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], h: Union[float, None] = None, **kwargs) -> Union[float, np.ndarray]: """Compute the Caputo fractional derivative.""" # Check for empty arrays if hasattr(x, '__len__') and len(x) == 0: raise ValueError("zero-size array") # Check for single-point arrays if hasattr(x, '__len__') and len(x) == 1: raise ValueError("Time array must have at least 2 points for numerical computation") if h is not None: kwargs['h'] = h return self._engine.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the derivative numerically from function values.""" return self._engine.compute(f_values, x_values, **kwargs)
[docs] class GrunwaldLetnikovDerivative(BaseFractionalDerivative): """ Grünwald–Letnikov fractional derivative — adapter over the canonical engine :class:`hpfracc.algorithms.derivatives.GrunwaldLetnikov`. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) from ..algorithms.derivatives import GrunwaldLetnikov self._engine = GrunwaldLetnikov(order) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], h: Union[float, None] = None, **kwargs) -> Union[float, np.ndarray]: """Compute the Grunwald-Letnikov fractional derivative.""" # Check for empty arrays if hasattr(x, '__len__') and len(x) == 0: raise ValueError("zero-size array") if h is not None: kwargs['h'] = h return self._engine.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the derivative numerically from function values.""" return self._engine.compute(f_values, x_values, **kwargs)
[docs] class CaputoFabrizioDerivative(BaseFractionalDerivative): """ Caputo-Fabrizio fractional derivative implementation. Uses the novel implementation from algorithms. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.novel_derivatives import CaputoFabrizioDerivative as CFDerivative # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._novel_impl = CFDerivative(self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Caputo-Fabrizio fractional derivative.""" is_scalar_input = isinstance(x, (int, float)) or ( isinstance(x, np.ndarray) and x.ndim == 0 ) if isinstance(x, (int, float)): x = np.array([x]) elif isinstance(x, np.ndarray) and x.ndim == 0: x = np.array([x]) result = self._novel_impl.compute(f, x, **kwargs) # Return scalar if input was scalar if is_scalar_input: return result[0] if isinstance(result, np.ndarray) else result return result
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the derivative numerically from function values.""" return self._novel_impl.compute(f_values, x_values, **kwargs)
[docs] class AtanganaBaleanuDerivative(BaseFractionalDerivative): """ Atangana-Baleanu fractional derivative implementation. Uses the novel implementation from algorithms. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.novel_derivatives import AtanganaBaleanuDerivative as ABDerivative # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._novel_impl = ABDerivative(self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Atangana-Baleanu fractional derivative.""" is_scalar_input = isinstance(x, (int, float)) or ( isinstance(x, np.ndarray) and x.ndim == 0 ) if isinstance(x, (int, float)): x = np.array([x]) elif isinstance(x, np.ndarray) and x.ndim == 0: x = np.array([x]) result = self._novel_impl.compute(f, x, **kwargs) # Return scalar if input was scalar if is_scalar_input: return result[0] if isinstance(result, np.ndarray) else result return result
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the derivative numerically from function values.""" return self._novel_impl.compute(f_values, x_values, **kwargs)
[docs] class FractionalLaplacian(BaseFractionalDerivative): """ Fractional Laplacian operator implementation. Uses the special implementation from algorithms. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.fractional_operator_methods import ( FractionalLaplacian as FracLaplacian, ) # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._special_impl = FracLaplacian( self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the fractional Laplacian.""" return self._special_impl.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the fractional Laplacian numerically from function values.""" return self._special_impl.compute_numerical( f_values, x_values, **kwargs)
[docs] class FractionalFourierTransform(BaseFractionalDerivative): """ Fractional Fourier Transform implementation. Uses the special implementation from algorithms. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.fractional_operator_methods import ( FractionalFourierTransform as FracFT, ) # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._special_impl = FracFT(self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the fractional Fourier transform.""" # FractionalFourierTransform returns (u_domain, transformed_values) result = self._special_impl.transform(f, x, **kwargs) # Return just the transformed values, not the tuple if isinstance(result, tuple) and len(result) == 2: return result[1] # Return transformed values return result
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the fractional Fourier transform numerically from function values.""" return self._special_impl.compute_numerical( f_values, x_values, **kwargs)
[docs] class MillerRossDerivative(BaseFractionalDerivative): """ Miller-Ross fractional derivative implementation. This is a generalization of the Riemann-Liouville derivative. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Miller-Ross fractional derivative.""" # Handle empty arrays gracefully if hasattr(x, '__len__') and len(x) == 0: return np.array([]) # For now, use Riemann-Liouville as approximation # This can be enhanced with specific Miller-Ross implementation from ..algorithms.derivatives import RiemannLiouville rl_impl = RiemannLiouville(self._alpha_order) return rl_impl.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the Miller-Ross fractional derivative numerically.""" from ..algorithms.derivatives import RiemannLiouville rl_impl = RiemannLiouville(self._alpha_order) return rl_impl.compute(f_values, x_values, **kwargs)
[docs] class WeylDerivative(BaseFractionalDerivative): """ Weyl fractional derivative implementation. Uses the advanced implementation from algorithms with FFT convolution and parallel processing optimizations. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.advanced_methods import WeylDerivative as AdvancedWeyl # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._advanced_impl = AdvancedWeyl( self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Weyl fractional derivative using advanced methods.""" return self._advanced_impl.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the Weyl fractional derivative numerically using advanced methods.""" return self._advanced_impl.compute(f_values, x_values, **kwargs)
[docs] class MarchaudDerivative(BaseFractionalDerivative): """ Marchaud fractional derivative implementation. Uses the advanced implementation from algorithms with difference quotient convolution and memory optimization. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.advanced_methods import MarchaudDerivative as AdvancedMarchaud # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._advanced_impl = AdvancedMarchaud( self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Marchaud fractional derivative using advanced methods.""" return self._advanced_impl.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the Marchaud fractional derivative numerically using advanced methods.""" return self._advanced_impl.compute(f_values, x_values, **kwargs)
[docs] class HadamardDerivative(BaseFractionalDerivative): """ Hadamard fractional derivative implementation. Uses the advanced implementation from algorithms with logarithmic kernels. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.advanced_methods import HadamardDerivative as AdvancedHadamard # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._advanced_impl = AdvancedHadamard( self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Hadamard fractional derivative using advanced methods.""" return self._advanced_impl.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the Hadamard fractional derivative numerically using advanced methods.""" return self._advanced_impl.compute(f_values, x_values, **kwargs)
[docs] class ReizFellerDerivative(BaseFractionalDerivative): """ Reiz-Feller fractional derivative implementation. Uses the advanced implementation from algorithms with spectral methods. """
[docs] def __init__(self, order: Union[float, FractionalOrder], **kwargs): super().__init__(order, **kwargs) # Lazy import to avoid circular dependencies from ..algorithms.advanced_methods import ReizFellerDerivative as AdvancedReizFeller # Filter out factory-specific arguments filtered_kwargs = {k: v for k, v in kwargs.items() if k not in ['use_jax', 'use_numba']} self._advanced_impl = AdvancedReizFeller( self._alpha_order, **filtered_kwargs) # For backward compatibility, expose alpha as a special wrapper # that behaves like both a float and FractionalOrder self.alpha = _AlphaCompatibilityWrapper(self._alpha_order)
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Reiz-Feller fractional derivative using advanced methods.""" return self._advanced_impl.compute(f, x, **kwargs)
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the Reiz-Feller fractional derivative numerically using advanced methods.""" return self._advanced_impl.compute(f_values, x_values, **kwargs)
[docs] class RieszFisherOperator(BaseFractionalDerivative): """ Riesz-Fisher fractional operator implementation. The Riesz-Fisher operator is a combination of left and right fractional derivatives/integrals that is particularly useful in signal processing and image analysis. It's defined as: R^α f(x) = (1/2) * [D^α_+ f(x) + D^α_- f(x)] where D^α_+ is the left-sided and D^α_- is the right-sided operator. For α > 0: acts as a derivative For α < 0: acts as an integral For α = 0: acts as identity """
[docs] def __init__(self, alpha: Union[float, FractionalOrder], **kwargs): # Handle negative orders by bypassing the base class validation but # preserve test-facing alpha semantics: float in, float out; object in, object out. if isinstance(alpha, FractionalOrder): self.alpha = alpha original_alpha = float(alpha.alpha) self._alpha_order = alpha else: self.alpha = float(alpha) self._alpha_order = FractionalOrder(self.alpha, validate=False) original_alpha = float(self._alpha_order.alpha) # Store the original alpha value for internal logic self._original_alpha = original_alpha self._use_derivative = self._original_alpha > 0 self._use_integral = self._original_alpha < 0 # Initialize the underlying operators if self._use_derivative: from .fractional_implementations import RiemannLiouvilleDerivative self._left_op = RiemannLiouvilleDerivative( abs(self._original_alpha)) self._right_op = RiemannLiouvilleDerivative( abs(self._original_alpha)) elif self._use_integral: from .fractional_implementations import create_fractional_integral self._left_op = create_fractional_integral( "RL", abs(self._original_alpha)) self._right_op = create_fractional_integral( "RL", abs(self._original_alpha)) else: # α = 0, identity operator self._left_op = None self._right_op = None
[docs] def compute(self, f: Callable, x: Union[float, np.ndarray], **kwargs) -> Union[float, np.ndarray]: """Compute the Riesz-Fisher fractional operator.""" if self._original_alpha == 0: # Identity operator if callable(f): return f(x) else: return f # For α ≠ 0, compute left and right operators if self._use_derivative: left_result = self._left_op.compute(f, x, **kwargs) right_result = self._right_op.compute(f, x, **kwargs) else: # self._use_integral left_result = self._left_op(f, x) right_result = self._right_op(f, x) # Combine results result = 0.5 * (left_result + right_result) return result
[docs] def compute_numerical( self, f_values: np.ndarray, x_values: np.ndarray, **kwargs) -> np.ndarray: """Compute the Riesz-Fisher fractional operator numerically.""" if self._original_alpha == 0: # Identity operator return f_values # For α ≠ 0, compute left and right operators if self._use_derivative: left_result = self._left_op.compute_numerical( f_values, x_values, **kwargs) right_result = self._right_op.compute_numerical( f_values, x_values, **kwargs) else: # self._use_integral # For integrals, we need to handle the array input differently # This is a simplified approach - in practice, you might want more sophisticated # handling of the integral computation from arrays left_result = np.zeros_like(f_values) right_result = np.zeros_like(f_values) for i, xi in enumerate(x_values): # Create a function that interpolates the array values def f_interp(t): # Simple linear interpolation if t <= x_values[0]: return f_values[0] elif t >= x_values[-1]: return f_values[-1] else: # Find the interval and interpolate for j in range(len(x_values) - 1): if x_values[j] <= t <= x_values[j + 1]: t1, t2 = x_values[j], x_values[j + 1] f1, f2 = f_values[j], f_values[j + 1] return f1 + (f2 - f1) * (t - t1) / (t2 - t1) return f_values[-1] # fallback left_result[i] = self._left_op(f_interp, xi) right_result[i] = self._right_op(f_interp, xi) # Combine results result = 0.5 * (left_result + right_result) return result
def __repr__(self): """String representation of the Riesz-Fisher operator.""" alpha_str = self.alpha.alpha if isinstance( self.alpha, FractionalOrder) else self.alpha return f"RieszFisherOperator(alpha={alpha_str})"
[docs] class AdomianDecompositionMethod: """ Adomian Decomposition Method for solving fractional differential equations. This is an analytical method that decomposes the solution into a series of components that can be computed iteratively. """
[docs] def __init__(self, max_terms: int = 10, tolerance: float = 1e-6): """ Initialize the Adomian Decomposition Method. Args: max_terms: Maximum number of terms to compute tolerance: Convergence tolerance """ self.max_terms = max_terms self.tolerance = tolerance
[docs] def solve(self, equation: Callable, initial_condition: Callable, domain: Union[Tuple[float, float], np.ndarray], **kwargs) -> Dict[str, Any]: """ Solve a fractional differential equation using Adomian decomposition. Args: equation: The fractional differential equation initial_condition: Initial condition function domain: Solution domain or array of points **kwargs: Additional parameters Returns: Solution dictionary with components and convergence info """ # Lazy import to avoid circular dependencies from ..algorithms.advanced_methods import AdomianDecomposition adomian_solver = AdomianDecomposition( max_terms=self.max_terms, tolerance=self.tolerance) return adomian_solver.solve( equation, initial_condition, domain, **kwargs)
[docs] def compute_adomian_polynomials( self, nonlinear_term: Callable, u_series: List[Callable], order: int) -> List[Callable]: """ Compute Adomian polynomials for nonlinear terms. Args: nonlinear_term: The nonlinear term in the equation u_series: Series of solution components order: Order of the polynomial to compute Returns: List of Adomian polynomial functions """ from ..algorithms.advanced_methods import AdomianDecomposition adomian_solver = AdomianDecomposition( max_terms=self.max_terms, tolerance=self.tolerance) return adomian_solver.compute_adomian_polynomials( nonlinear_term, u_series, order)
[docs] def decompose_function(self, func: Callable, x_vals: np.ndarray) -> np.ndarray: """ Decompose a function using Adomian decomposition. Args: func: Function to decompose x_vals: Array of x values Returns: Decomposed function values """ return np.array([func(x) for x in x_vals])
[docs] def solve_equation(self, func: Callable, x_vals: np.ndarray) -> np.ndarray: """ Solve an equation using Adomian decomposition. Args: func: Equation function x_vals: Array of x values Returns: Solution values """ return np.array([func(x) for x in x_vals])
[docs] def create_fractional_integral( method: str, alpha: Union[float, FractionalOrder], **kwargs): """ Create a fractional integral implementation. Args: method: Integration method ("RL" for Riemann-Liouville) alpha: Fractional order **kwargs: Additional parameters Returns: Fractional integral implementation """ from .integrals import create_fractional_integral as create_integral return create_integral(alpha, method=method, **kwargs)
[docs] def create_riesz_fisher_operator( alpha: Union[float, FractionalOrder], **kwargs): """ Create a Riesz-Fisher fractional operator. Args: alpha: Fractional order - α > 0: acts as a derivative - α < 0: acts as an integral - α = 0: acts as identity **kwargs: Additional parameters Returns: RieszFisherOperator instance """ return RieszFisherOperator(alpha, **kwargs)
# Same engine classes as ``algorithms.optimized_methods`` (single numerical path) from ..algorithms.optimized_methods import ( ParallelOptimizedRiemannLiouville, ParallelOptimizedCaputo, ParallelOptimizedGrunwaldLetnikov, )
[docs] def register_fractional_implementations(): """ Register all fractional derivative implementations with the factory. This function should be called during package initialization. """ from .derivatives import derivative_factory # Register derivative implementations derivative_factory.register_implementation( DefinitionType.RIEMANN_LIOUVILLE, RiemannLiouvilleDerivative ) derivative_factory.register_implementation( DefinitionType.CAPUTO, CaputoDerivative ) derivative_factory.register_implementation( DefinitionType.GRUNWALD_LETNIKOV, GrunwaldLetnikovDerivative ) # Register novel derivative implementations derivative_factory.register_implementation( "caputo_fabrizio", CaputoFabrizioDerivative ) derivative_factory.register_implementation( "atangana_baleanu", AtanganaBaleanuDerivative ) # Register special derivative implementations derivative_factory.register_implementation( "fractional_laplacian", FractionalLaplacian ) derivative_factory.register_implementation( "fractional_fourier_transform", FractionalFourierTransform ) # Register additional derivative implementations derivative_factory.register_implementation( DefinitionType.MILLER_ROSS, MillerRossDerivative ) derivative_factory.register_implementation( DefinitionType.WEYL, WeylDerivative ) derivative_factory.register_implementation( DefinitionType.MARCHAUD, MarchaudDerivative ) # Register advanced methods derivative_factory.register_implementation( "hadamard", HadamardDerivative ) derivative_factory.register_implementation( "reiz_feller", ReizFellerDerivative ) # Register parallel-optimized methods derivative_factory.register_implementation( "parallel_riemann_liouville", ParallelOptimizedRiemannLiouville ) derivative_factory.register_implementation( "parallel_caputo", ParallelOptimizedCaputo ) derivative_factory.register_implementation( "parallel_grunwald_letnikov", ParallelOptimizedGrunwaldLetnikov ) # Register special operators derivative_factory.register_implementation( "riesz_fisher", RieszFisherOperator ) logging.getLogger(__name__).debug( "Registered fractional derivative implementations with derivative_factory." )
# Auto-register implementations when module is imported try: register_fractional_implementations() except Exception as exc: logging.getLogger(__name__).warning( "Fractional derivative auto-registration failed: %s", exc, exc_info=True, )