#NEWLINE# @ defun #NEWLINE# def schur( ctx , A , overwrite_a = False ) : #NEWLINE# #INDENT# "\n    This routine computes the Schur decomposition of a square matrix A.\n    Given A, an unitary matrix Q is determined such that\n\n          Q' A Q = R                and               Q' Q = Q Q' = 1\n\n    where R is an upper right triangular matrix. Here ' denotes the\n    hermitian transpose (i.e. transposition and conjugation).\n\n    input:\n      A            : a real or complex square matrix\n      overwrite_a  : if true, allows modification of A which may improve\n                     performance. if false, A is not modified.\n\n    output:\n      Q : an unitary matrix\n      R : an upper right triangular matrix\n\n    return value:   (Q, R)\n\n    example:\n      >>> from mpmath import mp\n      >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])\n      >>> Q, R = mp.schur(A)\n      >>> mp.nprint(R, 3) # doctest:+SKIP\n      [2.0  0.417  -2.53]\n      [0.0    4.0  -4.74]\n      [0.0    0.0    9.0]\n      >>> print(mp.chop(A - Q * R * Q.transpose_conj()))\n      [0.0  0.0  0.0]\n      [0.0  0.0  0.0]\n      [0.0  0.0  0.0]\n\n    warning: The Schur decomposition is not unique.\n    " #NEWLINE# n = A . rows #NEWLINE# if ( n == 1 ) : #NEWLINE# #INDENT# return ( ctx . matrix ( [ [ 1 ] ] ) , A ) #NEWLINE# #UNINDENT# if ( not overwrite_a ) : #NEWLINE# #INDENT# A = A . copy ( ) #NEWLINE# #UNINDENT# T = ctx . matrix ( n , 1 ) #NEWLINE# hessenberg_reduce_0 ( ctx , A , T ) #NEWLINE# Q = A . copy ( ) #NEWLINE# hessenberg_reduce_1 ( ctx , Q , T ) #NEWLINE# for x in xrange ( n ) : #NEWLINE# #INDENT# for y in xrange ( ( x + 2 ) , n ) : #NEWLINE# #INDENT# A [ ( y , x ) ] = 0 #NEWLINE# #UNINDENT# #UNINDENT# hessenberg_qr ( ctx , A , Q ) #NEWLINE# return ( Q , A )