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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5eaefbf55c5b467595cb52c0034036d2133f802fbd20ca63b17edef4c3ec159a
4
- data.tar.gz: c1b9c4e619c032d11d1d68ca2a858b6da7286a67ac40e81c9c19b9f606f1385f
3
+ metadata.gz: 7109ef429b245037638da445a57e080330889ced172cdbca0402d861618742fe
4
+ data.tar.gz: f20970c13e3b51a34ebacaf3367072bd62ad45ad4954fa276f5352e65d1b68da
5
5
  SHA512:
6
- metadata.gz: 3f55c6f2e2ec23a4eac8d098227fc630109c8d3c605b148e281f910111bbe68fbcc79e3437275639c95f808aa63612e97cac44509219431b89bb79e9164321ba
7
- data.tar.gz: fd298edc25d8ea23c731727109622895a93804a39b8546598e95e19ec8b9235aba384e90c312f7215e175cb1fb0ff26d9bab8198d69554fe12cfd0e998be1986
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
@@ -18,3 +18,5 @@ gem "rubocop-rake", "~> 0.6"
18
18
  gem "minitest-reporters", "~> 1.5"
19
19
 
20
20
  gem "codecov", require: false, group: :test
21
+
22
+ gem "simplecov-console", "~>0.9", require: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hensel_code (0.3.0)
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 possible. 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. Therefore, even not in the pace I would want, I will continue to add information to the README to facilitate the use of the gem and to give some practical ideas of the computational possibilities enabled by it.
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
- ### Class Aliases
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 = "Homomorphic encoding of rational numbers."
12
- spec.description = "A Ruby library for homomorphically representing rational numbers as integers."
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
- raise WrongHenselCodeInputType, "number must be a Rational or an\
42
- Array of truncated p-adic Hensel codes and it was a #{number.class}"
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HenselCode
4
- VERSION = "0.3.1"
4
+ VERSION = "0.4.0"
5
5
  end
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.3.1
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-25 00:00:00.000000000 Z
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 homomorphically representing rational numbers as integers.
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: Homomorphic encoding of rational numbers.
99
+ summary: Error-free computation with homomorphic encoding of rational numbers.
98
100
  test_files: []