polysolve 0.1.0__tar.gz → 0.2.0__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.
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 jono
3
+ Copyright (c) 2025 Jonathan Rampersad
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
6
  associated documentation files (the "Software"), to deal in the Software without restriction, including
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polysolve
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: A Python library for representing, manipulating, and solving exponential functions using analytical methods and genetic algorithms, with optional CUDA acceleration.
5
5
  Author-email: Jonathan Rampersad <jonathan@jono-rams.work>
6
6
  License: MIT License
7
7
 
8
- Copyright (c) 2025 jono
8
+ Copyright (c) 2025 Jonathan Rampersad
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
11
11
  associated documentation files (the "Software"), to deal in the Software without restriction, including
@@ -22,8 +22,9 @@ License: MIT License
22
22
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23
23
  USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
- Project-URL: Homepage, https://gitea.jono-rams.work/jono/PolySolve
26
- Project-URL: Bug Tracker, https://gitea.jono-rams.work/jono/PolySolve/issues
25
+ Project-URL: Homepage, https://github.com/jono-rams/PolySolve
26
+ Project-URL: Source Code, https://github.com/jono-rams/PolySolve
27
+ Project-URL: Bug Tracker, https://github.com/jono-rams/PolySolve/issues
27
28
  Keywords: math,polynomial,genetic algorithm,cuda,equation solver
28
29
  Classifier: Development Status :: 4 - Beta
29
30
  Classifier: Intended Audience :: Developers
@@ -105,17 +106,22 @@ print(f"Value of f1 at x=5 is: {y_val}")
105
106
  # > Value of f1 at x=5 is: 30.0
106
107
 
107
108
  # 3. Get the derivative: 4x - 3
108
- df1 = f1.differential()
109
+ df1 = f1.derivative()
109
110
  print(f"Derivative of f1: {df1}")
110
111
  # > Derivative of f1: 4x - 3
111
112
 
112
- # 4. Find roots analytically using the quadratic formula
113
+ # 4. Get the 2nd derivative: 4
114
+ df1 = f1.nth_derivative(2)
115
+ print(f"2nd Derivative of f1: {df1}")
116
+ # > Derivative of f1: 4
117
+
118
+ # 5. Find roots analytically using the quadratic formula
113
119
  # This is exact and fast for degree-2 polynomials.
114
120
  roots_analytic = quadratic_solve(f1)
115
121
  print(f"Analytic roots: {sorted(roots_analytic)}")
116
122
  # > Analytic roots: [-1.0, 2.5]
117
123
 
118
- # 5. Find roots with the genetic algorithm (CPU)
124
+ # 6. Find roots with the genetic algorithm (CPU)
119
125
  # This can solve polynomials of any degree.
120
126
  ga_opts = GA_Options(num_of_generations=20)
121
127
  roots_ga = f1.get_real_roots(ga_opts, use_cuda=False)
@@ -138,10 +144,41 @@ While the code may work on other configurations, all contributions must pass the
138
144
 
139
145
  ## Contributing
140
146
 
