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 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: []