B
    da                 @   s  d Z ddlmZmZmZ ddlmZ ddlmZ dadd Z	da
dd	 Zdd
lZdd
lZG dd deZG dd deZG dd deZG dd deeZG dd deeZG dd deZG dd deeZG dd deeZG dd deZG dd deZG dd  d eZG d!d" d"eZG d#d$ d$eZdWd%d&Zd'd( Zd)d* Zd+d, Zd-d. Z d/d0 Z!dXd1d2Z"dYd3d4Z#d5d6 Z$d7d8 Z%d9d: Z&d;d< Z'd=d> Z(dZd?d@Z)G dAdB dBeZ*dCdD Z+dEdF Z,d[dHdIZ-d\dJdKZ.dLdM Z/dNdO Z0dPdQ Z1dRdS Z2dTdU Z3e4dVkre2  e3  d
S )]a  
Note: this module can be used in isolation (without the rest of scitbx).
All external dependencies (other than plain Python) are optional.

The primary purpose of this module is to provide compact
implementations of essential matrix/vector algorithms with minimal
external dependencies. Optimizations for execution performance are
used only if compactness is not affected. The scitbx/math module
provides faster C++ alternatives to some algorithms included here.
    )absolute_importdivisionprint_function)range)zipFc               C   s6   t dkr2yddlma  W n tk
r0   d a Y nX t S )NFr   )flex)_flex_importedscitbx.array_familyr   ImportError r   r   u/mnt/filia/a/genomebrowser/www/genomebrowser/fleming/tools/molprobity/modules/cctbx_project/scitbx/matrix/__init__.py
flex_proxy   s      
r   c              C   s6   t dkr2ydd l} W n tk
r,   d a Y nX | a t S )NFr   )_numpy_importedZnumpy.linalgr
   )numpyr   r   r   numpy_proxy   s      
r   Nc               @   s  e Zd ZdZeZdd Zdd Zdd Zdd	 Z	d
d Z
dd Zdd Zdd ZdddZdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zdd(d)Zd*d+ Zd,d- Zdd/d0Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Z d;d< Z!d=d> Z"d?d@ Z#dAdB Z$dCdD Z%e#Z&e%Z'dEdF Z(ddGdHZ)dIdJ Z*dKdL Z+ddNdOZ,dPdQ Z-dRdS Z.dTdU Z/dVdW Z0dXdY Z1dd[d\Z2d]d^ Z3d_d` Z4dadb Z5ddcddZ6ddedfZ7ddgdhZ8ddidjZ9ddkdlZ:dmdn Z;ddodpZ<ddqdrZ=ddsdtZ>ddvdwZ?ddxdyZ@ddzd{ZAdd|d}ZBdddZCdddZDdd ZEdd ZFdd ZGdd ZHdd ZIdd ZJdddZKdddZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdddZTdd ZUdd ZVdd ZWdS )recz
  Base rectangle object, used to store 2-dimensional data.

  Examples
  --------
  >>> from scitbx.matix import rec
  >>> m = rec((1, 2, 3, 4), (2, 2))
  >>> print m.trace()
  5
  >>> other = rec((1, 1, 1, 1), (2, 2))
  >>> print m.dot(other)
  10
  c             C   sV   t |dkstt|| js&| |}t ||d |d  ksBt|| _t|| _d S )N   r      )lenAssertionError
isinstancecontainer_typeelemstuplen)selfr   r   r   r   r   __init__5   s    
zrec.__init__c             C   s
   | j d S )Nr   )r   )r   r   r   r   n_rows=   s    z
rec.n_rowsc             C   s
   | j d S )Nr   )r   )r   r   r   r   	n_columns@   s    zrec.n_columnsc             C   s   t dd | jD | jS )Nc             S   s   g | ]
}| qS r   r   ).0er   r   r   
<listcomp>D   s    zrec.__neg__.<locals>.<listcomp>)r   r   r   )r   r   r   r   __neg__C   s    zrec.__neg__c                s@   | j |j kst| j |jt fddtt D | j S )Nc                s   g | ]} | |  qS r   r   )r   i)abr   r   r!   J   s    zrec.__add__.<locals>.<listcomp>)r   r   r   r   r   r   )r   otherr   )r$   r%   r   __add__F   s    zrec.__add__c                s@   | j |j kst| j |jt fddtt D | j S )Nc                s   g | ]} | |  qS r   r   )r   r#   )r$   r%   r   r   r!   P   s    zrec.__sub__.<locals>.<listcomp>)r   r   r   r   r   r   )r   r&   r   )r$   r%   r   __sub__L   s    zrec.__sub__c                s2  t  ds<t ttfs4t fdd| jD | jS t  | j}|  }| 	 } j}  |krt
dt| jt jf  	 }|dkrtd||  ||fS g }xft|D ]Z}xTt|D ]H}	d}
x4t|D ](}|
||| |  ||| |	   7 }
qW ||
 qW qW ||kr$t|S t|||fS )Nr   c                s   g | ]}|  qS r   r   )r   x)r&   r   r   r!   U   s    zrec.__mul__.<locals>.<listcomp>z2Incompatible matrices:
  self.n:  %s
  other.n: %sr   )r   )hasattrr   listr   r   r   r   colr   r   RuntimeErrorstrr   appendsqr)r   r&   r$   aracr%   bcresultr#   ksjr   )r&   r   __mul__R   s2    
(
zrec.__mul__c             C   s   t |tr|| S | | S )zscalar * matrix)r   r   r8   )r   r&   r   r   r   __rmul__o   s    