147
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
148
+ [![GitHub issues](https://img.shields.io/github/issues/jono-rams/PolySolve.svg?style=flat-square)](https://github.com/jono-rams/PolySolve/issues)
149
+ [![GitHub pull requests](https://img.shields.io/github/issues-pr/jono-rams/PolySolve.svg?style=flat-square)](https://github.com/jono-rams/PolySolve/pulls)
150
+
141
151
  Contributions are welcome! Whether it's a bug report, a feature request, or a pull request, please feel free to get involved.
142
152
 
143
153
  Please read our `CONTRIBUTING.md` file for details on our code of conduct and the process for submitting pull requests.
144
154
 
155
+ ## Contributors
156
+
157
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
158
+ <!-- prettier-ignore-start -->
159
+ <!-- markdownlint-disable -->
160
+ <table>
161
+ <tbody>
162
+ <tr>
163
+ <td align="center" valign="top" width="14.28%"><a href="https://jono-rams.work"><img src="https://avatars.githubusercontent.com/u/29872001?v=4?s=100" width="100px;" alt="Jonathan Rampersad"/><br /><sub><b>Jonathan Rampersad</b></sub></a><br /><a href="https://github.com/jono-rams/PolySolve/commits?author=jono-rams" title="Code">💻</a> <a href="https://github.com/jono-rams/PolySolve/commits?author=jono-rams" title="Documentation">📖</a> <a href="#infra-jono-rams" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
164
+ </tr>
165
+ </tbody>
166
+ <tfoot>
167
+ <tr>
168
+ <td align="center" size="13px" colspan="7">
169
+ <img src="https://raw.githubusercontent.com/all-contributors/all-contributors-cli/1b8533af435da9854653492b1327a23a4dbd0a10/assets/logo-small.svg">
170
+ <a href="https://all-contributors.js.org/docs/en/bot/usage">Add your contributions</a>
171
+ </img>
172
+ </td>
173
+ </tr>
174
+ </tfoot>
175
+ </table>
176
+
177
+ <!-- markdownlint-restore -->
178
+ <!-- prettier-ignore-end -->
179
+
180
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
181
+
145
182
  ## License
146
183
 
147
184
  This project is licensed under the MIT License - see the `LICENSE` file for details.
@@ -56,17 +56,22 @@ print(f"Value of f1 at x=5 is: {y_val}")
56
56
  # > Value of f1 at x=5 is: 30.0
57
57
 
58
58
  # 3. Get the derivative: 4x - 3
59
- df1 = f1.differential()
59
+ df1 = f1.derivative()
60
60
  print(f"Derivative of f1: {df1}")
61
61
  # > Derivative of f1: 4x - 3
62
62
 
63
- # 4. Find roots analytically using the quadratic formula
63
+ # 4. Get the 2nd derivative: 4
64
+ df1 = f1.nth_derivative(2)
65
+ print(f"2nd Derivative of f1: {df1}")
66
+ # > Derivative of f1: 4
67
+
68
+ # 5. Find roots analytically using the quadratic formula
64
69
  # This is exact and fast for degree-2 polynomials.
65
70
  roots_analytic = quadratic_solve(f1)
66
71
  print(f"Analytic roots: {sorted(roots_analytic)}")
67
72
  # > Analytic roots: [-1.0, 2.5]
68
73
 
69
- # 5. Find roots with the genetic algorithm (CPU)
74
+ # 6. Find roots with the genetic algorithm (CPU)
70
75
  # This can solve polynomials of any degree.
71
76
  ga_opts = GA_Options(num_of_generations=20)
72
77
  roots_ga = f1.get_real_roots(ga_opts, use_cuda=False)
@@ -89,10 +94,41 @@ While the code may work on other configurations, all contributions must pass the
89
94
 
90
95
  ## Contributing
91
96
 
97
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
98
+ [![GitHub issues](https://img.shields.io/github/issues/jono-rams/PolySolve.svg?style=flat-square)](https://github.com/jono-rams/PolySolve/issues)
99
+ [![GitHub pull requests](https://img.shields.io/github/issues-pr/jono-rams/PolySolve.svg?style=flat-square)](https://github.com/jono-rams/PolySolve/pulls)
100
+
92
101
  Contributions are welcome! Whether it's a bug report, a feature request, or a pull request, please feel free to get involved.
93
102
 
94
103
  Please read our `CONTRIBUTING.md` file for details on our code of conduct and the process for submitting pull requests.
95
104
 
105
+ ## Contributors
106
+
107
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
108
+ <!-- prettier-ignore-start -->
109
+ <!-- markdownlint-disable -->
110
+ <table>
111
+ <tbody>
112
+ <tr>
113
+ <td align="center" valign="top" width="14.28%"><a href="https://jono-rams.work"><img src="https://avatars.githubusercontent.com/u/29872001?v=4?s=100" width="100px;" alt="Jonathan Rampersad"/><br /><sub><b>Jonathan Rampersad</b></sub></a><br /><a href="https://github.com/jono-rams/PolySolve/commits?author=jono-rams" title="Code">💻</a> <a href="https://github.com/jono-rams/PolySolve/commits?author=jono-rams" title="Documentation">📖</a> <a href="#infra-jono-rams" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
114
+ </tr>
115
+ </tbody>
116
+ <tfoot>
117
+ <tr>
118
+ <td align="center" size="13px" colspan="7">
119
+ <img src="https://raw.githubusercontent.com/all-contributors/all-contributors-cli/1b8533af435da9854653492b1327a23a4dbd0a10/assets/logo-small.svg">
120
+ <a href="https://all-contributors.js.org/docs/en/bot/usage">Add your contributions</a>
121
+ </img>
122
+ </td>
123
+ </tr>
124
+ </tfoot>
125
+ </table>
126
+
127
+ <!-- markdownlint-restore -->
128
+ <!-- prettier-ignore-end -->
129
+
130
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
131
+
96
132
  ## License
97
133
 
98
134
  This project is licensed under the MIT License - see the `LICENSE` file for details.
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  # --- Core Metadata ---
7
7
  name = "polysolve"
8
- version = "0.1.0"
8
+ version = "0.2.0"
9
9
  authors = [
10
10
  { name="Jonathan Rampersad", email="jonathan@jono-rams.work" },
11
11
  ]
@@ -42,5 +42,6 @@ cuda12 = ["cupy-cuda12x"]
42
42
  dev = ["pytest"]
43
43
 
44
44
  [project.urls]
45
- Homepage = "https://gitea.jono-rams.work/jono/PolySolve"
46
- "Bug Tracker" = "https://gitea.jono-rams.work/jono/PolySolve/issues"
45
+ Homepage = "https://github.com/jono-rams/PolySolve"
46
+ "Source Code" = "https://github.com/jono-rams/PolySolve"
47
+ "Bug Tracker" = "https://github.com/jono-rams/PolySolve/issues"
@@ -1,7 +1,7 @@
1
1
  import math
2
2
  import numpy as np
3
3
  from dataclasses import dataclass
4
- from typing import List, Optional
4
+ from typing import List, Optional, Union
5
5
  import warnings
6
6
 
7
7
  # Attempt to import CuPy for CUDA acceleration.
@@ -108,6 +108,11 @@ class Function:
108
108
  def largest_exponent(self) -> int:
109
109
  """Returns the largest exponent of the function."""
110
110
  return self._largest_exponent
111
+
112
+ @property
113
+ def degree(self) -> int:
114
+ """Returns the largest exponent of the function."""
115
+ return self._largest_exponent
111
116
 
112
117
  def solve_y(self, x_val: float) -> float:
113
118
  """
@@ -129,15 +134,66 @@ class Function:
129
134
  Returns:
130
135
  Function: A new Function object representing the derivative.
131
136
  """
137
+ warnings.warn(
138
+ "The 'differential' function has been renamed. Please use 'derivative' instead.",
139
+ DeprecationWarning,
140
+ stacklevel=2
141
+ )
142
+
132
143
  self._check_initialized()
133
144
  if self._largest_exponent == 0:
134
145
  raise ValueError("Cannot differentiate a constant (Function of degree 0).")
135
146
 
147
+ return self.derivitive()
148
+
149
+
150
+ def derivative(self) -> 'Function':
151
+ """
152
+ Calculates the derivative of the function.
153
+
154
+ Returns:
155
+ Function: A new Function object representing the derivative.
156
+ """
157
+ self._check_initialized()
158
+ if self._largest_exponent == 0:
159
+ raise ValueError("Cannot differentiate a constant (Function of degree 0).")
160
+
136
161
  derivative_coefficients = np.polyder(self.coefficients)
137
162
 
138
163
  diff_func = Function(self._largest_exponent - 1)
139
164
  diff_func.set_coeffs(derivative_coefficients.tolist())
140
165
  return diff_func
166
+
167
+
168
+ def nth_derivative(self, n: int) -> 'Function':
169
+ """
170
+ Calculates the nth derivative of the function.
171
+
172
+ Args:
173
+ n (int): The order of the derivative to calculate.
174
+
175
+ Returns:
176
+ Function: A new Function object representing the nth derivative.
177
+ """
178
+ self._check_initialized()
179
+
180
+ if not isinstance(n, int) or n < 1:
181
+ raise ValueError("Derivative order 'n' must be a positive integer.")
182
+
183
+ if n > self.largest_exponent:
184
+ function = Function(0)
185
+ function.set_coeffs([0])
186
+ return function
187
+
188
+ if n == 1:
189
+ return self.derivative()
190
+
191
+ function = self
192
+ for _ in range(n):
193
+ function = function.derivative()
194
+
195
+ return function
196
+
141
197
 
142
198
  def get_real_roots(self, options: GA_Options = GA_Options(), use_cuda: bool = False) -> np.ndarray:
143
199
  """
@@ -336,34 +392,55 @@ class Function:
336
392
  result_func = Function(len(new_coefficients) - 1)
337
393
  result_func.set_coeffs(new_coefficients.tolist())
338
394
  return result_func
339
-
340
- def __mul__(self, scalar: int) -> 'Function':
341
- """Multiplies the function by a scalar constant."""
342
- self._check_initialized()
343
- if not isinstance(scalar, (int, float)):
344
- return NotImplemented
345
- if scalar == 0:
346
- raise ValueError("Cannot multiply a function by 0.")
395
+
396
+ def _multiply_by_scalar(self, scalar: Union[int, float]) -> 'Function':
397
+ """Helper method to multiply the function by a scalar constant."""
398
+ self._check_initialized() # It's good practice to check here too
347
399
 
400
+ if scalar == 0:
401
+ result_func = Function(0)
402
+ result_func.set_coeffs([0])
403
+ return result_func
404
+
348
405
  new_coefficients = self.coefficients * scalar
349
-
406
+
350
407
  result_func = Function(self._largest_exponent)
351
408
  result_func.set_coeffs(new_coefficients.tolist())
352
409
  return result_func
353
410
 
354
- def __rmul__(self, scalar: int) -> 'Function':
411
+ def _multiply_by_function(self, other: 'Function') -> 'Function':
412
+ """Helper method for polynomial multiplication (Function * Function)."""
413
+ self._check_initialized()
414
+ other._check_initialized()
415
+
416
+ # np.polymul performs convolution of coefficients to multiply polynomials
417
+ new_coefficients = np.polymul(self.coefficients, other.coefficients)
418
+
419
+ # The degree of the resulting polynomial is derived from the new coefficients
420
+ new_degree = len(new_coefficients) - 1
421
+
422
+ result_func = Function(new_degree)
423
+ result_func.set_coeffs(new_coefficients.tolist())
424
+ return result_func
425
+
426
+ def __mul__(self, other: Union['Function', int, float]) -> 'Function':
427
+ """Multiplies the function by a scalar constant."""
428
+ if isinstance(other, (int, float)):
429
+ return self._multiply_by_scalar(other)
430
+ elif isinstance(other, self.__class__):
431
+ return self._multiply_by_function(other)
432
+ else:
433
+ return NotImplemented
434
+
435
+ def __rmul__(self, scalar: Union[int, float]) -> 'Function':
355
436
  """Handles scalar multiplication from the right (e.g., 3 * func)."""
437
+
356
438
  return self.__mul__(scalar)
357
439
 
358
- def __imul__(self, scalar: int) -> 'Function':
440
+ def __imul__(self, other: Union['Function', int, float]) -> 'Function':
359
441
  """Performs in-place multiplication by a scalar (func *= 3)."""
360
- self._check_initialized()
361
- if not isinstance(scalar, (int, float)):
362
- return NotImplemented
363
- if scalar == 0:
364
- raise ValueError("Cannot multiply a function by 0.")
365
-
366
- self.coefficients *= scalar
442
+
443
+ self.coefficients *= other
367
444
  return self
368
445
 
369
446
 
@@ -408,9 +485,13 @@ if __name__ == '__main__':
408
485
  print(f"Value of f1 at x=5 is: {y}") # Expected: 2*(25) - 3*(5) - 5 = 50 - 15 - 5 = 30
409
486
 
410
487
  # Find the derivative: 4x - 3
411
- df1 = f1.differential()
488
+ df1 = f1.derivative()
412
489
  print(f"Derivative of f1: {df1}")
413
490
 
491
+ # Find the second derivative: 4
492
+ ddf1 = f1.nth_derivative(2)
493
+ print(f"Second derivative of f1: {ddf1}")
494
+
414
495
  # --- Root Finding ---
415
496
  # 1. Analytical solution for quadratic
416
497
  roots_analytic = quadratic_solve(f1)
@@ -448,4 +529,18 @@ if __name__ == '__main__':
448
529
 
449
530
  # Multiplication: (x + 10) * 3 = 3x + 30
450
531
  f_mul = f2 * 3
451
- print(f"f2 * 3 = {f_mul}")
532
+ print(f"f2 * 3 = {f_mul}")
533
+
534
+ # f3 represents 2x^2 + 3x + 1
535
+ f3 = Function(2)
536
+ f3.set_coeffs([2, 3, 1])
537
+ print(f"Function f3: {f3}")
538
+
539
+ # f4 represents 5x - 4
540
+ f4 = Function(1)
541
+ f4.set_coeffs([5, -4])
542
+ print(f"Function f4: {f4}")
543
+
544
+ # Multiply the two functions
545
+ product_func = f3 * f4
546
+ print(f"f3 * f4 = {product_func}")
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polysolve
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: A Python library for representing, manipulating, and solving exponential functions using analytical methods and genetic algorithms, with optional CUDA acceleration.
5
5
  Author-email: Jonathan Rampersad <jonathan@jono-rams.work>
6
6
  License: MIT License
7
7
 
8
- Copyright (c) 2025 jono
8
+ Copyright (c) 2025 Jonathan Rampersad
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
11
11
  associated documentation files (the "Software"), to deal in the Software without restriction, including
@@ -22,8 +22,9 @@ License: MIT License
22
22
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23
23
  USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
- Project-URL: Homepage, https://gitea.jono-rams.work/jono/PolySolve
26
- Project-URL: Bug Tracker, https://gitea.jono-rams.work/jono/PolySolve/issues
25
+ Project-URL: Homepage, https://github.com/jono-rams/PolySolve
26
+ Project-URL: Source Code, https://github.com/jono-rams/PolySolve
27
+ Project-URL: Bug Tracker, https://github.com/jono-rams/PolySolve/issues
27
28
  Keywords: math,polynomial,genetic algorithm,cuda,equation solver
28
29
  Classifier: Development Status :: 4 - Beta
29
30
  Classifier: Intended Audience :: Developers
@@ -105,17 +106,22 @@ print(f"Value of f1 at x=5 is: {y_val}")
105
106
  # > Value of f1 at x=5 is: 30.0
106
107
 
107
108
  # 3. Get the derivative: 4x - 3
108
- df1 = f1.differential()
109
+ df1 = f1.derivative()
109
110
  print(f"Derivative of f1: {df1}")
110
111
  # > Derivative of f1: 4x - 3
111
112
 
112
- # 4. Find roots analytically using the quadratic formula
113
+ # 4. Get the 2nd derivative: 4
114
+ df1 = f1.nth_derivative(2)
115
+ print(f"2nd Derivative of f1: {df1}")
116
+ # > Derivative of f1: 4
117
+
118
+ # 5. Find roots analytically using the quadratic formula
113
119
  # This is exact and fast for degree-2 polynomials.
114
120
  roots_analytic = quadratic_solve(f1)
115
121
  print(f"Analytic roots: {sorted(roots_analytic)}")
116
122
  # > Analytic roots: [-1.0, 2.5]
117
123
 
118
- # 5. Find roots with the genetic algorithm (CPU)
124
+ # 6. Find roots with the genetic algorithm (CPU)
119
125
  # This can solve polynomials of any degree.
120
126
  ga_opts = GA_Options(num_of_generations=20)
121
127
  roots_ga = f1.get_real_roots(ga_opts, use_cuda=False)
@@ -138,10 +144,41 @@ While the code may work on other configurations, all contributions must pass the
138
144
 
139
145
  ## Contributing
140
146
 
147
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
148
+ [![GitHub issues](https://img.shields.io/github/issues/jono-rams/PolySolve.svg?style=flat-square)](https://github.com/jono-rams/PolySolve/issues)
149
+ [![GitHub pull requests](https://img.shields.io/github/issues-pr/jono-rams/PolySolve.svg?style=flat-square)](https://github.com/jono-rams/PolySolve/pulls)
150
+
141
151
  Contributions are welcome! Whether it's a bug report, a feature request, or a pull request, please feel free to get involved.
142
152
 
143
153
  Please read our `CONTRIBUTING.md` file for details on our code of conduct and the process for submitting pull requests.
144
154
 
155
+ ## Contributors
156
+
157
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
158
+ <!-- prettier-ignore-start -->
159
+ <!-- markdownlint-disable -->
160
+ <table>
161
+ <tbody>
162
+ <tr>
163
+ <td align="center" valign="top" width="14.28%"><a href="https://jono-rams.work"><img src="https://avatars.githubusercontent.com/u/29872001?v=4?s=100" width="100px;" alt="Jonathan Rampersad"/><br /><sub><b>Jonathan Rampersad</b></sub></a><br /><a href="https://github.com/jono-rams/PolySolve/commits?author=jono-rams" title="Code">💻</a> <a href="https://github.com/jono-rams/PolySolve/commits?author=jono-rams" title="Documentation">📖</a> <a href="#infra-jono-rams" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
164
+ </tr>
165
+ </tbody>
166
+ <tfoot>
167
+ <tr>
168
+ <td align="center" size="13px" colspan="7">
169
+ <img src="https://raw.githubusercontent.com/all-contributors/all-contributors-cli/1b8533af435da9854653492b1327a23a4dbd0a10/assets/logo-small.svg">
170
+ <a href="https://all-contributors.js.org/docs/en/bot/usage">Add your contributions</a>
171
+ </img>
172
+ </td>
173
+ </tr>
174
+ </tfoot>
175
+ </table>
176
+
177
+ <!-- markdownlint-restore -->
178
+ <!-- prettier-ignore-end -->
179
+
180
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
181
+
145
182
  ## License
146
183
 
147
184
  This project is licensed under the MIT License - see the `LICENSE` file for details.
@@ -24,6 +24,18 @@ def linear_func() -> Function:
24
24
  f.set_coeffs([1, 10])
25
25
  return f
26
26
 
27
+ @pytest.fixture
28
+ def m_func_1() -> Function:
29
+ f = Function(2)
30
+ f.set_coeffs([2, 3, 1])
31
+ return f
32
+
33
+ @pytest.fixture
34
+ def m_func_2() -> Function:
35
+ f = Function(1)
36
+ f.set_coeffs([5, -4])
37
+ return f
38
+
27
39
  # --- Core Functionality Tests ---
28
40
 
29
41
  def test_solve_y(quadratic_func):
@@ -32,13 +44,20 @@ def test_solve_y(quadratic_func):
32
44
  assert quadratic_func.solve_y(0) == -5.0
33
45
  assert quadratic_func.solve_y(-1) == 0.0
34
46
 
35
- def test_differential(quadratic_func):
47
+ def test_derivative(quadratic_func):
36
48
  """Tests the calculation of the function's derivative."""
37
- derivative = quadratic_func.differential()
49
+ derivative = quadratic_func.derivative()
38
50
  assert derivative.largest_exponent == 1
39
51
  # The derivative of 2x^2 - 3x - 5 is 4x - 3
40
52
  assert np.array_equal(derivative.coefficients, [4, -3])
41
53
 
54
+ def test_nth_derivative(quadratic_func):
55
+ """Tests the calculation of the function's 2nd derivative."""
56
+ derivative = quadratic_func.nth_derivative(2)
57
+ assert derivative.largest_exponent == 0
58
+ # The derivative of 2x^2 - 3x - 5 is 4x - 3
59
+ assert np.array_equal(derivative.coefficients, [4])
60
+
42
61
  def test_quadratic_solve(quadratic_func):
43
62
  """Tests the analytical quadratic solver for exact roots."""
44
63
  roots = quadratic_solve(quadratic_func)
@@ -61,13 +80,20 @@ def test_subtraction(quadratic_func, linear_func):
61
80
  assert result.largest_exponent == 2
62
81
  assert np.array_equal(result.coefficients, [2, -4, -15])
63
82
 
64
- def test_multiplication(linear_func):
83
+ def test_scalar_multiplication(linear_func):
65
84
  """Tests the multiplication of a Function object by a scalar."""
66
85
  # (x + 10) * 3 = 3x + 30
67
86
  result = linear_func * 3
68
87
  assert result.largest_exponent == 1
69
88
  assert np.array_equal(result.coefficients, [3, 30])
70
89
 
90
+ def test_function_multiplication(m_func_1, m_func_2):
91
+ """Tests the multiplication of two Function objects."""
92
+ # (2x^2 + 3x + 1) * (5x -4) = 10x^3 + 7x^2 - 7x -4
93
+ result = m_func_1 * m_func_2
94
+ assert result.largest_exponent == 3
95
+ assert np.array_equal(result.coefficients, [10, 7, -7, -4])
96
+
71
97
  # --- Genetic Algorithm Root-Finding Tests ---
72
98
 
73
99
  def test_get_real_roots_numpy(quadratic_func):
File without changes