From a219460d207c2fecf097e8320028f9c085dd7b0c Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Sun, 28 May 2023 13:53:28 +0800 Subject: [PATCH] added bigint library --- src/mmath/bigint.nim | 253 +++++++++++++++++++++++++++++++++++++++++ src/mmath/hmatrix.nim | 149 ++++++++++++------------ src/mmath/hvector.nim | 28 ++--- src/mmath/pivot.nim | 5 +- src/mmath/rational.nim | 48 ++++++-- src/mmath/smatrix.nim | 133 +++++++++++----------- src/mmath/svector.nim | 39 ++++--- 7 files changed, 475 insertions(+), 180 deletions(-) create mode 100644 src/mmath/bigint.nim diff --git a/src/mmath/bigint.nim b/src/mmath/bigint.nim new file mode 100644 index 0000000..066b116 --- /dev/null +++ b/src/mmath/bigint.nim @@ -0,0 +1,253 @@ +import nwo/clib + +type mpz_t = object + mp_alloc : cint + mp_size : cint + mp_d : pointer + +type mpz_ptr = ptr[mpz_t] + +cxface: + include "" + # proc argp_parse*(argp : ptr[Argp], argc : cint, argv : cstringArray, flags : cint, arg_index : cint, ctx : pointer) : cint + proc mpz_init(state : mpz_ptr) : void + proc mpz_clear(state : mpz_ptr) : void + proc mpz_set_si(self : mpz_ptr, value : clong) : void + proc mpz_get_str(destination : cstring, base : cint, self : mpz_ptr) : cstring + proc mpz_sizeinbase(self : mpz_ptr, base :cint) : csize_t + proc mpz_add(rop : mpz_ptr, op1 : mpz_ptr, op2 : mpz_ptr) : void + proc mpz_add_ui(rop : mpz_ptr, op1 : mpz_ptr, op2 : culong) : void + proc mpz_sub(rop : mpz_ptr, op1 : mpz_ptr, op2 : mpz_ptr) : void + proc mpz_sub_ui(rop : mpz_ptr, op : mpz_ptr, op2 : culong) : void + proc mpz_ui_sub(rop : mpz_ptr, op2 : culong, op : mpz_ptr) : void + + proc mpz_mul(rop : mpz_ptr, op1 : mpz_ptr, op2 : mpz_ptr) : void + proc mpz_mul_si(rop : mpz_ptr, op1 : mpz_ptr, op2 : clong) : void + proc mpz_mul_ui(rop : mpz_ptr, op1 : mpz_ptr, op2 : culong) : void + + + proc mpz_cdiv_q(q : mpz_ptr, n : mpz_ptr, d : mpz_ptr) : void + proc mpz_cdiv_r(r : mpz_ptr, n : mpz_ptr, d : mpz_ptr) : void + proc mpz_fdiv_q(q : mpz_ptr, n : mpz_ptr, d : mpz_ptr) : void + proc mpz_fdiv_r(r : mpz_ptr, n : mpz_ptr, d : mpz_ptr) : void + proc mpz_tdiv_q(q : mpz_ptr, n : mpz_ptr, d : mpz_ptr) : void + proc mpz_tdiv_r(r : mpz_ptr, n : mpz_ptr, d : mpz_ptr) : void + + proc mpz_tdiv_q_ui(q : mpz_ptr, n : mpz_ptr, d : culong) : void + proc mpz_tdiv_r_ui(q : mpz_ptr, n : mpz_ptr, d : culong) : void + proc mpz_tdiv_ui(n : mpz_ptr, d : culong) : void + proc mpz_neg(rop : mpz_ptr, op : mpz_ptr) : void + + proc mpz_root(rop : mpz_ptr, op1: mpz_ptr, op2: culong) : int + proc mpz_sqrt(rop : mpz_ptr, op1: mpz_ptr) : void + proc mpz_pow_ui(rop : mpz_ptr, base: mpz_ptr, exp : culong) : void + proc mpz_abs(rop : mpz_ptr, op : mpz_ptr) : void + + proc mpz_cmp(op1 : mpz_ptr, op2 : mpz_ptr) : cint + + libs: + gmp + +proc `=destroy`*(n: var mpz_t) = + let mpz : mpz_ptr = addr(n) + mpz_clear(mpz) + +type BigInt* = ref mpz_t + +proc newBigInt*(value : int64): BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + mpz_init(mpz) + mpz_set_si(mpz, value.clong) + +proc toString*(n : BigInt, base : cint) : string = + let mpz : mpz_ptr = addr(n[]) + let size = mpz_sizeinbase(mpz, base.cint) + let space : cstring = cast[cstring](alloc(size)) + discard mpz_get_str(space, base, mpz) + result = $space + dealloc(space) + +proc `$`*(n : BigInt) : string = toString(n, 10) + +proc `+`*(n1 : BigInt, n2 : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_init(mpz) + mpz_add(mpz, mpz1, mpz2) + +proc `+`*(n1 : BigInt, n2 : culong) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + mpz_init(mpz) + mpz_add_ui(mpz, mpz1, n2.culong) + +proc `+`*(n1 : culong, n2 : BigInt) : BigInt = n2 + n1 + +proc `-`*(n1 : BigInt, n2 : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_init(mpz) + mpz_sub(mpz, mpz1, mpz2) + +proc `-`*(n1 : BigInt, n2 : culong) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + mpz_init(mpz) + mpz_sub_ui(mpz, mpz1, n2) + +proc `-`*(n1 : culong, n2 : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_init(mpz) + mpz_ui_sub(mpz, n1, mpz2) + +proc `*`*(n1 : BigInt, n2 : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_init(mpz) + mpz_mul(mpz, mpz1, mpz2) + +proc `*`*(n1 : BigInt, n2 : clong) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + mpz_init(mpz) + mpz_mul_si(mpz, mpz1, n2) + +proc `*`*(n1 : clong, n2 : BigInt) : BigInt = n2 * n1 + +proc `*`*(n1 : BigInt, n2 : culong) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + mpz_init(mpz) + mpz_mul_ui(mpz, mpz1, n2) + +proc `*`*(n1 : culong, n2 : BigInt) : BigInt = n2 * n1 + +proc `div`*(n1 : BigInt, n2 : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_init(mpz) + mpz_tdiv_q(mpz, mpz1, mpz2) + +proc `div`*(n1 : BigInt, n2 : culong) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + mpz_init(mpz) + mpz_tdiv_q_ui(mpz, mpz1, n2) + +proc `mod`*(n1 : BigInt, n2 : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_init(mpz) + mpz_tdiv_r(mpz, mpz1, mpz2) + +proc `mod`*(n1 : BigInt, n2 : culong) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n1[]) + mpz_init(mpz) + mpz_tdiv_r_ui(mpz, mpz1, n2) + +proc `-`*(m : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(m[]) + mpz_neg(mpz, mpz1) + +proc `+=`*(n1 : var BigInt, n2 : BigInt) : void = + let mpz : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_add(mpz, mpz, mpz2) + +proc `+=`*(n1 : var BigInt, n2 : culong) : void = + let mpz : mpz_ptr = addr(n1[]) + mpz_add_ui(mpz, mpz, n2) + +proc `-=`*(n1 : var BigInt, n2 : BigInt) : void = + let mpz : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_sub(mpz, mpz, mpz2) + +proc `-=`*(n1 : var BigInt, n2 : culong) : void = + let mpz : mpz_ptr = addr(n1[]) + mpz_sub_ui(mpz, mpz, n2) + +proc `*=`*(n1 : var BigInt, n2 : BigInt) : void = + let mpz : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_mul(mpz, mpz, mpz2) + +proc `*=`*(n1 : var BigInt, n2 : clong) : void = + let mpz : mpz_ptr = addr(n1[]) + mpz_mul_si(mpz, mpz, n2) + +proc `*=`*(n1 : var BigInt, n2 : culong) : void = + let mpz : mpz_ptr = addr(n1[]) + mpz_mul_ui(mpz, mpz, n2) + +proc `div=`*(n1 : var BigInt, n2 : BigInt) : void = + let mpz : mpz_ptr = addr(n1[]) + let mpz2 : mpz_ptr = addr(n2[]) + mpz_tdiv_q(mpz, mpz, mpz2) + +proc `div=`*(n1 : var BigInt, n2 : culong) : void = + let mpz : mpz_ptr = addr(n1[]) + mpz_tdiv_q_ui(mpz, mpz, n2) + +proc abs*(n : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n[]) + mpz_abs(mpz, mpz1) + +proc sqrt*(n : BigInt) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n[]) + mpz_sqrt(mpz, mpz1) + +proc pow*(n : BigInt, exp : culong) : BigInt = + new(result) + let mpz : mpz_ptr = addr(result[]) + let mpz1 : mpz_ptr = addr(n[]) + mpz_pow_ui(mpz, mpz1, exp) + +proc fact*(n : int) : BigInt = + result = newBigInt(1) + for i in 1..`*(n1 : BigInt, n2 : BigInt) : bool = cmp(n1, n2) > 0 +proc `==`*(n1 : BigInt, n2 : BigInt) : bool = cmp(n1, n2) == 0 +proc `<=`*(n1 : BigInt, n2 : BigInt) : bool = cmp(n1, n2) <= 0 +proc `>=`*(n1 : BigInt, n2 : BigInt) : bool = cmp(n1, n2) >= 0 diff --git a/src/mmath/hmatrix.nim b/src/mmath/hmatrix.nim index 1659825..2e6cb81 100644 --- a/src/mmath/hmatrix.nim +++ b/src/mmath/hmatrix.nim @@ -1,8 +1,6 @@ -from sequtils import newSeqWith, map -from nwo/utils import `...`, `-->`, box +from nwo/utils import `-->` from hvector import HVector, newHVector, buildHVector from pivot import HPivot, newHPivot, `[]`, `[]=`, len, SizeError, SingularMatrixError -from options import Option, none, some from math import sqrt type @@ -22,27 +20,36 @@ proc `[]=`*[T](m : var HMatrix[T], r, c :int, newValue : T) = m.data[r * m.columns + c] = newValue iterator items*[T](m: HMatrix[T]): (int, int, T) = - for i in 0...m.rows: - for j in 0...m.columns: + for i in 0.. max: max = abs(m[i, j]) max_index = j @@ -309,24 +316,24 @@ proc lu_pivot[T](m : var HMatrix[T], i : int, pivot : var HPivot[T]) = proc lup*[T](m : var HMatrix[T]) : HPivot[T] = result = newHPivot[T](m.rows) - for i in 0...m.rows: + for i in 0.. 0: - for k in (i + 1)...m.rows: + for k in (i + 1)..`, box +from nwo/utils import `-->`, box from svector import SVector from pivot import SPivot, newSPivot, `[]`, `[]=`, SingularMatrixError, len from math import sqrt -import random type SMatrix*[ROWS, COLUMNS: static[int], T] = object @@ -25,19 +23,24 @@ proc `[]=`*[ROWS, COLUMNS : static[int], T](m : var SMatrix[ROWS,COLUMNS,T], r, m.data[r * COLUMNS + c] = newValue iterator items*[ROWS, COLUMNS : static[int], T](m: SMatrix[ROWS,COLUMNS,T]): (int, int, T) = - for i in 0...m.rows: - for j in 0...m.columns: + for i in 0.. j: result[i, j] = m[i, j] elif i == j: @@ -282,8 +285,8 @@ proc tril*[SIZE : static[int], T](m : SquareSMatrix[SIZE, T], diag_replacement : result[i, j] = T.zero proc tril*[SIZE : static[int], T](m : SquareSMatrix[SIZE, T]) : SquareSMatrix[SIZE, T] = - for i in 0...m.rows: - for j in 0...m.columns: + for i in 0..= j: result[i, j] = m[i, j] else: @@ -292,18 +295,18 @@ proc tril*[SIZE : static[int], T](m : SquareSMatrix[SIZE, T]) : SquareSMatrix[SI proc lu_row[SIZE : static[int], T](m : var SquareSMatrix[SIZE, T], i : int) = if m[i, i] == T.zero: raise newException(SingularMatrixError, "Matrix is singular") - for j in i...m.columns: - for k in 0...i: + for j in i.. max: max = abs(m[i, j]) max_index = j @@ -311,23 +314,23 @@ proc lu_pivot[SIZE : static[int], T](m : var SquareSMatrix[SIZE, T], i : int, pi m.swap_rows(i, max_index, pivot) proc lu*[SIZE : static[int], T](m : var SquareSMatrix[SIZE, T]) = - for i in 0...m.rows: + for i in 0.. 0: - for k in (i + 1)...m.rows: + for k in (i + 1)..