acb_mat – matrices over complex numbers¶
-
class
flint.
acb_mat
¶ Represents a matrix over the complex numbers.
>>> A = acb_mat([[1,2+1j],[3,4]]) ** 2 / 5 >>> print(A.str(5, radius=False)) [1.4000 + 0.60000j, 2.0000 + 1.0000j] [ 3.0000, 4.4000 + 0.60000j]
-
charpoly
(s)¶ Returns the characteristic polynomial of s as an acb_poly.
>>> print(acb_mat(2, 2, [1, 1, 1, 0]).charpoly()) 1.00000000000000*x^2 + (-1.00000000000000)*x + (-1.00000000000000)
-
chop
(s, tol)¶ Returns a copy of s where real and imaginary parts of entries that are bounded by tol in magnitude have been replaced by exact zeros.
>>> A = acb_mat([[1, 1+1e-20j], [1e-20+1j, 1e-20+1e-20j]]) >>> A.chop(1e-6) [ 1.00000000000000, 1.00000000000000] [1.00000000000000j, 0]
-
conjugate
(s)¶ Returns the entrywise conjugate (not the conjugate transpose) of s.
>>> acb_mat([[1-2j, 1+3j]]).conjugate() [1.00000000000000 + 2.00000000000000j, 1.00000000000000 - 3.00000000000000j]
-
contains
(s, t)¶ Returns whether t is contained in s (in the sense of balls).
>>> A = acb_mat([[1,2],[3,4]]) >>> ((A / 3) * 3).contains(A) True >>> A.contains((A / 3) * 3) False >>> ((A / 3) * 3).contains(fmpz_mat([[1,2],[3,4]])) True >>> ((A / 3) * 3).contains(fmpz_mat([[1,2],[3,5]])) False >>> (A / 3).contains(fmpq_mat([[1,2],[3,4]]) / 3) True >>> ((A / 3) * 3).contains(arb_mat([[1,2],[3,4]])) True
-
convert
(type cls, x)¶ Attempts to convert x to an acb_mat, raising TypeError if unsuccessful.
-
convert_operand
(type cls, x)¶ Attempts to convert x to an acb_mat, returning NotImplemented if unsuccessful.
-
det
(s)¶ Returns the determinant of the square matrix s as an acb.
>>> A = acb_mat(3, 3, range(9)) >>> showgood(lambda: A.det(), dps=25) # singular 0 >>> A[2,2] = 10 >>> showgood(lambda: A.det(), dps=25) -6.000000000000000000000000 >>> showgood(lambda: (A * A).det()) 36.0000000000000 >>> print(acb_mat(0, 0).det()) 1.00000000000000
-
dft
(type cls, long n, long m=-1)¶ Returns the size n by n DFT matrix (optionally a separate number of columns m can be given in which case the periodic extension of the smaller dimension is used).
>>> print(acb_mat.dft(3).str(5, radius=False)) [0.57735, 0.57735, 0.57735] [0.57735, -0.28868 - 0.50000j, -0.28868 + 0.50000j] [0.57735, -0.28868 + 0.50000j, -0.28868 - 0.50000j]
-
eig
(s, bool left=False, bool right=False, multiple=False, algorithm=None, tol=None, long maxiter=0, bool nonstop=False)¶ Computes eigenvalues and optionally eigenvectors of this matrix. Returns either E, (E, L), (E, R) or (E, L, R) depending on whether the flags left and right are set, where E is a list of the eigenvalues, L is a matrix with the left eigenvectors as rows, and R is a matrix with the right eigenvectors as columns.
The algorithm can be “rump”, “vdhoeven_mourrain”, or None to use a default algorithm. Typically “rump” is slower and more accurate while “vdhoeven_mourrain” (the current default) is faster and less accurate.
>>> A = acb_mat([[2,3,5],[7,11,13],[17,19,23]]) >>> for c in A.eig(): print(c) ... [1.105299634957 +/- 6.34e-13] + [+/- 1.83e-13]j [-1.917027627441 +/- 2.64e-13] + [+/- 1.83e-13]j [36.811727992483 +/- 6.97e-13] + [+/- 1.83e-13]j >>> for c in A.eig(algorithm="rump"): print(c) ... [1.10529963495745 +/- 4.71e-15] + [+/- 2.92e-15]j [-1.91702762744092 +/- 8.45e-15] + [+/- 3.86e-15]j [36.8117279924835 +/- 4.72e-14] + [+/- 9.07e-15]j
With the left and right eigenvector matrices, a complete diagonalization of the matrix is produced:
>>> A = acb_mat([[2,3,5],[7,11,13],[17,19,23]]) >>> E, L, R = A.eig(left=True, right=True) >>> D = acb_mat(3,3) >>> for i in range(3): D[i,i] = E[i] ... >>> (L*A*R - D).contains(acb_mat(3,3)) True >>> (R*D*L - A).contains(acb_mat(3,3)) True
Ill-conditioned or large matrices may require high precision to isolate the eigenvalues:
>>> sum(acb_mat(arb_mat.hilbert(20,20)).eig()) Traceback (most recent call last): ... ValueError: failed to isolate eigenvalues (try higher prec, multiple=True for multiple eigenvalues, or nonstop=True to avoid the exception) >>> sum(acb_mat(arb_mat.hilbert(20,20)).eig(nonstop=True)) nan + nanj >>> showgood(lambda: sum(acb_mat(arb_mat.hilbert(20,20)).eig(nonstop=True)), parts=False) 2.47967321036454 + [+/- 1.48e-56]j
With default options, the method only succeeds if all eigenvalues can be isolated. Multiple (overlapping) eigenvalues can be handled by setting multiple = True.
>>> acb_mat.dft(4).eig() Traceback (most recent call last): ... ValueError: failed to isolate eigenvalues (try higher prec, multiple=True for multiple eigenvalues, or nonstop=True to avoid the exception) >>> acb_mat.dft(4).eig(nonstop=True) [nan + nanj, nan + nanj, nan + nanj, nan + nanj] >>> acb_mat.dft(4).eig(multiple=True) [[-1.0000000000000 +/- 2.26e-15] + [+/- 1.23e-15]j, [+/- 4.96e-16] + [-1.00000000000000 +/- 3.72e-16]j, [1.00000000000000 +/- 4.98e-16] + [+/- 3.42e-16]j, [1.00000000000000 +/- 4.98e-16] + [+/- 3.42e-16]j]
At this time, computing the eigenvectors is not supported with multiple eigenvalues:
>>> acb_mat.dft(4).eig(multiple=True, right=True) Traceback (most recent call last): ... NotImplementedError: eigenvectors not supported with multiple=True
The algorithm can also be set to “approx” to compute approximate eigenvalues and/or eigenvectors without error bounds.
>>> for c in acb_mat.dft(4).eig(algorithm="approx"): print(c.str(radius=False)) ... -0.999999999999999 - 7.85046229341892e-17j -2.35513868802566e-16 - 1.00000000000000j 1.00000000000000 - 6.64346650360854e-17j 0.999999999999999 - 5.14675360671472e-17j
If algorithm is set to “approx”, then multiple has no effect, and both eigenvalues and eigenvectors can be computed regardless of overlap.
>>> E = acb_mat.dft(4).eig(algorithm="approx") >>> E, R = acb_mat.dft(4).eig(right=True, algorithm="approx") >>> E, L = acb_mat.dft(4).eig(left=True, algorithm="approx") >>> E, L, R = acb_mat.dft(4).eig(left=True, right=True, algorithm="approx")
-
entries
(self)¶
-
exp
(s)¶ Returns the matrix exponential of s.
>>> print(acb_mat(2, 2, [1, 4, -2, 1]).exp()) [ [-2.58607310345045 +/- 5.06e-15], [1.18429895089106 +/- 1.15e-15]] [[-0.592149475445530 +/- 5.73e-16], [-2.58607310345045 +/- 5.06e-15]]
-
imag
¶ Entrywise imaginary part of this matrix as an arb_mat.
>>> print(acb_mat.dft(3).imag.str(5, radius=False)) [0, 0, 0] [0, -0.50000, 0.50000] [0, 0.50000, -0.50000]
-
inv
(s, bool nonstop=False)¶ Returns the inverse matrix of the square matrix s.
If s is numerically singular, raises
ZeroDivisionError
unless nonstop is set in which case a matrix with NaN entries is returned.>>> A = acb_mat(2, 2, [1, 5, 2, 4]) >>> print(A * A.inv()) [[1.00000000000000 +/- 6.11e-16], [+/- 3.34e-16]] [ [+/- 4.45e-16], [1.00000000000000 +/- 5.56e-16]] >>> A = acb_mat(2, 2, [1, 5, 2, 10]) >>> A.inv() Traceback (most recent call last): ... ZeroDivisionError: matrix is singular >>> A.inv(nonstop=True) [nan + nanj, nan + nanj] [nan + nanj, nan + nanj]
-
mid
(s)¶ Returns the matrix consisting of the midpoints of the entries of s.
>>> acb_mat([["1.5 +/- 0.1", 3]]).mid() [1.50000000000000, 3.00000000000000]
-
ncols
(s) → long¶ Returns the number of columns of s.
-
nrows
(s) → long¶ Returns the number of rows of s.
-
overlaps
(s, acb_mat t)¶ Returns whether s and t overlap (in the sense of balls).
>>> A = acb_mat([[1,2],[3,4]]) >>> ((A / 3) * 3).overlaps(A) True >>> ((A / 3) * 3 + 0.0001).overlaps(A) False
-
real
¶ Entrywise real part of this matrix as an arb_mat.
>>> print(acb_mat.dft(3).real.str(5, radius=False)) [0.57735, 0.57735, 0.57735] [0.57735, -0.28868, -0.28868] [0.57735, -0.28868, -0.28868]
-
repr
(self)¶
-
solve
(s, t, bool nonstop=False, algorithm=None)¶ Solves \(AX = B\) where A is a square matrix given by s and \(B\) is a matrix given by t.
If A is numerically singular, raises
ZeroDivisionError
unless nonstop is set in which case a matrix with NaN entries is returned.>>> A = acb_mat(2, 2, [1, 2, 3, 4]) >>> X = acb_mat(2, 3, range(6)) >>> B = A * X >>> print(A.solve(B)) [ [+/- 4.74e-15], [1.00000000000000 +/- 4.78e-15], [2.00000000000000 +/- 8.52e-15]] [[3.00000000000000 +/- 3.56e-15], [4.00000000000000 +/- 3.59e-15], [5.00000000000000 +/- 6.28e-15]] >>> acb_mat([[1,1],[0,0]]).solve(acb_mat(2,3), nonstop=True) [nan + nanj, nan + nanj, nan + nanj] [nan + nanj, nan + nanj, nan + nanj]
The optional algorithm can be None (default), “lu”, or “precond”. It can also be set to “approx” in which case an approximate floating-point solution (warning: without error bounds!) is returned.
-
str
(self, *args, **kwargs)¶
-
table
(self)¶
-
tolist
()¶ flint_mat.table(self)
-
trace
(s)¶ Returns the trace of the square matrix s as an acb.
>>> acb_mat([[3,4],[5,7]]).trace() 10.0000000000000
-
transpose
(s)¶ Returns the transpose of s.
-