From bc31936fb962b8078056e34aa91ab71c8f7e5692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 25 Sep 2019 15:01:50 +0200 Subject: [PATCH] using int_fast64 for vector_modn_sparse --- src/sage/modules/vector_modn_sparse.pxd | 14 +++-- src/sage/modules/vector_modn_sparse.pyx | 74 ++++++++++++++----------- 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/sage/modules/vector_modn_sparse.pxd b/src/sage/modules/vector_modn_sparse.pxd index 43cfb95a9a9..2e4e9f6ab41 100644 --- a/src/sage/modules/vector_modn_sparse.pxd +++ b/src/sage/modules/vector_modn_sparse.pxd @@ -1,5 +1,7 @@ +from sage.rings.finite_rings.stdint cimport * + cdef struct c_vector_modint: - int *entries + int_fast64_t *entries int p Py_ssize_t *positions Py_ssize_t degree @@ -8,10 +10,10 @@ cdef struct c_vector_modint: cdef int allocate_c_vector_modint(c_vector_modint* v, Py_ssize_t num_nonzero) except -1 cdef int init_c_vector_modint(c_vector_modint* v, int p, Py_ssize_t degree, Py_ssize_t num_nonzero) except -1 cdef void clear_c_vector_modint(c_vector_modint* v) -cdef Py_ssize_t binary_search0_modn(Py_ssize_t* v, Py_ssize_t n, int x) -cdef Py_ssize_t binary_search_modn(Py_ssize_t* v, Py_ssize_t n, int x, Py_ssize_t* ins) -cdef int get_entry(c_vector_modint* v, Py_ssize_t n) except -1 +cdef Py_ssize_t binary_search0_modn(Py_ssize_t* v, Py_ssize_t n, int_fast64_t x) +cdef Py_ssize_t binary_search_modn(Py_ssize_t* v, Py_ssize_t n, int_fast64_t x, Py_ssize_t* ins) +cdef int_fast64_t get_entry(c_vector_modint* v, Py_ssize_t n) except -1 cdef object to_list(c_vector_modint* v) -cdef int set_entry(c_vector_modint* v, Py_ssize_t n, int x) except -1 +cdef int set_entry(c_vector_modint* v, Py_ssize_t n, int_fast64_t x) except -1 cdef int add_c_vector_modint_init(c_vector_modint* sum, c_vector_modint* v, c_vector_modint* w, int multiple) except -1 -cdef int scale_c_vector_modint(c_vector_modint* v, int scalar) except -1 \ No newline at end of file +cdef int scale_c_vector_modint(c_vector_modint* v, int_fast64_t scalar) except -1 \ No newline at end of file diff --git a/src/sage/modules/vector_modn_sparse.pyx b/src/sage/modules/vector_modn_sparse.pyx index a2b7510a1b9..3a166786bfe 100644 --- a/src/sage/modules/vector_modn_sparse.pyx +++ b/src/sage/modules/vector_modn_sparse.pyx @@ -2,49 +2,54 @@ # Copyright (C) 2004, 2007 William Stein # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ############################################################################# from cysignals.memory cimport sig_malloc, sig_free from sage.modules.vector_modn_sparse cimport c_vector_modint + cdef int allocate_c_vector_modint(c_vector_modint* v, Py_ssize_t num_nonzero) except -1: """ Allocate memory for a c_vector_modint -- most user code won't call this. """ - v.entries = sig_malloc(num_nonzero*sizeof(int)) + v.entries = sig_malloc(num_nonzero*sizeof(int_fast64_t)) if v.entries == NULL: - raise MemoryError("Error allocating memory") + raise MemoryError("error allocating memory") v.positions = sig_malloc(num_nonzero*sizeof(Py_ssize_t)) if v.positions == NULL: sig_free(v.entries) - raise MemoryError("Error allocating memory") + raise MemoryError("error allocating memory") return 0 + cdef int init_c_vector_modint(c_vector_modint* v, int p, Py_ssize_t degree, Py_ssize_t num_nonzero) except -1: """ Initialize a c_vector_modint. """ if (allocate_c_vector_modint(v, num_nonzero) == -1): - raise MemoryError("Error allocating memory for sparse vector.") + raise MemoryError("error allocating memory for sparse vector") if p > 46340: clear_c_vector_modint(v) - raise OverflowError("The prime must be <= 46340.") + raise OverflowError("the prime must be <= 46340") v.num_nonzero = num_nonzero v.degree = degree v.p = p return 0 + cdef void clear_c_vector_modint(c_vector_modint* v): sig_free(v.entries) sig_free(v.positions) -cdef Py_ssize_t binary_search0_modn(Py_ssize_t* v, Py_ssize_t n, int x): + +cdef Py_ssize_t binary_search0_modn(Py_ssize_t* v, Py_ssize_t n, int_fast64_t x): """ Find the position of the int x in the array v, which has length n. - Returns -1 if x is not in the array v. + + Return -1 if x is not in the array v. """ if n == 0: return -1 @@ -52,7 +57,7 @@ cdef Py_ssize_t binary_search0_modn(Py_ssize_t* v, Py_ssize_t n, int x): cdef Py_ssize_t i, j, k i = 0 j = n-1 - while i<=j: + while i <= j: if i == j: if v[i] == x: return i @@ -66,10 +71,12 @@ cdef Py_ssize_t binary_search0_modn(Py_ssize_t* v, Py_ssize_t n, int x): return k return -1 -cdef Py_ssize_t binary_search_modn(Py_ssize_t* v, Py_ssize_t n, int x, Py_ssize_t* ins): + +cdef Py_ssize_t binary_search_modn(Py_ssize_t* v, Py_ssize_t n, int_fast64_t x, Py_ssize_t* ins): """ Find the position of the integer x in the array v, which has length n. - Returns -1 if x is not in the array v, and in this case ins is + + Return -1 if x is not in the array v, and in this case ins is set equal to the position where x should be inserted in order to obtain an ordered array. """ @@ -80,7 +87,7 @@ cdef Py_ssize_t binary_search_modn(Py_ssize_t* v, Py_ssize_t n, int x, Py_ssize_ cdef Py_ssize_t i, j, k i = 0 j = n-1 - while i<=j: + while i <= j: if i == j: if v[i] == x: ins[0] = i @@ -98,49 +105,54 @@ cdef Py_ssize_t binary_search_modn(Py_ssize_t* v, Py_ssize_t n, int x, Py_ssize_ else: # only possibility is that v[k] == x ins[0] = k return k - # end while ins[0] = j+1 return -1 -cdef int get_entry(c_vector_modint* v, Py_ssize_t n) except -1: + +cdef int_fast64_t get_entry(c_vector_modint* v, Py_ssize_t n) except -1: """ - Returns the n-th entry of the sparse vector v. This - would be v[n] in Python syntax. + Return the n-th entry of the sparse vector v. + + This would be v[n] in Python syntax. """ if n >= v.degree or n < 0: - raise IndexError("Index must be between 0 and the degree minus 1.") + raise IndexError("index must be between 0 and the degree minus 1") cdef Py_ssize_t m m = binary_search0_modn(v.positions, v.num_nonzero, n) if m == -1: return 0 return v.entries[m] + cdef object to_list(c_vector_modint* v): """ - Returns a Python list of 2-tuples (i,x), where x=v[i] runs + Return a Python list of 2-tuples (i,x), where x=v[i] runs through the nonzero elements of x, in order. """ cdef object X cdef Py_ssize_t i X = [] - for i from 0 <= i < v.num_nonzero: - X.append( (v.positions[i], v.entries[i]) ) + for i in range(v.num_nonzero): + X.append((v.positions[i], v.entries[i])) return X -cdef int set_entry(c_vector_modint* v, Py_ssize_t n, int x) except -1: + +cdef int set_entry(c_vector_modint* v, Py_ssize_t n, int_fast64_t x) except -1: """ Set the n-th component of the sparse vector v equal to x. + This would be v[n] = x in Python syntax. """ if n < 0 or n >= v.degree: - raise IndexError("Index (=%s) must be between 0 and %s."%(n, v.degree-1)) + raise IndexError("index (=%s) must be between 0 and %s" % (n, v.degree-1)) cdef Py_ssize_t i, m, ins cdef Py_ssize_t m2, ins2 cdef Py_ssize_t *pos - cdef int *e + cdef int_fast64_t *e x = x % v.p - if x<0: x = x + v.p + if x < 0: + x = x + v.p m = binary_search_modn(v.positions, v.num_nonzero, n, &ins) if m != -1: @@ -191,15 +203,16 @@ cdef int set_entry(c_vector_modint* v, Py_ssize_t n, int x) except -1: sig_free(e) sig_free(pos) + cdef int add_c_vector_modint_init(c_vector_modint* sum, c_vector_modint* v, c_vector_modint* w, int multiple) except -1: """ Set sum = v + multiple*w. """ if v.p != w.p: - raise ArithmeticError("The vectors must be modulo the same prime.") + raise ArithmeticError("the vectors must be modulo the same prime") if v.degree != w.degree: - raise ArithmeticError("The vectors must have the same degree.") + raise ArithmeticError("the vectors must have the same degree") cdef int s cdef Py_ssize_t nz, i, j, k @@ -260,12 +273,11 @@ cdef int add_c_vector_modint_init(c_vector_modint* sum, c_vector_modint* v, k = k + 1 # only increment if sum is nonzero! i = i + 1 j = j + 1 - #end if - # end while z.num_nonzero = k return 0 -cdef int scale_c_vector_modint(c_vector_modint* v, int scalar) except -1: + +cdef int scale_c_vector_modint(c_vector_modint* v, int_fast64_t scalar) except -1: scalar = scalar % v.p if scalar == 0: clear_c_vector_modint(v) @@ -274,8 +286,6 @@ cdef int scale_c_vector_modint(c_vector_modint* v, int scalar) except -1: if scalar < 0: scalar = scalar + v.p cdef Py_ssize_t i - for i from 0 <= i < v.num_nonzero: + for i in range(v.num_nonzero): v.entries[i] = (v.entries[i] * scalar) % v.p return 0 - -