zrec.__rmul__Nc          
   C   sv  | j }|  }|  }|d krdg||  }d}xlt|D ]`}d}xNt|D ]B}	x<t|D ]0}
||  |||	  |||
   7  < |d7 }qZW qLW ||7 }q:W t|S |j }| |kstd| }dg||  }d}d}xvt|D ]j}d}xPt|D ]D}	x>t|D ]2}
||  |||	  |||
   7  < |d7 }qW qW ||7 }||7 }qW ||krht|S t|||fS )Nr   r   zIncompatible matrices.)r   r   r   r   r0   r   r   )r   r&   r$   r1   r2   r4   Zjacr7   ikr#   r5   r%   r3   Zjbcr   r   r   transpose_multiplyu   s>    $$
zrec.transpose_multiplyc                s   t  fdd| jD | jS )Nc                s   g | ]}|  qS r   r   )r   r    )r&   r   r   r!      s    zrec.__div__.<locals>.<listcomp>)r   r   r   )r   r&   r   )r&   r   __div__   s    zrec.__div__c                s   t  fdd| jD | jS )Nc                s   g | ]}|  qS r   r   )r   r    )r&   r   r   r!      s    z#rec.__truediv__.<locals>.<listcomp>)r   r   r   )r   r&   r   )r&   r   __truediv__   s    zrec.__truediv__c                s   t  fdd| jD | jS )Nc                s   g | ]}|  qS r   r   )r   r    )r&   r   r   r!      s    z$rec.__floordiv__.<locals>.<listcomp>)r   r   r   )r   r&   r   )r&   r   __floordiv__   s    zrec.__floordiv__c                s   t  fdd| jD | jS )Nc                s   g | ]}|  qS r   r   )r   r    )r&   r   r   r!      s    zrec.__mod__.<locals>.<listcomp>)r   r   r   )r   r&   r   )r&   r   __mod__   s    zrec.__mod__c             C   s   | j ||   |  S )N)r   r   )r   iricr   r   r   __call__   s    zrec.__call__c             C   s
   t | jS )N)r   r   )r   r   r   r   __len__   s    zrec.__len__c             C   s
   | j | S )N)r   )r   r#   r   r   r   __getitem__   s    zrec.__getitem__c             C   s   t dd | jD | jS )Nc             S   s   g | ]}t |qS r   )float)r   r    r   r   r   r!      s    z rec.as_float.<locals>.<listcomp>)r   r   r   )r   r   r   r   as_float   s    zrec.as_floatc                s(   ddl m  t fdd| jD | jS )Nr   )rationalc                s   g | ]}  |qS r   )int)r   r    )rG   r   r   r!      s    z)rec.as_boost_rational.<locals>.<listcomp>)boost_adaptbx.boostrG   r   r   r   )r   r   )rG   r   as_boost_rational   s    zrec.as_boost_rationalTc             C   s8   |rt dd | jD | jS t dd | jD | jS d S )Nc             S   s   g | ]}t t|qS r   )rH   round)r   r    r   r   r   r!      s    zrec.as_int.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )rH   )r   r    r   r   r   r!      s    )r   r   r   )r   Zroundingr   r   r   as_int   s    z
rec.as_intc             C   s&   t  }|d k	st|| j| jS )N)r   r   Zarrayr   reshaper   )r   r   r   r   r   as_numpy_array   s    zrec.as_numpy_arrayc             C   s   t dd | jD | jS )Nc             S   s   g | ]}t |qS r   )abs)r   r    r   r   r   r!      s    z rec.each_abs.<locals>.<listcomp>)r   r   r   )r   r   r   r   each_abs   s    zrec.each_absr   c                s2   d   fddt fdd| jD | jS )Ng       @c                s4   t | }|  k r |7 }n| kr0|8 }|S )N)mathfmod)r    r)halfperiodr   r   	mod_short   s    
 
 z%rec.each_mod_short.<locals>.mod_shortc                s   g | ]} |qS r   r   )r   r    )rV   r   r   r!      s    z&rec.each_mod_short.<locals>.<listcomp>)r   r   r   )r   rU   r   )rT   rV   rU   r   each_mod_short   s    zrec.each_mod_shortc             C   s,   d }x"| j D ]}|d ks ||kr|}qW |S )N)r   )r   r4   r    r   r   r   min   s
    zrec.minc             C   s,   d }x"| j D ]}|d ks ||k r|}qW |S )N)r   )r   r4   r    r   r   r   max   s
    zrec.maxc             C   s@   d }x6t t| jD ]$}|d ks4| j| | j| kr|}qW |S )N)r   r   r   )r   r4   r#   r   r   r   	min_index   s
    zrec.min_indexc             C   s@   d }x6t t| jD ]$}|d ks4| j| | j| k r|}qW |S )N)r   r   r   )r   r4   r#   r   r   r   	max_index   s
    zrec.max_indexc             C   s    d}x| j D ]}||7 }qW |S )Nr   )r   )r   r4   r    r   r   r   sum   s    zrec.sumc             C   s    d}x| j D ]}||9 }qW |S )Nr   )r   )r   r4   r    r   r   r   product   s    zrec.productc             C   sL   |   |  kst|   }d}x&t|D ]}|| j|| |  7 }q*W |S )Nr   )r   r   r   r   r   )r   r   r4   r#   r   r   r   trace   s    z	rec.tracec             C   s$   d}x| j D ]}||| 7 }qW |S )Nr   )r   )r   r4   r    r   r   r   norm_sq   s    zrec.norm_sqc                s   t  fdd| jD | jS )Nc                s   g | ]}t | qS r   )rK   )r   r)   )digitsr   r   r!      s    zrec.round.<locals>.<listcomp>)r   r   r   )r   r`   r   )r`   r   rK      s    z	rec.roundc             C   s*   |   dks|  dkstt|  S )Nr   )r   r   r   rQ   sqrtr_   )r   r   r   r   __abs__  s    zrec.__abs__c             C   s   | t |  S )N)rO   )r   r   r   r   	normalize	  s    zrec.normalizec             C   s   d}| j }|d kr>xrtt|D ]}|| }||| 7 }q W nHt| j t|j ksVt|j }x(tt|D ]}||| ||  7 }qjW |S )Nr   )r   r   r   r   )r   r&   r4   r$   r#   vr%   r   r   r   dot  s    zrec.dotc             C   s   | j dkst| j |j kst| j}|j}t|d |d  |d |d   |d |d  |d |d   |d |d  |d |d   f| j S )N))   r   )r   rf   r   r   r   )r   r   r   r   )r   r&   r$   r%   r   r   r   cross  s    z	rec.crossc             C   s0   | j dkrtd|  }|tdd  d S )N)rf   rf   zNot a 3x3 matrix.rf   )r   g      ?)r   r-   r;   identityr_   )r   Zrtrr   r   r   is_r3_rotation_matrix_rms$  s    
 zrec.is_r3_rotation_matrix_rms:0yE>c             C   s    |   |k otd|   |k S )Nr   )ri   rO   determinant)r   rms_tolerancer   r   r   is_r3_rotation_matrix)  s    zrec.is_r3_rotation_matrixc             C   s
   | j dkS )N)	g      ?g        g        g        g      ?g        g        g        g      ?)r   )r   r   r   r   is_r3_identity_matrix-  s    zrec.is_r3_identity_matrixc             C   s
   | j dkS )z  Is the translation vector zero )g        g        g        )r   )r   r   r   r   is_col_zero0  s    zrec.is_col_zeroc             C   s   t dd | jD dkS )z Are all elements zero  c             S   s   g | ]}|d krdqS )r   r   r   )r   r)   r   r   r   r!   6  s    zrec.is_zero.<locals>.<listcomp>r   )r   r   )r   r   r   r   is_zero4  s    zrec.is_zeroc                s   t  fdd| jD dkS )z Are all elements zero  c                s   g | ]}t | krd qS )r   )rO   )r   r)   )epsr   r   r!   :  s    z&rec.is_approx_zero.<locals>.<listcomp>r   )r   r   )r   rq   r   )rq   r   is_approx_zero8  s    zrec.is_approx_zeroc             C   s   | j dkst| j\}}}}td|| ||   d d|| ||   d|| ||   d|| ||   d|| ||   d d|| ||   d|| ||   d|| ||   d|| ||   d f	S )N))r      )rs   r   r   r   )r   r   r   r0   )r   q0q1q2q3r   r   r   %unit_quaternion_as_r3_rotation_matrix<  s    ::z)rec.unit_quaternion_as_r3_rotation_matrixFc          	   C   s   | j dkrtd| j\	}}}}}}}	}
}|dkrt|}|rJtj| }t| t| |t| }t| t| |t| }nT|dkrtjd }t||}d}n0|dkrtj d }t| |}d}ntd|rd	| tj d	| tj d	| tj fS |||fS d
S )ab  
    Get the rotation angles around the axis x,y,z for rotation r
    Such that r = Rx*Ry*Rz
    Those angles are the Tait-Bryan angles form of Euler angles

    Note that typically there are two solutions, and this function will return
    only one. In the case that cos(beta) == 0 there are infinite number of
    solutions, the function returns the one where gamma = 0

    Args:
      deg : When False use radians, when True use degrees
      alternate_solution: return the alternate solution for the angles

    Returns:
      angles: containing rotation angles in the form
        (rotx, roty, rotz)
    )rf   rf   zNot a 3x3 matrix.)r   r   r   r   ry   zCan't calculate rotation angles   N)	r   r-   r   rQ   asinpiatan2cosArithmeticError)r   degZalternate_solutionZRxxZRxyZRxzZRyxZRyyZRyzZRzxZRzyZRzzbetaalphagammar   r   r   "r3_rotation_matrix_as_x_y_z_anglesD  s.    
 

"$
z&rec.r3_rotation_matrix_as_x_y_z_anglesc          	   C   s  | j dkrtd| j\	}}}}}}}}}	|| |	 }
|
dkrd|
 d }|| }|d9 }|| | }|| | }|| | }nf||kr||	krd}qd}n||	krd}nd}d}d}|dkr d| | |	 }||k rt||d }|| }|d9 }|| | }|| | }|| | }n|dkrd| | |	 }||k rLt||d }|| }|d9 }|| | }|| | }|| | }n^d|	 | | }||k rt||d }|| }|d9 }|| | }|| | }|| | }t||||fS )	N)rf   rf   zNot a 3x3 matrix.g      ?r   r   r   g?zNot a r3_rotation matrix.)r   r-   r   r,   )r   Zm00Zm01Zm02Zm10Zm11Zm12Zm20Zm21Zm22r^   wdr)   yzZmxZinvalid_cutoffZinvalid_messageZx_sqZy_sqZz_sqr   r   r   %r3_rotation_matrix_as_unit_quaternions  sd    
   
 

 
 z)rec.r3_rotation_matrix_as_unit_quaternionc       
      C   s   | j dkst|j dkst| j\}}}}|j\}}}}	t|| ||  ||  ||	  || ||  ||	  ||  || ||	  ||  ||  ||	 ||  ||  ||  fS )N))r   rs   )rs   r   )r   r   r   r,   )
r   r&   rt   ru   rv   rw   Zo0Zo1Zo2Zo3r   r   r   unit_quaternion_product  s    zrec.unit_quaternion_productc             C   s2   | j dkst| j\}}}}t|| | | fS )N))r   rs   )rs   r   )r   r   r   r,   )r   rt   ru   rv   rw   r   r   r   quaternion_inverse  s    zrec.quaternion_inversec       	      C   s   | j dkst| j\}}}}|dkr(d}|dk r4d}dt| }|rT|dtj 9 }t|||f}| }|dkrz|| }||fS )N))r   rs   )rs   r   g      ?g      g       @g     f@r   )r   r   r   rQ   acosr|   r,   length)	r   r   rt   ru   rv   rw   Zangle_alphaaxisZaxis_lengthr   r   r   !unit_quaternion_as_axis_and_angle  s       z%rec.unit_quaternion_as_axis_and_anglec       	      C   s   | j dkst|r |tjd 9 }|dtj  s6tdS |d }t|t| }}|  j\}}}t||| || || fS )N))rf   r   )r   rf   rz   r   )r   r   r   r   g      ?)	r   r   rQ   r|   r,   r~   sinrc   r   )	r   angler   hcr6   urd   r   r   r   r   !axis_and_angle_as_unit_quaternion  s     z%rec.axis_and_angle_as_unit_quaternionc             C   s   | j ||d}| S )N)r   r   )r   rx   )r   r   r   uqr   r   r   $axis_and_angle_as_r3_rotation_matrix  s    z(rec.axis_and_angle_as_r3_rotation_matrixc             C   s   | j dkstd}|r.|tjd 9 }dtj }|  }tdd}||}t|j}t	|t
| }	}
|r|| |	 ||	  ||
   S || |
 ||
  ||	   S d S )N))rf   r   )r   rf   g      ?rz   g     f@rf   )r   )r   r   rQ   r|   rc   rh   outer_productcross_product_matrixr   r~   r   )r   r   r   Zsecond_orderZ	prefactorZ	unit_axisZI3OPZCPr   r6   r   r   r   )axis_and_angle_as_r3_derivative_wrt_angle  s      



z-rec.axis_and_angle_as_r3_derivative_wrt_anglec             C   sB   | j dkst|j dkst||  j||d}t|| ||   fS )N))rf   r   )r   rf   )r   r   )r   r   r   rt)r   pointr   r   rS   r   r   r   #rt_for_rotation_around_axis_through  s
    
z'rec.rt_for_rotation_around_axis_throughc             C   s   | j dkst| j\}}}t|t|t|  }}}||krV||krVt| |dfS ||krv||krvt| d|fS td| |fS )N))rf   r   )r   rf   r   )r   r   r   rO   r,   )r   r)   r   r   r$   r%   r   r   r   r   ortho  s    z	rec.orthoc             C   s~   | j dkst|j | j kst|r0|tjd 9 }| }| }t|t| }}|| ||| d|   |||  S )N))rf   r   )r   rf   rz   r   )	r   r   rQ   r|   rc   r~   r   re   rg   )r   r   r   r   r   r)   r   r6   r   r   r   rotate_around_origin  s     zrec.rotate_around_originc             C   sP   | j dkst|r |tjd 9 }t|t| }}t|| ||f}||  S )N))r   r   rz   )r   r   rQ   r|   r~   r   r0   )r   r   r   r   r6   Zrotmatr   r   r   	rotate_2d  s     zrec.rotate_2dc             C   s(   dd l }|jdtdd | j|||dS )Nr   zyThe .rotate() method has been renamed to .rotate_around_origin() for clarity. Please update the code calling this method.r   )messagecategory
stacklevel)r   r   r   )warningswarnDeprecationWarningr   )r   r   r   r   r   r   r   r   rotate  s    z
rec.rotate绽|=c          
   C   s   | j dkst| j\}}}|| ||  }t|||  d |krJtdt|}||k rt|dkrltdS tdS |}| }	|| }
|	| }d| }t||
|
 |  |
| | |	|
| | ||| |  | |	 ||f	S )N))rf   r   )r   rf   r   zself is not a normal vector.r   )	r   r   r   r   r   r   r   r   r   )	r   r   r   r   ry   r   r   r   ry   )r   r   r   rO   r-   rQ   ra   r0   )r   Zsin_angle_is_zero_thresholdZis_normal_vector_thresholdr)   r   r   Zxxyyr6   usZvsr   rd   ocr   r   r   vector_to_001_rotation  s     
zrec.vector_to_001_rotationc             C   s   |d kr| }| j d dks,| j d dks,t|j d dksL|j d dksLtg }x,| jD ]"}x|jD ]}|||  qdW qXW t|t| jt|jfS )Nr   r   )r   r   r   r/   r   r   )r   r&   r4   r$   r%   r   r   r   r   $  s       zrec.outer_productc             C   sP   |   }|dkr|S |  }|dkr(|S || }|dkr<|S | |t| S )Nr   )r_   re   rQ   ra   )r   r&   value_if_undefinedZself_norm_sqZother_norm_sqr   r   r   r   	cos_angle.  s       zrec.cos_anglec             C   sD   | j |d}|d kr|S ttdtd|}|r@|dtj 9 }|S )N)r&   ry   r   rz   )r   rQ   r   rY   rX   r|   )r   r&   r   r   r   r4   r   r   r   r   7  s      z	rec.angleư>c             C   s   | j |dst|  d d }|dk rNt|dkrNtdt| dk rNd}n,|dkrzt|dkrztdt| dk rzd}t|d tj S )	zB
    Assuming it is a rotation matrix, tr(m) = 1+2*cos(alpha)
    )rl   g      ?r   r   r   gư>g      g     f@)rm   r   r^   rO   rQ   r   r|   )r   rq   argr   r   r   rotation_angle>  s    ( ( zrec.rotation_anglec             C   sN   | j |d}|d kr|S |dk r(|d9 }ttd|}|rJ|dtj 9 }|S )N)r&   r   ry   r   rz   )r   rQ   r   rX   r|   )r   r&   r   r   r   r4   r   r   r   accute_angleH  s       zrec.accute_anglec             C   s   | j d | j d kS )Nr   r   )r   )r   r   r   r   	is_squareP  s    zrec.is_squarec             C   s  |   st| j}| jd }|dkr,|d S |dkrT|d |d  |d |d   S |dkr|d |d |d  |d |d    |d |d |d  |d |d	     |d |d |d  |d |d	     S t }|d k	r||}||| j | S t	| d
S )Nr   r   r   rf   rs               )m)
r   r   r   r   r   doubleresizegridZmatrix_determinant_via_ludeterminant_via_lu)r   r   r   r   r   r   r   rk   S  s    
 x

zrec.determinantc             C   s  | j }|dkrtd|dS |dkr.td|dS | j}|dkrdt|d |d  |d	  |d
 f|dS |dkrt|d |d  |d |d   |d  |d  |d	 |d   |d |d  |d	 |d   |d  |d  |d |d   |d
 |d  |d	 |d   |d
  |d  |d	 |d   |d |d  |d |d   |d
  |d  |d |d   |d
 |d  |d |d   f	|dS |  sttdd S )N)r   r   r   )r   r   )r   r   )r   )r   r   rf   r   r   r   )rf   rf   rs   r   r   r   r   zNot implemented.)r   r   r   r   r   r-   )r   r   r   r   r   r   co_factor_matrix_transposedf  s*    (
    (zrec.co_factor_matrix_transposedc             C   s   |   st| j}|d dk r>|  }|dks2t|  | S t }|d k	r||| j}||	| |
  t||dS t }|d k	r|| j}||_||j|}t||dS t| dS )Nr   rs   )r   r   )r   )r   r   r   rk   r   r   r   r   r   r   Zmatrix_inversion_in_placer   r   ZasarrayshapeZravelZlinalginvinverse_via_lu)r   r   rk   r   r   r   r   r   r   inverse}  s&    zrec.inversec             C   sV   g }x:t |  D ]*}x$t |  D ]}|| || q$W qW t||  |  fS )N)r   r   r   r/   r   )r   r   r7   r#   r   r   r   	transpose  s
    zrec.transposec
             C   s  |   }
|  }|	}|	}|r<||d 7 }|dt|d  7 }||7 }|dkrxt|
D ]}||7 }xtt|D ]h}|d kr|t| ||7 }n||| || 7 }|d |kr|d7 }qn|d |
kst|dkrn||7 }qnW |d |
krX||7 }|r|d7 }||7 }|d7 }qXW || S )N= r   r   z, 
)r   r   r   r   r.   )r   
outer_openouter_close
inner_openinner_closeinner_close_followlabelone_row_per_lineformatprefixnrncr6   indentr@   rA   r   r   r   _mathematica_or_matlab_form  s4    
 
 zrec._mathematica_or_matlab_form c             C   s8   | j ddddd||||d	}|r(|d7 }|dd}|S )N{},)	r   r   r   r   r   r   r   r   r   z//MatrixFormr    z*^)r   replace)r   r   r   r   r   Zmatrix_formr4   r   r   r   mathematica_form  s     zrec.mathematica_formc             C   s   | j ddddd||||d	S )N[]r   ;)	r   r   r   r   r   r   r   r   r   )r   )r   r   r   r   r   r   r   r   matlab_form  s    zrec.matlab_formc             C   sP   | j \}}| j}t|dkr&t|}ndt|d t|d f }d|||f S )Nrf   z(%s, ..., %s)r   ry   zmatrix.rec(elems=%s, n=(%d,%d)))r   r   r   r.   )r   Zn0Zn1r    r   r   r   __repr__  s    

zrec.__repr__c             C   s   | j ddS )NT)r   )r   )r   r   r   r   __str__  s    zrec.__str__c             C   sH   g }| j \}}x4t|D ](}|t| j|| |d |   qW |S )Nr   )r   r   r/   r+   r   )r   r4   r   r   r@   r   r   r   as_list_of_lists  s
    
(zrec.as_list_of_listsc             C   s`   | j dkst| j}|d |d |d |d |d  d |d |d	  d |d
 |d  d fS )N)rf   rf   r   rs   r   r   rf   g       @r   r   r   r   )r   r   r   )r   r   r   r   r   as_sym_mat3  s    zrec.as_sym_mat3c             C   s   | j dkst| jS )N)rf   rf   )r   r   r   )r   r   r   r   as_mat3  s    zrec.as_mat3c             C   s4   t  }|d k	st|| j}||| j |S )N)r   r   r   r   rM   r   r   )r   r   r4   r   r   r   as_flex_double_matrix  s
    zrec.as_flex_double_matrixc             C   s4   t  }|d k	st|| j}||| j |S )N)r   r   rH   r   rM   r   r   )r   r   r4   r   r   r   as_flex_int_matrix  s
    zrec.as_flex_int_matrixr   r   r   r   c       	      C   s   d|d   kr| j d ks$n td|d   krB| j d ksHn tt|d |d |d }t|d |d |d }g }x*|D ]"}x|D ]}|| || qW qW t|t|t|fS )Nr   r   )r   r   r   r/   r   r   )	r   stopstartstepZi_rowsZi_columsr4   r@   rA   r   r   r   extract_block  s    $$

