U
    Kvf2O                     @   s  d dl mZ dgZd dlZzd dlmZ W n  ek
rJ   d dlmZ Y nX d dlZd dl	Z
d dlmZ d dlmZ d dlmZmZmZmZmZ d dlmZmZmZ d d	lmZ G d
d deZdd Zdd Zedddeddd edddedddedddedddedddedddgZddgZ dd Z!dd Z"d d! Z#d"d# Z$G d$d% d%eZ%d&d' Z&d(d) Z'd*d+ Z(d,d-d.d/d0d1d2d3d4d5g
Z)d6d7 Z*dS )8    )print_functionLinearConstraintN)Mapping)
PatsyError)Origin)atleast_2d_column_defaultrepr_pretty_delegaterepr_pretty_implno_picklingassert_no_pickling)TokenOperatorinfix_parse)_parsing_error_testc                   @   s6   e Zd ZdZd	ddZeZdd ZeZ	e
dd ZdS )
r   ap  A linear constraint in matrix form.

    This object represents a linear constraint of the form `Ax = b`.

    Usually you won't be constructing these by hand, but instead get them as
    the return value from :meth:`DesignInfo.linear_constraint`.

    .. attribute:: coefs

       A 2-dimensional ndarray with float dtype, representing `A`.

    .. attribute:: constants

       A 2-dimensional single-column ndarray with float dtype, representing
       `b`.

    .. attribute:: variable_names

       A list of strings giving the names of the variables being
       constrained. (Used only for consistency checking.)
    Nc                 C   s   t || _ttj|td| _|d kr>tj| jjd td}tj|td}t	|| _
| j
jdksr| j
jd dkrztd| jjdks| jjd t|krtd| jjd dkrtd| jjd | j
jd krtdd S )	Ndtyper         z1constants is not (convertible to) a column matrixzwrong shape for coefsz/must have at least one row in constraint matrixz*shape mismatch between coefs and constants)listvariable_namesnpZ
atleast_2dasarrayfloatcoefszerosshaper   	constantsndim
ValueErrorlen)selfr   r   r    r!   4/tmp/pip-unpacked-wheel-68fdvdus/patsy/constraint.py__init__2   s    

 zLinearConstraint.__init__c                 C   s    |rt t|| | j| j| jgS N)AssertionErrorr	   r   r   r   )r    pcycler!   r!   r"   _repr_pretty_C   s    zLinearConstraint._repr_pretty_c                 C   sf   |st d|d j}|D ]}|j|krt dqtdd |D }tdd |D }| |||S )a  Create a new LinearConstraint by ANDing together several existing
        LinearConstraints.

        :arg constraints: An iterable of LinearConstraint objects. Their
          :attr:`variable_names` attributes must all match.
        :returns: A new LinearConstraint object.
        zno constraints specifiedr   zvariable names don't matchc                 S   s   g | ]
}|j qS r!   )r   .0cr!   r!   r"   
<listcomp>Y   s     z,LinearConstraint.combine.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r!   )r   r)   r!   r!   r"   r,   Z   s     )r   r   r   Zvstack)clsconstraintsr   
constraintr   r   r!   r!   r"   combineJ   s    	


zLinearConstraint.combine)N)__name__
__module____qualname____doc__r#   r   __repr__r(   r
   __getstate__classmethodr0   r!   r!   r!   r"   r      s   
c                  C   s  zddl m}  W n  tk
r0   ddlm}  Y nX tddgddg}|jddgksVt| |jddgg | |jdgg tddgddgddggdd	g}| |jddgddgg | |jdgd	gg |jj	t
	tkst|jj	t
	tksttd
gdgg}| |jdgg dd l}|ttd
gddgg |ttd
gdggg |ttd
gddggddg |ttd
dgddggddg |ttd
gdggg g |ttd
dgg  |ttd
dgt
d t| d S )Nr   assert_equalZfoobarr   r      
      a   br   r   )numpy.testingr9   ImportErrornumpy.testing.utilsr   r   r%   r   r   r   r   r   pytestraisesr   r   r   )r9   lcrE   r!   r!   r"   test_LinearConstraint]   s4      rH   c                  C   s   t t ddgddgt ddgddgdgg} | jddgks@tzddlm} W n  tk
