#NEWLINE# def scale_from_matrix( matrix ) : #NEWLINE# #INDENT# 'Return scaling factor, origin and direction from scaling matrix.\n\n    >>> factor = random.random() * 10 - 5\n    >>> origin = numpy.random.random(3) - 0.5\n    >>> direct = numpy.random.random(3) - 0.5\n    >>> S0 = scale_matrix(factor, origin)\n    >>> factor, origin, direction = scale_from_matrix(S0)\n    >>> S1 = scale_matrix(factor, origin, direction)\n    >>> is_same_transform(S0, S1)\n    True\n    >>> S0 = scale_matrix(factor, origin, direct)\n    >>> factor, origin, direction = scale_from_matrix(S0)\n    >>> S1 = scale_matrix(factor, origin, direction)\n    >>> is_same_transform(S0, S1)\n    True\n\n    ' #NEWLINE# M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) #NEWLINE# M33 = M [ : 3 , : 3 ] #NEWLINE# factor = ( numpy . trace ( M33 ) - 2.0 ) #NEWLINE# try : #NEWLINE# #INDENT# ( l , V ) = numpy . linalg . eig ( l ) #NEWLINE# i = numpy . where ( ( abs ( ( numpy . real ( l ) - factor ) ) < 1e-08 ) ) [ 0 ] [ 0 ] #NEWLINE# direction = numpy . real ( V [ : , i ] ) . squeeze ( ) #NEWLINE# direction /= vector_norm ( direction ) #NEWLINE# #UNINDENT# except IndexError : #NEWLINE# #INDENT# factor = ( ( factor + 2.0 ) / 3.0 ) #NEWLINE# direction = None #NEWLINE# #UNINDENT# ( l , V ) = numpy . linalg . eig ( M ) #NEWLINE# i = numpy . where ( ( abs ( ( numpy . real ( l ) - 1.0 ) ) < 1e-08 ) ) [ 0 ] #NEWLINE# if ( not len ( i ) ) : #NEWLINE# #INDENT# raise ValueError ( 'no eigenvector corresponding to eigenvalue 1' ) #NEWLINE# #UNINDENT# origin = numpy . real ( V [ : , i [ ( - 1 ) ] ] ) . squeeze ( ) #NEWLINE# origin /= origin [ 3 ] #NEWLINE# return ( factor , origin , direction )