zrec.extract_blockc             C   s|   | |krdS |d krdS t t|tr2| j|jkS xDt|  D ]4}x.t|  D ]}| |||||f krRdS qRW q@W dS )NTF)
issubclasstyper   r   r   r   r   )r   r&   r@   rA   r   r   r   __eq__  s       z
rec.__eq__c             C   s   |  | S )N)r   )r   r&   r   r   r   __ne__  s    z
rec.__ne__c             C   s  | j \}}d}xlt|D ]`}d}xNt|D ]B}| ||}t|tsFt|dkrZ|j d }q*|j d |ks*tq*W ||7 }qW d}x^t|D ]R}d}	x@t|D ]4}| ||}|dkr|j d }	q|j d |	kstqW ||	7 }qW dg||  }
d}xt|D ]}d}xt|D ]v}| ||}|j \}}	d}xNt|D ]B}|| | | }x*t|	D ]}|| |
|| < |d7 }qRW q4W ||	7 }qW ||kst||7 }qW ||kstt|
||fdS )Nr   r   )r   r   )r   r   r   r   r   )r   r   r   Z	result_nrr@   Zpart_nrrA   partZ	result_ncZpart_ncZresult_elemsZ	result_irZ	result_icZi_partZpart_irZi_resultZpart_icr   r   r   resolve_partitions  sL    

 
 

zrec.resolve_partitions)N)T)r   )N)rj   )FF)F)F)F)FF)F)F)F)F)r   r   )N)N)NF)r   )NF)r   FNr   F)r   FNr   )r   r   )X__name__
__module____qualname____doc__r   r   r   r   r   r"   r'   r(   r8   r9   r;   r<   r=   r>   r?   rB   rC   rD   rF   rJ   rL   rN   rP   rW   rX   rY   rZ   r[   r\   r]   r^   r_   rK   rb   	length_sqr   rc   re   rg   ri   rm   rn   ro   rp   rr   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   $   s   
!

	



/4






	

 



	



"    
   
		

r   c               @   s   e Zd ZeZdd ZdS )mutable_recc             C   s   || j |< d S )N)r   )r   r#   r)   r   r   r   __setitem__F  s    zmutable_rec.__setitem__N)r   r   r   r+   r   r   r   r   r   r   r   C  s   r   c                   s   e Zd Z fddZ  ZS )	row_mixinc                s   t t| |dt|f d S )Nr   )superr   r   r   )r   r   )	__class__r   r   r   K  s    zrow_mixin.__init__)r   r   r   r   __classcell__r   r   )r   r   r   I  s   r   c               @   s   e Zd ZdS )rowN)r   r   r   r   r   r   r   r   N  s    r   c               @   s   e Zd ZdS )mutable_rowN)r   r   r   r   r   r   r   r   O  s    r   c                   s,   e Zd Z fddZdd ZeeZ  ZS )	col_mixinc                s   t t| |t|df d S )Nr   )r   r   r   r   )r   r   )r   r   r   r   S  s    zcol_mixin.__init__c                s$   t j|  fddt|D S )Nc                s   g | ]} qS r   r   )r   r#   )r$   r%   uniformr   r   r!   X  s    z$col_mixin.random.<locals>.<listcomp>)randomr   r   )clsr   r$   r%   r   )r$   r%   r   r   r   V  s    zcol_mixin.random)r   r   r   r   r   classmethodr   r   r   )r   r   r   Q  s   r   c               @   s   e Zd ZdZdS )r,   a8  
    Class type built on top of rec and col_mixin, allows for single-dimensional
    vectors.  This is especially convenient when working with 3D coordinate
    data in Python.

    Examples
    --------
    >>> from scitbx.matrix import col
    >>> vector = col([3, 0, 4])
    >>> print abs(vector)
    5.0
    N)r   r   r   r   r   r   r   r   r,   [  s   r,   c               @   s   e Zd ZdS )mutable_colN)r   r   r   r   r   r   r   r  j  s    r  c               @   s   e Zd Zdd ZdS )r0   c             C   s>   t |}t|d d }||| ks(tt| |||f d S )Ng      ?)r   rH   r   r   r   )r   r   lr   r   r   r   r   n  s    zsqr.__init__N)r   r   r   r   r   r   r   r   r0   l  s   r0   c               @   s   e Zd Zdd ZdS )diagc             C   sZ   t |}dd t|| D }x$t|D ]}|| |||d  < q(W t| |||f d S )Nc             S   s   g | ]}d qS )r   r   )r   r#   r   r   r   r!   x  s    z!diag.__init__.<locals>.<listcomp>r   )r   r   r   r   )r   Z
diag_elemsr   r   r#   r   r   r   r   v  s
    zdiag.__init__N)r   r   r   r   r   r   r   r   r  t  s   r  c                   s   e Zd Z fddZ  ZS )rh   c                s   t t| d|  d S )N)r   )r   rh   r   )r   r   )r   r   r   r     s    zidentity.__init__)r   r   r   r   r   r   r   )r   r   rh   }  s   rh   c                   s   e Zd Z fddZ  ZS )	inversionc                s   t t| d|  d S )N)ry   )r   r  r   )r   r   )r   r   r   r     s    zinversion.__init__)r   r   r   r   r   r   r   )r   r   r    s   r  c               @   s   e Zd ZdddZdS )symNc             C   sl   |d kst dt|dks t |}t| |d |d |d |d |d |d |d |d |d f	d	 d S )
NzNot implemented.r   r   rf   rs   r   r   r   )rf   rf   )r   r   r   r   )r   r   sym_mat3r   r   r   r   r     s    zsym.__init__)NN)r   r   r   r   r   r   r   r   r    s   r  c             C   sR   |rt t }}n
tt }}t| tr2|d|  dS | \}}|d||  ||fdS )N)r   )r   )r   r   )r  r   r,   r   r   rH   )r   mutableZcol_tZrec_tr   r   r   r   r   zeros  s    

r	  c             C   s   t | ddS )NT)r  )r	  )r   r   r   r   mutable_zeros  s    r
  c             C   s*   t | }t|}x|D ]}||7 }qW |S )z+ The sum of the given sequence of matrices )iternext)iterablesequencer4   r   r   r   r   r\     s
    
r\   c          
   C   s*   | \}}}t d| ||d| | |df	S )zMatrix associated with vector cross product:
  a.cross(b) is equivalent to cross_product_matrix(a) * b
Useful for simplification of equations. Used frequently in
robotics and classical mechanics literature.
r   )r0   )ZvvvZv0Zv1Zv2r   r   r   r     s
    
r   c             C   s   t | t |kstd }xZt| |D ]L\}}|dkrB|dkrpd S q$|dkrNd S || }|d krd|}q$||kr$d S q$W |d krdS |S )Nr   )r   r   r   )vector_1vector_2r4   e1e2r   r   r   r   &linearly_dependent_pair_scaling_factor  s       r  c             C   s   t | dkst| d | d  }| d | d  }| d | d  }||}| }||}| }|dkst|dkrxd S tdtd|||| d  }	t|	}
|||dk r|
d	9 }
|r|
d
tj	 9 }
|
S )Nrs   r   r   r   rf   g      g      ?g      ?ry   rz   )
r   r   rg   r   rY   rX   re   rQ   r   r|   )sitesr   Zd_01Zd_21Zd_23Zn_0121Zn_0121_normZn_2123Zn_2123_normr   r4   r   r   r   _dihedral_angle  s$    


 r  c             C   s2   t  }|d krt| |dS ddlm} || |dS )N)r  r   r   )dihedral_angle)r   r  Zscitbx.mathr  )r  r   r   r  r   r   r   r    s
    r  c             C   s8   t | }t || }|j||d}|t ||  | jS )zAbout 6 times slower than the implementation below.
     Interestingly, a C++ implementation is still 2 times slower than
     the implementation below, due to the tuple-vec3 conversion overhead.
  )r   r   )r,   r   r   )axis_point_1axis_point_2r   r   r   pivotr   rS   r   r   r   __rotate_point_around_axis  s    
r  c             C   s4   ||   ||  }|\}}}||  }||||fS )N)rg   re   )point_1point_2point_3r   r$   r%   r   r   r   r   r   plane_equation  s    
r  c       
      C   s   t |dksttt|d t|d t|d d\}}}}| \}}}t|d |d  |d  }	|	dkrrdS t|| ||  ||  | |	 S )z
  http://mathworld.wolfram.com/Point-PlaneDistance.html
  Given three points describing a plane and a fourth point outside the plane,
  return the distance from the fourth point to the plane.
  rf   r   r   r   )r  r  r  N)r   r   r  r,   rQ   ra   rO   )
xyzpointsr$   r%   r   r   r)   r   r   Zdenr   r   r   distance_from_plane  s    


 r!  c             C   sJ   t | dkstx4| dd  D ]$}t|| d d d}||krdS qW dS )Nrf   )r  r   FT)r   r   r!  )r   	tolerancer   r   r   r   r   all_in_plane  s     r#  c       
      C   s`   ddl m} || g}||g}||g}|| }|| }||||| |  }	|	S )z'
  Slow version based on flex arrays
  r   )r   )r	   r   vec3_doublere   )
