Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sage
Path: blob/develop/src/sage/matrix/matrix_complex_ball_dense.pyx
4081 views
1
# distutils: libraries = flint
2
r"""
3
Arbitrary precision complex ball matrices
4
5
AUTHORS:
6
7
- Clemens Heuberger (2014-10-25): Initial version.
8
9
This is an incomplete interface to the `acb_mat module
10
<https://flintlib.org/doc/acb_mat.html>`_ of FLINT; it may be useful to refer
11
to its documentation for more details.
12
13
TESTS::
14
15
sage: mat = matrix(CBF, 2, 2, range(4))
16
sage: x = polygen(QQ)
17
sage: pol = x^3 + 2
18
sage: pol(mat)
19
[8.000000000000000 11.00000000000000]
20
[22.00000000000000 41.00000000000000]
21
22
sage: mat = matrix(ComplexBallField(20), 2, 2, list(range(4)))*i/3 # needs sage.symbolic
23
sage: loads(dumps(mat)).identical(mat) # needs sage.symbolic
24
True
25
"""
26
# ****************************************************************************
27
# Copyright (C) 2014 Clemens Heuberger <[email protected]>
28
#
29
# This program is free software: you can redistribute it and/or modify
30
# it under the terms of the GNU General Public License as published by
31
# the Free Software Foundation, either version 2 of the License, or
32
# (at your option) any later version.
33
# http://www.gnu.org/licenses/
34
# ****************************************************************************
35
from cpython.object cimport Py_EQ, Py_NE
36
from cysignals.signals cimport sig_on, sig_str, sig_off
37
38
from sage.arith.power cimport generic_power_pos
39
from sage.libs.flint.acb cimport *
40
from sage.libs.flint.acb_mat cimport *
41
from sage.libs.gmp.mpz cimport mpz_fits_ulong_p, mpz_get_ui
42
from sage.matrix.constructor import matrix
43
from sage.matrix.args cimport SparseEntry, MatrixArgs_init
44
from sage.rings.complex_interval cimport ComplexIntervalFieldElement
45
from sage.rings.complex_arb cimport (
46
ComplexBall,
47
ComplexIntervalFieldElement_to_acb,
48
acb_to_ComplexIntervalFieldElement)
49
from sage.rings.integer cimport Integer
50
from sage.rings.polynomial.polynomial_complex_arb cimport Polynomial_complex_arb
51
from sage.structure.element cimport Element, Matrix
52
from sage.structure.parent cimport Parent
53
from sage.structure.sequence import Sequence
54
55
from sage.misc.superseded import experimental
56
from sage.rings.polynomial import polynomial_ring_constructor
57
58
59
cdef void matrix_to_acb_mat(acb_mat_t target, source) noexcept:
60
"""
61
Convert a matrix containing :class:`ComplexIntervalFieldElement` to an ``acb_mat_t``.
62
63
INPUT:
64
65
- ``target`` -- an ``acb_mat_t``
66
67
- ``source`` -- a matrix consisting of :class:`ComplexIntervalFieldElement`
68
69
OUTPUT:
70
71
None.
72
"""
73
cdef unsigned long nrows, ncols, r, c
74
75
nrows = acb_mat_nrows(target)
76
ncols = acb_mat_ncols(target)
77
78
for r in range(nrows):
79
for c in range(ncols):
80
ComplexIntervalFieldElement_to_acb(acb_mat_entry(target, r, c),
81
source[r][c])
82
83
cdef ComplexIntervalFieldElement _to_CIF(acb_t source, ComplexIntervalFieldElement template):
84
cdef ComplexIntervalFieldElement result
85
result = template._new()
86
acb_to_ComplexIntervalFieldElement(
87
result, source)
88
return result
89
90
cdef Matrix_generic_dense acb_mat_to_matrix(acb_mat_t source, Parent CIF):
91
"""
92
Convert an ``acb_mat_t`` to a matrix containing :class:`ComplexIntervalFieldElement`.
93
94
INPUT:
95
96
- ``source`` -- an ``acb_mat_t``
97
98
- ``precision`` -- positive integer
99
100
OUTPUT:
101
102
A :class:`~sage.matrix.matrix_generic_dense.Matrix_generic_dense`
103
containing :class:`ComplexIntervalFieldElement`.
104
"""
105
cdef unsigned long nrows, ncols, r, c
106
cdef ComplexIntervalFieldElement template
107
108
nrows = acb_mat_nrows(source)
109
ncols = acb_mat_ncols(source)
110
template = CIF(0)
111
112
return matrix(
113
[[_to_CIF(acb_mat_entry(source, r, c), template)
114
for c in range(ncols)]
115
for r in range(nrows)])
116
117
cdef inline long prec(Matrix_complex_ball_dense mat) noexcept:
118
return mat._base_ring._prec
119
120
cdef class Matrix_complex_ball_dense(Matrix_dense):
121
"""
122
Matrix over a complex ball field. Implemented using the
123
``acb_mat`` type of the FLINT library.
124
125
EXAMPLES::
126
127
sage: MatrixSpace(CBF, 3)(2)
128
[2.000000000000000 0 0]
129
[ 0 2.000000000000000 0]
130
[ 0 0 2.000000000000000]
131
sage: matrix(CBF, 1, 3, [1, 2, -3])
132
[ 1.000000000000000 2.000000000000000 -3.000000000000000]
133
"""
134
def __cinit__(self):
135
"""
136
Create and allocate memory for the matrix.
137
138
EXAMPLES::
139
140
sage: from sage.matrix.matrix_complex_ball_dense import Matrix_complex_ball_dense
141
sage: a = Matrix_complex_ball_dense.__new__( # indirect doctest
142
....: Matrix_complex_ball_dense, Mat(CBF, 2), 0, 0, 0)
143
sage: type(a)
144
<class 'sage.matrix.matrix_complex_ball_dense.Matrix_complex_ball_dense'>
145
"""
146
sig_str("FLINT exception")
147
acb_mat_init(self.value, self._nrows, self._ncols)
148
sig_off()
149
150
def __dealloc__(self):
151
"""
152
Free all the memory allocated for this matrix.
153
154
EXAMPLES::
155
156
sage: a = Matrix(CBF, 2, [1, 2, 3, 4]) # indirect doctest
157
sage: del a
158
"""
159
acb_mat_clear(self.value)
160
161
cdef Matrix_complex_ball_dense _new(self, Py_ssize_t nrows, Py_ssize_t ncols):
162
r"""
163
Return a new matrix over the same base ring.
164
"""
165
cdef Parent P
166
if nrows == self._nrows and ncols == self._ncols:
167
P = self._parent
168
else:
169
P = self.matrix_space(nrows, ncols)
170
return Matrix_complex_ball_dense.__new__(Matrix_complex_ball_dense, P, None, None, None)
171
172
def __init__(self, parent, entries=None, copy=None, bint coerce=True):
173
r"""
174
Initialize a dense matrix over the complex ball field.
175
176
INPUT:
177
178
- ``parent`` -- a matrix space over a complex ball field
179
180
- ``entries`` -- see :func:`matrix`
181
182
- ``copy`` -- ignored (for backwards compatibility)
183
184
- ``coerce`` -- if ``False``, assume without checking that the
185
entries lie in the base ring
186
187
EXAMPLES:
188
189
The ``__init__`` function is called implicitly in each of the
190
examples below to actually fill in the values of the matrix.
191
192
We create a `2 \times 2` and a `1\times 4` matrix::
193
194
sage: matrix(CBF, 2, 2, range(4))
195
[ 0 1.000000000000000]
196
[2.000000000000000 3.000000000000000]
197
sage: Matrix(CBF, 1, 4, range(4))
198
[ 0 1.000000000000000 2.000000000000000 3.000000000000000]
199
200
If the number of columns isn't given, it is determined from the
201
number of elements in the list. ::
202
203
sage: matrix(CBF, 2, range(4))
204
[ 0 1.000000000000000]
205
[2.000000000000000 3.000000000000000]
206
sage: matrix(CBF, 2, range(6))
207
[ 0 1.000000000000000 2.000000000000000]
208
[3.000000000000000 4.000000000000000 5.000000000000000]
209
210
Another way to make a matrix is to create the space of matrices and
211
convert lists into it. ::
212
213
sage: A = Mat(CBF, 2); A
214
Full MatrixSpace of 2 by 2 dense matrices over
215
Complex ball field with 53 bits of precision
216
sage: A(range(4))
217
[ 0 1.000000000000000]
218
[2.000000000000000 3.000000000000000]
219
220
Actually it is only necessary that the input can be converted to a
221
list, so the following also works::
222
223
sage: v = reversed(range(4)); type(v)
224
<...iterator'>
225
sage: A(v)
226
[3.000000000000000 2.000000000000000]
227
[1.000000000000000 0]
228
229
Matrices can have many rows or columns (in fact, on a 64-bit
230
machine they could have up to `2^{63}-1` rows or columns)::
231
232
sage: v = matrix(CBF, 1, 10^5, range(10^5))
233
sage: v.parent()
234
Full MatrixSpace of 1 by 100000 dense matrices over
235
Complex ball field with 53 bits of precision
236
237
TESTS::
238
239
sage: MatrixSpace(CBF, 0, 0).one()
240
[]
241
sage: Matrix(CBF, 0, 100)
242
0 x 100 dense matrix over Complex ball field with 53 bits
243
of precision (use the '.str()' method to see the entries)
244
sage: Matrix(CBF, 100, 0)
245
100 x 0 dense matrix over Complex ball field with 53 bits
246
of precision (use the '.str()' method to see the entries)
247
"""
248
ma = MatrixArgs_init(parent, entries)
249
cdef ComplexBall z
250
for t in ma.iter(coerce, True):
251
se = <SparseEntry>t
252
z = <ComplexBall>se.entry
253
acb_set(acb_mat_entry(self.value, se.i, se.j), z.value)
254
255
cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, object x):
256
"""
257
Set position ``i``, ``j`` of this matrix to ``x``.
258
259
The object ``x`` must be of type ``ComplexBall``.
260
261
INPUT:
262
263
- ``i`` -- row
264
265
- ``j`` -- column
266
267
- ``x`` -- must be ComplexBall! The value to set ``self[i,j]`` to.
268
269
EXAMPLES::
270
271
sage: a = matrix(CBF, 2, 3, range(6)); a
272
[ 0 1.000000000000000 2.000000000000000]
273
[3.000000000000000 4.000000000000000 5.000000000000000]
274
sage: a[0, 0] = 10
275
sage: a
276
[10.00000000000000 1.000000000000000 2.000000000000000]
277
[3.000000000000000 4.000000000000000 5.000000000000000]
278
"""
279
acb_set(acb_mat_entry(self.value, i, j), (<ComplexBall> x).value)
280
281
cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
282
"""
283
Return ``(i, j)`` entry of this matrix as a new ComplexBall.
284
285
.. warning::
286
287
This is very unsafe; it assumes ``i`` and ``j`` are in the right
288
range.
289
290
EXAMPLES::
291
292
sage: a = MatrixSpace(CBF, 3)(range(9)); a
293
[ 0 1.000000000000000 2.000000000000000]
294
[3.000000000000000 4.000000000000000 5.000000000000000]
295
[6.000000000000000 7.000000000000000 8.000000000000000]
296
sage: a[1, 2]
297
5.000000000000000
298
sage: a[4, 7]
299
Traceback (most recent call last):
300
...
301
IndexError: matrix index out of range
302
sage: a[-1, 0]
303
6.000000000000000
304
"""
305
cdef ComplexBall z = ComplexBall.__new__(ComplexBall)
306
z._parent = self._base_ring
307
acb_set(z.value, acb_mat_entry(self.value, i, j))
308
return z
309
310
cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
311
"""
312
Copy the ``(iSrc, jSrc)`` entry of ``src`` into the ``(iDst, jDst)``
313
entry of ``self``.
314
315
.. warning::
316
317
This is very unsafe; it assumes ``iSrc``, ``jSrc``, ``iDst`` and
318
``jDst`` are in the right range, and that ``src`` is a
319
Matrix_complex_ball_dense with the same base ring as ``self``.
320
321
INPUT:
322
323
- ``iDst`` - the row to be copied to in ``self``.
324
- ``jDst`` - the column to be copied to in ``self``.
325
- ``src`` - the matrix to copy from. Should be a
326
Matrix_complex_ball_dense with the same base ring as
327
``self``.
328
- ``iSrc`` - the row to be copied from in ``src``.
329
- ``jSrc`` - the column to be copied from in ``src``.
330
331
TESTS::
332
333
sage: m = MatrixSpace(CBF,3,4)(range(12))
334
sage: m
335
[ 0 1.000000000000000 2.000000000000000 3.000000000000000]
336
[4.000000000000000 5.000000000000000 6.000000000000000 7.000000000000000]
337
[8.000000000000000 9.000000000000000 10.00000000000000 11.00000000000000]
338
sage: m.transpose()
339
[ 0 4.000000000000000 8.000000000000000]
340
[1.000000000000000 5.000000000000000 9.000000000000000]
341
[2.000000000000000 6.000000000000000 10.00000000000000]
342
[3.000000000000000 7.000000000000000 11.00000000000000]
343
sage: m.matrix_from_rows([0,2])
344
[ 0 1.000000000000000 2.000000000000000 3.000000000000000]
345
[8.000000000000000 9.000000000000000 10.00000000000000 11.00000000000000]
346
sage: m.matrix_from_columns([1,3])
347
[1.000000000000000 3.000000000000000]
348
[5.000000000000000 7.000000000000000]
349
[9.000000000000000 11.00000000000000]
350
sage: m.matrix_from_rows_and_columns([1,2],[0,3])
351
[4.000000000000000 7.000000000000000]
352
[8.000000000000000 11.00000000000000]
353
"""
354
cdef Matrix_complex_ball_dense _src = <Matrix_complex_ball_dense> src
355
acb_set(acb_mat_entry(self.value, iDst, jDst), acb_mat_entry(_src.value, iSrc, jSrc))
356
357
cpdef _richcmp_(left, right, int op):
358
r"""
359
EXAMPLES::
360
361
sage: a = matrix(CBF, [[1,2],[3,4]])
362
sage: b = matrix(CBF, [[1,2],[3,4]])
363
sage: a == b
364
True
365
sage: a + 1/3 == b + 1/3
366
False
367
sage: a < b
368
Traceback (most recent call last):
369
...
370
TypeError: no order is defined on complex ball matrices
371
372
TESTS::
373
374
sage: a = matrix(CBF, [1/3])
375
sage: b = matrix(CBF, [1/3])
376
sage: a == a or b == b or a[0,0] == a[0,0] or a[0,0] == b[0,0]
377
False
378
"""
379
cdef Matrix_complex_ball_dense lt = <Matrix_complex_ball_dense> left
380
cdef Matrix_complex_ball_dense rt = <Matrix_complex_ball_dense> right
381
if op == Py_EQ:
382
return acb_mat_eq(lt.value, rt.value)
383
elif op == Py_NE:
384
return acb_mat_ne(lt.value, rt.value)
385
else:
386
raise TypeError("no order is defined on complex ball matrices")
387
388
def identical(self, Matrix_complex_ball_dense other):
389
r"""
390
Test if the corresponding entries of two complex ball matrices
391
represent the same balls.
392
393
EXAMPLES::
394
395
sage: a = matrix(CBF, [[1/3,2],[3,4]])
396
sage: b = matrix(CBF, [[1/3,2],[3,4]])
397
sage: a == b
398
False
399
sage: a.identical(b)
400
True
401
"""
402
return acb_mat_equal(self.value, other.value)
403
404
def overlaps(self, Matrix_complex_ball_dense other):
405
r"""
406
Test if two matrices with complex ball entries represent overlapping
407
sets of complex matrices.
408
409
EXAMPLES::
410
411
sage: b = CBF(0, RBF(0, rad=0.1r)); b
412
[+/- 0.101]*I
413
sage: matrix(CBF, [0, b]).overlaps(matrix(CBF, [b, 0]))
414
True
415
sage: matrix(CBF, [1, 0]).overlaps(matrix(CBF, [b, 0]))
416
False
417
"""
418
return acb_mat_overlaps(self.value, other.value)
419
420
def contains(self, Matrix_complex_ball_dense other):
421
r"""
422
Test if the set of complex matrices represented by ``self`` is
423
contained in that represented by ``other``.
424
425
EXAMPLES::
426
427
sage: b = CBF(0, RBF(0, rad=.1r)); b
428
[+/- 0.101]*I
429
sage: matrix(CBF, [0, b]).contains(matrix(CBF, [0, 0]))
430
True
431
sage: matrix(CBF, [0, b]).contains(matrix(CBF, [b, 0]))
432
False
433
sage: matrix(CBF, [b, b]).contains(matrix(CBF, [b, 0]))
434
True
435
"""
436
return acb_mat_contains(self.value, other.value)
437
438
def __neg__(self):
439
r"""
440
TESTS::
441
442
sage: -matrix(CBF, [[1,2]])
443
[-1.000000000000000 -2.000000000000000]
444
"""
445
cdef Matrix_complex_ball_dense res = self._new(self._nrows, self._ncols)
446
sig_on()
447
acb_mat_neg(res.value, self.value)
448
sig_off()
449
return res
450
451
cpdef _add_(self, other):
452
r"""
453
TESTS::
454
455
sage: matrix(CBF, [[1,2]])._add_(matrix(CBF, [3,4]))
456
[4.000000000000000 6.000000000000000]
457
"""
458
cdef Matrix_complex_ball_dense res = self._new(self._nrows, self._ncols)
459
sig_on()
460
acb_mat_add(res.value, self.value, (<Matrix_complex_ball_dense> other).value, prec(self))
461
sig_off()
462
return res
463
464
cpdef _sub_(self, other):
465
r"""
466
TESTS::
467
468
sage: matrix(CBF, [[1,2]])._sub_(matrix(CBF, [3,4]))
469
[-2.000000000000000 -2.000000000000000]
470
"""
471
cdef Matrix_complex_ball_dense res = self._new(self._nrows, self._ncols)
472
sig_on()
473
acb_mat_sub(res.value, self.value, (<Matrix_complex_ball_dense> other).value, prec(self))
474
sig_off()
475
return res
476
477
cpdef _lmul_(self, Element a):
478
r"""
479
TESTS::
480
481
sage: matrix(CBF, [[1,2]])._lmul_(CBF(I))
482
[1.000000000000000*I 2.000000000000000*I]
483
"""
484
cdef Matrix_complex_ball_dense res = self._new(self._nrows, self._ncols)
485
sig_on()
486
acb_mat_scalar_mul_acb(res.value, self.value, (<ComplexBall> a).value, prec(self))
487
sig_off()
488
return res
489
490
cpdef _rmul_(self, Element a):
491
r"""
492
TESTS::
493
494
sage: matrix(CBF, [[1,2]])._rmul_(CBF(I))
495
[1.000000000000000*I 2.000000000000000*I]
496
"""
497
return self._lmul_(a)
498
499
cdef _matrix_times_matrix_(self, Matrix other):
500
r"""
501
TESTS::
502
503
sage: matrix(CBF, [[1,2]])*matrix([[3], [4]]) # indirect doctest
504
[11.00000000000000]
505
"""
506
cdef Matrix_complex_ball_dense res = self._new(self._nrows, other._ncols)
507
sig_on()
508
acb_mat_mul(res.value, self.value, (<Matrix_complex_ball_dense> other).value, prec(self))
509
sig_off()
510
return res
511
512
cpdef _pow_int(self, n):
513
r"""
514
Return the ``n``-th power of this matrix.
515
516
EXAMPLES::
517
518
sage: mat = matrix(CBF, [[1/2, 1/3], [1, 1]])
519
sage: mat**2
520
[[0.5833333333333...] [0.500000000000000 +/- ...e-16]]
521
[ 1.500000000000000 [1.333333333333333 +/- ...e-16]]
522
sage: mat**(-2)
523
[ [48.00000000000...] [-18.00000000000...]]
524
[[-54.0000000000...] [21.000000000000...]]
525
526
TESTS::
527
528
sage: mat**(0r)
529
[1.000000000000000 0]
530
[ 0 1.000000000000000]
531
532
sage: mat**(1/2)
533
Traceback (most recent call last):
534
...
535
NotImplementedError: non-integral exponents not supported
536
537
sage: (-(matrix(CBF, [2])**(-2**100))[0,0].log(2)).log(2)
538
[100.000000000000 +/- ...e-14]
539
sage: (-(matrix(CBF, [2])**(-2**64+1))[0,0].log(2)).log(2)
540
[64.0000000000000 +/- ...e-14]
541
"""
542
cdef Matrix_complex_ball_dense res = self._new(self._nrows, self._ncols)
543
cdef Matrix_complex_ball_dense tmp
544
cdef unsigned long expo
545
n = Integer(n)
546
if self._nrows != self._ncols:
547
raise ArithmeticError("self must be a square matrix")
548
549
neg = (n < 0)
550
if neg:
551
n = -n
552
if mpz_fits_ulong_p((<Integer>n).value):
553
expo = mpz_get_ui((<Integer>n).value)
554
sig_on()
555
acb_mat_pow_ui(res.value, self.value, expo, prec(self))
556
sig_off()
557
else:
558
tmp = generic_power_pos(self, n)
559
acb_mat_set(res.value, tmp.value)
560
if neg:
561
sig_on()
562
acb_mat_inv(res.value, res.value, prec(self))
563
sig_off()
564
565
return res
566
567
def __invert__(self):
568
r"""
569
TESTS::
570
571
sage: ~matrix(CBF, [[1/2, 1/3], [1, 1]])
572
[ [6.00000000000000 +/- ...e-15] [-2.00000000000000 +/- ...e-15]]
573
[[-6.00000000000000 +/- ...e-15] [3.00000000000000 +/- ...e-15]]
574
sage: ~matrix(CBF, [[1/2, 1/3]])
575
Traceback (most recent call last):
576
...
577
ArithmeticError: self must be a square matrix
578
sage: mat = matrix(CBF, [[1/3, 1/2], [0, 1]]) - 1/3
579
sage: ~mat
580
Traceback (most recent call last):
581
...
582
ZeroDivisionError: unable to compute the inverse, is the matrix singular?
583
"""
584
if not self.is_square():
585
raise ArithmeticError("self must be a square matrix")
586
cdef Matrix_complex_ball_dense res = self._new(self._nrows, self._ncols)
587
sig_on()
588
cdef bint success = acb_mat_inv(res.value, self.value, prec(self))
589
sig_off()
590
if success:
591
return res
592
else:
593
raise ZeroDivisionError("unable to compute the inverse, is the matrix singular?")
594
595
def transpose(self):
596
r"""
597
Return the transpose of ``self``.
598
599
EXAMPLES::
600
601
sage: m = matrix(CBF, 2, 3, [1, 2, 3, 4, 5, 6])
602
sage: m.transpose()
603
[1.000000000000000 4.000000000000000]
604
[2.000000000000000 5.000000000000000]
605
[3.000000000000000 6.000000000000000]
606
sage: m.transpose().parent()
607
Full MatrixSpace of 3 by 2 dense matrices over Complex ball field with 53 bits of precision
608
609
TESTS::
610
611
sage: m = matrix(CBF,2,3,range(6))
612
sage: m.subdivide([1],[2])
613
sage: m
614
[ 0 1.000000000000000|2.000000000000000]
615
[-----------------------------------+-----------------]
616
[3.000000000000000 4.000000000000000|5.000000000000000]
617
sage: m.transpose()
618
[ 0|3.000000000000000]
619
[1.000000000000000|4.000000000000000]
620
[-----------------+-----------------]
621
[2.000000000000000|5.000000000000000]
622
623
sage: m = matrix(CBF,0,2)
624
sage: m.subdivide([],[1])
625
sage: m.subdivisions()
626
([], [1])
627
sage: m.transpose().subdivisions()
628
([1], [])
629
630
sage: m = matrix(CBF,2,0)
631
sage: m.subdivide([1],[])
632
sage: m.subdivisions()
633
([1], [])
634
sage: m.transpose().subdivisions()
635
([], [1])
636
"""
637
cdef Py_ssize_t nc = self._ncols
638
cdef Py_ssize_t nr = self._nrows
639
cdef Matrix_complex_ball_dense trans = self._new(nc, nr)
640
acb_mat_transpose(trans.value, self.value)
641
if self._subdivisions is not None:
642
row_divs, col_divs = self.subdivisions()
643
trans.subdivide(col_divs, row_divs)
644
return trans
645
646
def _solve_right_nonsingular_square(self, Matrix_complex_ball_dense rhs, check_rank=None):
647
r"""
648
TESTS::
649
650
sage: matrix(CBF, [[1/2, 1/3], [1, 1]]).solve_right(vector([-1, 1]))
651
([-8.00000000000000 +/- ...], [9.00000000000000 +/- ...])
652
sage: matrix(CBF, 2, 2, 0).solve_right(vector([-1, 1]))
653
Traceback (most recent call last):
654
...
655
ValueError: unable to invert this matrix
656
sage: b = CBF(0, RBF(0, rad=.1r))
657
sage: matrix(CBF, [[1, 1], [0, b]]).solve_right(vector([-1, 1]))
658
Traceback (most recent call last):
659
...
660
ValueError: unable to invert this matrix
661
"""
662
cdef Matrix_complex_ball_dense res = self._new(self._nrows, rhs._ncols)
663
sig_on()
664
success = acb_mat_solve(res.value, self.value, rhs.value, min(prec(self), prec(rhs)))
665
sig_off()
666
if success:
667
return res
668
else:
669
raise ValueError("unable to invert this matrix")
670
671
def determinant(self):
672
r"""
673
Compute the determinant of this matrix.
674
675
EXAMPLES::
676
677
sage: matrix(CBF, [[1/2, 1/3], [1, 1]]).determinant()
678
[0.1666666666666667 +/- ...e-17]
679
sage: matrix(CBF, [[1/2, 1/3], [1, 1]]).det()
680
[0.1666666666666667 +/- ...e-17]
681
sage: matrix(CBF, [[1/2, 1/3]]).determinant()
682
Traceback (most recent call last):
683
...
684
ValueError: self must be a square matrix
685
"""
686
cdef ComplexBall res = ComplexBall.__new__(ComplexBall)
687
res._parent = self._base_ring
688
if self._nrows != self._ncols:
689
raise ValueError("self must be a square matrix")
690
sig_on()
691
acb_mat_det(res.value, self.value, prec(self))
692
sig_off()
693
return res
694
695
def trace(self):
696
r"""
697
Compute the trace of this matrix.
698
699
EXAMPLES::
700
701
sage: matrix(CBF, [[1/3, 1/3], [1, 1]]).trace()
702
[1.333333333333333 +/- ...e-16]
703
sage: matrix(CBF, [[1/2, 1/3]]).trace()
704
Traceback (most recent call last):
705
...
706
ValueError: self must be a square matrix
707
"""
708
cdef ComplexBall res = ComplexBall.__new__(ComplexBall)
709
res._parent = self._base_ring
710
if self._nrows != self._ncols:
711
raise ValueError("self must be a square matrix")
712
sig_on()
713
acb_mat_trace(res.value, self.value, prec(self))
714
sig_off()
715
return res
716
717
def charpoly(self, var='x', algorithm=None):
718
r"""
719
Compute the characteristic polynomial of this matrix.
720
721
EXAMPLES::
722
723
sage: from sage.matrix.benchmark import hilbert_matrix
724
sage: mat = hilbert_matrix(5).change_ring(ComplexBallField(10))
725
sage: mat.charpoly()
726
x^5 + ([-1.8 +/- 0.0258])*x^4 + ([0.3 +/- 0.05...)*x^3 +
727
([+/- 0.0...])*x^2 + ([+/- 0.0...])*x + [+/- 0.0...]
728
729
TESTS::
730
731
sage: mat.charpoly(algorithm='hessenberg')
732
x^5 + ([-1.8 +/- 0.04...])*x^4 + ([0.3 +/- 0.08...])*x^3
733
+ ([+/- 0.0...])*x^2 + ([+/- ...e-4])*x + [+/- ...e-6]
734
sage: mat.charpoly('y')
735
y^5 + ([-1.8 +/- 0.02...])*y^4 + ([0.3 +/- 0.05...])*y^3 +
736
([+/- 0.0...])*y^2 + ([+/- 0.0...])*y + [+/- 0.0...]
737
"""
738
if self._nrows != self._ncols:
739
raise ValueError("self must be a square matrix")
740
if algorithm is not None:
741
return super(Matrix_dense, self).charpoly(var=var, algorithm=algorithm)
742
Pol = polynomial_ring_constructor._single_variate(self.base_ring(), var)
743
cdef Polynomial_complex_arb res = Polynomial_complex_arb(Pol)
744
sig_on()
745
acb_mat_charpoly(res._poly, self.value, prec(self))
746
sig_off()
747
return res
748
749
@experimental(issue_number=30393)
750
def eigenvalues(self, other=None, *, extend=None):
751
r"""
752
(Experimental.) Compute rigorous enclosures of the eigenvalues of this matrix.
753
754
INPUT:
755
756
- ``self`` -- an `n \times n` matrix
757
- ``other`` -- unsupported (generalized eigenvalue problem), should be ``None``
758
- ``extend`` -- ignored
759
760
OUTPUT:
761
762
A :class:`~sage.structure.sequence.Sequence` of complex balls of
763
length equal to the size of the matrix.
764
765
Each element represents one eigenvalue with the correct multiplicities
766
in case of overlap. The output intervals are either disjoint or
767
identical, and identical intervals are guaranteed to be grouped
768
consecutively. Each complete run of `k` identical balls thus represents
769
a cluster of exactly `k` eigenvalues which could not be separated from
770
each other at the current precision, but which could be isolated from
771
the other eigenvalues.
772
773
There is currently no guarantee that the algorithm converges as the
774
working precision is increased.
775
776
See the `FLINT documentation <https://flintlib.org/doc/acb_mat.html#c.acb_mat_eig_multiple>`__
777
for more information.
778
779
EXAMPLES::
780
781
sage: from sage.matrix.benchmark import hilbert_matrix
782
sage: mat = hilbert_matrix(5).change_ring(CBF)
783
sage: mat.eigenvalues()
784
doctest:...: FutureWarning: This class/method/function is marked as experimental.
785
...
786
[[1.567050691098...] + [+/- ...]*I, [0.208534218611...] + [+/- ...]*I,
787
[3.287928...e-6...] + [+/- ...]*I, [0.000305898040...] + [+/- ...]*I,
788
[0.011407491623...] + [+/- ...]*I]
789
790
sage: mat = Permutation([2, 1, 4, 5, 3]).to_matrix().dense_matrix().change_ring(CBF)
791
sage: mat.eigenvalues()
792
Traceback (most recent call last):
793
...
794
ValueError: unable to certify the eigenvalues
795
sage: precond = matrix(ZZ, [[-1, -2, 2, 2, -2], [2, -2, -2, -2, 2],
796
....: [-2, 2, -1, 2, 1], [2, 1, -1, 0, 2], [-2, 0, 1, -1, 1]])
797
sage: (~precond*mat*precond).eigenvalues()
798
[[-0.5000000000000...] + [-0.8660254037844...]*I, [-1.000000000000...] + [+/- ...]*I,
799
[-0.5000000000000...] + [0.8660254037844...]*I,
800
[1.000000000000...] + [+/- ...]*I, [1.000000000000...] + [+/- ...]*I]
801
802
.. SEEALSO:: :meth:`eigenvectors_right`
803
"""
804
if self._nrows != self._ncols:
805
raise ValueError("self must be a square matrix")
806
cdef long n = self._ncols
807
cdef acb_ptr eigval_approx, eigval
808
cdef acb_mat_t eigvec_approx
809
if other is not None:
810
raise NotImplementedError
811
try:
812
eigval_approx = _acb_vec_init(n)
813
acb_mat_init(eigvec_approx, n, n)
814
acb_mat_approx_eig_qr(eigval_approx, NULL, eigvec_approx, self.value, NULL, 0, prec(self))
815
eigval = _acb_vec_init(n)
816
if not acb_mat_eig_multiple(eigval, self.value, eigval_approx, eigvec_approx, prec(self)):
817
raise ValueError("unable to certify the eigenvalues")
818
res = _acb_vec_to_list(eigval, n, self._parent._base)
819
finally:
820
acb_mat_clear(eigvec_approx)
821
_acb_vec_clear(eigval, n)
822
_acb_vec_clear(eigval_approx, n)
823
return Sequence(res)
824
825
@experimental(issue_number=30393)
826
def eigenvectors_right_approx(self, other=None, *, extend=None):
827
r"""
828
(Experimental.) Compute *non-rigorous* approximations of the
829
eigenvalues and eigenvectors of this matrix.
830
831
INPUT:
832
833
- ``self`` -- an `n \times n` matrix
834
- ``other`` -- unsupported (generalized eigenvalue problem), should be ``None``
835
- ``extend`` -- ignored
836
837
OUTPUT:
838
839
A list of triples of the form ``(eigenvalue, [eigenvector], 1)``. The
840
eigenvalue and the entries of the eigenvector are complex balls with
841
zero radius.
842
843
No guarantees are made about the accuracy of the output.
844
845
See the `FLINT documentation <https://flintlib.org/doc/acb_mat.html#c.acb_mat_approx_eig_qr>`__
846
for more information.
847
848
EXAMPLES::
849
850
sage: from sage.matrix.benchmark import hilbert_matrix
851
sage: mat = hilbert_matrix(3).change_ring(CBF)
852
sage: eigval, eigvec, _ = mat.eigenvectors_right_approx()[0]
853
doctest:...: FutureWarning: This class/method/function is marked as experimental.
854
...
855
sage: eigval
856
[1.40831892712...]
857
sage: eigval.rad()
858
0.00000000
859
sage: eigvec
860
[([0.8270449269720...], [0.4598639043655...], [0.3232984352444...])]
861
sage: (mat - eigval)*eigvec[0]
862
([1e-15 +/- ...], [2e-15 +/- ...], [+/- ...])
863
864
.. SEEALSO:: :meth:`eigenvectors_right`
865
"""
866
if self._nrows != self._ncols:
867
raise ValueError("self must be a square matrix")
868
cdef long n = self._ncols
869
cdef Matrix_complex_ball_dense eigvec = self._new(n, n)
870
cdef acb_ptr _eigval
871
if other is not None:
872
raise NotImplementedError
873
try:
874
_eigval = _acb_vec_init(n)
875
acb_mat_approx_eig_qr(_eigval, NULL, eigvec.value, self.value, NULL, 0, prec(self))
876
eigval = _acb_vec_to_list(_eigval, n, self._parent._base)
877
finally:
878
_acb_vec_clear(_eigval, n)
879
return [(val, [vec], 1) for val, vec in zip(eigval, eigvec.columns())]
880
881
@experimental(issue_number=30393)
882
def eigenvectors_right(self, other=None, *, extend=None):
883
r"""
884
(Experimental.) Compute rigorous enclosures of the eigenvalues and
885
eigenvectors of this matrix.
886
887
INPUT:
888
889
- ``self`` -- an `n \times n` matrix
890
- ``other`` -- unsupported (generalized eigenvalue problem), should be ``None``
891
- ``extend`` -- ignored
892
893
OUTPUT:
894
895
A list of triples of the form ``(eigenvalue, [eigenvector], 1)``.
896
897
Unlike :meth:`eigenvalues` and :meth:`eigenvectors_right_approx`, this
898
method currently fails in the presence of multiple eigenvalues.
899
900
Additionally, there is currently no guarantee that the algorithm
901
converges as the working precision is increased.
902
903
See the `FLINT documentation <https://flintlib.org/doc/acb_mat.html#c.acb_mat_eig_simple>`__
904
for more information.
905
906
EXAMPLES::
907
908
sage: from sage.matrix.benchmark import hilbert_matrix
909
sage: mat = hilbert_matrix(3).change_ring(CBF)
910
sage: eigval, eigvec, _ = mat.eigenvectors_right()[0]
911
doctest:...: FutureWarning: This class/method/function is marked as experimental.
912
...
913
sage: eigval
914
[1.40831892712...] + [+/- ...]*I
915
sage: eigvec
916
[([0.82704492697...] + [+/- ...]*I, [0.45986390436...] + [+/- ...]*I, [0.32329843524...] + [+/- ...]*I)]
917
sage: (mat - eigval)*eigvec[0]
918
([+/- ...] + [+/- ...]*I, [+/- ...] + [+/- ...]*I, [+/- ...] + [+/- ...]*I)
919
920
.. SEEALSO:: :meth:`eigenvectors_right_approx`, :meth:`eigenvalues`
921
"""
922
if self._nrows != self._ncols:
923
raise ValueError("self must be a square matrix")
924
cdef long n = self._ncols
925
cdef acb_ptr eigval_approx, _eigval
926
cdef acb_mat_t eigvec_approx
927
cdef Matrix_complex_ball_dense eigvec = self._new(n, n)
928
if other is not None:
929
raise NotImplementedError
930
try:
931
_eigval = _acb_vec_init(n)
932
eigval_approx = _acb_vec_init(n)
933
acb_mat_init(eigvec_approx, n, n)
934
acb_mat_approx_eig_qr(eigval_approx, NULL, eigvec_approx, self.value, NULL, 0, prec(self))
935
if not acb_mat_eig_simple(_eigval, NULL, eigvec.value, self.value, eigval_approx, eigvec_approx, prec(self)):
936
raise ValueError("unable to isolate the eigenvalues (multiple eigenvalues?)")
937
eigval = _acb_vec_to_list(_eigval, n, self._parent._base)
938
finally:
939
acb_mat_clear(eigvec_approx)
940
_acb_vec_clear(_eigval, n)
941
_acb_vec_clear(eigval_approx, n)
942
return [(val, [vec], 1) for val, vec in zip(eigval, eigvec.columns())]
943
944
def eigenvectors_left_approx(self, other=None, *, extend=None):
945
r"""
946
(Experimental.) Compute *non-rigorous* approximations of the
947
left eigenvalues and eigenvectors of this matrix.
948
949
INPUT:
950
951
- ``self`` -- an `n \times n` matrix
952
- ``other`` -- unsupported (generalized eigenvalue problem), should be ``None``
953
- ``extend`` -- ignored
954
955
OUTPUT:
956
957
A list of triples of the form ``(eigenvalue, [eigenvector], 1)``. The
958
eigenvalue and the entries of the eigenvector are complex balls with
959
zero radius.
960
961
No guarantees are made about the accuracy of the output.
962
963
See the `FLINT documentation <https://flintlib.org/doc/acb_mat.html#c.acb_mat_approx_eig_qr>`__
964
for more information.
965
966
EXAMPLES::
967
968
sage: mat = matrix(CBF, 3, [2, 3, 5, 7, 11, 13, 17, 19, 23])
969
sage: eigval, eigvec, _ = mat.eigenvectors_left_approx()[0]
970
sage: eigval
971
[1.1052996349... +/- ...]
972
sage: eigvec[0]
973
([0.69817246751...], [-0.67419514369...], [0.240865343781...])
974
sage: eigvec[0] * (mat - eigval)
975
([+/- ...], [+/- ...], [+/- ...])
976
977
.. SEEALSO:: :meth:`eigenvectors_left`
978
"""
979
return self.transpose().eigenvectors_right_approx(other=None, extend=extend)
980
981
def eigenvectors_left(self, other=None, *, extend=True):
982
r"""
983
(Experimental.) Compute rigorous enclosures of the eigenvalues and
984
left eigenvectors of this matrix.
985
986
INPUT:
987
988
- ``self`` -- an `n \times n` matrix
989
- ``other`` -- unsupported (generalized eigenvalue problem), should be ``None``
990
- ``extend`` -- ignored
991
992
OUTPUT:
993
994
A list of triples of the form ``(eigenvalue, [eigenvector], 1)``.
995
996
Unlike :meth:`eigenvalues` and :meth:`eigenvectors_left_approx`, this
997
method currently fails in the presence of multiple eigenvalues.
998
999
Additionally, there is currently no guarantee that the algorithm
1000
converges as the working precision is increased.
1001
1002
See the `FLINT documentation <https://flintlib.org/doc/acb_mat.html#c.acb_mat_eig_simple>`__
1003
for more information.
1004
1005
EXAMPLES::
1006
1007
sage: mat = matrix(CBF, 3, [2, 3, 5, 7, 11, 13, 17, 19, 23])
1008
sage: eigval, eigvec, _ = mat.eigenvectors_left()[0]
1009
sage: eigval
1010
[1.1052996349...] + [+/- ...]*I
1011
sage: eigvec[0]
1012
([0.69817246751...] + [+/- ...]*I, [-0.67419514369...] + [+/- ...]*I, [0.240865343781...] + [+/- ...]*I)
1013
sage: eigvec[0] * (mat - eigval)
1014
([+/- ...] + [+/- ...]*I, [+/- ...] + [+/- ...]*I, [+/- ...] + [+/- ...]*I)
1015
1016
.. SEEALSO:: :meth:`eigenvectors_right`, :meth:`eigenvalues`, :meth:`eigenvectors_left_approx`
1017
"""
1018
return self.transpose().eigenvectors_right(other=other, extend=extend)
1019
1020
def exp(self):
1021
r"""
1022
Compute the exponential of this matrix.
1023
1024
EXAMPLES::
1025
1026
sage: matrix(CBF, [[i*pi, 1], [0, i*pi]]).exp() # needs sage.symbolic
1027
[[-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I [-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I]
1028
[ 0 [-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I]
1029
sage: matrix(CBF, [[1/2, 1/3]]).exp()
1030
Traceback (most recent call last):
1031
...
1032
ValueError: self must be a square matrix
1033
"""
1034
cdef Matrix_complex_ball_dense res = self._new(self._nrows, self._ncols)
1035
if self._nrows != self._ncols:
1036
raise ValueError("self must be a square matrix")
1037
sig_on()
1038
acb_mat_exp(res.value, self.value, prec(self))
1039
sig_off()
1040
return res
1041
1042
cdef _acb_vec_to_list(acb_ptr vec, long n, Parent parent):
1043
cdef ComplexBall b
1044
res = []
1045
for i in range(n):
1046
b = ComplexBall.__new__(ComplexBall)
1047
b._parent = parent
1048
acb_set(b.value, &vec[i])
1049
res.append(b)
1050
return res
1051
1052