passagemath-ntl 10.6.38__cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-ntl might be problematic. Click here for more details.
- passagemath_ntl/__init__.py +3 -0
- passagemath_ntl-10.6.38.dist-info/METADATA +122 -0
- passagemath_ntl-10.6.38.dist-info/RECORD +162 -0
- passagemath_ntl-10.6.38.dist-info/WHEEL +6 -0
- passagemath_ntl-10.6.38.dist-info/top_level.txt +3 -0
- passagemath_ntl.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
- passagemath_ntl.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_ntl.libs/libmpfi-ad12a86d.so.0.0.0 +0 -0
- passagemath_ntl.libs/libmpfr-9d41ebf1.so.6.2.1 +0 -0
- passagemath_ntl.libs/libntl-1bc30f7e.so.45.0.0 +0 -0
- sage/all__sagemath_ntl.py +7 -0
- sage/libs/all__sagemath_ntl.py +3 -0
- sage/libs/mpfi/__init__.pxd +287 -0
- sage/libs/mpfi/types.pxd +10 -0
- sage/libs/ntl/GF2.pxd +18 -0
- sage/libs/ntl/GF2E.pxd +28 -0
- sage/libs/ntl/GF2EX.pxd +12 -0
- sage/libs/ntl/GF2X.pxd +81 -0
- sage/libs/ntl/ZZ.pxd +93 -0
- sage/libs/ntl/ZZX.pxd +85 -0
- sage/libs/ntl/ZZ_p.pxd +28 -0
- sage/libs/ntl/ZZ_pE.pxd +37 -0
- sage/libs/ntl/ZZ_pEX.pxd +106 -0
- sage/libs/ntl/ZZ_pX.pxd +122 -0
- sage/libs/ntl/__init__.py +4 -0
- sage/libs/ntl/all.py +72 -0
- sage/libs/ntl/conversion.pxd +106 -0
- sage/libs/ntl/convert.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/convert.pxd +7 -0
- sage/libs/ntl/convert.pyx +38 -0
- sage/libs/ntl/decl.pxi +18 -0
- sage/libs/ntl/error.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/error.pyx +63 -0
- sage/libs/ntl/lzz_p.pxd +20 -0
- sage/libs/ntl/lzz_pX.pxd +59 -0
- sage/libs/ntl/mat_GF2.pxd +30 -0
- sage/libs/ntl/mat_GF2E.pxd +30 -0
- sage/libs/ntl/mat_ZZ.pxd +59 -0
- sage/libs/ntl/misc.pxi +33 -0
- sage/libs/ntl/ntl_GF2.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2.pxd +5 -0
- sage/libs/ntl/ntl_GF2.pyx +281 -0
- sage/libs/ntl/ntl_GF2E.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2E.pxd +8 -0
- sage/libs/ntl/ntl_GF2E.pyx +488 -0
- sage/libs/ntl/ntl_GF2EContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
- sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
- sage/libs/ntl/ntl_GF2EX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2EX.pxd +10 -0
- sage/libs/ntl/ntl_GF2EX.pyx +251 -0
- sage/libs/ntl/ntl_GF2X.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2X.pxd +5 -0
- sage/libs/ntl/ntl_GF2X.pyx +771 -0
- sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
- sage/libs/ntl/ntl_ZZ.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ.pxd +7 -0
- sage/libs/ntl/ntl_ZZ.pyx +541 -0
- sage/libs/ntl/ntl_ZZX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZX.pxd +7 -0
- sage/libs/ntl/ntl_ZZX.pyx +1206 -0
- sage/libs/ntl/ntl_ZZ_p.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
- sage/libs/ntl/ntl_ZZ_p.pyx +509 -0
- sage/libs/ntl/ntl_ZZ_pContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
- sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
- sage/libs/ntl/ntl_ZZ_pE.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
- sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
- sage/libs/ntl/ntl_ZZ_pEContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
- sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
- sage/libs/ntl/ntl_ZZ_pEX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
- sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
- sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
- sage/libs/ntl/ntl_ZZ_pX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
- sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
- sage/libs/ntl/ntl_lzz_p.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_p.pxd +8 -0
- sage/libs/ntl/ntl_lzz_p.pyx +440 -0
- sage/libs/ntl/ntl_lzz_pContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
- sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
- sage/libs/ntl/ntl_lzz_pX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
- sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
- sage/libs/ntl/ntl_mat_GF2.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
- sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
- sage/libs/ntl/ntl_mat_GF2E.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
- sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
- sage/libs/ntl/ntl_mat_ZZ.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
- sage/libs/ntl/ntl_mat_ZZ.pyx +1523 -0
- sage/libs/ntl/ntl_tools.pxd +3 -0
- sage/libs/ntl/ntlwrap.h +53 -0
- sage/libs/ntl/ntlwrap_impl.h +743 -0
- sage/libs/ntl/types.pxd +157 -0
- sage/libs/ntl/vec_GF2.pxd +26 -0
- sage/libs/ntl/vec_GF2E.pxd +2 -0
- sage/matrix/all__sagemath_ntl.py +1 -0
- sage/matrix/matrix_modn_dense_double.pxd +10 -0
- sage/matrix/matrix_modn_dense_float.pxd +9 -0
- sage/matrix/matrix_modn_dense_template.pxi +3257 -0
- sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
- sage/matrix/matrix_modn_sparse.pxd +8 -0
- sage/misc/all__sagemath_ntl.py +1 -0
- sage/rings/all__sagemath_ntl.py +7 -0
- sage/rings/bernmm.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/bernmm.pyx +161 -0
- sage/rings/bernoulli_mod_p.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/bernoulli_mod_p.pyx +313 -0
- sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
- sage/rings/finite_rings/finite_field_ntl_gf2e.py +305 -0
- sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
- sage/rings/padics/all__sagemath_ntl.py +5 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2368 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3277 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1739 -0
- sage/rings/padics/padic_ZZ_pX_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
- sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
- sage/rings/padics/padic_ext_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ext_element.pxd +38 -0
- sage/rings/padics/padic_ext_element.pyx +512 -0
- sage/rings/padics/pow_computer_ext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/pow_computer_ext.pxd +107 -0
- sage/rings/padics/pow_computer_ext.pyx +2401 -0
- sage/rings/polynomial/all__sagemath_ntl.py +1 -0
- sage/rings/polynomial/evaluation_ntl.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/evaluation_ntl.pxd +7 -0
- sage/rings/polynomial/evaluation_ntl.pyx +70 -0
- sage/rings/polynomial/polynomial_gf2x.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
- sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2049 -0
- sage/rings/polynomial/polynomial_template.pxi +842 -0
- sage/rings/polynomial/polynomial_template_header.pxi +11 -0
- sage/rings/polynomial/polynomial_zz_pex.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
- sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
- sage/rings/real_mpfi.pxd +50 -0
- sage/schemes/all__sagemath_ntl.py +1 -0
- sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
- sage/schemes/hyperelliptic_curves/hypellfrob.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/schemes/hyperelliptic_curves/hypellfrob.pyx +252 -0
|
@@ -0,0 +1,1523 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-ntl
|
|
2
|
+
# distutils: libraries = NTL_LIBRARIES gmp M_LIBRARIES
|
|
3
|
+
# distutils: extra_compile_args = NTL_CFLAGS
|
|
4
|
+
# distutils: include_dirs = NTL_INCDIR
|
|
5
|
+
# distutils: library_dirs = NTL_LIBDIR
|
|
6
|
+
# distutils: extra_link_args = NTL_LIBEXTRA
|
|
7
|
+
# distutils: language = c++
|
|
8
|
+
# sage.doctest: needs sage.libs.pari
|
|
9
|
+
|
|
10
|
+
#*****************************************************************************
|
|
11
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
12
|
+
#
|
|
13
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
14
|
+
#
|
|
15
|
+
# This code is distributed in the hope that it will be useful,
|
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
18
|
+
# General Public License for more details.
|
|
19
|
+
#
|
|
20
|
+
# The full text of the GPL is available at:
|
|
21
|
+
#
|
|
22
|
+
# http://www.gnu.org/licenses/
|
|
23
|
+
#*****************************************************************************
|
|
24
|
+
|
|
25
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
26
|
+
from sage.ext.cplusplus cimport ccrepr
|
|
27
|
+
|
|
28
|
+
include 'misc.pxi'
|
|
29
|
+
include 'decl.pxi'
|
|
30
|
+
|
|
31
|
+
from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
|
|
32
|
+
from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
|
|
33
|
+
from cpython.object cimport PyObject_RichCompare
|
|
34
|
+
|
|
35
|
+
from sage.libs.ntl.ntl_ZZ import unpickle_class_args
|
|
36
|
+
|
|
37
|
+
cdef inline ntl_ZZ make_ZZ(ZZ_c* x):
|
|
38
|
+
cdef ntl_ZZ y
|
|
39
|
+
y = ntl_ZZ()
|
|
40
|
+
y.x = x[0]
|
|
41
|
+
del x
|
|
42
|
+
return y
|
|
43
|
+
|
|
44
|
+
# You must do sig_on() before calling this function
|
|
45
|
+
cdef inline ntl_ZZ make_ZZ_sig_off(ZZ_c* x):
|
|
46
|
+
cdef ntl_ZZ y = make_ZZ(x)
|
|
47
|
+
sig_off()
|
|
48
|
+
return y
|
|
49
|
+
|
|
50
|
+
cdef inline ntl_mat_ZZ make_mat_ZZ(mat_ZZ_c* x):
|
|
51
|
+
cdef ntl_mat_ZZ y
|
|
52
|
+
y = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
|
|
53
|
+
y.x = x[0]
|
|
54
|
+
del x
|
|
55
|
+
y.__nrows = y.x.NumRows()
|
|
56
|
+
y.__ncols = y.x.NumCols()
|
|
57
|
+
return y
|
|
58
|
+
|
|
59
|
+
# You must do sig_on() before calling this function
|
|
60
|
+
cdef inline ntl_mat_ZZ make_mat_ZZ_sig_off(mat_ZZ_c* x):
|
|
61
|
+
cdef ntl_mat_ZZ y = make_mat_ZZ(x)
|
|
62
|
+
sig_off()
|
|
63
|
+
return y
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
##############################################################################
|
|
67
|
+
#
|
|
68
|
+
# ntl_mat_ZZ: Matrices over the integers via NTL
|
|
69
|
+
#
|
|
70
|
+
##############################################################################
|
|
71
|
+
|
|
72
|
+
cdef class ntl_mat_ZZ():
|
|
73
|
+
# see ntl_mat_ZZ.pxd for data members
|
|
74
|
+
r"""
|
|
75
|
+
The \class{mat_ZZ} class implements arithmetic with matrices over `\Z`.
|
|
76
|
+
"""
|
|
77
|
+
def __init__(self, nrows=0, ncols=0, v=None):
|
|
78
|
+
r"""
|
|
79
|
+
The \class{mat_ZZ} class implements arithmetic with matrices over `\Z`.
|
|
80
|
+
|
|
81
|
+
EXAMPLES::
|
|
82
|
+
|
|
83
|
+
sage: M = ntl.mat_ZZ(3,3) ; M
|
|
84
|
+
[
|
|
85
|
+
[0 0 0]
|
|
86
|
+
[0 0 0]
|
|
87
|
+
[0 0 0]
|
|
88
|
+
]
|
|
89
|
+
sage: ntl.mat_ZZ(3,3,[1..9])
|
|
90
|
+
[
|
|
91
|
+
[1 2 3]
|
|
92
|
+
[4 5 6]
|
|
93
|
+
[7 8 9]
|
|
94
|
+
]
|
|
95
|
+
"""
|
|
96
|
+
cdef unsigned long i, j
|
|
97
|
+
cdef ntl_ZZ tmp
|
|
98
|
+
if nrows == 0 and ncols == 0:
|
|
99
|
+
return
|
|
100
|
+
nrows = int(nrows)
|
|
101
|
+
ncols = int(ncols)
|
|
102
|
+
self.x.SetDims(nrows, ncols)
|
|
103
|
+
self.__nrows = nrows
|
|
104
|
+
self.__ncols = ncols
|
|
105
|
+
if v is not None:
|
|
106
|
+
for i from 0 <= i < nrows:
|
|
107
|
+
for j from 0 <= j < ncols:
|
|
108
|
+
tmp = ntl_ZZ(v[i*ncols+j])
|
|
109
|
+
mat_ZZ_setitem(&self.x, i, j, &tmp.x)
|
|
110
|
+
|
|
111
|
+
def __reduce__(self):
|
|
112
|
+
"""
|
|
113
|
+
EXAMPLES::
|
|
114
|
+
|
|
115
|
+
sage: m = ntl.mat_ZZ(3, 2, range(6)); m
|
|
116
|
+
[
|
|
117
|
+
[0 1]
|
|
118
|
+
[2 3]
|
|
119
|
+
[4 5]
|
|
120
|
+
]
|
|
121
|
+
sage: loads(dumps(m))
|
|
122
|
+
[
|
|
123
|
+
[0 1]
|
|
124
|
+
[2 3]
|
|
125
|
+
[4 5]
|
|
126
|
+
]
|
|
127
|
+
sage: loads(dumps(m)) == m
|
|
128
|
+
True
|
|
129
|
+
"""
|
|
130
|
+
return unpickle_class_args, (ntl_mat_ZZ, (self.__nrows, self.__ncols, self.list()))
|
|
131
|
+
|
|
132
|
+
def __repr__(self):
|
|
133
|
+
"""
|
|
134
|
+
Return the string representation of ``self``.
|
|
135
|
+
|
|
136
|
+
EXAMPLES::
|
|
137
|
+
|
|
138
|
+
sage: M = ntl.mat_ZZ(2,3,[5..10]) ; M.__repr__()
|
|
139
|
+
'[\n[5 6 7]\n[8 9 10]\n]'
|
|
140
|
+
"""
|
|
141
|
+
return ccrepr(self.x).replace('[[','[\n[',1)
|
|
142
|
+
|
|
143
|
+
def __mul__(ntl_mat_ZZ self, other):
|
|
144
|
+
"""
|
|
145
|
+
Multiply two matrices.
|
|
146
|
+
|
|
147
|
+
EXAMPLES::
|
|
148
|
+
|
|
149
|
+
sage: M = ntl.mat_ZZ(2,2,[8..11]) ; N = ntl.mat_ZZ(2,2,[-1..2])
|
|
150
|
+
sage: M*N
|
|
151
|
+
[
|
|
152
|
+
[1 18]
|
|
153
|
+
[1 22]
|
|
154
|
+
]
|
|
155
|
+
"""
|
|
156
|
+
cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
|
|
157
|
+
if not isinstance(self, ntl_mat_ZZ):
|
|
158
|
+
self = ntl_mat_ZZ(self)
|
|
159
|
+
if not isinstance(other, ntl_mat_ZZ):
|
|
160
|
+
other = ntl_mat_ZZ(other)
|
|
161
|
+
sig_on()
|
|
162
|
+
mat_ZZ_mul(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
|
|
163
|
+
sig_off()
|
|
164
|
+
return r
|
|
165
|
+
|
|
166
|
+
def __sub__(ntl_mat_ZZ self, other):
|
|
167
|
+
"""
|
|
168
|
+
Return ``self - other``.
|
|
169
|
+
|
|
170
|
+
EXAMPLES::
|
|
171
|
+
|
|
172
|
+
sage: M = ntl.mat_ZZ(2,2,[8..11]) ; N = ntl.mat_ZZ(2,2,[-1..2])
|
|
173
|
+
sage: M-N
|
|
174
|
+
[
|
|
175
|
+
[9 9]
|
|
176
|
+
[9 9]
|
|
177
|
+
]
|
|
178
|
+
"""
|
|
179
|
+
cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
|
|
180
|
+
if not isinstance(self, ntl_mat_ZZ):
|
|
181
|
+
self = ntl_mat_ZZ(self)
|
|
182
|
+
if not isinstance(other, ntl_mat_ZZ):
|
|
183
|
+
other = ntl_mat_ZZ(other)
|
|
184
|
+
sig_on()
|
|
185
|
+
mat_ZZ_sub(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
|
|
186
|
+
sig_off()
|
|
187
|
+
return r
|
|
188
|
+
|
|
189
|
+
def __add__(ntl_mat_ZZ self, other):
|
|
190
|
+
"""
|
|
191
|
+
Return ``self + other``.
|
|
192
|
+
|
|
193
|
+
EXAMPLES::
|
|
194
|
+
|
|
195
|
+
sage: M = ntl.mat_ZZ(2,2,[8..11]) ; N = ntl.mat_ZZ(2,2,[-1..2])
|
|
196
|
+
sage: M+N
|
|
197
|
+
[
|
|
198
|
+
[7 9]
|
|
199
|
+
[11 13]
|
|
200
|
+
]
|
|
201
|
+
"""
|
|
202
|
+
cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
|
|
203
|
+
if not isinstance(self, ntl_mat_ZZ):
|
|
204
|
+
self = ntl_mat_ZZ(self)
|
|
205
|
+
if not isinstance(other, ntl_mat_ZZ):
|
|
206
|
+
other = ntl_mat_ZZ(other)
|
|
207
|
+
sig_on()
|
|
208
|
+
mat_ZZ_add(r.x, (<ntl_mat_ZZ>self).x, (<ntl_mat_ZZ>other).x)
|
|
209
|
+
sig_off()
|
|
210
|
+
return r
|
|
211
|
+
|
|
212
|
+
def __richcmp__(ntl_mat_ZZ self, other, int op):
|
|
213
|
+
"""
|
|
214
|
+
Compare ``self`` to ``other``.
|
|
215
|
+
|
|
216
|
+
EXAMPLES::
|
|
217
|
+
|
|
218
|
+
sage: M = ntl.mat_ZZ(2,2,[3..6])
|
|
219
|
+
sage: N = M^2
|
|
220
|
+
sage: M == M
|
|
221
|
+
True
|
|
222
|
+
sage: M == N
|
|
223
|
+
False
|
|
224
|
+
sage: M == 0
|
|
225
|
+
False
|
|
226
|
+
sage: M < ntl.mat_ZZ(2,2,[4,4,4,4])
|
|
227
|
+
True
|
|
228
|
+
sage: M != ntl.mat_ZZ(1,1,[3])
|
|
229
|
+
True
|
|
230
|
+
sage: M != 0
|
|
231
|
+
True
|
|
232
|
+
"""
|
|
233
|
+
cdef ntl_mat_ZZ b
|
|
234
|
+
try:
|
|
235
|
+
b = <ntl_mat_ZZ?>other
|
|
236
|
+
except TypeError:
|
|
237
|
+
return NotImplemented
|
|
238
|
+
return PyObject_RichCompare(self.list(), other.list(), op)
|
|
239
|
+
|
|
240
|
+
def __pow__(ntl_mat_ZZ self, long e, ignored):
|
|
241
|
+
"""
|
|
242
|
+
Return ``self`` to the e power.
|
|
243
|
+
|
|
244
|
+
EXAMPLES::
|
|
245
|
+
|
|
246
|
+
sage: M = ntl.mat_ZZ(2,2,[8..11])
|
|
247
|
+
sage: M**4
|
|
248
|
+
[
|
|
249
|
+
[56206 62415]
|
|
250
|
+
[69350 77011]
|
|
251
|
+
]
|
|
252
|
+
sage: M**0
|
|
253
|
+
[
|
|
254
|
+
[1 0]
|
|
255
|
+
[0 1]
|
|
256
|
+
]
|
|
257
|
+
sage: M**(-1)
|
|
258
|
+
Traceback (most recent call last):
|
|
259
|
+
...
|
|
260
|
+
ValueError: cannot take negative powers of matrices.
|
|
261
|
+
"""
|
|
262
|
+
if self.__nrows != self.__ncols:
|
|
263
|
+
raise TypeError("cannot take powers of non-square matrices.")
|
|
264
|
+
if e < 0:
|
|
265
|
+
raise ValueError("cannot take negative powers of matrices.")
|
|
266
|
+
cdef ntl_mat_ZZ r = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
|
|
267
|
+
sig_on()
|
|
268
|
+
mat_ZZ_power(r.x, (<ntl_mat_ZZ>self).x, e)
|
|
269
|
+
sig_off()
|
|
270
|
+
return r
|
|
271
|
+
|
|
272
|
+
def nrows(self):
|
|
273
|
+
"""
|
|
274
|
+
Return the number of rows in ``self``.
|
|
275
|
+
|
|
276
|
+
EXAMPLES::
|
|
277
|
+
|
|
278
|
+
sage: M = ntl.mat_ZZ(5,5,range(25))
|
|
279
|
+
sage: M.nrows()
|
|
280
|
+
5
|
|
281
|
+
"""
|
|
282
|
+
return self.__nrows
|
|
283
|
+
|
|
284
|
+
def ncols(self):
|
|
285
|
+
"""
|
|
286
|
+
Return the number of columns in ``self``.
|
|
287
|
+
|
|
288
|
+
EXAMPLES::
|
|
289
|
+
|
|
290
|
+
sage: M = ntl.mat_ZZ(5,8,range(40))
|
|
291
|
+
sage: M.ncols()
|
|
292
|
+
8
|
|
293
|
+
"""
|
|
294
|
+
return self.__ncols
|
|
295
|
+
|
|
296
|
+
def __setitem__(self, ij, x):
|
|
297
|
+
"""
|
|
298
|
+
Given a tuple (i, j), return self[i,j].
|
|
299
|
+
|
|
300
|
+
EXAMPLES::
|
|
301
|
+
|
|
302
|
+
sage: M = ntl.mat_ZZ(2,9,[3..20])
|
|
303
|
+
sage: M[1,7] ## indirect doctest
|
|
304
|
+
19
|
|
305
|
+
"""
|
|
306
|
+
cdef ntl_ZZ y
|
|
307
|
+
cdef int i, j
|
|
308
|
+
if not isinstance(x, ntl_ZZ):
|
|
309
|
+
y = ntl_ZZ(x)
|
|
310
|
+
else:
|
|
311
|
+
y = x
|
|
312
|
+
if not isinstance(ij, tuple) or len(ij) != 2:
|
|
313
|
+
raise TypeError('ij must be a 2-tuple')
|
|
314
|
+
i, j = int(ij[0]),int(ij[1])
|
|
315
|
+
if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
|
|
316
|
+
raise IndexError("array index out of range")
|
|
317
|
+
sig_on()
|
|
318
|
+
mat_ZZ_setitem(&self.x, i, j, &y.x)
|
|
319
|
+
sig_off()
|
|
320
|
+
|
|
321
|
+
def __getitem__(self, ij):
|
|
322
|
+
"""
|
|
323
|
+
EXAMPLES::
|
|
324
|
+
|
|
325
|
+
sage: m = ntl.mat_ZZ(3, 2, range(6))
|
|
326
|
+
sage: m[0,0] ## indirect doctest
|
|
327
|
+
0
|
|
328
|
+
sage: m[2,1]
|
|
329
|
+
5
|
|
330
|
+
sage: m[3,2] # oops, 0 based
|
|
331
|
+
Traceback (most recent call last):
|
|
332
|
+
...
|
|
333
|
+
IndexError: array index out of range
|
|
334
|
+
"""
|
|
335
|
+
cdef int i, j
|
|
336
|
+
if not isinstance(ij, tuple) or len(ij) != 2:
|
|
337
|
+
raise TypeError('ij must be a 2-tuple')
|
|
338
|
+
i, j = ij
|
|
339
|
+
if i < 0 or i >= self.__nrows or j < 0 or j >= self.__ncols:
|
|
340
|
+
raise IndexError("array index out of range")
|
|
341
|
+
sig_on()
|
|
342
|
+
return make_ZZ_sig_off(mat_ZZ_getitem(&self.x, i+1, j+1))
|
|
343
|
+
|
|
344
|
+
def list(self):
|
|
345
|
+
"""
|
|
346
|
+
EXAMPLES::
|
|
347
|
+
|
|
348
|
+
sage: m = ntl.mat_ZZ(3, 4, range(12)); m
|
|
349
|
+
[
|
|
350
|
+
[0 1 2 3]
|
|
351
|
+
[4 5 6 7]
|
|
352
|
+
[8 9 10 11]
|
|
353
|
+
]
|
|
354
|
+
sage: m.list()
|
|
355
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
|
356
|
+
"""
|
|
357
|
+
cdef int i, j
|
|
358
|
+
sig_on()
|
|
359
|
+
L = [make_ZZ(mat_ZZ_getitem(&self.x, i+1, j+1))
|
|
360
|
+
for i from 0 <= i < self.__nrows
|
|
361
|
+
for j from 0 <= j < self.__ncols]
|
|
362
|
+
sig_off()
|
|
363
|
+
return L
|
|
364
|
+
|
|
365
|
+
def determinant(self, deterministic=True):
|
|
366
|
+
"""
|
|
367
|
+
Return the determinant of ``self``.
|
|
368
|
+
|
|
369
|
+
EXAMPLES::
|
|
370
|
+
|
|
371
|
+
sage: ntl.mat_ZZ(8,8,[3..66]).determinant()
|
|
372
|
+
0
|
|
373
|
+
sage: ntl.mat_ZZ(2,5,range(10)).determinant()
|
|
374
|
+
Traceback (most recent call last):
|
|
375
|
+
...
|
|
376
|
+
TypeError: cannot take determinant of non-square matrix.
|
|
377
|
+
sage: ntl.mat_ZZ(4,4,[next_prime(2**i) for i in range(16)]).determinant()
|
|
378
|
+
-10248
|
|
379
|
+
sage: ntl.mat_ZZ(4,4,[ ZZ.random_element() for _ in range(16) ]).determinant() # random
|
|
380
|
+
678
|
|
381
|
+
"""
|
|
382
|
+
if self.__nrows != self.__ncols:
|
|
383
|
+
raise TypeError("cannot take determinant of non-square matrix.")
|
|
384
|
+
sig_on()
|
|
385
|
+
return make_ZZ_sig_off(mat_ZZ_determinant(&self.x, deterministic))
|
|
386
|
+
|
|
387
|
+
def HNF(self, D=None):
|
|
388
|
+
r"""
|
|
389
|
+
The input matrix A=self is an n x m matrix of rank m (so n >=
|
|
390
|
+
m), and D is a multiple of the determinant of the lattice L
|
|
391
|
+
spanned by the rows of A. The output W is the Hermite Normal
|
|
392
|
+
Form of A; that is, W is the unique m x m matrix whose rows
|
|
393
|
+
span L, such that
|
|
394
|
+
|
|
395
|
+
- W is lower triangular,
|
|
396
|
+
- the diagonal entries are positive,
|
|
397
|
+
- any entry below the diagonal is a nonnegative number
|
|
398
|
+
strictly less than the diagonal entry in its column.
|
|
399
|
+
|
|
400
|
+
This is implemented using the algorithm of [P. Domich,
|
|
401
|
+
R. Kannan and L. Trotter, Math. Oper. Research 12:50-59,
|
|
402
|
+
1987].
|
|
403
|
+
|
|
404
|
+
TIMINGS:
|
|
405
|
+
|
|
406
|
+
NTL is not very good compared to MAGMA, unfortunately::
|
|
407
|
+
|
|
408
|
+
sage: a = MatrixSpace(ZZ,200).random_element(x=-2, y=2) # -2 to 2
|
|
409
|
+
sage: A = ntl.mat_ZZ(200,200)
|
|
410
|
+
sage: for i in range(a.nrows()):
|
|
411
|
+
....: for j in range(a.ncols()):
|
|
412
|
+
....: A[i,j] = a[i,j]
|
|
413
|
+
sage: t = cputime(); d = A.determinant()
|
|
414
|
+
sage: cputime(t) # random
|
|
415
|
+
0.33201999999999998
|
|
416
|
+
sage: t = cputime(); B = A.HNF(d) # long time (5s on sage.math, 2011)
|
|
417
|
+
sage: cputime(t) # random
|
|
418
|
+
6.4924050000000006
|
|
419
|
+
|
|
420
|
+
In comparison, MAGMA does this much more quickly:
|
|
421
|
+
\begin{verbatim}
|
|
422
|
+
> A := MatrixAlgebra(IntegerRing(),200)![Random(-2,2) : i in [1..200^2]];
|
|
423
|
+
> time d := Determinant(A);
|
|
424
|
+
Time: 0.140
|
|
425
|
+
> time H := HermiteForm(A);
|
|
426
|
+
Time: 0.290
|
|
427
|
+
\end{verbatim}
|
|
428
|
+
|
|
429
|
+
Also, PARI is also faster than NTL if one uses the flag 1 to
|
|
430
|
+
the mathnf routine. The above takes 16 seconds in PARI.
|
|
431
|
+
|
|
432
|
+
TESTS::
|
|
433
|
+
|
|
434
|
+
sage: ntl.mat_ZZ(2,2,[1..4]).HNF()
|
|
435
|
+
[
|
|
436
|
+
[1 0]
|
|
437
|
+
[0 2]
|
|
438
|
+
]
|
|
439
|
+
"""
|
|
440
|
+
cdef ntl_ZZ _D
|
|
441
|
+
if D is None:
|
|
442
|
+
_D = self.determinant()
|
|
443
|
+
else:
|
|
444
|
+
_D = ntl_ZZ(D)
|
|
445
|
+
sig_on()
|
|
446
|
+
return make_mat_ZZ_sig_off(mat_ZZ_HNF(&self.x, &_D.x))
|
|
447
|
+
|
|
448
|
+
def charpoly(self):
|
|
449
|
+
"""
|
|
450
|
+
Find the characteristic polynomial of self, and return it
|
|
451
|
+
as an NTL ZZX.
|
|
452
|
+
|
|
453
|
+
EXAMPLES::
|
|
454
|
+
|
|
455
|
+
sage: M = ntl.mat_ZZ(2,2,[1,2,3,4])
|
|
456
|
+
sage: M.charpoly()
|
|
457
|
+
[-2 -5 1]
|
|
458
|
+
sage: type(_)
|
|
459
|
+
<class 'sage.libs.ntl.ntl_ZZX.ntl_ZZX'>
|
|
460
|
+
sage: M.determinant()
|
|
461
|
+
-2
|
|
462
|
+
"""
|
|
463
|
+
cdef ntl_ZZX r = ntl_ZZX()
|
|
464
|
+
sig_on()
|
|
465
|
+
mat_ZZ_CharPoly(r.x, self.x)
|
|
466
|
+
sig_off()
|
|
467
|
+
return r
|
|
468
|
+
|
|
469
|
+
def BKZ_FP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
470
|
+
r"""
|
|
471
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
472
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
473
|
+
describe here only the differences in the calling syntax.
|
|
474
|
+
|
|
475
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
476
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
477
|
+
but the running time increases exponentially with BlockSize.
|
|
478
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
479
|
+
|
|
480
|
+
* The optional parameter "prune" can be set to any positive
|
|
481
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
482
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
483
|
+
running time, and hence allow much bigger block size, but the
|
|
484
|
+
quality of the reduction is of course not as good in general.
|
|
485
|
+
Higher values of prune mean better quality, and slower running
|
|
486
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
487
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
488
|
+
|
|
489
|
+
* The QP1 variant uses quad_float precision to compute
|
|
490
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
491
|
+
of the block reduction algorithm. This seems adequate for
|
|
492
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
493
|
+
precision uniformly throughout.
|
|
494
|
+
|
|
495
|
+
INPUT:
|
|
496
|
+
|
|
497
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
498
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
499
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
500
|
+
- ``prune`` -- see above (default: 0)
|
|
501
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
502
|
+
|
|
503
|
+
EXAMPLES::
|
|
504
|
+
|
|
505
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
506
|
+
sage: a = A._ntl_()
|
|
507
|
+
sage: a.BKZ_FP(); a
|
|
508
|
+
2
|
|
509
|
+
[
|
|
510
|
+
[0 0 0 0 0]
|
|
511
|
+
[0 0 0 0 0]
|
|
512
|
+
[0 0 0 0 0]
|
|
513
|
+
[0 1 2 3 4]
|
|
514
|
+
[5 3 1 -1 -3]
|
|
515
|
+
]
|
|
516
|
+
|
|
517
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
518
|
+
sage: r = a.BKZ_FP(U=U); U
|
|
519
|
+
[
|
|
520
|
+
[0 1 0 0 0]
|
|
521
|
+
[1 0 0 0 0]
|
|
522
|
+
[0 0 1 0 0]
|
|
523
|
+
[0 0 0 1 0]
|
|
524
|
+
[0 0 0 0 1]
|
|
525
|
+
]
|
|
526
|
+
"""
|
|
527
|
+
if U is None:
|
|
528
|
+
sig_on()
|
|
529
|
+
rank = mat_ZZ_BKZ_FP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
530
|
+
sig_off()
|
|
531
|
+
return rank
|
|
532
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
533
|
+
sig_on()
|
|
534
|
+
rank = mat_ZZ_BKZ_FP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
535
|
+
sig_off()
|
|
536
|
+
return rank
|
|
537
|
+
else:
|
|
538
|
+
raise TypeError("parameter U has wrong type.")
|
|
539
|
+
|
|
540
|
+
def BKZ_QP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
541
|
+
r"""
|
|
542
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
543
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
544
|
+
describe here only the differences in the calling syntax.
|
|
545
|
+
|
|
546
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
547
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
548
|
+
but the running time increases exponentially with BlockSize.
|
|
549
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
550
|
+
|
|
551
|
+
* The optional parameter "prune" can be set to any positive
|
|
552
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
553
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
554
|
+
running time, and hence allow much bigger block size, but the
|
|
555
|
+
quality of the reduction is of course not as good in general.
|
|
556
|
+
Higher values of prune mean better quality, and slower running
|
|
557
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
558
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
559
|
+
|
|
560
|
+
* The QP1 variant uses quad_float precision to compute
|
|
561
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
562
|
+
of the block reduction algorithm. This seems adequate for
|
|
563
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
564
|
+
precision uniformly throughout.
|
|
565
|
+
|
|
566
|
+
INPUT:
|
|
567
|
+
|
|
568
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
569
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
570
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
571
|
+
- ``prune`` -- see above (default: 0)
|
|
572
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
573
|
+
|
|
574
|
+
EXAMPLES::
|
|
575
|
+
|
|
576
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
577
|
+
sage: a = A._ntl_()
|
|
578
|
+
sage: a.BKZ_QP(); a
|
|
579
|
+
2
|
|
580
|
+
[
|
|
581
|
+
[0 0 0 0 0]
|
|
582
|
+
[0 0 0 0 0]
|
|
583
|
+
[0 0 0 0 0]
|
|
584
|
+
[0 1 2 3 4]
|
|
585
|
+
[5 3 1 -1 -3]
|
|
586
|
+
]
|
|
587
|
+
|
|
588
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
589
|
+
sage: r = a.BKZ_QP(U=U); U
|
|
590
|
+
[
|
|
591
|
+
[0 1 0 0 0]
|
|
592
|
+
[1 0 0 0 0]
|
|
593
|
+
[0 0 1 0 0]
|
|
594
|
+
[0 0 0 1 0]
|
|
595
|
+
[0 0 0 0 1]
|
|
596
|
+
]
|
|
597
|
+
"""
|
|
598
|
+
if U is None:
|
|
599
|
+
sig_on()
|
|
600
|
+
rank = mat_ZZ_BKZ_QP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
601
|
+
sig_off()
|
|
602
|
+
return rank
|
|
603
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
604
|
+
sig_on()
|
|
605
|
+
rank = mat_ZZ_BKZ_QP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
606
|
+
sig_off()
|
|
607
|
+
return rank
|
|
608
|
+
else:
|
|
609
|
+
raise TypeError("parameter U has wrong type.")
|
|
610
|
+
|
|
611
|
+
def BKZ_QP1(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
612
|
+
r"""
|
|
613
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
614
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
615
|
+
describe here only the differences in the calling syntax.
|
|
616
|
+
|
|
617
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
618
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
619
|
+
but the running time increases exponentially with BlockSize.
|
|
620
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
621
|
+
|
|
622
|
+
* The optional parameter "prune" can be set to any positive
|
|
623
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
624
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
625
|
+
running time, and hence allow much bigger block size, but the
|
|
626
|
+
quality of the reduction is of course not as good in general.
|
|
627
|
+
Higher values of prune mean better quality, and slower running
|
|
628
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
629
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
630
|
+
|
|
631
|
+
* The QP1 variant uses quad_float precision to compute
|
|
632
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
633
|
+
of the block reduction algorithm. This seems adequate for
|
|
634
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
635
|
+
precision uniformly throughout.
|
|
636
|
+
|
|
637
|
+
INPUT:
|
|
638
|
+
|
|
639
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
640
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
641
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
642
|
+
- ``prune`` -- see above (default: 0)
|
|
643
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
644
|
+
|
|
645
|
+
EXAMPLES::
|
|
646
|
+
|
|
647
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
648
|
+
sage: a = A._ntl_()
|
|
649
|
+
sage: a.BKZ_QP1(); a
|
|
650
|
+
2
|
|
651
|
+
[
|
|
652
|
+
[0 0 0 0 0]
|
|
653
|
+
[0 0 0 0 0]
|
|
654
|
+
[0 0 0 0 0]
|
|
655
|
+
[0 1 2 3 4]
|
|
656
|
+
[5 3 1 -1 -3]
|
|
657
|
+
]
|
|
658
|
+
|
|
659
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
660
|
+
sage: r = a.BKZ_QP1(U=U); U
|
|
661
|
+
[
|
|
662
|
+
[0 1 0 0 0]
|
|
663
|
+
[1 0 0 0 0]
|
|
664
|
+
[0 0 1 0 0]
|
|
665
|
+
[0 0 0 1 0]
|
|
666
|
+
[0 0 0 0 1]
|
|
667
|
+
]
|
|
668
|
+
"""
|
|
669
|
+
if U is None:
|
|
670
|
+
sig_on()
|
|
671
|
+
rank = mat_ZZ_BKZ_QP1(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
672
|
+
sig_off()
|
|
673
|
+
return rank
|
|
674
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
675
|
+
sig_on()
|
|
676
|
+
rank = mat_ZZ_BKZ_QP1_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
677
|
+
sig_off()
|
|
678
|
+
return rank
|
|
679
|
+
else:
|
|
680
|
+
raise TypeError("parameter U has wrong type.")
|
|
681
|
+
|
|
682
|
+
def BKZ_XD(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
683
|
+
r"""
|
|
684
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
685
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
686
|
+
describe here only the differences in the calling syntax.
|
|
687
|
+
|
|
688
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
689
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
690
|
+
but the running time increases exponentially with BlockSize.
|
|
691
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
692
|
+
|
|
693
|
+
* The optional parameter "prune" can be set to any positive
|
|
694
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
695
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
696
|
+
running time, and hence allow much bigger block size, but the
|
|
697
|
+
quality of the reduction is of course not as good in general.
|
|
698
|
+
Higher values of prune mean better quality, and slower running
|
|
699
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
700
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
701
|
+
|
|
702
|
+
* The QP1 variant uses quad_float precision to compute
|
|
703
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
704
|
+
of the block reduction algorithm. This seems adequate for
|
|
705
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
706
|
+
precision uniformly throughout.
|
|
707
|
+
|
|
708
|
+
INPUT:
|
|
709
|
+
|
|
710
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
711
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
712
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
713
|
+
- ``prune`` -- see above (default: 0)
|
|
714
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
715
|
+
|
|
716
|
+
EXAMPLES::
|
|
717
|
+
|
|
718
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
719
|
+
sage: a = A._ntl_()
|
|
720
|
+
sage: a.BKZ_XD(); a
|
|
721
|
+
2
|
|
722
|
+
[
|
|
723
|
+
[0 0 0 0 0]
|
|
724
|
+
[0 0 0 0 0]
|
|
725
|
+
[0 0 0 0 0]
|
|
726
|
+
[0 1 2 3 4]
|
|
727
|
+
[5 3 1 -1 -3]
|
|
728
|
+
]
|
|
729
|
+
|
|
730
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
731
|
+
sage: r = a.BKZ_XD(U=U); U
|
|
732
|
+
[
|
|
733
|
+
[0 1 0 0 0]
|
|
734
|
+
[1 0 0 0 0]
|
|
735
|
+
[0 0 1 0 0]
|
|
736
|
+
[0 0 0 1 0]
|
|
737
|
+
[0 0 0 0 1]
|
|
738
|
+
]
|
|
739
|
+
"""
|
|
740
|
+
if U is None:
|
|
741
|
+
sig_on()
|
|
742
|
+
rank = mat_ZZ_BKZ_XD(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
743
|
+
sig_off()
|
|
744
|
+
return rank
|
|
745
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
746
|
+
sig_on()
|
|
747
|
+
rank = mat_ZZ_BKZ_XD_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
748
|
+
sig_off()
|
|
749
|
+
return rank
|
|
750
|
+
else:
|
|
751
|
+
raise TypeError("parameter U has wrong type.")
|
|
752
|
+
|
|
753
|
+
def BKZ_RR(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
754
|
+
r"""
|
|
755
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
756
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
757
|
+
describe here only the differences in the calling syntax.
|
|
758
|
+
|
|
759
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
760
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
761
|
+
but the running time increases exponentially with BlockSize.
|
|
762
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
763
|
+
|
|
764
|
+
* The optional parameter "prune" can be set to any positive
|
|
765
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
766
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
767
|
+
running time, and hence allow much bigger block size, but the
|
|
768
|
+
quality of the reduction is of course not as good in general.
|
|
769
|
+
Higher values of prune mean better quality, and slower running
|
|
770
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
771
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
772
|
+
|
|
773
|
+
* The QP1 variant uses quad_float precision to compute
|
|
774
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
775
|
+
of the block reduction algorithm. This seems adequate for
|
|
776
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
777
|
+
precision uniformly throughout.
|
|
778
|
+
|
|
779
|
+
INPUT:
|
|
780
|
+
|
|
781
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
782
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
783
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
784
|
+
- ``prune`` -- see above (default: 0)
|
|
785
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
786
|
+
|
|
787
|
+
EXAMPLES::
|
|
788
|
+
|
|
789
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
790
|
+
sage: a = A._ntl_()
|
|
791
|
+
sage: a.BKZ_RR(); a
|
|
792
|
+
2
|
|
793
|
+
[
|
|
794
|
+
[0 0 0 0 0]
|
|
795
|
+
[0 0 0 0 0]
|
|
796
|
+
[0 0 0 0 0]
|
|
797
|
+
[0 1 2 3 4]
|
|
798
|
+
[5 3 1 -1 -3]
|
|
799
|
+
]
|
|
800
|
+
|
|
801
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
802
|
+
sage: r = a.BKZ_RR(U=U); U
|
|
803
|
+
[
|
|
804
|
+
[0 1 0 0 0]
|
|
805
|
+
[1 0 0 0 0]
|
|
806
|
+
[0 0 1 0 0]
|
|
807
|
+
[0 0 0 1 0]
|
|
808
|
+
[0 0 0 0 1]
|
|
809
|
+
]
|
|
810
|
+
"""
|
|
811
|
+
if U is None:
|
|
812
|
+
sig_on()
|
|
813
|
+
rank = mat_ZZ_BKZ_RR(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
814
|
+
sig_off()
|
|
815
|
+
return rank
|
|
816
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
817
|
+
sig_on()
|
|
818
|
+
rank = mat_ZZ_BKZ_RR_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
819
|
+
sig_off()
|
|
820
|
+
return rank
|
|
821
|
+
else:
|
|
822
|
+
raise TypeError("parameter U has wrong type.")
|
|
823
|
+
|
|
824
|
+
def G_BKZ_FP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
825
|
+
r"""
|
|
826
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
827
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
828
|
+
describe here only the differences in the calling syntax.
|
|
829
|
+
|
|
830
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
831
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
832
|
+
but the running time increases exponentially with BlockSize.
|
|
833
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
834
|
+
|
|
835
|
+
* The optional parameter "prune" can be set to any positive
|
|
836
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
837
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
838
|
+
running time, and hence allow much bigger block size, but the
|
|
839
|
+
quality of the reduction is of course not as good in general.
|
|
840
|
+
Higher values of prune mean better quality, and slower running
|
|
841
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
842
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
843
|
+
|
|
844
|
+
* The QP1 variant uses quad_float precision to compute
|
|
845
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
846
|
+
of the block reduction algorithm. This seems adequate for
|
|
847
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
848
|
+
precision uniformly throughout.
|
|
849
|
+
|
|
850
|
+
INPUT:
|
|
851
|
+
|
|
852
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
853
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
854
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
855
|
+
- ``prune`` -- see above (default: 0)
|
|
856
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
857
|
+
|
|
858
|
+
EXAMPLES::
|
|
859
|
+
|
|
860
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
861
|
+
sage: a = A._ntl_()
|
|
862
|
+
sage: a.G_BKZ_FP(); a
|
|
863
|
+
2
|
|
864
|
+
[
|
|
865
|
+
[0 0 0 0 0]
|
|
866
|
+
[0 0 0 0 0]
|
|
867
|
+
[0 0 0 0 0]
|
|
868
|
+
[0 1 2 3 4]
|
|
869
|
+
[5 3 1 -1 -3]
|
|
870
|
+
]
|
|
871
|
+
|
|
872
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
873
|
+
sage: r = a.G_BKZ_FP(U=U); U
|
|
874
|
+
[
|
|
875
|
+
[0 1 0 0 0]
|
|
876
|
+
[1 0 0 0 0]
|
|
877
|
+
[0 0 1 0 0]
|
|
878
|
+
[0 0 0 1 0]
|
|
879
|
+
[0 0 0 0 1]
|
|
880
|
+
]
|
|
881
|
+
"""
|
|
882
|
+
if U is None:
|
|
883
|
+
sig_on()
|
|
884
|
+
rank = mat_ZZ_G_BKZ_FP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
885
|
+
sig_off()
|
|
886
|
+
return rank
|
|
887
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
888
|
+
sig_on()
|
|
889
|
+
rank = mat_ZZ_G_BKZ_FP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
890
|
+
sig_off()
|
|
891
|
+
return rank
|
|
892
|
+
else:
|
|
893
|
+
raise TypeError("parameter U has wrong type.")
|
|
894
|
+
|
|
895
|
+
def G_BKZ_QP(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
896
|
+
r"""
|
|
897
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
898
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
899
|
+
describe here only the differences in the calling syntax.
|
|
900
|
+
|
|
901
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
902
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
903
|
+
but the running time increases exponentially with BlockSize.
|
|
904
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
905
|
+
|
|
906
|
+
* The optional parameter "prune" can be set to any positive
|
|
907
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
908
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
909
|
+
running time, and hence allow much bigger block size, but the
|
|
910
|
+
quality of the reduction is of course not as good in general.
|
|
911
|
+
Higher values of prune mean better quality, and slower running
|
|
912
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
913
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
914
|
+
|
|
915
|
+
* The QP1 variant uses quad_float precision to compute
|
|
916
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
917
|
+
of the block reduction algorithm. This seems adequate for
|
|
918
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
919
|
+
precision uniformly throughout.
|
|
920
|
+
|
|
921
|
+
INPUT:
|
|
922
|
+
|
|
923
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
924
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
925
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
926
|
+
- ``prune`` -- see above (default: 0)
|
|
927
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
928
|
+
|
|
929
|
+
EXAMPLES::
|
|
930
|
+
|
|
931
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
932
|
+
sage: a = A._ntl_()
|
|
933
|
+
sage: a.G_BKZ_QP(); a
|
|
934
|
+
2
|
|
935
|
+
[
|
|
936
|
+
[0 0 0 0 0]
|
|
937
|
+
[0 0 0 0 0]
|
|
938
|
+
[0 0 0 0 0]
|
|
939
|
+
[0 1 2 3 4]
|
|
940
|
+
[5 3 1 -1 -3]
|
|
941
|
+
]
|
|
942
|
+
|
|
943
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
944
|
+
sage: r = a.G_BKZ_QP(U=U); U
|
|
945
|
+
[
|
|
946
|
+
[0 1 0 0 0]
|
|
947
|
+
[1 0 0 0 0]
|
|
948
|
+
[0 0 1 0 0]
|
|
949
|
+
[0 0 0 1 0]
|
|
950
|
+
[0 0 0 0 1]
|
|
951
|
+
]
|
|
952
|
+
"""
|
|
953
|
+
if U is None:
|
|
954
|
+
sig_on()
|
|
955
|
+
rank = mat_ZZ_G_BKZ_QP(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
956
|
+
sig_off()
|
|
957
|
+
return rank
|
|
958
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
959
|
+
sig_on()
|
|
960
|
+
rank = mat_ZZ_G_BKZ_QP_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
961
|
+
sig_off()
|
|
962
|
+
return rank
|
|
963
|
+
else:
|
|
964
|
+
raise TypeError("parameter U has wrong type.")
|
|
965
|
+
|
|
966
|
+
def G_BKZ_QP1(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
967
|
+
r"""
|
|
968
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
969
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
970
|
+
describe here only the differences in the calling syntax.
|
|
971
|
+
|
|
972
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
973
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
974
|
+
but the running time increases exponentially with BlockSize.
|
|
975
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
976
|
+
|
|
977
|
+
* The optional parameter "prune" can be set to any positive
|
|
978
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
979
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
980
|
+
running time, and hence allow much bigger block size, but the
|
|
981
|
+
quality of the reduction is of course not as good in general.
|
|
982
|
+
Higher values of prune mean better quality, and slower running
|
|
983
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
984
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
985
|
+
|
|
986
|
+
* The QP1 variant uses quad_float precision to compute
|
|
987
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
988
|
+
of the block reduction algorithm. This seems adequate for
|
|
989
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
990
|
+
precision uniformly throughout.
|
|
991
|
+
|
|
992
|
+
INPUT:
|
|
993
|
+
|
|
994
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
995
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
996
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
997
|
+
- ``prune`` -- see above (default: 0)
|
|
998
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
999
|
+
|
|
1000
|
+
EXAMPLES::
|
|
1001
|
+
|
|
1002
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
1003
|
+
sage: a = A._ntl_()
|
|
1004
|
+
sage: a.G_BKZ_QP1(); a
|
|
1005
|
+
2
|
|
1006
|
+
[
|
|
1007
|
+
[0 0 0 0 0]
|
|
1008
|
+
[0 0 0 0 0]
|
|
1009
|
+
[0 0 0 0 0]
|
|
1010
|
+
[0 1 2 3 4]
|
|
1011
|
+
[5 3 1 -1 -3]
|
|
1012
|
+
]
|
|
1013
|
+
|
|
1014
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
1015
|
+
sage: r = a.G_BKZ_QP1(U=U); U
|
|
1016
|
+
[
|
|
1017
|
+
[0 1 0 0 0]
|
|
1018
|
+
[1 0 0 0 0]
|
|
1019
|
+
[0 0 1 0 0]
|
|
1020
|
+
[0 0 0 1 0]
|
|
1021
|
+
[0 0 0 0 1]
|
|
1022
|
+
]
|
|
1023
|
+
"""
|
|
1024
|
+
if U is None:
|
|
1025
|
+
sig_on()
|
|
1026
|
+
rank = mat_ZZ_G_BKZ_QP1(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
1027
|
+
sig_off()
|
|
1028
|
+
return rank
|
|
1029
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
1030
|
+
sig_on()
|
|
1031
|
+
rank = mat_ZZ_G_BKZ_QP1_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
1032
|
+
sig_off()
|
|
1033
|
+
return rank
|
|
1034
|
+
else:
|
|
1035
|
+
raise TypeError("parameter U has wrong type.")
|
|
1036
|
+
|
|
1037
|
+
def G_BKZ_XD(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
1038
|
+
r"""
|
|
1039
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
1040
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
1041
|
+
describe here only the differences in the calling syntax.
|
|
1042
|
+
|
|
1043
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
1044
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
1045
|
+
but the running time increases exponentially with BlockSize.
|
|
1046
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
1047
|
+
|
|
1048
|
+
* The optional parameter "prune" can be set to any positive
|
|
1049
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
1050
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
1051
|
+
running time, and hence allow much bigger block size, but the
|
|
1052
|
+
quality of the reduction is of course not as good in general.
|
|
1053
|
+
Higher values of prune mean better quality, and slower running
|
|
1054
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
1055
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
1056
|
+
|
|
1057
|
+
* The QP1 variant uses quad_float precision to compute
|
|
1058
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
1059
|
+
of the block reduction algorithm. This seems adequate for
|
|
1060
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
1061
|
+
precision uniformly throughout.
|
|
1062
|
+
|
|
1063
|
+
INPUT:
|
|
1064
|
+
|
|
1065
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
1066
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
1067
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
1068
|
+
- ``prune`` -- see above (default: 0)
|
|
1069
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
1070
|
+
|
|
1071
|
+
EXAMPLES::
|
|
1072
|
+
|
|
1073
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
1074
|
+
sage: a = A._ntl_()
|
|
1075
|
+
sage: a.G_BKZ_XD(); a
|
|
1076
|
+
2
|
|
1077
|
+
[
|
|
1078
|
+
[0 0 0 0 0]
|
|
1079
|
+
[0 0 0 0 0]
|
|
1080
|
+
[0 0 0 0 0]
|
|
1081
|
+
[0 1 2 3 4]
|
|
1082
|
+
[5 3 1 -1 -3]
|
|
1083
|
+
]
|
|
1084
|
+
|
|
1085
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
1086
|
+
sage: r = a.G_BKZ_XD(U=U); U
|
|
1087
|
+
[
|
|
1088
|
+
[0 1 0 0 0]
|
|
1089
|
+
[1 0 0 0 0]
|
|
1090
|
+
[0 0 1 0 0]
|
|
1091
|
+
[0 0 0 1 0]
|
|
1092
|
+
[0 0 0 0 1]
|
|
1093
|
+
]
|
|
1094
|
+
"""
|
|
1095
|
+
if U is None:
|
|
1096
|
+
sig_on()
|
|
1097
|
+
rank = mat_ZZ_G_BKZ_XD(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
1098
|
+
sig_off()
|
|
1099
|
+
return rank
|
|
1100
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
1101
|
+
sig_on()
|
|
1102
|
+
rank = mat_ZZ_G_BKZ_XD_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
1103
|
+
sig_off()
|
|
1104
|
+
return rank
|
|
1105
|
+
else:
|
|
1106
|
+
raise TypeError("parameter U has wrong type.")
|
|
1107
|
+
|
|
1108
|
+
def G_BKZ_RR(self, U=None, delta=0.99, BlockSize=10, prune=0, verbose=False):
|
|
1109
|
+
r"""
|
|
1110
|
+
All BKZ methods are equivalent to the LLL routines,
|
|
1111
|
+
except that Block Korkin-Zolotarev reduction is applied. We
|
|
1112
|
+
describe here only the differences in the calling syntax.
|
|
1113
|
+
|
|
1114
|
+
* The optional parameter "BlockSize" specifies the size of the
|
|
1115
|
+
blocks in the reduction. High values yield shorter vectors,
|
|
1116
|
+
but the running time increases exponentially with BlockSize.
|
|
1117
|
+
BlockSize should be between 2 and the number of rows of B.
|
|
1118
|
+
|
|
1119
|
+
* The optional parameter "prune" can be set to any positive
|
|
1120
|
+
number to invoke the Volume Heuristic from [Schnorr and
|
|
1121
|
+
Horner, Eurocrypt '95]. This can significantly reduce the
|
|
1122
|
+
running time, and hence allow much bigger block size, but the
|
|
1123
|
+
quality of the reduction is of course not as good in general.
|
|
1124
|
+
Higher values of prune mean better quality, and slower running
|
|
1125
|
+
time. When prune == 0, pruning is disabled. Recommended
|
|
1126
|
+
usage: for BlockSize >= 30, set 10 <= prune <= 15.
|
|
1127
|
+
|
|
1128
|
+
* The QP1 variant uses quad_float precision to compute
|
|
1129
|
+
Gram-Schmidt, but uses double precision in the search phase
|
|
1130
|
+
of the block reduction algorithm. This seems adequate for
|
|
1131
|
+
most purposes, and is faster than QP, which uses quad_float
|
|
1132
|
+
precision uniformly throughout.
|
|
1133
|
+
|
|
1134
|
+
INPUT:
|
|
1135
|
+
|
|
1136
|
+
- ``U`` -- permutation matrix (see LLL, default: ``None``)
|
|
1137
|
+
- ``delta`` -- reduction parameter (default: 0.99)
|
|
1138
|
+
- ``BlockSize`` -- see above (default: 10)
|
|
1139
|
+
- ``prune`` -- see above (default: 0)
|
|
1140
|
+
- ``verbose`` -- print verbose output (default: ``False``)
|
|
1141
|
+
|
|
1142
|
+
EXAMPLES::
|
|
1143
|
+
|
|
1144
|
+
sage: A = Matrix(ZZ,5,5,range(25))
|
|
1145
|
+
sage: a = A._ntl_()
|
|
1146
|
+
sage: a.G_BKZ_RR(); a
|
|
1147
|
+
2
|
|
1148
|
+
[
|
|
1149
|
+
[0 0 0 0 0]
|
|
1150
|
+
[0 0 0 0 0]
|
|
1151
|
+
[0 0 0 0 0]
|
|
1152
|
+
[0 1 2 3 4]
|
|
1153
|
+
[5 3 1 -1 -3]
|
|
1154
|
+
]
|
|
1155
|
+
|
|
1156
|
+
sage: U = ntl.mat_ZZ(2,2) # note that the dimension doesn't matter
|
|
1157
|
+
sage: r = a.G_BKZ_RR(U=U); U
|
|
1158
|
+
[
|
|
1159
|
+
[0 1 0 0 0]
|
|
1160
|
+
[1 0 0 0 0]
|
|
1161
|
+
[0 0 1 0 0]
|
|
1162
|
+
[0 0 0 1 0]
|
|
1163
|
+
[0 0 0 0 1]
|
|
1164
|
+
]
|
|
1165
|
+
"""
|
|
1166
|
+
if U is None:
|
|
1167
|
+
sig_on()
|
|
1168
|
+
rank = mat_ZZ_G_BKZ_RR(self.x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
1169
|
+
sig_off()
|
|
1170
|
+
return rank
|
|
1171
|
+
elif isinstance(U, ntl_mat_ZZ):
|
|
1172
|
+
sig_on()
|
|
1173
|
+
rank = mat_ZZ_G_BKZ_RR_U(self.x, (<ntl_mat_ZZ>U).x, float(delta), int(BlockSize), int(prune), 0, int(verbose))
|
|
1174
|
+
sig_off()
|
|
1175
|
+
return rank
|
|
1176
|
+
else:
|
|
1177
|
+
raise TypeError("parameter U has wrong type.")
|
|
1178
|
+
|
|
1179
|
+
def LLL(self, a=3, b=4, return_U=False, verbose=False):
|
|
1180
|
+
r"""
|
|
1181
|
+
Perform LLL reduction of ``self`` (puts \code{self} in an LLL form).
|
|
1182
|
+
|
|
1183
|
+
\code{self} is an `m x n` matrix, viewed as `m` rows of
|
|
1184
|
+
`n`-vectors. `m` may be less than, equal to, or greater than `n`,
|
|
1185
|
+
and the rows need not be linearly independent. ``self`` is
|
|
1186
|
+
transformed into an LLL-reduced basis, and the return value is
|
|
1187
|
+
the rank r of ``self`` so as det2 (see below). The first `m-r` rows
|
|
1188
|
+
of ``self`` are zero.
|
|
1189
|
+
|
|
1190
|
+
More specifically, elementary row transformations are
|
|
1191
|
+
performed on \code{self} so that the nonzero rows of
|
|
1192
|
+
new-\code{self} form an LLL-reduced basis for the lattice
|
|
1193
|
+
spanned by the rows of old-\code{self}. The default reduction
|
|
1194
|
+
parameter is `\delta=3/4`, which means that the squared length
|
|
1195
|
+
of the first nonzero basis vector is no more than `2^{r-1}`
|
|
1196
|
+
times that of the shortest vector in the lattice.
|
|
1197
|
+
|
|
1198
|
+
det2 is calculated as the \emph{square} of the determinant of
|
|
1199
|
+
the lattice---note that sqrt(det2) is in general an integer
|
|
1200
|
+
only when r = n.
|
|
1201
|
+
|
|
1202
|
+
If return_U is True, a value U is returned which is the
|
|
1203
|
+
transformation matrix, so that U is a unimodular m x m matrix
|
|
1204
|
+
with U * old-\code{self} = new-\code{self}. Note that the
|
|
1205
|
+
first m-r rows of U form a basis (as a lattice) for the kernel
|
|
1206
|
+
of old-B.
|
|
1207
|
+
|
|
1208
|
+
The parameters a and b allow an arbitrary reduction parameter
|
|
1209
|
+
`\delta=a/b`, where `1/4 < a/b \leq 1`, where a and b are positive
|
|
1210
|
+
integers. For a basis reduced with parameter delta, the
|
|
1211
|
+
squared length of the first nonzero basis vector is no more
|
|
1212
|
+
than `1/(delta-1/4)^{r-1}` times that of the shortest vector in
|
|
1213
|
+
the lattice.
|
|
1214
|
+
|
|
1215
|
+
The algorithm employed here is essentially the one in Cohen's
|
|
1216
|
+
book: [H. Cohen, A Course in Computational Algebraic Number
|
|
1217
|
+
Theory, Springer, 1993]
|
|
1218
|
+
|
|
1219
|
+
INPUT:
|
|
1220
|
+
|
|
1221
|
+
- ``a`` -- parameter a as described above (default: 3)
|
|
1222
|
+
- ``b`` -- parameter b as described above (default: 4)
|
|
1223
|
+
- ``return_U`` -- return U as described above
|
|
1224
|
+
- ``verbose`` -- if ``True`` NTL will produce some verbatim messages on
|
|
1225
|
+
what's going on internally (default: ``False``)
|
|
1226
|
+
|
|
1227
|
+
OUTPUT:
|
|
1228
|
+
|
|
1229
|
+
(rank,det2,[U]) where rank,det2, and U are as described
|
|
1230
|
+
above and U is an optional return value if return_U is ``True``.
|
|
1231
|
+
|
|
1232
|
+
EXAMPLES::
|
|
1233
|
+
|
|
1234
|
+
sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
|
|
1235
|
+
sage: M.LLL()
|
|
1236
|
+
(2, 54)
|
|
1237
|
+
sage: M
|
|
1238
|
+
[
|
|
1239
|
+
[0 0 0]
|
|
1240
|
+
[2 1 0]
|
|
1241
|
+
[-1 1 3]
|
|
1242
|
+
]
|
|
1243
|
+
sage: M=ntl.mat_ZZ(4,4,[-6,9,-15,-18,4,-6,10,12,10,-16,18,35,-24,36,-46,-82]); M
|
|
1244
|
+
[
|
|
1245
|
+
[-6 9 -15 -18]
|
|
1246
|
+
[4 -6 10 12]
|
|
1247
|
+
[10 -16 18 35]
|
|
1248
|
+
[-24 36 -46 -82]
|
|
1249
|
+
]
|
|
1250
|
+
sage: M.LLL()
|
|
1251
|
+
(3, 19140)
|
|
1252
|
+
sage: M
|
|
1253
|
+
[
|
|
1254
|
+
[0 0 0 0]
|
|
1255
|
+
[0 -2 0 0]
|
|
1256
|
+
[-2 1 -5 -6]
|
|
1257
|
+
[0 -1 -7 5]
|
|
1258
|
+
]
|
|
1259
|
+
|
|
1260
|
+
WARNING: This method modifies \code{self}. So after applying
|
|
1261
|
+
this method your matrix will be a vector of vectors.
|
|
1262
|
+
"""
|
|
1263
|
+
cdef ZZ_c *det2
|
|
1264
|
+
cdef ntl_mat_ZZ U
|
|
1265
|
+
if return_U:
|
|
1266
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1267
|
+
sig_on()
|
|
1268
|
+
rank = int(mat_ZZ_LLL_U(&det2, &self.x, &U.x, int(a), int(b), int(verbose)))
|
|
1269
|
+
|
|
1270
|
+
return rank, make_ZZ_sig_off(det2), U
|
|
1271
|
+
else:
|
|
1272
|
+
sig_on()
|
|
1273
|
+
rank = int(mat_ZZ_LLL(&det2,&self.x,int(a),int(b),int(verbose)))
|
|
1274
|
+
return rank, make_ZZ_sig_off(det2)
|
|
1275
|
+
|
|
1276
|
+
def LLL_FP(self, delta=0.75, return_U=False, verbose=False):
|
|
1277
|
+
r"""
|
|
1278
|
+
Perform approximate LLL reduction of \code{self} (puts
|
|
1279
|
+
\code{self} in an LLL form) subject to the following
|
|
1280
|
+
conditions:
|
|
1281
|
+
|
|
1282
|
+
The precision is double.
|
|
1283
|
+
|
|
1284
|
+
The return value is the rank of B.
|
|
1285
|
+
|
|
1286
|
+
Classical Gram-Schmidt Orthogonalization is used:
|
|
1287
|
+
|
|
1288
|
+
This choice uses classical methods for computing the
|
|
1289
|
+
Gram-Schmidt orthogonalization. It is fast but prone to
|
|
1290
|
+
stability problems. This strategy was first proposed by
|
|
1291
|
+
Schnorr and Euchner [C. P. Schnorr and M. Euchner,
|
|
1292
|
+
Proc. Fundamentals of Computation Theory, LNCS 529, pp. 68-85,
|
|
1293
|
+
1991]. The version implemented here is substantially
|
|
1294
|
+
different, improving both stability and performance.
|
|
1295
|
+
|
|
1296
|
+
If return_U is True, then also U is returned which is
|
|
1297
|
+
the transition matrix: `U * self_{old} = self_{new}`
|
|
1298
|
+
|
|
1299
|
+
The optional argument 'delta' is the reduction parameter, and
|
|
1300
|
+
may be set so that 0.50 <= delta < 1. Setting it close to 1
|
|
1301
|
+
yields shorter vectors, and also improves the stability, but
|
|
1302
|
+
increases the running time. Recommended value: delta =
|
|
1303
|
+
0.99.
|
|
1304
|
+
|
|
1305
|
+
The optional parameter 'verbose' can be set to see all kinds
|
|
1306
|
+
of fun things printed while the routine is executing. A
|
|
1307
|
+
status report is also printed every once in a while.
|
|
1308
|
+
|
|
1309
|
+
INPUT:
|
|
1310
|
+
|
|
1311
|
+
- ``delta`` -- as described above (0.5 <= delta < 1.0) (default: 0.75)
|
|
1312
|
+
- ``return_U`` -- return U as described above
|
|
1313
|
+
- ``verbose`` -- if ``True`` NTL will produce some verbatim messages on
|
|
1314
|
+
what's going on internally (default: ``False``)
|
|
1315
|
+
|
|
1316
|
+
OUTPUT:
|
|
1317
|
+
|
|
1318
|
+
(rank,[U]) where rank and U are as described above and U
|
|
1319
|
+
is an optional return value if ``return_U`` is ``True``.
|
|
1320
|
+
|
|
1321
|
+
EXAMPLES::
|
|
1322
|
+
|
|
1323
|
+
sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
|
|
1324
|
+
sage: M.LLL_FP()
|
|
1325
|
+
2
|
|
1326
|
+
sage: M
|
|
1327
|
+
[
|
|
1328
|
+
[0 0 0]
|
|
1329
|
+
[2 1 0]
|
|
1330
|
+
[-1 1 3]
|
|
1331
|
+
]
|
|
1332
|
+
sage: M=ntl.mat_ZZ(4,4,[-6,9,-15,-18,4,-6,10,12,10,-16,18,35,-24,36,-46,-82]); M
|
|
1333
|
+
[
|
|
1334
|
+
[-6 9 -15 -18]
|
|
1335
|
+
[4 -6 10 12]
|
|
1336
|
+
[10 -16 18 35]
|
|
1337
|
+
[-24 36 -46 -82]
|
|
1338
|
+
]
|
|
1339
|
+
sage: M.LLL_FP()
|
|
1340
|
+
3
|
|
1341
|
+
sage: M
|
|
1342
|
+
[
|
|
1343
|
+
[0 0 0 0]
|
|
1344
|
+
[0 -2 0 0]
|
|
1345
|
+
[-2 1 -5 -6]
|
|
1346
|
+
[0 -1 -7 5]
|
|
1347
|
+
]
|
|
1348
|
+
|
|
1349
|
+
WARNING: This method modifies \code{self}. So after applying this
|
|
1350
|
+
method your matrix will be a vector of vectors.
|
|
1351
|
+
"""
|
|
1352
|
+
cdef ntl_mat_ZZ U
|
|
1353
|
+
if return_U:
|
|
1354
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1355
|
+
sig_on()
|
|
1356
|
+
rank = int(mat_ZZ_LLL_FP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1357
|
+
sig_off()
|
|
1358
|
+
return rank, U
|
|
1359
|
+
else:
|
|
1360
|
+
sig_on()
|
|
1361
|
+
rank = int(mat_ZZ_LLL_FP(self.x,float(delta),0,0,int(verbose)))
|
|
1362
|
+
sig_off()
|
|
1363
|
+
return rank
|
|
1364
|
+
|
|
1365
|
+
def LLL_QP(self, delta, return_U=False, verbose=False):
|
|
1366
|
+
r"""
|
|
1367
|
+
Perform the same reduction as \code{self.LLL_FP} using the
|
|
1368
|
+
same calling conventions but with quad float precision.
|
|
1369
|
+
|
|
1370
|
+
EXAMPLES::
|
|
1371
|
+
|
|
1372
|
+
sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
|
|
1373
|
+
sage: M.LLL_QP(delta=0.75)
|
|
1374
|
+
2
|
|
1375
|
+
"""
|
|
1376
|
+
cdef ntl_mat_ZZ U
|
|
1377
|
+
if return_U:
|
|
1378
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1379
|
+
sig_on()
|
|
1380
|
+
rank = int(mat_ZZ_LLL_QP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1381
|
+
sig_off()
|
|
1382
|
+
return rank, U
|
|
1383
|
+
else:
|
|
1384
|
+
sig_on()
|
|
1385
|
+
rank = int(mat_ZZ_LLL_QP(self.x,float(delta),0,0,int(verbose)))
|
|
1386
|
+
sig_off()
|
|
1387
|
+
return rank
|
|
1388
|
+
|
|
1389
|
+
def LLL_XD(self, delta, return_U=False, verbose=False):
|
|
1390
|
+
r"""
|
|
1391
|
+
Perform the same reduction as \code{self.LLL_FP} using the
|
|
1392
|
+
same calling conventions but with extended exponent double
|
|
1393
|
+
precision.
|
|
1394
|
+
|
|
1395
|
+
EXAMPLES::
|
|
1396
|
+
|
|
1397
|
+
sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
|
|
1398
|
+
sage: M.LLL_XD(delta=0.75)
|
|
1399
|
+
2
|
|
1400
|
+
"""
|
|
1401
|
+
cdef ntl_mat_ZZ U
|
|
1402
|
+
if return_U:
|
|
1403
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1404
|
+
sig_on()
|
|
1405
|
+
rank = int(mat_ZZ_LLL_XD_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1406
|
+
sig_off()
|
|
1407
|
+
return rank, U
|
|
1408
|
+
else:
|
|
1409
|
+
sig_on()
|
|
1410
|
+
rank = int(mat_ZZ_LLL_XD(self.x,float(delta),0,0,int(verbose)))
|
|
1411
|
+
sig_off()
|
|
1412
|
+
return rank
|
|
1413
|
+
|
|
1414
|
+
def LLL_RR(self, delta, return_U=False, verbose=False):
|
|
1415
|
+
r"""
|
|
1416
|
+
Perform the same reduction as \code{self.LLL_FP} using the
|
|
1417
|
+
same calling conventions but with arbitrary precision floating
|
|
1418
|
+
point numbers.
|
|
1419
|
+
|
|
1420
|
+
EXAMPLES::
|
|
1421
|
+
|
|
1422
|
+
sage: M=ntl.mat_ZZ(3,3,[1,2,3,4,5,6,7,8,9])
|
|
1423
|
+
sage: M.LLL_RR(delta=0.75)
|
|
1424
|
+
2
|
|
1425
|
+
"""
|
|
1426
|
+
cdef ntl_mat_ZZ U
|
|
1427
|
+
if return_U:
|
|
1428
|
+
U = ntl_mat_ZZ.__new__(ntl_mat_ZZ)
|
|
1429
|
+
sig_on()
|
|
1430
|
+
rank = int(mat_ZZ_LLL_RR_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1431
|
+
sig_off()
|
|
1432
|
+
return rank, U
|
|
1433
|
+
else:
|
|
1434
|
+
sig_on()
|
|
1435
|
+
rank = int(mat_ZZ_LLL_RR(self.x,float(delta),0,0,int(verbose)))
|
|
1436
|
+
sig_off()
|
|
1437
|
+
return rank
|
|
1438
|
+
|
|
1439
|
+
# Givens Orthogonalization. This is a bit slower, but generally
|
|
1440
|
+
# much more stable, and is really the preferred orthogonalization
|
|
1441
|
+
# strategy. For a nice description of this, see Chapter 5 of
|
|
1442
|
+
# [G. Golub and C. van Loan, Matrix Computations, 3rd edition,
|
|
1443
|
+
# Johns Hopkins Univ. Press, 1996].
|
|
1444
|
+
|
|
1445
|
+
def G_LLL_FP(self, delta, return_U=False, verbose=False):
|
|
1446
|
+
r"""
|
|
1447
|
+
Perform the same reduction as self.LLL_FP using the same
|
|
1448
|
+
calling conventions but uses the Givens Orthogonalization.
|
|
1449
|
+
|
|
1450
|
+
Givens Orthogonalization. This is a bit slower, but generally
|
|
1451
|
+
much more stable, and is really the preferred
|
|
1452
|
+
orthogonalization strategy. For a nice description of this,
|
|
1453
|
+
see Chapter 5 of [G. Golub and C. van Loan, Matrix
|
|
1454
|
+
Computations, 3rd edition, Johns Hopkins Univ. Press, 1996].
|
|
1455
|
+
"""
|
|
1456
|
+
cdef ntl_mat_ZZ U
|
|
1457
|
+
if return_U:
|
|
1458
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1459
|
+
sig_on()
|
|
1460
|
+
rank = int(mat_ZZ_G_LLL_FP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1461
|
+
sig_off()
|
|
1462
|
+
return rank, U
|
|
1463
|
+
else:
|
|
1464
|
+
sig_on()
|
|
1465
|
+
rank = int(mat_ZZ_G_LLL_FP(self.x,float(delta),0,0,int(verbose)))
|
|
1466
|
+
sig_off()
|
|
1467
|
+
return rank
|
|
1468
|
+
|
|
1469
|
+
def G_LLL_QP(self, delta, return_U=False, verbose=False):
|
|
1470
|
+
r"""
|
|
1471
|
+
Perform the same reduction as self.G_LLL_FP using the same
|
|
1472
|
+
calling conventions but with quad float precision.
|
|
1473
|
+
"""
|
|
1474
|
+
cdef ntl_mat_ZZ U
|
|
1475
|
+
if return_U:
|
|
1476
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1477
|
+
sig_on()
|
|
1478
|
+
rank = int(mat_ZZ_G_LLL_QP_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1479
|
+
sig_off()
|
|
1480
|
+
return rank, U
|
|
1481
|
+
else:
|
|
1482
|
+
sig_on()
|
|
1483
|
+
rank = int(mat_ZZ_G_LLL_QP(self.x,float(delta),0,0,int(verbose)))
|
|
1484
|
+
sig_off()
|
|
1485
|
+
return rank
|
|
1486
|
+
|
|
1487
|
+
def G_LLL_XD(self, delta, return_U=False, verbose=False):
|
|
1488
|
+
r"""
|
|
1489
|
+
Perform the same reduction as self.G_LLL_FP using the same
|
|
1490
|
+
calling conventions but with extended exponent double
|
|
1491
|
+
precision.
|
|
1492
|
+
"""
|
|
1493
|
+
cdef ntl_mat_ZZ U
|
|
1494
|
+
if return_U:
|
|
1495
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1496
|
+
sig_on()
|
|
1497
|
+
rank = int(mat_ZZ_G_LLL_XD_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1498
|
+
sig_off()
|
|
1499
|
+
return rank, U
|
|
1500
|
+
else:
|
|
1501
|
+
sig_on()
|
|
1502
|
+
rank = int(mat_ZZ_G_LLL_XD(self.x,float(delta),0,0,int(verbose)))
|
|
1503
|
+
sig_off()
|
|
1504
|
+
return rank
|
|
1505
|
+
|
|
1506
|
+
def G_LLL_RR(self, delta, return_U=False, verbose=False):
|
|
1507
|
+
r"""
|
|
1508
|
+
Perform the same reduction as self.G_LLL_FP using the same
|
|
1509
|
+
calling conventions but with arbitrary precision floating
|
|
1510
|
+
point numbers.
|
|
1511
|
+
"""
|
|
1512
|
+
cdef ntl_mat_ZZ U
|
|
1513
|
+
if return_U:
|
|
1514
|
+
U = ntl_mat_ZZ(self.__nrows, self.__nrows)
|
|
1515
|
+
sig_on()
|
|
1516
|
+
rank = int(mat_ZZ_G_LLL_RR_U(self.x, U.x, float(delta), 0, 0, int(verbose)))
|
|
1517
|
+
sig_off()
|
|
1518
|
+
return rank, U
|
|
1519
|
+
else:
|
|
1520
|
+
sig_on()
|
|
1521
|
+
rank = int(mat_ZZ_G_LLL_RR(self.x,float(delta),0,0,int(verbose)))
|
|
1522
|
+
sig_off()
|
|
1523
|
+
return rank
|