r  r  r   r   r$   r%   pabapprojr   r   r   __project_point_on_axis  s    r)  c             C   s   | \}}}|\}}}|\}	}
}|| || ||   }}}|	| |
| ||   }}}|| ||  ||  }|| ||  ||  }|| }|||  |||  |||  f}|S )a  
  Project a 3D coordinate on a given arbitrary axis.

  :param axis_point_1: tuple representing 3D coordinate at one end of the axis
  :param axis_point_2: tuple representing 3D coordinate at other end of the axis
  :param point: tuple representing 3D coordinate of starting point to rotate
  :param deg: Python boolean (default=False), specifies whether the angle is
    in degrees
  :returns: Python tuple (len=3) of rotated point
  r   )r  r  r   ZaxZayazZbxZbyZbzZpxpyZpzZabxZabyZabzZapxZapyZapzZ	ap_dot_abZ	ab_dot_abbracketsr(  r   r   r   project_point_on_axis  s    


"r-  c       +      C   s  |r|t jd 9 }| \}}}|\}}	}
|\}}}|| |	| |
|   }}}|d }|d }|d }|| | }|d }t |}t || }d| | }|| | }|| | }|| | }|| || ||   }}}|| | }|||  } |||  }!|||  }"|| | }#|||  }$|||  }%|||  }&|| | }'|| ||   ||!  | }(||" ||#  ||$  | })||% ||&  ||'  | }*|(|)|*fS )a  
  Rotate a 3D coordinate about a given arbitrary axis by the specified angle.

  :param axis_point_1: tuple representing 3D coordinate at one end of the axis
  :param axis_point_2: tuple representing 3D coordinate at other end of the axis
  :param point: tuple representing 3D coordinate of starting point to rotate
  :param angle: rotation angle (defaults to radians)
  :param deg: Python boolean (default=False), specifies whether the angle is
    in degrees
  :returns: Python tuple (len=3) of rotated point
  g     f@r   g      ?r   )rQ   r|   r~   r   )+r  r  r   r   r   ZxaZyaZzaxbZybZzbr)   r   r   ZxlZylZzlZxlsqZylsqZzlsqZdlsqZdlcaZdsaZocaZxlyloZxlzloZylzloZxmaZymaZzmaZm1Zm2Zm3Zm4Zm5Zm6Zm7Zm8Zm9Zx_newZy_newZz_newr   r   r   rotate_point_around_axis.  s>     



