polysolve 0.6.1__tar.gz → 0.6.2__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
  Metadata-Version: 2.4
2
2
  Name: polysolve
3
- Version: 0.6.1
3
+ Version: 0.6.2
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
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  # --- Core Metadata ---
7
7
  name = "polysolve"
8
- version = "0.6.1"
8
+ version = "0.6.2"
9
9
  authors = [
10
10
  { name="Jonathan Rampersad", email="jonathan@jono-rams.work" },
11
11
  ]
@@ -746,6 +746,21 @@ class Function:
746
746
  return NotImplemented
747
747
 
748
748
  return self
749
+
750
+ def __eq__(self, other: object) -> bool:
751
+ """
752
+ Checks if two Function objects are equal by comparing
753
+ their coefficients.
754
+ """
755
+ # Check if the 'other' object is even a Function
756
+ if not isinstance(other, Function):
757
+ return NotImplemented
758
+
759
+ # Ensure both are initialized before trying to access .coefficients
760
+ if not self._initialized or not other._initialized:
761
+ return False
762
+
763
+ return np.array_equal(self.coefficients, other.coefficients)
749
764
 
750
765
 
751
766
  def quadratic_solve(self) -> Optional[List[float]]:
@@ -770,9 +785,35 @@ class Function:
770
785
  return None # No real roots
771
786
 
772
787
  sqrt_discriminant = math.sqrt(discriminant)
773
- root1 = (-b + sqrt_discriminant) / (2 * a)
774
- root2 = (-b - sqrt_discriminant) / (2 * a)
788
+
789
+ # 1. Calculate the first root.
790
+ # We use math.copysign(val, sign) to get the sign of b.
791
+ # This ensures (-b - sign*sqrt) is always an *addition*
792
+ # (or subtraction of a smaller from a larger number),
793
+ # avoiding catastrophic cancellation.
794
+ root1 = (-b - math.copysign(sqrt_discriminant, b)) / (2 * a)
795
+
796
+ # 2. Calculate the second root using Vieta's formulas.
797
+ # We know that root1 * root2 = c / a.
798
+ # This is just a division, which is numerically stable.
799
+
800
+ # Handle the edge case where c=0.
801
+ # If c=0, then root1 is 0.0, and root2 is -b/a
802
+ # We can't divide by root1=0, so we check.
803
+ if root1 == 0.0:
804
+ # If c is also 0, the other root is -b/a
805
+ if c == 0.0:
806
+ root2 = -b / a
807
+ else:
808
+ # This case (root1=0 but c!=0) shouldn't happen
809
+ # with real numbers, but it's safe to just
810
+ # return the one root we found.
811
+ return [0.0]
812
+ else:
813
+ # Standard case: Use Vieta's formula
814
+ root2 = (c / a) / root1
775
815
 
816
+ # Return roots in a consistent order
776
817
  return [root1, root2]
777
818
 
778
819
  # Example Usage
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polysolve
3
- Version: 0.6.1
3
+ Version: 0.6.2
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
@@ -37,6 +37,12 @@ def m_func_2() -> Function:
37
37
  f.set_coeffs([5, -4])
38
38
  return f
39
39
 
40
+ @pytest.fixture
41
+ def base_func():
42
+ f = Function(2)
43
+ f.set_coeffs([1, 2, 3])
44
+ return f
45
+
40
46
  # --- Core Functionality Tests ---
41
47
 
42
48
  def test_solve_y(quadratic_func):
@@ -95,6 +101,32 @@ def test_function_multiplication(m_func_1, m_func_2):
95
101
  assert result.largest_exponent == 3
96
102
  assert np.array_equal(result.coefficients, [10, 7, -7, -4])
97
103
 
104
+ def test_equality(base_func):
105
+ """Tests the __eq__ method for the Function class."""
106
+
107
+ # 1. Test for equality with a new, identical object
108
+ f_identical = Function(2)
109
+ f_identical.set_coeffs([1, 2, 3])
110
+ assert base_func == f_identical
111
+
112
+ # 2. Test for inequality (different coefficients)
113
+ f_different = Function(2)
114
+ f_different.set_coeffs([1, 9, 3])
115
+ assert base_func != f_different
116
+
117
+ # 3. Test for inequality (different degree)
118
+ f_diff_degree = Function(1)
119
+ f_diff_degree.set_coeffs([1, 2])
120
+ assert base_func != f_diff_degree
121
+
122
+ # 4. Test against a different type
123
+ assert base_func != "some_string"
124
+ assert base_func != 123
125
+
126
+ # 5. Test against an uninitialized Function
127
+ f_uninitialized = Function(2)
128
+ assert base_func != f_uninitialized
129
+
98
130
  # --- Genetic Algorithm Root-Finding Tests ---
99
131
 
100
132
  def test_get_real_roots_numpy(quadratic_func):
File without changes
File without changes
File without changes