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.
- {polysolve-0.1.0 → polysolve-0.2.0}/LICENSE +1 -1
- {polysolve-0.1.0/src/polysolve.egg-info → polysolve-0.2.0}/PKG-INFO +44 -7
- {polysolve-0.1.0 → polysolve-0.2.0}/README.md +39 -3
- {polysolve-0.1.0 → polysolve-0.2.0}/pyproject.toml +4 -3
- {polysolve-0.1.0 → polysolve-0.2.0}/src/polysolve/__init__.py +116 -21
- {polysolve-0.1.0 → polysolve-0.2.0/src/polysolve.egg-info}/PKG-INFO +44 -7
- {polysolve-0.1.0 → polysolve-0.2.0}/tests/test_polysolve.py +29 -3
- {polysolve-0.1.0 → polysolve-0.2.0}/setup.cfg +0 -0
- {polysolve-0.1.0 → polysolve-0.2.0}/src/polysolve.egg-info/SOURCES.txt +0 -0
- {polysolve-0.1.0 → polysolve-0.2.0}/src/polysolve.egg-info/dependency_links.txt +0 -0
- {polysolve-0.1.0 → polysolve-0.2.0}/src/polysolve.egg-info/requires.txt +0 -0
- {polysolve-0.1.0 → polysolve-0.2.0}/src/polysolve.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025
|
|
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.
|
|
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
|
|
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://
|
|
26
|
-
Project-URL:
|
|
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.
|
|
109
|
+
df1 = f1.derivative()
|
|
109
110
|
print(f"Derivative of f1: {df1}")
|
|
110
111
|
# > Derivative of f1: 4x - 3
|
|
111
112
|
|
|
112
|
-
# 4.
|
|
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
|
-
#
|
|
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
|
+
[](http://makeapullrequest.com)
|
|
148
|
+
[](https://github.com/jono-rams/PolySolve/issues)
|
|
149
|
+
[](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.
|
|
59
|
+
df1 = f1.derivative()
|
|
60
60
|
print(f"Derivative of f1: {df1}")
|
|
61
61
|
# > Derivative of f1: 4x - 3
|
|
62
62
|
|
|
63
|
-
# 4.
|
|
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
|
-
#
|
|
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
|
+
[](http://makeapullrequest.com)
|
|
98
|
+
[](https://github.com/jono-rams/PolySolve/issues)
|
|
99
|
+
[](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.
|
|
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://
|
|
46
|
-
"
|
|
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
|
|
341
|
-
"""
|
|
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
|
|
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,
|
|
440
|
+
def __imul__(self, other: Union['Function', int, float]) -> 'Function':
|
|
359
441
|
"""Performs in-place multiplication by a scalar (func *= 3)."""
|
|
360
|
-
|
|
361
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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://
|
|
26
|
-
Project-URL:
|
|
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.
|
|
109
|
+
df1 = f1.derivative()
|
|
109
110
|
print(f"Derivative of f1: {df1}")
|
|
110
111
|
# > Derivative of f1: 4x - 3
|
|
111
112
|
|
|
112
|
-
# 4.
|
|
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
|
-
#
|
|
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
|
+
[](http://makeapullrequest.com)
|
|
148
|
+
[](https://github.com/jono-rams/PolySolve/issues)
|
|
149
|
+
[](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
|
|
47
|
+
def test_derivative(quadratic_func):
|
|
36
48
|
"""Tests the calculation of the function's derivative."""
|
|
37
|
-
derivative = quadratic_func.
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|