r0  c               @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )r   a  
  Object for representing associated rotation and translation matrices.  These
  will usually be a 3x3 matrix and a 1x3 matrix, internally represented by
  objects of type :py:class:`scitbx.matrix.sqr` and
  :py:class:`scitbx.matrix.col`.  Transformations may be applied to
  :py:mod:`scitbx.array_family.flex` arrays using the overloaded
  multiplication operator.

  Examples
  --------
  >>> from scitbx.matrix import rt
  >>> symop = rt((-1,0,0,0,1,0,0,0,-1), (0,0.5,0)) # P21 symop
  >>> from scitbx.array_family import flex
  >>> sites_frac = flex.vec3_double([(0.1,0.1,0.1), (0.1,0.2,0.3)])
  >>> sites_symm = symop * sites_frac
  >>> print list(sites_symm)
  [(-0.1, 0.6, -0.1), (-0.1, 0.7, -0.3)]
  c             C   sx   t |d dr t|d j| _nt|d | _t |d drNt|d j| _nt|d | _| j | j ksttd S )Nr   r   r   )r*   r0   r   rS   r,   tr   r   )r   Z	tuple_r_tr   r   r   r   r  s    zrt.__init__c             C   s>   t |tr&t| j|j | j|j fS t| j| j| fS d S )N)r   r   rS   r1  )r   r&   r   r   r   r'   }  s    
z
rt.__add__c             C   s>   t |tr&t| j|j | j|j fS t| j| j| fS d S )N)r   r   rS   r1  )r   r&   r   r   r   r(     s    
z
rt.__sub__c             C   sb  t |tr,t| j|j | j|j | j fS t |tr|j| jjkrXt| j| | jfS |j| jjkrv| j| | j S tdt| t|f t| jj	}t |t
tfr
t||kr| jt| | j S t||| krt| jt| | jfS tdt| t|f |dkrFt }|d k	rFt ||jrF| jj	| | jj	 S tdt| t|f d S )Nz@cannot multiply %s by %s: incompatible number of rows or columnsz9cannot multiply %s by %s: incompatible number of elementsrf   zcannot multiply %s by %s)r   r   rS   r1  r   r   
ValueErrorreprr   r   r+   r   r,   r0   r   r$  	TypeError)r   r&   r   r   r   r   r   r8     s0    
"