rp   ddlm} Y nX || jddgddgg || j	dgdgg dd l
}|tt jg  |tt jt dgdgt dgdgg d S )Nr>   r@   r   r   r8   )r   r0   r   r%   rB   r9   rC   rD   r   r   rE   rF   r   )combr9   rE   r!   r!   r"   test_LinearConstraint_combine   s    
rJ   ,r   i=+r   d   -*   /NUMBERVARIABLEc                    s    fdd}|S )Nc                    s.   dkr|}n}t |t f| j  |S )N__OP__)r   r   matchspan)scannerZtoken_stringZactual_typestringtyper!   r"   
make_token   s    z _token_maker.<locals>.make_tokenr!   )r[   rZ   r\   r!   rY   r"   _token_maker   s    r]   c                 C   s   d}d}d dd tD }d}d}t|tdd	}d d
d |D }|ttj| f|ttj| f|td| f|td| f|td| f|d fg}t	|}	|	
| \}
}|rt| t| }tdt| ||d |
S )Nz\(z\)|c                 S   s   g | ]}t |jqS r!   )reescape
token_type)r*   opr!   r!   r"   r,      s     z(_tokenize_constraint.<locals>.<listcomp>z&[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?z\s+T)keyreversec                 S   s   g | ]}t |qS r!   )r_   r`   )r*   nr!   r!   r"   r,      s     rU   rT   rS   z unrecognized token in constraintr   )join_opssortedr   r]   r   LPARENRPARENr_   Scannerscanr   r   )rZ   r   Z	lparen_reZ	rparen_reZop_reZnum_reZwhitespace_reZvariable_relexiconrX   tokensleftoveroffsetr!   r!   r"   _tokenize_constraint   s,    	
rq   c               
   C   sv  d} t | dddg}ddtjddd	fd
ddtjdddfddg	}t||D ]X\}}t|ts^t|j|d kspt|jt	| |d |d kst|j
|d ksHtqHdd l}|tt ddg t ddg ddgddgfD ]:}t d|}t|dkstdd |D dddgkstqt ddg}t|dks2tdd |D dd d!d"gksRtd#d |D d$d dd"gksrtd S )%Nz2 * (a + b) = qr>   r@   q)rS   r   r   2)rP   r   r;   rP   r?      ()rT   rt      r>   )rM         rM   )rT   	   r<   r@   r<      ))rL         rL   )rT         rr   r   r   r   r;   z1 + @bz@bZaaza aa ac                 S   s   g | ]
}|j qS r!   extrar*   tr!   r!   r"   r,      s     z-test__tokenize_constraint.<locals>.<listcomp>z2 * a[1,1],za[1,1]c                 S   s   g | ]
}|j qS r!   )r[   r   r!   r!   r"   r,      s     rS   rP   rT   rK   c                 S   s   g | ]
}|j qS r!   r   r   r!   r!   r"   r,      s     rs   )rq   r   ri   rj   zip
isinstancer%   r[   originr   r   rE   rF   r   r   )codern   	expectedsgotexpectedrE   namesr!   r!   r"   test__tokenize_constraint   s8    	
 r   c                 C   s   t t| |ttS r$   )r   rq   rg   _atomic)rZ   r   r!   r!   r"   parse_constraint   s    
 r   c                   @   sv   e 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d Zdd Zdd Zdd ZdddZdS )_EvalConstraintc                 C   sD   || _ t|| _| j| j| j| j| j| j| j	| j
