From 3d2c724ad45fe4ee445a43143dfa3507f210772b Mon Sep 17 00:00:00 2001 From: Jonathan Rampersad Date: Tue, 17 Jun 2025 14:06:45 -0400 Subject: [PATCH] feat: Add nth derivative function and fix: typo derivitive->derivative --- src/polysolve/__init__.py | 36 +++++++++++++++++++++++++++++++++--- tests/test_polysolve.py | 11 +++++++++-- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/polysolve/__init__.py b/src/polysolve/__init__.py index ef9c9b1..6f2ae5a 100644 --- a/src/polysolve/__init__.py +++ b/src/polysolve/__init__.py @@ -130,7 +130,7 @@ class Function: Function: A new Function object representing the derivative. """ warnings.warn( - "The 'differential' function has been renamed. Please use 'derivitive' instead.", + "The 'differential' function has been renamed. Please use 'derivative' instead.", DeprecationWarning, stacklevel=2 ) @@ -142,7 +142,7 @@ class Function: return self.derivitive() - def derivitive(self) -> 'Function': + def derivative(self) -> 'Function': """ Calculates the derivative of the function. @@ -160,6 +160,36 @@ class Function: return diff_func + def nth_derivative(self, n: int) -> 'Function': + """ + Calculates the nth derivative of the function. + + Args: + n (int): The order of the derivative to calculate. + + Returns: + Function: A new Function object representing the nth derivative. + """ + self._check_initialized() + + if not isinstance(n, int) or n < 1: + raise ValueError("Derivative order 'n' must be a positive integer.") + + if n > self.largest_exponent: + function = Function(0) + function.set_coeffs([0]) + return function + + if n == 1: + return self.derivative() + + function = self + for _ in range(n): + function = function.derivative() + + return function + + def get_real_roots(self, options: GA_Options = GA_Options(), use_cuda: bool = False) -> np.ndarray: """ Uses a genetic algorithm to find the approximate real roots of the function (where y=0). @@ -429,7 +459,7 @@ if __name__ == '__main__': print(f"Value of f1 at x=5 is: {y}") # Expected: 2*(25) - 3*(5) - 5 = 50 - 15 - 5 = 30 # Find the derivative: 4x - 3 - df1 = f1.differential() + df1 = f1.derivative() print(f"Derivative of f1: {df1}") # --- Root Finding --- diff --git a/tests/test_polysolve.py b/tests/test_polysolve.py index ad03ca5..4bf0f11 100644 --- a/tests/test_polysolve.py +++ b/tests/test_polysolve.py @@ -32,13 +32,20 @@ def test_solve_y(quadratic_func): assert quadratic_func.solve_y(0) == -5.0 assert quadratic_func.solve_y(-1) == 0.0 -def test_differential(quadratic_func): +def test_derivative(quadratic_func): """Tests the calculation of the function's derivative.""" - derivative = quadratic_func.differential() + derivative = quadratic_func.derivative() assert derivative.largest_exponent == 1 # The derivative of 2x^2 - 3x - 5 is 4x - 3 assert np.array_equal(derivative.coefficients, [4, -3]) +def test_nth_derivative(quadratic_func): + """Tests the calculation of the function's 2nd derivative.""" + derivative = quadratic_func.nth_derivative(2) + assert derivative.largest_exponent == 0 + # The derivative of 2x^2 - 3x - 5 is 4x - 3 + assert np.array_equal(derivative.coefficients, [4]) + def test_quadratic_solve(quadratic_func): """Tests the analytical quadratic solver for exact roots.""" roots = quadratic_solve(quadratic_func)