hensel_code 0.3.1 → 0.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +8 -1
- data/README.md +77 -2
- data/hensel_code.gemspec +2 -2
- data/lib/hensel_code/finite_gadic_expansion.rb +66 -0
- data/lib/hensel_code/truncated_finite_gadic_expansion.rb +3 -2
- data/lib/hensel_code/version.rb +1 -1
- data/lib/hensel_code.rb +2 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7109ef429b245037638da445a57e080330889ced172cdbca0402d861618742fe
|
4
|
+
data.tar.gz: f20970c13e3b51a34ebacaf3367072bd62ad45ad4954fa276f5352e65d1b68da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0c8425fd3252229dfa7f837cfacc7a1f0de10afd9e0e5946ee86f7da23fa5ed0c826e2cff02b711834f0d37b8f13ff9c22c7aa71da342efa15e2653789252aa
|
7
|
+
data.tar.gz: e2a24c597c7d3fd415ef3c8ab7fd7eea11ca9ed66fbffff2b8e6055095edc1b29787e3527479a555305918d05f9b58ddea6e0d9ca75a21b8347aa48581bf7062
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## [0.4.0] - 2022-03-29
|
2
|
+
- Add the fourth type of supported Hensel code: the finite-segement g-adic Hensel code.
|
3
|
+
|
4
|
+
## [0.3.1] - 2022-03-25
|
5
|
+
- Fix the method `random_distinct_numbers` in `Tools` which was allowing duplicated random numbers.
|
6
|
+
|
1
7
|
## [0.3.0] - 2022-03-12
|
2
8
|
|
3
9
|
- Add the `Polynomial` class for arithmetic with fixed-length polynomials
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hensel_code (0.3.
|
4
|
+
hensel_code (0.3.1)
|
5
5
|
openssl (~> 3.0.0)
|
6
6
|
prime (~> 0.1.2)
|
7
7
|
|
@@ -52,9 +52,15 @@ GEM
|
|
52
52
|
docile (~> 1.1)
|
53
53
|
simplecov-html (~> 0.11)
|
54
54
|
simplecov_json_formatter (~> 0.1)
|
55
|
+
simplecov-console (0.9.1)
|
56
|
+
ansi
|
57
|
+
simplecov
|
58
|
+
terminal-table
|
55
59
|
simplecov-html (0.12.3)
|
56
60
|
simplecov_json_formatter (0.1.4)
|
57
61
|
singleton (0.1.1)
|
62
|
+
terminal-table (3.0.2)
|
63
|
+
unicode-display_width (>= 1.1.1, < 3)
|
58
64
|
unicode-display_width (2.1.0)
|
59
65
|
|
60
66
|
PLATFORMS
|
@@ -70,6 +76,7 @@ DEPENDENCIES
|
|
70
76
|
rubocop (~> 1.21)
|
71
77
|
rubocop-minitest (~> 0.17.2)
|
72
78
|
rubocop-rake (~> 0.6)
|
79
|
+
simplecov-console (~> 0.9)
|
73
80
|
|
74
81
|
BUNDLED WITH
|
75
82
|
2.3.8
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
 [](https://codecov.io/gh/davidwilliam/hensel_code) [](https://github.com/rubocop/rubocop)   
|
4
4
|
|
5
|
-
***NOTICE:*** this README is beign constantly updated. I am currently focused on coding since I want to release as many different types of Hensel codes as
|
5
|
+
***NOTICE:*** this README is beign constantly updated. I am currently focused on coding since I want to release as many different types of Hensel codes and as many interesting features as time allows. At the same time, I want this README to be as informative as possible even for those completely unfamiliar with p-adic numbers and Hensel codes.
|
6
6
|
|
7
7
|
Hensel Code allows you to homomorphically encode rational numbers as integers using the finite-segment p-adic arithmetic, also known as Hensel codes.
|
8
8
|
|
@@ -14,6 +14,12 @@ Rao also remarks that the theory of Hensel codes, although lifted from the p-adi
|
|
14
14
|
|
15
15
|
A p-adic number can be uniquely written as a inifite p-adic expansion, for `p` prime, where the associated coefficients are integers between `0` and `p - 1`. When this p-adic expansion is finite in length, then we have a finite-segment p-adic expansion. When we only consider the constant term of a p-adic expansion, then we have a truncated finite-segment p-adic expansion. There many types of representations of rationals lifted from the p-adic number theory, and therefore many types of Hensel codes.
|
16
16
|
|
17
|
+
## History
|
18
|
+
|
19
|
+
The theory of p-adic numbers was introduced by Kurt Hensel in the early 1900's ([Theorie der algebraischen Zahlen](https://books.google.com/books?hl=en&lr=&id=0w3vAAAAMAAJ&oi=fnd&pg=PR3&dq=Theorie+der+algebraischen+Zahlen&ots=kQfsAd0GYZ&sig=dGsTggln9njYkc2zNYT5hkk2lXU#v=onepage&q=Theorie%20der%20algebraischen%20Zahlen&f=false)). Introductions to p-adic numbers are provided by George Bachman (Introduction to p-Adic Numbers and Valuation Theory), Neal Koblitz ([P-Adic Numbers, P-Adic Analysis, and Zeta Functions](https://books.google.com/books?hl=en&lr=&id=8sTgBwAAQBAJ&oi=fnd&pg=PA1&dq=P-Adic+Numbers,+P-Adic+Analysis,+and+Zeta+Functions&ots=fWIImSqW7-&sig=29LdWtpjSkmQ2kWvVFDmmG5SsOo#v=onepage&q=P-Adic%20Numbers%2C%20P-Adic%20Analysis%2C%20and%20Zeta%20Functions&f=false)), Kurt Mahler ([Introduction to p-adic numbers and their functions](https://books.google.com/books?hl=en&lr=&id=kbc8AAAAIAAJ&oi=fnd&pg=PA1&dq=Introduction+to+P-Adic+Numbers+and+Their+Functions&ots=GFpDeD8vMG&sig=TNSPVG0YA676rlflM9CfogQP7t8)), and Fernando Gouveia ([p-adic Number](https://books.google.com/books?hl=en&lr=&id=VWjsDwAAQBAJ&oi=fnd&pg=PR5&ots=MdgpeNTWLX&sig=9LzgTUkSzN76E1EOD7wna0c8S0I#v=onepage&q&f=false)).
|
20
|
+
|
21
|
+
The foundation of the particular application of finite-segement p-adic arithemetic (also known as Hensel codes) for error-free computation can be found in the works of Alparslan, Krishnamurthy, Rao, and Subramanian (Finite p-adic number systems with possible applications, [Finite segmentp-adic number systems with applications to exact computation](https://link.springer.com/article/10.1007/BF03051174), [p-Adic arithmetic procedures for exact matrix computations](https://link.springer.com/article/10.1007/BF03046725), [Error-Free Polynomial Matrix Computations](https://link.springer.com/book/10.1007/978-1-4612-5118-7)), Gregory ([Methods and Applications of Error-Free Computation](https://link.springer.com/book/10.1007/978-1-4612-5242-9), [Error-free computation with rational numbers](https://link.springer.com/article/10.1007/BF01933164), [Error-free computation with finite number systems](https://dl.acm.org/doi/abs/10.1145/1057502.1057503?casa_token=LTLotJJYEPAAAAAA:PQwNY8-RcpuSQyfCkEMv1xIpd10RlR-y7JeTWkCkYNQ3c1IroGEGzk4TVH_5JJ954sJsvcHRlTldtQ), [The use of finite-segmentp-adic arithmetic for exact computation](https://link.springer.com/article/10.1007/BF01930898)), Miola ([Algebraic approach to p-adic conversion of rational numbers](https://www.sciencedirect.com/science/article/abs/pii/002001908490022X)), Morrison ([Parallel p-adic computation](https://www.sciencedirect.com/science/article/abs/pii/0020019088901597)). Many algorithms, ideas, and concepts in Hensel codes are greatly benefitted by the remarkable series The Art of Computer Programming by Donald Knuth.
|
22
|
+
|
17
23
|
## Mathematical Background
|
18
24
|
|
19
25
|
In our Wiki, you can find a brief [introduction to the mathematical background on Hensel codes](https://github.com/davidwilliam/hensel_code/wiki/Mathematical-Background). We will continue to update that area as we update the gem.
|
@@ -45,6 +51,7 @@ There are several types of Hensel codes in the finite-segment p-adic number theo
|
|
45
51
|
1. Truncated finite-segment p-adic Hensel codes
|
46
52
|
2. Finite-segment p-adic Hensel codes
|
47
53
|
3. Truncated finite-segment g-adic Hensel codes
|
54
|
+
4. Finite-segmenet g-adic Hensel codes
|
48
55
|
|
49
56
|
For each type of supported Hensel code I will briefly discuss their properties and capabilities as well as unique features that make each type of Hensel code distinct from each other.
|
50
57
|
|
@@ -620,7 +627,75 @@ h4.to_r
|
|
620
627
|
# => (84245698732457344123/198437243845987593234524)
|
621
628
|
```
|
622
629
|
|
623
|
-
|
630
|
+
## Finite-segment g-adic Hensel codes
|
631
|
+
|
632
|
+
### Description
|
633
|
+
The finite-segment g-adic Hensel codes are analogous to the relationship between truncated finite p-adic expansions and finite p-adic expansions. With the finite-segement g-adic Hensel codes, we have a collection of fixed-degree univariate polynomials for each one of `k` distinct primes used to compute a g-adic Hensel code.
|
634
|
+
|
635
|
+
### Unique Benefits
|
636
|
+
|
637
|
+
Finite-segement g-adic Hensel codes combine the best of two worlds: multiple independent Hensel codes which can be computed in parallel / in a distributed manner and computations using fixed-degree polynomials where for each `b`-bit prime `p_i`, the maximum expansion of all computations will take at most `1 + 2b` bits. Combining parallel/distributed computation with minimal computation expansion can be beneficial for a number of applications including massive parallel computations and egde computing.
|
638
|
+
|
639
|
+
### Usage
|
640
|
+
```ruby
|
641
|
+
primes = [241, 251, 257]
|
642
|
+
r = 3
|
643
|
+
rat1 = Rational(2,3)
|
644
|
+
rat2 = Rational(5,9)
|
645
|
+
h1 = HenselCode::FiniteGadicExpansion.new primes, r, rat1
|
646
|
+
# => <HenselCode: ["81 + 80p + 80p^2", "168 + 83p + 167p^2", "172 + 85p + 171p^2"]>
|
647
|
+
h2 = HenselCode::FiniteGadicExpansion.new primes, r, rat2
|
648
|
+
# => <HenselCode: ["188 + 26p + 107p^2", "140 + 111p + 139p^2", "229 + 199p + 142p^2"]>
|
649
|
+
h1.to_r
|
650
|
+
# => (2/3)
|
651
|
+
h2.to_r
|
652
|
+
# => (5/9)
|
653
|
+
h1.to_a
|
654
|
+
# => [[81, 80, 80], [168, 83, 167], [172, 85, 171]]
|
655
|
+
h2.to_a
|
656
|
+
# => [[188, 26, 107], [140, 111, 139], [229, 199, 142]]
|
657
|
+
```
|
658
|
+
|
659
|
+
### Arithmetic
|
660
|
+
```ruby
|
661
|
+
h1_plus_h2 = h1 + h2
|
662
|
+
# => <HenselCode: ["28 + 107p + 187p^2", "57 + 195p + 55p^2", "144 + 28p + 57p^2"]>
|
663
|
+
h1_minus_h2 = h1 - h2
|
664
|
+
# => <HenselCode: ["134 + 53p + 214p^2", "28 + 223p + 27p^2", "200 + 142p + 28p^2"]>
|
665
|
+
h1_times_h2 = h1 * h2
|
666
|
+
# => <HenselCode: ["45 + 98p + 71p^2", "177 + 241p + 92p^2", "67 + 133p + 9p^2"]>
|
667
|
+
h1_div_h2 = h1 / h2
|
668
|
+
# => <HenselCode: ["194 + 192p + 192p^2", "202 + 200p + 200p^2", "104 + 51p + 154p^2"]>
|
669
|
+
h2.inverse
|
670
|
+
# => <HenselCode: ["50 + 48p + 48p^2", "52 + 50p + 50p^2", "156 + 205p + 102p^2"]>
|
671
|
+
h1 * h2.inverse
|
672
|
+
# => <HenselCode: ["194 + 192p + 192p^2", "202 + 200p + 200p^2", "104 + 51p + 154p^2"]>
|
673
|
+
h2 * h2.inverse
|
674
|
+
# => <HenselCode: ["1 + 0p + 0p^2", "1 + 0p + 0p^2", "1 + 0p + 0p^2"]>
|
675
|
+
```
|
676
|
+
|
677
|
+
and we can check that
|
678
|
+
|
679
|
+
```ruby
|
680
|
+
h1_plus_h2.to_r
|
681
|
+
# => (11/9)
|
682
|
+
rat1 + rat2
|
683
|
+
# => (11/9)
|
684
|
+
h1_minus_h2.to_r
|
685
|
+
# => (1/9)
|
686
|
+
rat1 - rat2
|
687
|
+
# => (1/9)
|
688
|
+
h1_times_h2.to_r
|
689
|
+
# => (10/27)
|
690
|
+
rat1 * rat2
|
691
|
+
# => (10/27)
|
692
|
+
h1_div_h2.to_r
|
693
|
+
# => (6/5)
|
694
|
+
rat1 / rat2
|
695
|
+
# => (6/5)
|
696
|
+
```
|
697
|
+
|
698
|
+
## Class Aliases
|
624
699
|
|
625
700
|
Since some classes can have long names, here are some aliases that can be used for keeping the lines of code shorter:
|
626
701
|
|
data/hensel_code.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["David William Silva"]
|
9
9
|
spec.email = ["contact@davidwsilva.com"]
|
10
10
|
|
11
|
-
spec.summary = "
|
12
|
-
spec.description = "A Ruby library for
|
11
|
+
spec.summary = "Error-free computation with homomorphic encoding of rational numbers."
|
12
|
+
spec.description = "A Ruby library for error-free computation via homomorphic encoding of rational numbers as integers."
|
13
13
|
spec.homepage = "https://github.com/davidwilliam/hensel_code"
|
14
14
|
spec.license = "MIT"
|
15
15
|
spec.required_ruby_version = ">= 2.6.0"
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HenselCode
|
4
|
+
# truncated finite g-adic expansion hensel code class
|
5
|
+
class FiniteGadicExpansion < GAdicBase
|
6
|
+
def modululi
|
7
|
+
primes.map { |prime| prime**exponent }
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_a
|
11
|
+
hensel_code.map(&:to_a)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
hensel_code.map(&:to_s).to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"<HenselCode: #{self}>"
|
20
|
+
end
|
21
|
+
|
22
|
+
def inverse
|
23
|
+
new_hensel_code = hensel_code.map(&:inverse)
|
24
|
+
self.class.new primes, exponent, new_hensel_code
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def evaluate(operation, other)
|
30
|
+
new_hensel_code = hensel_code.zip(other.hensel_code).map { |pair| pair[0].send(operation, pair[1]) }
|
31
|
+
self.class.new primes, exponent, new_hensel_code
|
32
|
+
end
|
33
|
+
|
34
|
+
def valid_number?(number)
|
35
|
+
if number.is_a?(Rational)
|
36
|
+
@rational = number
|
37
|
+
elsif number.is_a?(Array) && number.map(&:class).uniq == [HenselCode::FinitePadicExpansion]
|
38
|
+
@hensel_code = number
|
39
|
+
decode
|
40
|
+
else
|
41
|
+
message = "number must be a Rational or an\
|
42
|
+
Array of finite p-adic Hensel codes and it was a #{number.class}"
|
43
|
+
raise WrongHenselCodeInputType, message
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid_hensel_code?(new_hensel_code)
|
48
|
+
condition = new_hensel_code.is_a?(Array) && new_hensel_code.map(&:class).uniq == [HenselCode::FPE]
|
49
|
+
message = "must be an array of finite p-adic Hensel codes"
|
50
|
+
raise WrongHenselCodeInputType, message unless condition
|
51
|
+
end
|
52
|
+
|
53
|
+
def encode
|
54
|
+
@g = primes.inject(:*)
|
55
|
+
@hensel_code = primes.map do |prime|
|
56
|
+
FinitePadicExpansion.new prime, exponent, rational
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def decode
|
61
|
+
hs = hensel_code.map { |h| h.to_truncated.hensel_code }
|
62
|
+
h = TruncatedFinitePadicExpansion.new g, exponent, crt(modululi, hs)
|
63
|
+
@rational = h.to_r
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -38,8 +38,9 @@ module HenselCode
|
|
38
38
|
@hensel_code = number
|
39
39
|
decode
|
40
40
|
else
|
41
|
-
|
42
|
-
|
41
|
+
message = "number must be a Rational or an\
|
42
|
+
Array of truncated p-adic Hensel codes and it was a #{number.class}"
|
43
|
+
raise WrongHenselCodeInputType, message
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
data/lib/hensel_code/version.rb
CHANGED
data/lib/hensel_code.rb
CHANGED
@@ -23,11 +23,13 @@ module HenselCode
|
|
23
23
|
autoload :GAdicVerifier, "hensel_code/gadic_verifier"
|
24
24
|
autoload :ModularArithmetic, "hensel_code/modular_arithmetic"
|
25
25
|
autoload :FinitePadicExpansion, "hensel_code/finite_padic_expansion"
|
26
|
+
autoload :FiniteGadicExpansion, "hensel_code/finite_gadic_expansion"
|
26
27
|
autoload :TruncatedFinitePadicExpansion, "hensel_code/truncated_finite_padic_expansion"
|
27
28
|
autoload :TruncatedFiniteGadicExpansion, "hensel_code/truncated_finite_gadic_expansion"
|
28
29
|
|
29
30
|
# aliases for classes with long names
|
30
31
|
TFPE = TruncatedFinitePadicExpansion
|
32
|
+
FPE = TruncatedFinitePadicExpansion
|
31
33
|
HCWDPAE = HenselCodesWithDifferentPrimesAndExponents
|
32
34
|
WHIT = WrongHenselCodeInputType
|
33
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hensel_code
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David William Silva
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: openssl
|
@@ -38,7 +38,8 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.1.2
|
41
|
-
description: A Ruby library for
|
41
|
+
description: A Ruby library for error-free computation via homomorphic encoding of
|
42
|
+
rational numbers as integers.
|
42
43
|
email:
|
43
44
|
- contact@davidwsilva.com
|
44
45
|
executables: []
|
@@ -56,6 +57,7 @@ files:
|
|
56
57
|
- codecov
|
57
58
|
- hensel_code.gemspec
|
58
59
|
- lib/hensel_code.rb
|
60
|
+
- lib/hensel_code/finite_gadic_expansion.rb
|
59
61
|
- lib/hensel_code/finite_padic_expansion.rb
|
60
62
|
- lib/hensel_code/gadic_base.rb
|
61
63
|
- lib/hensel_code/gadic_verifier.rb
|
@@ -94,5 +96,5 @@ requirements: []
|
|
94
96
|
rubygems_version: 3.3.3
|
95
97
|
signing_key:
|
96
98
|
specification_version: 4
|
97
|
-
summary:
|
99
|
+
summary: Error-free computation with homomorphic encoding of rational numbers.
|
98
100
|
test_files: []
|