| j| jd
| _d S )N)
)rT   r   )rS   r   )rM   r   )rO   r   )rM   r   )rO   r   )rP   r   )rR   r   )rL   r   )rK   r   )_variable_namesr   _N_eval_variable_eval_number_eval_unary_plus_eval_unary_minus_eval_binary_plus_eval_binary_minus_eval_binary_multiply_eval_binary_div_eval_binary_eq_eval_binary_comma	_dispatch)r    r   r!   r!   r"   r#      s    
z_EvalConstraint.__init__c                 C   s   t |d | j dkS Nr   )r   allr   )r    r   r!   r!   r"   is_constant  s    z_EvalConstraint.is_constantc                 C   s2   |j j}tj| jd ftd}d|| j|< |S )Nr   r   )tokenr   r   r   r   r   r   index)r    treevarr   r!   r!   r"   r     s    z_EvalConstraint._eval_variablec                 C   s*   t j| jd ftd}t|jj|d< |S )Nr   r   )r   r   r   r   r   r   )r    r   r   r!   r!   r"   r     s    z_EvalConstraint._eval_numberc                 C   s   |  |jd S r   evalargsr    r   r!   r!   r"   r     s    z _EvalConstraint._eval_unary_plusc                 C   s   d|  |jd  S )Nr   r   r   r   r!   r!   r"   r     s    z!_EvalConstraint._eval_unary_minusc                 C   s    |  |jd |  |jd  S Nr   r   r   r   r!   r!   r"   r      s    z!_EvalConstraint._eval_binary_plusc                 C   s    |  |jd |  |jd  S r   r   r   r!   r!   r"   r   #  s    z"_EvalConstraint._eval_binary_minusc                 C   sF   |  |jd }|  |jd }| |s:td|jd ||d  S )Nr   r   z1Can't divide by a variable in a linear constraintr   r   r   r   r   r    r   leftrightr!   r!   r"   r   &  s    
z _EvalConstraint._eval_binary_divc                 C   sZ   |  |jd }|  |jd }| |r6|d | S | |rL||d  S td|d S )Nr   r   r   z=Can't multiply one variable by another in a linear constraintr   r   r!   r!   r"   r   .  s    

z%_EvalConstraint._eval_binary_multiplyc                 C   s   t |j}g }t|D ]8\}}|jdkr|| j|dd |jd|  ||< q| |d }| |d }|d | j |d | j  }t|dkrt	d||d  |d  }	t
| j||	}
||
 t
|S )NrL   Tr/   r   r   z!no variables appear in constraintr   )r   r   	enumerater[   appendr   r   r   r   r   r   r   r0   )r    r   r   r.   iargr   r   r   Zconstantr/   r!   r!   r"   r   9  s    



z_EvalConstraint._eval_binary_eqc                 C   s6   | j |jd dd}| j |jd dd}t||gS )Nr   Tr   r   )r   r   r   r0   r   r!   r!   r"   r   M  s    z"_EvalConstraint._eval_binary_commaFc                 C   s   |j t|jf}|| jkst| j| |}|rt|tr>|S |j| jd ksRtt	
|d | j dkrttd|t| j|d | j |d  S nt|trtd||S d S )Nr   r   z#term is constant, with no variablesr   zunexpected constraint object)r[   r   r   r   r%   r   r   sizer   r   r   r   r   )r    r   r/   rc   valr!   r!   r"   r   R  s$    


z_EvalConstraint.evalN)F)r1   r2   r3   r#   r   r   r   r   r   r   r   r   r   r   r   r   r!   r!   r!   r"   r      s   r   c                 C   s  t | tr*| j|kr&td| j|f | S t | trtjt| t|ftd}tt| }t	 }t
t| D ]x\}\}}||kr||}n t |tjr|}ntd|f ||krtd|| f || d|||f< |||< qpt|||S t | tr| g} t | tr| rt | d trg }	| D ]F}
t |
tsPtd|
f t|
|}t|}|	|j|dd	 q2t|	S t | trt| d
krtd| \}}t|||S tj| td}t||S )zaThis is the internal interface implementing
    DesignInfo.linear_constraint, see there for docs.z?LinearConstraint has wrong variable_names (got %r, expected %r)r   z#unrecognized variable name/index %rzduplicated constraint on %rr   r   zexpected a string, not %rTr   r   z#constraint tuple must have length 2)r   r   r   r   r   r   r   r   r   setr   six	iteritemsr   integer_typesaddstrr   r   r   r   r   r0   tupler   )Zconstraint_liker   r   r   usedr   namevalueidxr.   r   r   Z	evaluatorZcoefr!   r!   r"   linear_constrainth  sh    






