This repository has been archived by the owner on Jan 30, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
using int_fast64 for vector_modn_sparse
- Loading branch information
Showing
2 changed files
with
50 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,57 +2,62 @@ | |
# Copyright (C) 2004, 2007 William Stein <[email protected]> | ||
# 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 = <int*>sig_malloc(num_nonzero*sizeof(int)) | ||
v.entries = <int_fast64_t*>sig_malloc(num_nonzero*sizeof(int_fast64_t)) | ||
if v.entries == NULL: | ||
raise MemoryError("Error allocating memory") | ||
raise MemoryError("error allocating memory") | ||
v.positions = <Py_ssize_t*>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 | ||
|
||
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 | ||
|
||
|