hensel_code 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![example workflow](https://github.com/davidwilliam/hensel_code/actions/workflows/main.yml/badge.svg) [![codecov](https://codecov.io/gh/davidwilliam/hensel_code/branch/main/graph/badge.svg?token=XJ0C0U7P2M)](https://codecov.io/gh/davidwilliam/hensel_code) [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop) ![GitHub](https://img.shields.io/github/license/davidwilliam/hensel_code) ![Gem](https://img.shields.io/gem/v/hensel_code) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/davidwilliam/hensel_code)
|
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: []
|