r   c                 C   s   zddl m} W n  tk
r0   ddlm} Y nX t| |}td| t|||}td| ||j|j ||j|j ||j	|j	 ||jj
t
t ||j	j
t
t d S )Nr   r8   r   r   )rB   r9   rC   rD   r   printr   r   r   r   r   r   r   )inputvarnamesr   r   r9   r   r   r!   r!   r"   _check_lincon  s    


r   c                  C   s  dd l } ddlm} t}|tddgddgddgddggdgg | tttddgddgddg |ddiddgddggdgg ||dd	gddgddgddggdgdgg ||dd	gddgddgddggdgdgg |ddiddgddggdgg ||d
dgddgddgddggdgdgg ||ddgddgddgddggdgdgg | ttddiddg | ttdddddg |t	ddgddgddggdgg |t	ddgddggddgddgddggdgdgg |dddgddggdgg |dddgddggdgg |dddgddggdgg |dddgddggdgg |dddgddgddggdgdgg |dddgddgddggdgdgg |ddgddgddgddggdgdgg | ttdddigddg |dddgddggdgg |dddgddggdgg |dddgddgddggdgdgg |dddgddgddgddggdgdgdgg |dddgddggdgg |d ddgddggdgg |d!ddgddggdgg |d"ddgddgddggdgdgg |d#ddgddgddggdgdgg |d$ddd%gdddgdddgdddggdgdgdgg |d&dd'gddggdgg |d(d)gd*gfddgd(d)ggd*gg |d(d)gd)d+ggd*gd,ggfddgd(d)gd)d+ggd*gd,gg | ttddgdgdgfddg | ttddgfddg |d(d)gddgd(d)ggdgg |d(d)gd)d+ggddgd(d)gd)d+ggdgdgg |t	d(d)gddgd(d)ggdgg |t	d(d)gd)d+ggddgd(d)gd)d+ggdgdgg | ttd ddg d S )-Nr   )OrderedDictr>   r@   r   r;   r   )r>   r   )r@   r;   rA   )r   r;   rr   )r>   r   r?   rt   za = 2za - 2z	a + 1 = 3z	a + b = 3za = 2, b = 3zb = 3, a = 2zb = 3z#2 * (a + b/3) + b + 2*3/4 = 1 + 2*3g?g      @z+2 * -aza - b, a + b = 2r   za = 1, a = 2, a = 3za * 2z-a = 1z(2 + a - a) * bz	a = 1 = bza = (1 = b)za = 1, a = b = cr+   z	a + 1 = 2za + 1r<   r=      (   #   )
rE   Zpatsy.compatr   r   r   rF   r   r   r   array)rE   r   r   r!   r!   r"   test_linear_constraint  s    *   
  
 .  
&8&&*
 &
 && &" 
  2& 
r   z	a + <f>ooza = 1, <1 = 1>, b = 1za = 1, <b * 2 - b + (-2/2 * b)>za = 1, <1>, b = 2za = 1, <2 * b = b + b>, cza + <a * b> + cza + 2 / <b> + cza = 1, 2 * <(a = b)>, cza = 1, a + <(a = b)>, cza = 1, <(a, b)> + 2, cc                  C   s   dd } t | t d S )Nc                 S   s   t | dddgS )Nr>   r@   r+   )r   )Zbad_coder!   r!   r"   doit  s    ztest_eval_errors.<locals>.doit)r   _parse_eval_error_tests)r   r!   r!   r"   test_eval_errors  s    r   )+
__future__r   __all__r_   collections.abcr   rC   collectionsr   Znumpyr   Zpatsyr   Zpatsy.originr   Z
patsy.utilr   r   r	   r
   r   Zpatsy.infix_parserr   r   r   Zpatsy.parse_formular   objectr   rH   rJ   rg   r   r]   rq   r   r   r   r   r   r   r   r   r!   r!   r!   r"   <module>   s\   A%







$u>N