z
rt.__mul__c             C   s   | j  }t||| j  fS )N)rS   r   r   r1  )r   r_invr   r   r   r     s    
z
rt.inversec             C   s   | j  }t||| j  fS )N)rS   r   r   r1  )r   r5  r   r   r   inverse_assuming_orthogonal_r  s    
z rt.inverse_assuming_orthogonal_rc             C   s   t | j | j fS )N)r   rS   rF   r1  )r   r   r   r   rF     s    zrt.as_floatc             C   s   | j  | j  kst| j  }g }xBt|D ]6}|| j j|| |d |   || j|  q0W |dg|  |d t	||d |d fS )Nr   r   )
rS   r   r   r   r   extendr   r/   r1  r   )r   r   r4   Zi_rowr   r   r   as_augmented_matrix  s    
"
zrt.as_augmented_matrixN)r   r   r   r   r   r'   r(   r8   r   r6  rF   r8  r   r   r   r   r   ^  s   r   c             C   s   dd | D S )Nc             S   s   g | ]}t |qS r   )r,   )r   elemr   r   r   r!     s    zcol_list.<locals>.<listcomp>r   )seqr   r   r   col_list      r;  c             C   s   dd | D S )Nc             S   s   g | ]}t |qS r   )r   )r   r9  r   r   r   r!     s    zrow_list.<locals>.<listcomp>r   )r:  r   r   r   row_list  r<  r=  Tc             C   s  d}t | || kstdg| }dg|d  }xtt|D ]h}d}x:t|D ].}| || |  }	|	dk rn|	 }	|	|krL|	}qLW |dkr|rt|d S d| ||< q:W d}
x
t|D ]}xft|D ]Z}| || |  }x4t|D ](}|| || |  | || |   8 }qW || || | < qW d}xt||D ]}| || |  }x6t|D ]*}|| || |  | || |   8 }qRW || || | < |dk r| }|| | }	|	|kr4|	}|}
q4W ||
kr2xFt|D ]:}|
| | || |  }}| | | |  | |< | |< qW ||  d7  < || ||
< |
||< | || |  dkrb|r^t|d S |d |k rd| || |   }	x0t|d |D ]}| || |   |	9  < qW qW |S )Nz*lu_decomposition_in_place: singular matrixg        r   r   g      ?)r   r   r   r-   )r$   r   raise_if_singularZis_singular_messageZvvpivot_indicesr#   Zbigr7   ZdumZimaxr\   r5   r:   Zjkr   r   r   lu_decomposition_in_place  sh    
   ( *
 


 "r@  c       
      C   s  t | || kst|}xt|D ]}|| }||krF|rBtddS || }|| ||< ||krx8t||D ] }	|| || |	  ||	  8 }qnW n|r|}|||< q"W xlt|d ddD ]X}|| }x2t|d |D ] }	|| || |	  ||	  8 }qW || || |   ||< qW dS )Nz3lu_back_substitution: pivot_indices[i] out of rangeFr   ry   T)r   r   r   r-   )
r$   r   r?  r%   r>  iir#   Zpivot_indices_ir\   r7   r   r   r   lu_back_substitution  s.     "  rB  c             C   s   |   st| jd }|dkr&tg S t| j}t||d}dg||  }xXt|D ]L}dg| }d||< t||||d x$t|D ]}|| ||| | < qW qTW t|S )Nr   )r$   r   g        g      ?)r$   r   r?  r%   )	r   r   r   r0   r+   r   r@  r   rB  )r   r   r$   r?  rS   r7   r%   r#   r   r   r   r     s    
 

r   c             C   s   |   st| jd }|dkr"dS t| j}t||dd}|d krFdS d}x$t|D ]}|||| |  9 }qTW |d d r| }|S )Nr   r   F)r$   r   r>  ry   r   )r   r   r   r+   r   r@  r   )r   r   r$   r?  r4   r#   r   r   r   r     s    
 
r   c             C   s   | j dkstt|  dks"t|  |  }ddlm} || }t	|
 }t	| }t|d |d |d gdd}t|d	 |d
 |d gdd}t|d |d |d gdd}dt|d  |  | dt|d  |  |  dt|d  |  |  }	| |	 }
|
S )a  
  Return nearest orthonormal matrix, R, of M from
  R := M*(M^t * M)^{-1/2}  where ^t means transpose of matrix or vector
  e1, e2, e3, lambda1, lambda2, lambda3  are eigenvectors and respective eigenvalues of (M^t * M )
  (M^t * M )^{-1/2} = 1/sqrt(lambda1) * e1*e1^t + 1/sqrt(lambda2) * e2*e2^t + 1/sqrt(lambda3) * e3*e3^t
  http://people.csail.mit.edu/bkph/articles/Nearest_Orthonormal_Matrix.pdf
  )rf   rf   g:0yE>r   )eigensystemr   r   )r   rf   )r   rf   rs   r   r   r   r   g      ?)r   r   rO   rk   r   Zscitbx.linalgrC  Zreal_symmetricr   r+   valuesZvectorsr   rQ   ra   )ZMmxZMtMmxrC  esZevaluesZevectorsZevec1Zevec2Zevec3ZMtMinvsqrtmxZRmxr   r   r   find_nearest_orthonormal_matrix"  s    : rF  c        J         s   yddl m}  W n, tk
