twosquares 0.0.3__cp312-cp312-win_amd64.whl → 0.0.4__cp312-cp312-win_amd64.whl

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.

Potentially problematic release.


This version of twosquares might be problematic. Click here for more details.

@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: twosquares
3
+ Version: 0.0.4
4
+ Summary: A package for very efficiently decomposing a number n into all possible x**2 + y**2 = n solutions.
5
+ Author-email: Ryan Heard <ryanwheard@gmail.com>
6
+ License: MIT
7
+ Project-URL: Repository, https://github.com/rheard/twosquares
8
+ Keywords: math
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: Implementation :: CPython
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: sympy<=1.12.1
20
+ Requires-Dist: complexint>=0.0.5
21
+ Dynamic: license
22
+ Dynamic: license-file
23
+
24
+ I've defined this process as "decomposing" a number $n$ into the possible solutions $x^2 + y^2 = n$.
25
+
26
+ # twosquares
27
+
28
+ `twosquares` exposes two simple methods for this number-theory task:
29
+
30
+ * `decompose_prime(p)` — find the unique non-negative pair (a, b) with $a^2 + b^2 = p$ for $p = 2$ or any prime $p \equiv 1 \bmod 4$.
31
+
32
+ * `decompose_number(n)` — find the unique non-negative pairs (a, b) with $a^2 + b^2 = n$ for any number $n$.
33
+
34
+ ### Algorithm
35
+ Here is an explanation for the algorithm in this repo:
36
+
37
+ This builds on the algorithm described by Stan Wagon (1990),
38
+ based on work by Serret and Hermite (1848), and Cornacchia (1908).
39
+
40
+ The first thing to know is that there is a deterministic algorithm to quickly find the 1 and only solution for primes $p$ that are $\equiv 1 \bmod 4$.
41
+ The solution is to simply use Euclid's algorithm. This is the heart of the general algorithm for any $n$, which is described here:
42
+
43
+ 1. Factor $n$. This is the hardest, most time-consuming step.
44
+ We'll say this factoring has the form $2^t * (p_1 ^ {k_1} * p_2 ^ {k_2} * ...) * (q_1 ^ {j_1} * q_2 ^ {j_2} * ...)$
45
+ Where $t$ is the 2's exponent, all of the primes $p$ are $\equiv 1 \bmod 4$, and all of the primes $q$ are $\equiv 3 \bmod 4$
46
+
47
+ 1. If any of primes $q$ (which are $\equiv 3 \bmod 4$) have an exponent $j$ that is odd, then there are no solutions.
48
+ 2. If there are no primes $p$ (that are $\equiv 1 \bmod 4$), there are no solutions.
49
+
50
+ 2. Construct a "base number" to use during the combinatorics later. We'll start with the 2's power, we will start the base number off as $(1 - i)^t$
51
+
52
+ 3. Now, for each prime $q^j$ in the factoring (the ones $\equiv 3 \bmod 4$):
53
+
54
+ 1. Multiply the base number by $(-qi)^{ j / 2 }$ Where $-qi$ is an imaginary number with $0$ real and $-q$ complex part, and it is raised to the power of $j / 2$.
55
+ Note that from the rules laid out in step 1 above, $j$ is guaranteed to be even so this will always be an integer.
56
+
57
+ 4. Next will begin the combinatorics for the $p$ group, however 1 member of the $p$ group does not need to engage in this combinatorics (reasons why below).
58
+ So we'll select the first prime $p \equiv 3 \bmod 4$, and create it's "imaginary decomposition". This is a complex number $x+yi$ made from the solution $x^2 + y^2 = p$.
59
+ Multiply the base number by this number too.
60
+
61
+ 1. If the exponent for this $p$ (the $k$ value) was 1 then $p$ can be removed entirely from the group.
62
+ 2. If $k$ was greater than $1$, it should be decremented, and the remaining instances of $p$ in the factorization still need to undergo the following combinatorics.
63
+
64
+ 5. Now we need to use combinations of (`True`, `False`) of length $\sum k$ to drive the combinatorics going forward.
65
+ Python has a product method for this, or you can simply count up using binary numbers to `1<<sum(k)` and look at the bits of this counter.
66
+
67
+ For every possible combination of true/false called "choices":
68
+ 1. Start this solution with the base number.
69
+ 2. For each factor $p$ left, one time for each exponent $k$:
70
+
71
+ 1. Get the next "choice" (true/false)
72
+ 2. Get the "imaginary decomposition" of the factor, either $x+yi$ if the choice was true or $x-yi$ if the choice was false
73
+ 3. Multiply the total number by this either positive or negative imaginary decomposition
74
+
75
+ 3. The real and imaginary part of the total number now constitute a solution for $x^2 + y^2 = n$! Amazing!!
76
+
77
+ 1. The numbers are then sorted so that $x<y$, and this is a unique solution that may or may not have been found already.
78
+
79
+ Doing this we can rapidly break any number $n$ up into all of its possible $x^2 + y^2$ solutions!
80
+
81
+ Note: Remember how we didn't do combinatorics for a single exponent of the $p$ group?
82
+ If that exponent of that base were included, we would simply get back the same solutions but in reverse order.
83
+ The problem uses addition and is associative, so we do not care about order.
84
+ Thus we can effectively halve the compute time with the combinatorics by excluding the other half of that particular exponent.
85
+
86
+ ### Example
87
+
88
+ As an example, lets look at $n = 19890$.
89
+ This number's factorization looks like: $2 * 3^2 * 5 * 13 * 17$.
90
+ The set of primes $p$ (that are $\equiv 1 \bmod 4$) are $5$, $13$ and $17$ (all having an exponent $k$ of $1$).
91
+ The set of primes $q$ (that are $\equiv 3 \bmod 4$) is $3$, with the only exponent $j$ being 2.
92
+
93
+ Starting with the rules we can see that all of the primes $q$ have an even exponent ($2$ in this case) and there are primes in the $p$ group, so there must be at least 1 solution for this number!
94
+
95
+ The 2's exponent is $1$, so we will say our base number is $(1-i)^1$ or just $1 - i$
96
+
97
+ There is only a single prime in the $q$ group, so we will multiply the base number by $(-3i)^1$ which gives $-3 - 3i$
98
+
99
+ We'll take the first prime in the $p$ group ($5$) and decompose that number, we find we get $5 = 1^2 + 2^2$.
100
+ We use this composition to construct a complex number $1 + 2i$. Now multiply the base number by this.
101
+ This is the real base number, which is $3 - 9i$
102
+
103
+ Now for combinatorics to produce all the different solutions. The remaining 2 primes $p$ have the following decompositions:
104
+
105
+ $13 = 2^2 + 3^2$
106
+
107
+ $17 = 1^2 + 4^2$
108
+
109
+ 1. Using the positive values: Multiply the base number by $2+3i$ and $1+4i$ (from the solutions for both of these primes),
110
+ and we get $69 + 123i$, which is magically our first solution: $19890 = 69^2 + 123^2$
111
+
112
+ 2. Using the negative values: Multiply the base number by $2-3i$ and $1-4i$, and we get $-129 + 57i$,
113
+ which using the absolute values of these gives our next solution: $19890 = 129^2 + 57^2$
114
+
115
+ 3. Using positive for 13 and negative for 17: Multiply the base number by $2+3i$ and $1-4i$, and we get $-3 - 141i$, which again gives our next solution: $19890 = 3^2 + 141^2$
116
+
117
+ 4. Lastly it should be obvious: Multiply the base number by $2-3i$ and $1+4i$, we get our final answer: $19890 = 87^2 + 111^2$
118
+
119
+ So in conclusion, the following are all equal to $19890$: $69^2 + 123^2$, $129^2 + 57^2$, $3^2 + 141^2$, $87^2 + 111^2$
120
+
121
+ Everything laid out in this example is performed by the following Python code:
122
+
123
+ ```python
124
+ from twosquares import decompose_number
125
+
126
+ print(decompose_number(19890)) # prints {(69, 123), (57, 129), (3, 141), (87, 111)}
127
+ ```
128
+
129
+ ## Advanced Usage
130
+
131
+ It is possible to skip the factoring step and instead build a factored dictionary and pass that to `decompose_number` instead.
132
+ `decompose_number({2: 1, 3: 2, 5: 1, 13: 1, 17: 1})` will produce the same result as `decompose_number(19890)`.
133
+ If the factoring dictionary has been carefully crafted to comply with the rules laid out in step 1 of the algorithm section above,
134
+ then `limited_checks=True` can be passed as an argument to skip these validations.
135
+
136
+ It is an interesting fact that the upper bound of solutions can be quickly computed by $\prod (j + 1)$.
137
+ If a minimum number of solutions is required, this can be quickly validated by passing `check_count` as an integer.
@@ -0,0 +1,7 @@
1
+ twosquares.cp312-win_amd64.pyd,sha256=KZJrUgxlmy6GjrCmzSdpuKFarebSvhyQiZxXcLYp39k,57344
2
+ twosquares-0.0.4.dist-info/licenses/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
3
+ twosquares-stubs/__init__.pyi,sha256=zxJdomt96aOuU9ZVM192-HjNhFWFOZqfQ0As6NzKqWY,223
4
+ twosquares-0.0.4.dist-info/METADATA,sha256=38WJyEvAjhKIDXaUQKzKYJSLmfLczvBidKdCWZM98qU,8053
5
+ twosquares-0.0.4.dist-info/WHEEL,sha256=8UP9x9puWI0P1V_d7K2oMTBqfeLNm21CTzZ_Ptr0NXU,101
6
+ twosquares-0.0.4.dist-info/top_level.txt,sha256=cmwZJ1cFpL4b3RqCi5RJt2KNOy2visqUEzW4ug0tapc,28
7
+ twosquares-0.0.4.dist-info/RECORD,,
Binary file
@@ -1,31 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: twosquares
3
- Version: 0.0.3
4
- Summary: A package for very efficiently decomposing a number n into all possible x**2 + y**2 = n solutions.
5
- Author-email: Ryan Heard <ryanwheard@gmail.com>
6
- License: MIT
7
- Project-URL: Repository, https://github.com/rheard/twosquares
8
- Keywords: math
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: Programming Language :: Python :: 3.9
11
- Classifier: Programming Language :: Python :: 3.10
12
- Classifier: Programming Language :: Python :: 3.11
13
- Classifier: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
15
- Classifier: Programming Language :: Python :: Implementation :: CPython
16
- Requires-Python: >=3.9
17
- Description-Content-Type: text/markdown
18
- License-File: LICENSE
19
- Requires-Dist: sympy<=1.12.1
20
- Requires-Dist: complexint>=0.0.5
21
- Dynamic: license
22
- Dynamic: license-file
23
-
24
- # twosquares
25
- Fast, exact decompositions of integers as sums of two squares.
26
-
27
- `twosquares` exposes two simple methods for this number-theory task:
28
-
29
- * `decompose_prime(p)` — find the unique nonnegative pair (a, b) with a² + b² = p for p = 2 or prime p ≡ 1 (mod 4).
30
-
31
- * `decompose_number(n)` — enumerate all nonnegative pairs (a, b) with a² + b² = n (canonical pairs only).
@@ -1,7 +0,0 @@
1
- twosquares.cp312-win_amd64.pyd,sha256=vHJARdu44tqNt4GZw3AStqypqNa9icwWfcMQBVfLALQ,57856
2
- twosquares-0.0.3.dist-info/licenses/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
3
- twosquares-stubs/__init__.pyi,sha256=zxJdomt96aOuU9ZVM192-HjNhFWFOZqfQ0As6NzKqWY,223
4
- twosquares-0.0.3.dist-info/METADATA,sha256=Zj6EQT47UHKRoufvpmA_ndin4gmUtGwiI3Im7DJiwQQ,1272
5
- twosquares-0.0.3.dist-info/WHEEL,sha256=8UP9x9puWI0P1V_d7K2oMTBqfeLNm21CTzZ_Ptr0NXU,101
6
- twosquares-0.0.3.dist-info/top_level.txt,sha256=cmwZJ1cFpL4b3RqCi5RJt2KNOy2visqUEzW4ug0tapc,28
7
- twosquares-0.0.3.dist-info/RECORD,,