passagemath-iml 10.6.46__cp310-cp310-musllinux_1_2_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.
- passagemath_iml/__init__.py +3 -0
- passagemath_iml-10.6.46.dist-info/METADATA +95 -0
- passagemath_iml-10.6.46.dist-info/RECORD +18 -0
- passagemath_iml-10.6.46.dist-info/WHEEL +5 -0
- passagemath_iml-10.6.46.dist-info/top_level.txt +3 -0
- passagemath_iml.libs/libflint-edf7fb90.so.22.0.0 +0 -0
- passagemath_iml.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_iml.libs/libgfortran-67378ab2.so.5.0.0 +0 -0
- passagemath_iml.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_iml.libs/libiml-7e8f179c.so.0.1.1 +0 -0
- passagemath_iml.libs/libmpfr-1fc8ea36.so.6.2.2 +0 -0
- passagemath_iml.libs/libopenblasp-r0-503f0c35.3.29.so +0 -0
- sage/all__sagemath_iml.py +2 -0
- sage/libs/all__sagemath_iml.py +1 -0
- sage/libs/iml.pxd +10 -0
- sage/matrix/all__sagemath_iml.py +1 -0
- sage/matrix/matrix_integer_iml.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_iml.pyx +316 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: passagemath-iml
|
|
3
|
+
Version: 10.6.46
|
|
4
|
+
Summary: passagemath: Linear Algebra with IML
|
|
5
|
+
Author-email: The Sage Developers <sage-support@googlegroups.com>
|
|
6
|
+
Maintainer: Matthias Köppe, passagemath contributors
|
|
7
|
+
License-Expression: GPL-2.0-or-later
|
|
8
|
+
Project-URL: release notes, https://github.com/passagemath/passagemath/releases
|
|
9
|
+
Project-URL: repo (upstream), https://github.com/sagemath/sage
|
|
10
|
+
Project-URL: repo, https://github.com/passagemath/passagemath
|
|
11
|
+
Project-URL: documentation, https://passagemath.org/docs/latest
|
|
12
|
+
Project-URL: homepage (upstream), https://www.sagemath.org
|
|
13
|
+
Project-URL: discourse, https://passagemath.discourse.group
|
|
14
|
+
Project-URL: tracker (upstream), https://github.com/sagemath/sage/issues
|
|
15
|
+
Project-URL: tracker, https://github.com/passagemath/passagemath/issues
|
|
16
|
+
Classifier: Development Status :: 6 - Mature
|
|
17
|
+
Classifier: Intended Audience :: Education
|
|
18
|
+
Classifier: Intended Audience :: Science/Research
|
|
19
|
+
Classifier: Operating System :: POSIX
|
|
20
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
21
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
22
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
28
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
29
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
30
|
+
Requires-Python: <3.15,>=3.10
|
|
31
|
+
Description-Content-Type: text/x-rst
|
|
32
|
+
Requires-Dist: cysignals!=1.12.4; sys_platform == "win32"
|
|
33
|
+
Requires-Dist: cysignals!=1.12.0,>=1.11.2
|
|
34
|
+
Requires-Dist: passagemath-environment~=10.6.46.0
|
|
35
|
+
Requires-Dist: passagemath-categories~=10.6.46.0
|
|
36
|
+
Requires-Dist: passagemath-flint~=10.6.46.0
|
|
37
|
+
Requires-Dist: passagemath-modules~=10.6.46.0
|
|
38
|
+
Provides-Extra: test
|
|
39
|
+
Requires-Dist: passagemath-repl; extra == "test"
|
|
40
|
+
|
|
41
|
+
======================================
|
|
42
|
+
passagemath: Linear Algebra with IML
|
|
43
|
+
======================================
|
|
44
|
+
|
|
45
|
+
`passagemath <https://github.com/passagemath/passagemath>`__ is open
|
|
46
|
+
source mathematical software in Python, released under the GNU General
|
|
47
|
+
Public Licence GPLv2+.
|
|
48
|
+
|
|
49
|
+
It is a fork of `SageMath <https://www.sagemath.org/>`__, which has been
|
|
50
|
+
developed 2005-2025 under the motto “Creating a Viable Open Source
|
|
51
|
+
Alternative to Magma, Maple, Mathematica, and MATLAB”.
|
|
52
|
+
|
|
53
|
+
The passagemath fork uses the motto "Creating a Free Passage Between the
|
|
54
|
+
Scientific Python Ecosystem and Mathematical Software Communities."
|
|
55
|
+
It was created in October 2024 with the following goals:
|
|
56
|
+
|
|
57
|
+
- providing modularized installation with pip,
|
|
58
|
+
- establishing first-class membership in the scientific Python
|
|
59
|
+
ecosystem,
|
|
60
|
+
- giving `clear attribution of upstream
|
|
61
|
+
projects <https://groups.google.com/g/sage-devel/c/6HO1HEtL1Fs/m/G002rPGpAAAJ>`__,
|
|
62
|
+
- providing independently usable Python interfaces to upstream
|
|
63
|
+
libraries,
|
|
64
|
+
- offering `platform portability and integration testing
|
|
65
|
+
services <https://github.com/passagemath/passagemath/issues/704>`__
|
|
66
|
+
to upstream projects,
|
|
67
|
+
- inviting collaborations with upstream projects,
|
|
68
|
+
- `building a professional, respectful, inclusive
|
|
69
|
+
community <https://groups.google.com/g/sage-devel/c/xBzaINHWwUQ>`__,
|
|
70
|
+
- `empowering Sage users to participate in the scientific Python ecosystem
|
|
71
|
+
<https://github.com/passagemath/passagemath/issues/248>`__ by publishing packages,
|
|
72
|
+
- developing a port to `Pyodide <https://pyodide.org/en/stable/>`__ for
|
|
73
|
+
serverless deployment with Javascript,
|
|
74
|
+
- developing a native Windows port.
|
|
75
|
+
|
|
76
|
+
`Full documentation <https://passagemath.org/docs/latest/html/en/index.html>`__ is
|
|
77
|
+
available online.
|
|
78
|
+
|
|
79
|
+
passagemath attempts to support and provides binary wheels suitable for
|
|
80
|
+
all major Linux distributions and recent versions of macOS.
|
|
81
|
+
|
|
82
|
+
Binary wheels for native Windows (x86_64) are are available for a subset of
|
|
83
|
+
the passagemath distributions. Use of the full functionality of passagemath
|
|
84
|
+
on Windows currently requires the use of Windows Subsystem for Linux (WSL)
|
|
85
|
+
or virtualization.
|
|
86
|
+
|
|
87
|
+
The supported Python versions in the passagemath 10.6.x series are 3.10.x-3.14.x.
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
About this pip-installable distribution package
|
|
91
|
+
-----------------------------------------------
|
|
92
|
+
|
|
93
|
+
This pip-installable distribution ``passagemath-iml``
|
|
94
|
+
provides modules that depend on the library
|
|
95
|
+
`IML <https://cs.uwaterloo.ca/~astorjoh/iml.html>`_.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
passagemath_iml/__init__.py,sha256=NdO4g5bk11MJItshkI4te7taUE-Jn-7HzocKeHLETRQ,80
|
|
2
|
+
passagemath_iml.libs/libflint-edf7fb90.so.22.0.0,sha256=MD3YZou85hLe1nME9zmMO9rgpWntwei2_yI19VNhFGo,12776233
|
|
3
|
+
passagemath_iml.libs/libgcc_s-2d945d6c.so.1,sha256=NdOgO2If8roY3PSnJ81CsBa1rjMvN_uWPCo_V0ThwEY,203337
|
|
4
|
+
passagemath_iml.libs/libgfortran-67378ab2.so.5.0.0,sha256=A91Op_3ABLyRZ8zL3gXSHIQx8Ole8PHTFZ3TMRbmGxs,1738025
|
|
5
|
+
passagemath_iml.libs/libgmp-28992bcb.so.10.5.0,sha256=chvEgOPn69KHFEAC4oKOFhJ2LjYfSTYlyAEyFvE1hJg,668217
|
|
6
|
+
passagemath_iml.libs/libiml-7e8f179c.so.0.1.1,sha256=6v-Mg2s6sS4oxRv2mAWy1WzqVxj6ECUnahrtt053p3c,594137
|
|
7
|
+
passagemath_iml.libs/libmpfr-1fc8ea36.so.6.2.2,sha256=6QZDznN7C9yVcv5AG5GpXZWrvxsAw1kqTlkqECWjLIQ,931889
|
|
8
|
+
passagemath_iml.libs/libopenblasp-r0-503f0c35.3.29.so,sha256=9TXSi3fPF12lvTfJcZfd4EzbsJAUcTs8M7j0Hau7RKk,23179593
|
|
9
|
+
sage/all__sagemath_iml.py,sha256=JkCUqCbgv_BfDU5GkGqRvZ2D9YxOqr5UDA1MndDmGXc,62
|
|
10
|
+
sage/libs/all__sagemath_iml.py,sha256=Fxq15-6XT5V8u-vDT34I88lKPruA0VGDT3bqpmULCg8,42
|
|
11
|
+
sage/libs/iml.pxd,sha256=5JdoculaJjo2Z1Z8sGzo-5ZHRQXELsTDdf-16kjCWBQ,363
|
|
12
|
+
sage/matrix/all__sagemath_iml.py,sha256=Fxq15-6XT5V8u-vDT34I88lKPruA0VGDT3bqpmULCg8,42
|
|
13
|
+
sage/matrix/matrix_integer_iml.cpython-310-aarch64-linux-gnu.so,sha256=yk98d5amAHfs2uAjYAFmR1PKnTmE6Lpkty28qPITvjU,595145
|
|
14
|
+
sage/matrix/matrix_integer_iml.pyx,sha256=b97lePKykguBEaks3FdfzN3IUNlZo3S_CtbAJMQQ0X4,9236
|
|
15
|
+
passagemath_iml-10.6.46.dist-info/METADATA,sha256=CkeweII4HPcO0NcaiizVCcM8CcscsaYC8HP8x60wn1E,4406
|
|
16
|
+
passagemath_iml-10.6.46.dist-info/WHEEL,sha256=qvx19vD_zYvGQFVzkH0wrT4tVIal9wOVogYGQfy9ymw,113
|
|
17
|
+
passagemath_iml-10.6.46.dist-info/top_level.txt,sha256=ka1mTeqr1T6DIwrqKXQw4y_4AOqEQ6B83AVk3UnUO8w,22
|
|
18
|
+
passagemath_iml-10.6.46.dist-info/RECORD,,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-iml
|
sage/libs/iml.pxd
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-iml
|
|
2
|
+
from sage.libs.gmp.types cimport mpz_t
|
|
3
|
+
|
|
4
|
+
cdef extern from "iml.h":
|
|
5
|
+
cdef enum SOLU_POS:
|
|
6
|
+
LeftSolu
|
|
7
|
+
RightSolu
|
|
8
|
+
|
|
9
|
+
cdef long nullspaceMP(long n, long m, const mpz_t *A, mpz_t * *mp_N_pass)
|
|
10
|
+
cdef void nonsingSolvLlhsMM(SOLU_POS solupos, long n, long m, mpz_t *mp_A, mpz_t *mp_B, mpz_t *mp_N, mpz_t mp_D)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-iml
|
|
Binary file
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-iml
|
|
2
|
+
# distutils: libraries = iml
|
|
3
|
+
# sage.doctest: needs sage.libs.iml
|
|
4
|
+
|
|
5
|
+
from cysignals.signals cimport sig_check, sig_on, sig_str, sig_off
|
|
6
|
+
from cysignals.memory cimport sig_malloc, sig_free, check_allocarray
|
|
7
|
+
|
|
8
|
+
from sage.libs.flint.fmpz cimport *
|
|
9
|
+
from sage.libs.flint.fmpz_mat cimport *
|
|
10
|
+
from sage.libs.gmp.mpz cimport *
|
|
11
|
+
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
|
|
12
|
+
from sage.misc.verbose import verbose
|
|
13
|
+
from sage.rings.integer cimport Integer
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
########## iml -- integer matrix library ###########
|
|
17
|
+
from sage.libs.iml cimport *
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _rational_kernel_iml(Matrix_integer_dense self):
|
|
21
|
+
"""
|
|
22
|
+
Return the rational (left) kernel of this matrix.
|
|
23
|
+
|
|
24
|
+
OUTPUT:
|
|
25
|
+
|
|
26
|
+
A matrix ``K`` such that ``self * K = 0``, and the number of columns of
|
|
27
|
+
K equals the nullity of ``self``.
|
|
28
|
+
|
|
29
|
+
EXAMPLES::
|
|
30
|
+
|
|
31
|
+
sage: from sage.matrix.matrix_integer_iml import _rational_kernel_iml
|
|
32
|
+
sage: m = matrix(ZZ, 5, 5, [1+i+i^2 for i in range(25)])
|
|
33
|
+
sage: _rational_kernel_iml(m)
|
|
34
|
+
[ 1 3]
|
|
35
|
+
[-3 -8]
|
|
36
|
+
[ 3 6]
|
|
37
|
+
[-1 0]
|
|
38
|
+
[ 0 -1]
|
|
39
|
+
|
|
40
|
+
sage: V1 = _rational_kernel_iml(m).column_space().change_ring(QQ)
|
|
41
|
+
sage: V2 = m._rational_kernel_flint().column_space().change_ring(QQ)
|
|
42
|
+
sage: assert V1 == V2
|
|
43
|
+
"""
|
|
44
|
+
if self._nrows == 0 or self._ncols == 0:
|
|
45
|
+
return self.matrix_space(self._ncols, 0).zero_matrix()
|
|
46
|
+
|
|
47
|
+
cdef long dim
|
|
48
|
+
cdef unsigned long i,j,k
|
|
49
|
+
cdef mpz_t *mp_N
|
|
50
|
+
time = verbose('computing null space of %s x %s matrix using IML' % (self._nrows, self._ncols))
|
|
51
|
+
cdef mpz_t * m = fmpz_mat_to_mpz_array(self._matrix)
|
|
52
|
+
sig_on()
|
|
53
|
+
dim = nullspaceMP(self._nrows, self._ncols, m, &mp_N)
|
|
54
|
+
sig_off()
|
|
55
|
+
# Now read the answer as a matrix.
|
|
56
|
+
cdef Matrix_integer_dense M
|
|
57
|
+
M = self._new(self._ncols, dim)
|
|
58
|
+
k = 0
|
|
59
|
+
for i in range(self._ncols):
|
|
60
|
+
for j in range(dim):
|
|
61
|
+
fmpz_set_mpz(fmpz_mat_entry(M._matrix, i, j), mp_N[k])
|
|
62
|
+
k += 1
|
|
63
|
+
mpz_array_clear(m, self._nrows * self._ncols)
|
|
64
|
+
mpz_array_clear(mp_N, dim * self._ncols)
|
|
65
|
+
verbose("finished computing null space", time)
|
|
66
|
+
return M
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _invert_iml(Matrix_integer_dense self, use_nullspace=False, check_invertible=True):
|
|
70
|
+
"""
|
|
71
|
+
Invert this matrix using IML. The output matrix is an integer
|
|
72
|
+
matrix and a denominator.
|
|
73
|
+
|
|
74
|
+
INPUT:
|
|
75
|
+
|
|
76
|
+
- ``self`` -- an invertible matrix
|
|
77
|
+
|
|
78
|
+
- ``use_nullspace`` -- boolean (default: ``False``); whether to
|
|
79
|
+
use nullspace algorithm, which is slower, but doesn't require
|
|
80
|
+
checking that the matrix is invertible as a precondition
|
|
81
|
+
|
|
82
|
+
- ``check_invertible`` -- boolean (default: ``True``); whether to
|
|
83
|
+
check that the matrix is invertible
|
|
84
|
+
|
|
85
|
+
OUTPUT: `A`, `d` such that ``A*self == d``
|
|
86
|
+
|
|
87
|
+
- ``A`` -- a matrix over ZZ
|
|
88
|
+
|
|
89
|
+
- ``d`` -- integer
|
|
90
|
+
|
|
91
|
+
ALGORITHM: Uses IML's `p`-adic nullspace function.
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: from sage.matrix.matrix_integer_iml import _invert_iml
|
|
96
|
+
sage: a = matrix(ZZ,3,[1,2,5, 3,7,8, 2,2,1])
|
|
97
|
+
sage: b, d = _invert_iml(a); b,d
|
|
98
|
+
(
|
|
99
|
+
[ 9 -8 19]
|
|
100
|
+
[-13 9 -7]
|
|
101
|
+
[ 8 -2 -1], 23
|
|
102
|
+
)
|
|
103
|
+
sage: a*b
|
|
104
|
+
[23 0 0]
|
|
105
|
+
[ 0 23 0]
|
|
106
|
+
[ 0 0 23]
|
|
107
|
+
|
|
108
|
+
AUTHORS:
|
|
109
|
+
|
|
110
|
+
- William Stein
|
|
111
|
+
"""
|
|
112
|
+
if self._nrows != self._ncols:
|
|
113
|
+
raise TypeError("self must be a square matrix.")
|
|
114
|
+
|
|
115
|
+
P = self.parent()
|
|
116
|
+
time = verbose('computing inverse of %s x %s matrix using IML' % (self._nrows, self._ncols))
|
|
117
|
+
if use_nullspace:
|
|
118
|
+
A = self.augment(P.identity_matrix())
|
|
119
|
+
K = A._rational_kernel_iml()
|
|
120
|
+
d = -K[self._nrows,0]
|
|
121
|
+
if K.ncols() != self._ncols or d == 0:
|
|
122
|
+
raise ZeroDivisionError("input matrix must be nonsingular")
|
|
123
|
+
B = K[:self._nrows]
|
|
124
|
+
verbose("finished computing inverse using IML", time)
|
|
125
|
+
return B, d
|
|
126
|
+
else:
|
|
127
|
+
if check_invertible and self.rank() != self._nrows:
|
|
128
|
+
raise ZeroDivisionError("input matrix must be nonsingular")
|
|
129
|
+
return _solve_iml(self, P.identity_matrix(), right=True)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _solve_iml(Matrix_integer_dense self, Matrix_integer_dense B, right=True):
|
|
133
|
+
"""
|
|
134
|
+
Let A equal ``self`` be a square matrix. Given B return an integer
|
|
135
|
+
matrix C and an integer d such that ``self`` ``C*A == d*B`` if right is
|
|
136
|
+
False or ``A*C == d*B`` if right is True.
|
|
137
|
+
|
|
138
|
+
OUTPUT:
|
|
139
|
+
|
|
140
|
+
- ``C`` -- integer matrix
|
|
141
|
+
|
|
142
|
+
- ``d`` -- integer denominator
|
|
143
|
+
|
|
144
|
+
EXAMPLES::
|
|
145
|
+
|
|
146
|
+
sage: from sage.matrix.matrix_integer_iml import _solve_iml
|
|
147
|
+
sage: A = matrix(ZZ,4,4,[0, 1, -2, -1, -1, 1, 0, 2, 2, 2, 2, -1, 0, 2, 2, 1])
|
|
148
|
+
sage: B = matrix(ZZ,3,4, [-1, 1, 1, 0, 2, 0, -2, -1, 0, -2, -2, -2])
|
|
149
|
+
sage: C, d = _solve_iml(A, B, right=False); C
|
|
150
|
+
[ 6 -18 -15 27]
|
|
151
|
+
[ 0 24 24 -36]
|
|
152
|
+
[ 4 -12 -6 -2]
|
|
153
|
+
|
|
154
|
+
::
|
|
155
|
+
|
|
156
|
+
sage: d
|
|
157
|
+
12
|
|
158
|
+
|
|
159
|
+
::
|
|
160
|
+
|
|
161
|
+
sage: C*A == d*B
|
|
162
|
+
True
|
|
163
|
+
|
|
164
|
+
::
|
|
165
|
+
|
|
166
|
+
sage: A = matrix(ZZ,4,4,[0, 1, -2, -1, -1, 1, 0, 2, 2, 2, 2, -1, 0, 2, 2, 1])
|
|
167
|
+
sage: B = matrix(ZZ,4,3, [-1, 1, 1, 0, 2, 0, -2, -1, 0, -2, -2, -2])
|
|
168
|
+
sage: C, d = _solve_iml(A, B)
|
|
169
|
+
sage: C
|
|
170
|
+
[ 12 40 28]
|
|
171
|
+
[-12 -4 -4]
|
|
172
|
+
[ -6 -25 -16]
|
|
173
|
+
[ 12 34 16]
|
|
174
|
+
|
|
175
|
+
::
|
|
176
|
+
|
|
177
|
+
sage: d
|
|
178
|
+
12
|
|
179
|
+
|
|
180
|
+
::
|
|
181
|
+
|
|
182
|
+
sage: A*C == d*B
|
|
183
|
+
True
|
|
184
|
+
|
|
185
|
+
Test wrong dimensions::
|
|
186
|
+
|
|
187
|
+
sage: A = random_matrix(ZZ, 4, 4)
|
|
188
|
+
sage: B = random_matrix(ZZ, 2, 3)
|
|
189
|
+
sage: _solve_iml(B, A)
|
|
190
|
+
Traceback (most recent call last):
|
|
191
|
+
...
|
|
192
|
+
ValueError: self must be a square matrix
|
|
193
|
+
sage: _solve_iml(A, B, right=False)
|
|
194
|
+
Traceback (most recent call last):
|
|
195
|
+
...
|
|
196
|
+
ArithmeticError: B's number of columns must match self's number of rows
|
|
197
|
+
sage: _solve_iml(A, B, right=True)
|
|
198
|
+
Traceback (most recent call last):
|
|
199
|
+
...
|
|
200
|
+
ArithmeticError: B's number of rows must match self's number of columns
|
|
201
|
+
|
|
202
|
+
Check that this can be interrupted properly (:issue:`15453`)::
|
|
203
|
+
|
|
204
|
+
sage: A = random_matrix(ZZ, 2000, 2000)
|
|
205
|
+
sage: B = random_matrix(ZZ, 2000, 2000)
|
|
206
|
+
sage: t0 = walltime()
|
|
207
|
+
sage: alarm(2); _solve_iml(A, B) # long time
|
|
208
|
+
Traceback (most recent call last):
|
|
209
|
+
...
|
|
210
|
+
AlarmInterrupt
|
|
211
|
+
sage: t = walltime(t0)
|
|
212
|
+
sage: t < 10 or t
|
|
213
|
+
True
|
|
214
|
+
|
|
215
|
+
ALGORITHM: Uses IML.
|
|
216
|
+
|
|
217
|
+
AUTHORS:
|
|
218
|
+
|
|
219
|
+
- Martin Albrecht
|
|
220
|
+
"""
|
|
221
|
+
cdef unsigned long i, j, k
|
|
222
|
+
cdef mpz_t *mp_N
|
|
223
|
+
cdef mpz_t mp_D
|
|
224
|
+
cdef Matrix_integer_dense M
|
|
225
|
+
cdef Integer D
|
|
226
|
+
|
|
227
|
+
if self._nrows != self._ncols:
|
|
228
|
+
# This is *required* by the IML function we call below.
|
|
229
|
+
raise ValueError("self must be a square matrix")
|
|
230
|
+
|
|
231
|
+
if self._nrows == 1:
|
|
232
|
+
return B, self[0,0]
|
|
233
|
+
|
|
234
|
+
cdef SOLU_POS solu_pos
|
|
235
|
+
|
|
236
|
+
if right:
|
|
237
|
+
if self._ncols != B._nrows:
|
|
238
|
+
raise ArithmeticError("B's number of rows must match self's number of columns")
|
|
239
|
+
|
|
240
|
+
n = self._ncols
|
|
241
|
+
m = B._ncols
|
|
242
|
+
|
|
243
|
+
P = self.matrix_space(n, m)
|
|
244
|
+
if self._nrows == 0 or self._ncols == 0:
|
|
245
|
+
return P.zero_matrix(), Integer(1)
|
|
246
|
+
|
|
247
|
+
if m == 0 or n == 0:
|
|
248
|
+
return self.new_matrix(nrows = n, ncols = m), Integer(1)
|
|
249
|
+
|
|
250
|
+
solu_pos = RightSolu
|
|
251
|
+
|
|
252
|
+
else: # left
|
|
253
|
+
if self._nrows != B._ncols:
|
|
254
|
+
raise ArithmeticError("B's number of columns must match self's number of rows")
|
|
255
|
+
|
|
256
|
+
n = self._ncols
|
|
257
|
+
m = B._nrows
|
|
258
|
+
|
|
259
|
+
P = self.matrix_space(m, n)
|
|
260
|
+
if self._nrows == 0 or self._ncols == 0:
|
|
261
|
+
return P.zero_matrix(), Integer(1)
|
|
262
|
+
|
|
263
|
+
if m == 0 or n == 0:
|
|
264
|
+
return self.new_matrix(nrows = m, ncols = n), Integer(1)
|
|
265
|
+
|
|
266
|
+
solu_pos = LeftSolu
|
|
267
|
+
|
|
268
|
+
sig_check()
|
|
269
|
+
verbose("Initializing mp_N and mp_D")
|
|
270
|
+
mp_N = <mpz_t *> sig_malloc( n * m * sizeof(mpz_t) )
|
|
271
|
+
for i in range(n * m):
|
|
272
|
+
mpz_init(mp_N[i])
|
|
273
|
+
mpz_init(mp_D)
|
|
274
|
+
verbose("Done with initializing mp_N and mp_D")
|
|
275
|
+
cdef mpz_t * mself = fmpz_mat_to_mpz_array(self._matrix)
|
|
276
|
+
cdef mpz_t * mB = fmpz_mat_to_mpz_array(B._matrix)
|
|
277
|
+
try:
|
|
278
|
+
verbose('Calling solver n = %s, m = %s' % (n,m))
|
|
279
|
+
sig_on()
|
|
280
|
+
nonsingSolvLlhsMM(solu_pos, n, m, mself, mB, mp_N, mp_D)
|
|
281
|
+
sig_off()
|
|
282
|
+
M = self._new(P.nrows(), P.ncols())
|
|
283
|
+
k = 0
|
|
284
|
+
for i from 0 <= i < M._nrows:
|
|
285
|
+
for j from 0 <= j < M._ncols:
|
|
286
|
+
fmpz_set_mpz(fmpz_mat_entry(M._matrix,i,j), mp_N[k])
|
|
287
|
+
k += 1
|
|
288
|
+
D = Integer.__new__(Integer)
|
|
289
|
+
mpz_set(D.value, mp_D)
|
|
290
|
+
return M, D
|
|
291
|
+
finally:
|
|
292
|
+
mpz_clear(mp_D)
|
|
293
|
+
mpz_array_clear(mself, self.nrows() * self.ncols())
|
|
294
|
+
mpz_array_clear(mB, B.nrows() * B.ncols())
|
|
295
|
+
mpz_array_clear(mp_N, n*m)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
cdef inline mpz_t * fmpz_mat_to_mpz_array(fmpz_mat_t m) except? NULL:
|
|
299
|
+
cdef mpz_t * entries = <mpz_t *>check_allocarray(fmpz_mat_nrows(m), sizeof(mpz_t) * fmpz_mat_ncols(m))
|
|
300
|
+
cdef size_t i, j
|
|
301
|
+
cdef size_t k = 0
|
|
302
|
+
sig_on()
|
|
303
|
+
for i in range(fmpz_mat_nrows(m)):
|
|
304
|
+
for j in range(fmpz_mat_ncols(m)):
|
|
305
|
+
mpz_init(entries[k])
|
|
306
|
+
fmpz_get_mpz(entries[k], fmpz_mat_entry(m, i, j))
|
|
307
|
+
k += 1
|
|
308
|
+
sig_off()
|
|
309
|
+
return entries
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
cdef inline void mpz_array_clear(mpz_t * a, size_t length) noexcept:
|
|
313
|
+
cdef size_t i
|
|
314
|
+
for i in range(length):
|
|
315
|
+
mpz_clear(a[i])
|
|
316
|
+
sig_free(a)
|