r<   td d } dd  t}Y nX | j | j}tdd}|jdksbt	|j
dkspt	td	d}|jd
kst	|j
dkst	tdd}|jdkst	|j
dkst	tdd}|jdkst	|j
dkst	tdd}|jdkst	|j
dks
t	tdd}|j
dks$t	td}d	|d	< t|dksFt	x<dD ]4}td|}| dkslt	| dksLt	qLW tttd	dd}t|dkst	|d	 dkst	|d  dkst	d|  dkst	x4dddggD ]$}|| j
|td j
kst	qW tttd	dd}||d ksFt	td! d"ks\t	|| }t|d#f}|  d$kst	|j d%kst	|j d&kst	|td' }|j d%kst	|j d(kst	|td# }	|	j d%ks t	|	j d)kst	||	 }|j d*ks0t	|j d+ksDt	|	| }	|	j d,ks`t	|	j d-kstt	|	 }|j d.kst	|j d/kst	|	 }| d0kst	|jd
d1 d2kst	|jd3d1 d4kst	|jd5d1 d,kst	|jd6d1 | ks*t	|jd6d3d7 d8ksFt	|jd
d6d3d9 d:ksdt	|jdd;dd9 d<kst	x|tdD ]p}
xhtdD ]\}tg |
df}tg d|f}|| }|j
tdg|
|  kst	|j|
|fkst	qW qW ttd	d=}
ttd	d>}ttd?d@}ttd>d}t|
|ft||f }|j dAksdt	|j dBksxt	|j }| dCkst	| }| dAkst	|j }| dDkst	| }| dBkst	td>g d>kst	tdddEdFg dGkst	tdddH}| }|jdks>t	td>g}| }| dIksbt	tdJ}| }|jd3kst	 |dKst	tdL}| d	kst	| }| dMkst	||  dNkst	||  dNkst	t|dOf}| }|j | kst	|| j dNks6t	|| j dNksNt	|j dPdQdRksjt	|| j dSkst	|| j dSkst	ttdTdUdVdWdXdYdZd[d\g	td]f} |j|j  d^st	| }|  } |j|js t	 |j|jst	td_d5dH}td`dadH}|| }|j|j| ksJt	|j|jks\t	|| }||j| |j ks~t	||j
 }|j|j| kst	|j|jkst	||j
 }||j| |j kst	y|td	g  W nL t!k
	r2 } z,t"|#db	st	t"|$dc	s"t	W d d }~X Y nX |y|d	g  W nL t!k
	r } z,t"|#db	snt	t"|$dd	st	W d d }~X Y nX |t% }|d k	rtde n8||&dfdgg }t'||j&	st	 |dhdig	st	yddjl(m)} W n tk

r   Y n(X  t|*dd>ddkf dl
s8t	 tdm+ j
dn
sRt	tdo, j
d#k
sjt	 tdp- dq
st	tdr. dk
st	tds/ dtk
st	tdr0 d	k
st	tds1 d	k
st	tds2 duk
st	tdv3 dwkst	tdx4 dFkst	t5d# dyks2t	 tdz6td{d d|sTt	 tdz7td{d}srt	 tdzj7td{d~ddst	 tdj7td{d~ddst	 tdzj8td{d~ddst	 tdj8td{d~ddst	td>d>dddddddddd	dd	ddg}| }  | ds:t	tdddddddddg	}|jddd~dddkspt	tg }| dkst	|jd~ddkst	td	g}| dkst	|jd~dddkst	tttd	dd}tttd	dd} |9|| | st	 |9|| | s8t	 |9 | | sTt	 |9|| | srt	 |9 | | st	td	ddg}t:d=d@g}|;|< d=d@gd@dgddggkst	|; < d	ddgdd>dgdddggks t	t=ttdd}|< ddd>gdd	dtgd>dtdggks<t	 |> ttdsXt	|? dksjt	|d k	r|@ }	|	A |jkst	 |	|ddst	xtdD ]}!tg d|!fd}"tB|"d|! kst	t"|"dkst	|" dkst	|"jd~ddkst	tg |!dfd}"tB|"d|! ks8t	t"|"dksJt	|" dks\t	|"jd~ddkst	qW tdgd
d}"tB|"dkst	t"|"dkst	|" dkst	|"jd~ddkst	td#}"tB|"dkst	t"|"dkst	|" dkst	|"jd~ddks&t	t:d}"tB|"dks@t	t"|"dksRt	|" dksdt	|"jd~ddkszt	tdd;}"tB|"dkst	t"|"dkst	|" dkst	|"jdd~dddkst	d}d}t||}t||}||kst	|d k	r0|C|}|D|E| ||ks0t	tFd>}x^td>D ]R}#xJtd>D ]>}$|#|$krn||#|$d	ksP|#|$kr||#|$dksPt	qPW qBW tGd>}x^td>D ]R}#xJtd>D ]>}$|#|$kr||#|$dks|#|$kr||#|$dkst	qW qW td}"|"d H d tdks&t	x0dD ](}"t|"}" |"|"I ds,t	q,W tdO}"td}dtJjK d }%|"L||%}&|+ }|"||"|  }'|&||&|  }( |'7|(|%st	td}"|"jLtdzdd~d}& |&dst	 |"j7|&d~dds
t	td}td}"|"jL|dd~d}& tM|"dăs>t	 tM|&dăsRt	 |"j7|&d~ddŃslt	 |&dƃs|t	tdjNddǍ}) |)dȃst	tFd}*|*O }+|+P \},}- |-Q|,|*st	|jNdd~dɍ}. |.dʃst	|.R } ||" |&st	 |jQdd~dɍ|s"t	td˃}/|/jStd̃dd~d΍}0 |0tdσ dЃsVt	tdуT j
d^ksnt	td҃T j
dkst	 tdԃ+ T dՃst	t:dz}t:d}|U|t:dуkst	tdփ}td׃} |U|tV|| st	tW}	 |	d	ddgdddgd؍ds t	 |	dddgd	ddgd؍dكsDt	|	tdd	d	gd	d	d	gd؍d ksjt	|	d	d	d	gtdd	d	gd؍d kst	|	tdddgtdddgd؍dkst	tXddgdۍ}x|D ]}t'|tst	qW  |ddgst	tYddgdۍ}x|D ]}t'|t:st	qW  |ddgs>t	dd݄ }	tg ddgdH}|	|dksht	tg dd	gdH}|	|dkst	tg d	dgdH}|	|dkst	xtg t:g gD ]v}t|gd	d	gdH}|	|dkst	t||gd	dgdH}|	|dkst	t||gdd	gdH}|	|dkst	qW xBtd	gt:d	ggD ]*}t|gd	d	gdH}|	|dksNt	qNW ttd	dgtdd>ggd	dgdH}|	|dkst	ttd	dgtdd>ggdd	gdH}|	|dkst	ttd	ddd>gtdtdddggd	dgdH}|	|dks&t	ttd	ddd>gtdtdddggdd	gdH}|	|dksdt	ttd	ddd>dtdgddtddgddgd	dgdH}|	|dkst	ttd	ddd>dtdgddtdddgddgdd	gdH}|	|dkst	ttd?dudddFddddg	tddddwd"ddddg	tdddddddddg	tddddddddd g	gddgdH}|Z jd~ddkst	ttd	ddd>dtdgddtdddd=d?duddgddtdFddddd@dddg	d5dtdwd"ddddddddddgd!dtdddgddtddddgddgddgdH}|Z jd~ddks@t	 fdd}1|1tg d	 |1tdgd |1td>gd> |1tdgd> d |1td	ddd>gd= |1tdgd d |1tdTdUdVdWdXdYdZd[d\g	d	 |1tdgd d |1tddd	d
dddddِdddddd	dgd tFdd}|[ sNt	|O }2 |2dȃsft	td}.td} |.R |st	|O }2 |2|.st	xtd=D ]}3tj\d>dd	d+ }4tj\d>dd	d+ }5|4R }6|5R }7|4]|5}8|8R }9 |9|6|7 st	|5]|4}:|:R }; |;|7|6 s<t	xT|4|6f|5|7f|8|9f|:|;fgD ]4\}.}|[ spt	|O }2 |2R |sZt	qZW qW td} |^ dst	|[ rt	td}< |<d tdst	td}=t"|= j
dkst	|d k	r6t"|=_  j
dks6t	t`tXdgd> ddd ksZt	tatXdgd> dd kszt	tXd d!d"d#g}>d$}? t`|>d~d|?st	 ta|>d~d|?st	| d k	rvdd%l mb}@ xNd&D ]D}A|@|>d |>d	 |>d dd~d'jc}B tdf |Btef |Bst	qW |@|>d |>d	 |>d d(jc}B tff |Bttgf |Bd svt	td#}Ctd)}Dtd*}Eth|C|D|Ed+\}}}}|E|D|C d  d }F ||Fd  ||Fd	   ||Fd   | dst	d,}G d-tid.dd/d0gd1s t	tiddddgd1}|d ksBt	tidddzdgd1} |d	sft	tj }H|Hd krtd2 n>tttdddH}|k }|l dd	dgdd>dtggkst	td	d|dd3dddd4d5g	}tm|}I |Ij
d6st	 |I d7 st	|I[ dk s&t	td	d|dd3d	ddd4d8g	}tm|}I |Ij
d9 sbt	 |I d: sxt	|I[  st	td; d S (<  Nr   )
test_utilsz0INFO: libtbx not available: some tests disabled.c             S   s   dS )NTr   )r$   r%   r   r   r   approx_equalF  r<  z exercise_1.<locals>.approx_equal)r   )r   r   r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   rf   )r   r   r   r   r   r   )r   r   r   )r   r   r   ))r   r   )r   r   )r   r   z{}z[]r   )rf   r   r   rf   z{{3, 6}, {9, 12}, {15, 18}}z {{-2, -4}, {-6, -8}, {-10, -12}})r   rJ  [   )rf   rs      )r   r   rf   z{{-1, -2}, {-3, -4}, {-5, -6}}z){{9, 12, 15}, {19, 26, 33}, {29, 40, 51}}z{{1}, {2}, {3}})rf   r   r   z{{4}, {7}, {9}}z{{3}, {5}, {6}}z+{{18, 24, 30}, {38, 52, 66}, {58, 80, 102}}z{{7}, {12}, {15}}z2{{-9, -12, -15}, {-19, -26, -33}, {-29, -40, -51}}z{{-4}, {-7}, {-9}}zD{{-9.0, -12.0, -15.0}, {-19.0, -26.0, -33.0}, {-29.0, -40.0, -51.0}}z{{-4.0}, {-7.0}, {-9.0}}zL{{-9, -12, -15, -4}, {-19, -26, -33, -7}, {-29, -40, -51, -9}, {0, 0, 0, 1}})r   z{{-9}})r   r   z{{-9, -12}, {-19, -26}})rf   rf   )rs   rs   )r   r   z{{-9, -15}, {-29, -51}})r   r   r   z{{-26, -7}, {0, 1}})rs   rf   z{{-19, -26, -33}, {0, 0, 0}}
   rs         z1{{90, 96, 102}, {216, 231, 246}, {342, 366, 390}}z{{33}, {79}, {125}}z1{{90, 216, 342}, {96, 231, 366}, {102, 246, 390}}z{{33, 79, 125}}i   ;   )r   r   z{{0.25}})r   r   rJ  	   )g      ?gʿg      ?gUUUUUU?)	r   r   rf   r   ry   rP     iz<{{7.0, -1.0, -3.0}, {12.0, -3.0, -5.0}, {33.0, -7.0, -14.0}}z3{{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}})r   rI  rf   z-0.0z0.0z{{0.0}, {-3.0}, {-5.0}}z{{0.0}, {0.0}, {0.0}}g=b?gw;?gLh:g3i?g{gb;NglCD:g~/2Ylg-ǴͿ)g(\?g(\gQ?)	r   r   r   r   r   r   r   r   r   )	r   rS  rf   rI  r   rR  rJ  r   r   )r   irf   )rf   r   zcannot multiply z(: incompatible number of rows or columnsz!: incompatible number of elementsz-INFO: scitbx.array_family.flex not available.)ry   r   rf   )r   rJ  rs   )i  i'  i  )iM  i"  i  )rG   g      ?)g      ?r   g      ?)rI  rf   i)g$I$Iҿg۶m۶m?g۶m۶m)ry   r   rJ  )g333333gffffff@g333333@)g333333?gɿg?)r   rf   rs   )rs   r   rf   r      )r   rf   rs      )	r   r   rf   rs   r   r   r   r   rR  z!{{1, 0, 0}, {0, 2, 0}, {0, 0, 3}})r   r   r   )r   r   r   g      ?gRDT!?T)r   -   )ry   r   r      ry   rS  igh og,C?gZd;ǿgDJ?g"~?gܵ|g&S:g_vOgh oݿZrotationz%.6gz  )r   r   r   r   zv  rotation={{-0.9533, 0.2413, -0.1815},
            {0.2702, 0.414, -0.8692},
            {-0.1346, -0.8777, -0.4599}})r   z{{1}}z&$)r   r   z&${{1}}rT  )rf   r   (      <   rR  )r  )	r   rf   rs   rf   r   r   rs   r   r   g-q=)rq   zmatrix.rec(elems=(), n=(0,%d))zmatrix.rec(elems=(), n=(%d,0))zmatrix.rec(elems=(2,), n=(1,1))z{{2}}z[2]z$matrix.rec(elems=(1, 2, 3), n=(3,1))z{{1},
 {2},
 {3}}z	[1; 2; 3]z[1;
 2;
 3])rf   r   r   z$matrix.rec(elems=(3, 2, 1), n=(1,3))z{{3, 2, 1}}z	[3, 2, 1])r   r   rf   rs   r   r   r   r   rR  ry   rI  rJ  z'matrix.rec(elems=(1, ..., -3), n=(4,3))z2{{1, 2, 3},
 {4, 5, 6},
 {7, 8, 9},
 {-1, -2, -3}}z'[1, 2, 3; 4, 5, 6; 7, 8, 9; -1, -2, -3]r   @)r   r   r   z6@m=[1, 2, 3;
@   4, 5, 6;
@   7, 8, 9;
@   -1, -2, -3])r   r   rf   rs   r   r   )g)\(?gGz?gjt?r   )g      ?g      ?g      ?))r   r   r   )r   rI  r   )rI  r   r   )r   r   rI  )rI  rs   r   K   )r   r   r   )g        g}?gHG?)g1D?g ׸?g A~)go ?gjݿg޿%   gڨ.1<?gd.V'9@)g=tP?gbJ*gdL)r   )r   r   r   r   )r   r   )g#7ܪX?gy?g?n|b?g[ѿ)gI+G=@g+Hg/$)R@)gףp=
<@gtHgQ@gjg@)r   r   r   )gF<@gd;OGgZd;ߏQ@)g1:@gcR&HgRS8 R@)r   r   r   )r   r   ry   )	r   r   r   r   ry   r   r   r   ry   )r   rf   i)	g⇥j7ӿg7gԯg7g|Cb?g\1"տgԯ?g\1"?gG\R)gc-BX?gRgl)g7?gCΨIgPn;!?)r  r  gUUUUUU?)r   r   )r:  c             S   s   |    S )N)r   r   )r$   r   r   r   f  r<  zexercise_1.<locals>.fz{{1, 3}, {2, 4}}z{{1}, {2}, {3}, {4}}z{{1, 2, 5, 6}, {3, 4, 7, 8}}z {{1, 2}, {3, 4}, {5, 6}, {7, 8}}z{{1, 2, 3, 7}, {4, 5, 6, 8}})r   rf   z!{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}                                           !   "   #   $   &   '   )   *   +   ,   .   /   0   1   z{{11, 12, 13, 21, 22, 23},
 {14, 15, 16, 24, 25, 26},
 {17, 18, 19, 27, 28, 29},
 {31, 32, 33, 41, 42, 43},
 {34, 35, 36, 44, 45, 46},
 {37, 38, 39, 47, 48, 49}})r   rs   )r   rs   z{{1, 2, 3, 7, 8, 9, 10},
 {4, 5, 6, 11, 12, 13, 14},
 {15, 16, 17, 24, 25, 26, 27},
 {18, 19, 20, 28, 29, 30, 31},
 {21, 22, 23, 32, 33, 34, 35},
 {36, 37, 38, 39, 40, 41, 42}}c                s    t | d|st |  |s&t|dkrt| d}|j| jksHt ||  t| jd dsft | | t| jd dstt|d} || std S )N)r   r   )r   )r   r   rk   r   r   rh   )r   expectedmiZmii)rH  r   r   check  s    

zexercise_1.<locals>.checkgg6iͿgO贁N?g7i6пg?gƒ_,?gK~ǿgX%?g?gg?gO贁N)g3Ey?g3Ey?g3Ey?r   )	gUUUUUU?gUUUUUU?gUUUUUU?gUUUUUU?gUUUUUU?gUUUUUUgUUUUUUgUUUUUU?gUUUUUUտ)r   r$   r%   )	gQ?gGz?gffffffg?gQgQg
ףp=
gQgq=
ףpͿgsT/ܝ?)g?ggffffff@)g?g?g333333?)	r   r   r   r   r   r   r   r   r   z/(0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)z#(1/2, -1/2, -1/2, 0, 1, 0, 0, 0, 1)F)r  r   )r  )g%C	gX9v?gB`"[@)gHzGgZd;O?g)\(@)gGzgm@gbX9@)g~jt?gh|?5?gd;O	@gd@)
group_args)FT)r  r  r   r   r   )r  r  r   )rM  rO  rZ  )r   5   rc  )r  r  r  )r   r   r   gU@)r   r   r   )r   r   r   )ry   r   r   )r  r   zINFO: numpy not available.g      gZd;O?g?)	g6?g(M?gmS?gGg=E`g?g!էgk2'?gT?g      g?)	gͿ%?g8o?gYǣ"gq%ܿg5o?gM5"g        g<f ?g%,"q,?g      ?ZOK)nlibtbxrG  r
   printr-   rH  Exception_expectedr	  r   r   r   r  r   r   r   r   r+   r   r   r,   re   r   rS   r1  rF   r8  r   r   r0   rk   r   r   r6  r2  r.   
startswithendswithr   r$  r   rI   rG   rH   rc   rP   rW   rX   rY   rZ   r[   r\   r]   r^   r  r   r   r   r;   r   r   r   r  r   r   r   allr3  r   rM   r   rh   r  rL   r   rQ   r|   r   rO   r   r   r   r   rx   r   r   rg   r   r  r;  r=  r   rm   r   r   ri   rJ   r  r  r  __dict__r0  r  r-  r)  r  r!  r   rN   tolistrF  )JrG  r  r$   r   r:  r%   r   r   r    r_  r1   r3   ZatbrZbtgZgrtZgrttZgttZgtttr   r}  r6   siZmiorS   r1  Zgrgtr   gvrG   Zmdr#   r)   r@   rA   r   r   Zx_perpZy_perpZzero_rotationidqr   r   r   r  Zraar~  Zuqri_trialZuq1Zuq2Zr1Zr2Zuqp12Zrp12Zuqp21Zrp21rd   Z	rational1r  r|  r  r   argsr  r  r  Zpoint_in_planer  r   Rr   )rH  r   
exercise_1@  s   








$ 







 & &

  &
"""""(
*.*





DD
 

$$&&*
 
 $$,,46"




& 


$ 



2"
"  r  c              C   s  dddgdddgddd	gd
ddgdddgdddgdddgdddgdddgdddgdd d!gd"d#d$gd%d&d'gd(d)d*gd+d,d-gg} t | d.d/stdddgdddgddd	gd
ddgdddgdddgdddgdddgdd0dgdddgdd d!gd"d#d$gd%d&d'gd(d)d*gd+d,d-gg} t | d.d/rtd S )1Ngv4@gCl@gHz=@gHz5@gK7@gn=@gNbX95@g-@g#~j>@gv5@gh|?5@gףp=
?@g㥛 5@gʡE6@gCl=@g r5@g r@gx<@g-4@gx	@gHz@@g|?5^4@gQ@gNbX9@@gFx5@gOn@gh|?@@g/$5@g%C@g|?5^*@@g}?5^I6@g$C@gtF@@gB`"{5@gV-@g㥛 ;@gp=
4@g!rh	@gDl	A@gI+g6@g/$@gA`в@@gT㥛Ā6@gzGa@g(\?@g{Gzt?)r   r"  g;On?)r#  r   )r   r   r   r   
exercise_2  s@    r  __main__)F)F)F)F)T)T)5r   
__future__r   r   r   	six.movesr   r   r   r   r   r   rQ   r   objectr   r   r   r   r   r   r,   r  r0   r  rh   r  r  r	  r
  r\   r   r  r  r  r  r  r!  r#  r)  r-  r0  r   r;  r=  r@  rB  r   r   rF  r  r  r   r   r   r   r   <module>
   sv         %
	






+[
1
    k$
