# [ 1 0 ]
# [ 0 B ]
#
+ # We could still do a pivot_one_by_one() here, but it would
+ # pointlessly subract a bunch of zeros and multiply by one.
B = A1[1:,1:]
- P2, L2, D2 = ldlt_naive(B)
+ P2, L2, D2 = block_ldlt_naive(B)
P1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
[ZZ(0), P2]])
L1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
[ZZ(0), D2]])
return (P1,L1,D1)
- if A1[0,0].abs() > alpha*omega_1:
- # Higham step (1)
- # The top-left entry is our 1x1 pivot.
- C = A1[1:n,0]
- B = A1[1:,1:]
+ def pivot_one_by_one(M, c=None):
+ # Perform a one-by-one pivot on "M," swapping row/columns "c".
+ # If "c" is None, no swap is performed.
+ if c is not None:
+ P1 = copy(M.matrix_space().identity_matrix())
+ P1.swap_rows(0,c)
+ M = P1.T * M * P1
- P2, L2, D2 = block_ldlt_naive(B - (C*C.transpose())/A1[0,0])
+ # The top-left entry is now our 1x1 pivot.
+ C = M[1:n,0]
+ B = M[1:,1:]
+
+ P2, L2, D2 = block_ldlt_naive(B - (C*C.transpose())/M[0,0])
+
+ if c is None:
+ P1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
+ [0*C, P2]])
+ else:
+ P1 = P1*block_matrix(2,2, [[ZZ(1), ZZ(0)],
+ [0*C, P2]])
- P1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
- [0*C, P2]])
L1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
- [P2.transpose()*C/A1[0,0], L2]])
- D1 = block_matrix(2,2, [[A1[0,0], ZZ(0)],
- [0*C, D2]])
+ [P2.transpose()*C/M[0,0], L2]])
+ D1 = block_matrix(2,2, [[M[0,0], ZZ(0)],
+ [0*C, D2]])
return (P1,L1,D1)
+ if A1[0,0].abs() > alpha*omega_1:
+ return pivot_one_by_one(A1)
+
r = 1 + column_1_subdiag.index(omega_1)
# If the matrix is Hermitian, we need only look at the above-
omega_r = max( a_rj.abs() for a_rj in A1[:r,r].list() )
if A1[0,0].abs()*omega_r >= alpha*(omega_1^2):
- # Higham step (2)
- # The top-left entry is our 1x1 pivot.
- C = A1[1:n,0]
- B = A1[1:,1:]
-
- P2, L2, D2 = block_ldlt_naive(B - (C*C.transpose())/A1[0,0])
-
- P1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
- [0*C, P2]])
- L1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
- [P2.transpose()*C/A1[0,0], L2]])
- D1 = block_matrix(2,2, [[A1[0,0], ZZ(0)],
- [0*C, D2]])
-
- return (P1,L1,D1)
-
+ return pivot_one_by_one(A1)
if A1[r,r].abs() > alpha*omega_r:
# Higham step (3)
# Another 1x1 pivot, but this time swapping indices 0,r.
- P1 = copy(A1.matrix_space().identity_matrix())
- P1.swap_rows(0,s)
- A1 = P1.T * A1 * P1
-
- # The top-left entry is now our 1x1 pivot.
- C = A1[1:n,0]
- B = A1[1:,1:]
-
- P2, L2, D2 = block_ldlt_naive(B - (C*C.transpose())/A1[0,0])
-
- P1 = P1*block_matrix(2,2, [[ZZ(1), ZZ(0)],
- [0*C, P2]])
- L1 = block_matrix(2,2, [[ZZ(1), ZZ(0)],
- [P2.transpose()*C/A1[0,0], L2]])
- D1 = block_matrix(2,2, [[A1[0,0], ZZ(0)],
- [0*C, D2]])
-
- return (P1,L1,D1)
+ return pivot_one_by_one(A1,r)
# Higham step (4)
# If we made it here, we have to do a 2x2 pivot.