Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
330
Task/P-Adic-numbers-basic/Go/p-adic-numbers-basic.go
Normal file
330
Task/P-Adic-numbers-basic/Go/p-adic-numbers-basic.go
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// constants
|
||||
const EMX = 64 // exponent maximum (if indexing starts at -EMX)
|
||||
const DMX = 100000 // approximation loop maximum
|
||||
const AMX = 1048576 // argument maximum
|
||||
const PMAX = 32749 // prime maximum
|
||||
|
||||
// global variables
|
||||
var p1 = 0
|
||||
var p = 7 // default prime
|
||||
var k = 11 // precision
|
||||
|
||||
func abs(a int) int {
|
||||
if a >= 0 {
|
||||
return a
|
||||
}
|
||||
return -a
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
type Ratio struct {
|
||||
a, b int
|
||||
}
|
||||
|
||||
type Padic struct {
|
||||
v int
|
||||
d [2 * EMX]int // add EMX to index to be consistent wih FB
|
||||
}
|
||||
|
||||
// (re)initialize receiver from Ratio, set 'sw' to print
|
||||
func (pa *Padic) r2pa(q Ratio, sw int) int {
|
||||
a := q.a
|
||||
b := q.b
|
||||
if b == 0 {
|
||||
return 1
|
||||
}
|
||||
if b < 0 {
|
||||
b = -b
|
||||
a = -a
|
||||
}
|
||||
if abs(a) > AMX || b > AMX {
|
||||
return -1
|
||||
}
|
||||
if p < 2 || k < 1 {
|
||||
return 1
|
||||
}
|
||||
p = min(p, PMAX) // maximum short prime
|
||||
k = min(k, EMX-1) // maxumum array length
|
||||
if sw != 0 {
|
||||
fmt.Printf("%d/%d + ", a, b) // numerator, denominator
|
||||
fmt.Printf("0(%d^%d)\n", p, k) // prime, precision
|
||||
}
|
||||
|
||||
// (re)initialize
|
||||
pa.v = 0
|
||||
p1 = p - 1
|
||||
pa.d = [2 * EMX]int{}
|
||||
if a == 0 {
|
||||
return 0
|
||||
}
|
||||
i := 0
|
||||
|
||||
// find -exponent of p in b
|
||||
for b%p == 0 {
|
||||
b = b / p
|
||||
i--
|
||||
}
|
||||
s := 0
|
||||
r := b % p
|
||||
|
||||
// modular inverse for small p
|
||||
b1 := 1
|
||||
for b1 <= p1 {
|
||||
s += r
|
||||
if s > p1 {
|
||||
s -= p
|
||||
}
|
||||
if s == 1 {
|
||||
break
|
||||
}
|
||||
b1++
|
||||
}
|
||||
if b1 == p {
|
||||
fmt.Println("r2pa: impossible inverse mod")
|
||||
return -1
|
||||
}
|
||||
pa.v = EMX
|
||||
for {
|
||||
// find exponent of P in a
|
||||
for a%p == 0 {
|
||||
a = a / p
|
||||
i++
|
||||
}
|
||||
|
||||
// valuation
|
||||
if pa.v == EMX {
|
||||
pa.v = i
|
||||
}
|
||||
|
||||
// upper bound
|
||||
if i >= EMX {
|
||||
break
|
||||
}
|
||||
|
||||
// check precision
|
||||
if (i - pa.v) > k {
|
||||
break
|
||||
}
|
||||
|
||||
// next digit
|
||||
pa.d[i+EMX] = a * b1 % p
|
||||
if pa.d[i+EMX] < 0 {
|
||||
pa.d[i+EMX] += p
|
||||
}
|
||||
|
||||
// remainder - digit * divisor
|
||||
a -= pa.d[i+EMX] * b
|
||||
if a == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Horner's rule
|
||||
func (pa *Padic) dsum() int {
|
||||
t := min(pa.v, 0)
|
||||
s := 0
|
||||
for i := k - 1 + t; i >= t; i-- {
|
||||
r := s
|
||||
s *= p
|
||||
if r != 0 && (s/r-p != 0) {
|
||||
// overflow
|
||||
s = -1
|
||||
break
|
||||
}
|
||||
s += pa.d[i+EMX]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// add b to receiver
|
||||
func (pa *Padic) add(b Padic) *Padic {
|
||||
c := 0
|
||||
r := Padic{}
|
||||
r.v = min(pa.v, b.v)
|
||||
for i := r.v; i <= k+r.v; i++ {
|
||||
c += pa.d[i+EMX] + b.d[i+EMX]
|
||||
if c > p1 {
|
||||
r.d[i+EMX] = c - p
|
||||
c = 1
|
||||
} else {
|
||||
r.d[i+EMX] = c
|
||||
c = 0
|
||||
}
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
// complement of receiver
|
||||
func (pa *Padic) cmpt() *Padic {
|
||||
c := 1
|
||||
r := Padic{}
|
||||
r.v = pa.v
|
||||
for i := pa.v; i <= k+pa.v; i++ {
|
||||
c += p1 - pa.d[i+EMX]
|
||||
if c > p1 {
|
||||
r.d[i+EMX] = c - p
|
||||
c = 1
|
||||
} else {
|
||||
r.d[i+EMX] = c
|
||||
c = 0
|
||||
}
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
// rational reconstruction
|
||||
func (pa *Padic) crat() {
|
||||
fl := false
|
||||
s := pa
|
||||
j := 0
|
||||
i := 1
|
||||
|
||||
// denominator count
|
||||
for i <= DMX {
|
||||
// check for integer
|
||||
j = k - 1 + pa.v
|
||||
for j >= pa.v {
|
||||
if s.d[j+EMX] != 0 {
|
||||
break
|
||||
}
|
||||
j--
|
||||
}
|
||||
fl = ((j - pa.v) * 2) < k
|
||||
if fl {
|
||||
fl = false
|
||||
break
|
||||
}
|
||||
|
||||
// check negative integer
|
||||
j = k - 1 + pa.v
|
||||
for j >= pa.v {
|
||||
if p1-s.d[j+EMX] != 0 {
|
||||
break
|
||||
}
|
||||
j--
|
||||
}
|
||||
fl = ((j - pa.v) * 2) < k
|
||||
if fl {
|
||||
break
|
||||
}
|
||||
|
||||
// repeatedly add self to s
|
||||
s = s.add(*pa)
|
||||
i++
|
||||
}
|
||||
if fl {
|
||||
s = s.cmpt()
|
||||
}
|
||||
|
||||
// numerator: weighted digit sum
|
||||
x := s.dsum()
|
||||
y := i
|
||||
if x < 0 || y > DMX {
|
||||
fmt.Println(x, y)
|
||||
fmt.Println("crat: fail")
|
||||
} else {
|
||||
// negative powers
|
||||
i = pa.v
|
||||
for i <= -1 {
|
||||
y *= p
|
||||
i++
|
||||
}
|
||||
|
||||
// negative rational
|
||||
if fl {
|
||||
x = -x
|
||||
}
|
||||
fmt.Print(x)
|
||||
if y > 1 {
|
||||
fmt.Printf("/%d", y)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
|
||||
// print expansion
|
||||
func (pa *Padic) printf(sw int) {
|
||||
t := min(pa.v, 0)
|
||||
for i := k - 1 + t; i >= t; i-- {
|
||||
fmt.Print(pa.d[i+EMX])
|
||||
if i == 0 && pa.v < 0 {
|
||||
fmt.Print(".")
|
||||
}
|
||||
fmt.Print(" ")
|
||||
}
|
||||
fmt.Println()
|
||||
// rational approximation
|
||||
if sw != 0 {
|
||||
pa.crat()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := [][]int{
|
||||
/* rational reconstruction depends on the precision
|
||||
until the dsum-loop overflows */
|
||||
{2, 1, 2, 4, 1, 1},
|
||||
{4, 1, 2, 4, 3, 1},
|
||||
{4, 1, 2, 5, 3, 1},
|
||||
{4, 9, 5, 4, 8, 9},
|
||||
{26, 25, 5, 4, -109, 125},
|
||||
{49, 2, 7, 6, -4851, 2},
|
||||
{-9, 5, 3, 8, 27, 7},
|
||||
{5, 19, 2, 12, -101, 384},
|
||||
/* two decadic pairs */
|
||||
{2, 7, 10, 7, -1, 7},
|
||||
{34, 21, 10, 9, -39034, 791},
|
||||
/* familiar digits */
|
||||
{11, 4, 2, 43, 679001, 207},
|
||||
{-8, 9, 23, 9, 302113, 92},
|
||||
{-22, 7, 3, 23, 46071, 379},
|
||||
{-22, 7, 32749, 3, 46071, 379},
|
||||
{35, 61, 5, 20, 9400, 109},
|
||||
{-101, 109, 61, 7, 583376, 6649},
|
||||
{-25, 26, 7, 13, 5571, 137},
|
||||
{1, 4, 7, 11, 9263, 2837},
|
||||
{122, 407, 7, 11, -517, 1477},
|
||||
/* more subtle */
|
||||
{5, 8, 7, 11, 353, 30809},
|
||||
}
|
||||
|
||||
sw := 0
|
||||
a := Padic{}
|
||||
b := Padic{}
|
||||
|
||||
for _, d := range data {
|
||||
q := Ratio{d[0], d[1]}
|
||||
p = d[2]
|
||||
k = d[3]
|
||||
sw = a.r2pa(q, 1)
|
||||
if sw == 1 {
|
||||
break
|
||||
}
|
||||
a.printf(0)
|
||||
q.a = d[4]
|
||||
q.b = d[5]
|
||||
sw = sw | b.r2pa(q, 1)
|
||||
if sw == 1 {
|
||||
break
|
||||
}
|
||||
if sw == 0 {
|
||||
b.printf(0)
|
||||
c := a.add(b)
|
||||
fmt.Println("+ =")
|
||||
c.printf(1)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue