B
    < [OO                 @   sr  d dl mZ dgZd dlZd dlmZ 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    /lib/python3.7/site-packages/patsy/constraint.py__init__/   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_@   s    zLinearConstraint._repr_pretty_c             C   sj   |st d|d j}x|D ]}|j|krt dqW 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>V   s    z,LinearConstraint.combine.<locals>.<listcomp>c             S   s   g | ]
}|j qS r    )r   )r'   r(   r    r    r!   r)   W   s    )r   r   r   Z	row_stack)clsconstraintsr   
constraintr   r   r    r    r!   combineG   s    	


zLinearConstraint.combine)N)__name__
__module____qualname____doc__r"   r   __repr__r&   r
   __getstate__classmethodr-   r    r    r    r!   r      s   
c              C   s  y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m} |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fooZbarr   r      
      a)assert_raises   b)r   r   )numpy.testingr5   ImportErrornumpy.testing.utilsr   r   r#   r   r   r   r   r   
nose.toolsr:   r   r   r   )r5   Zlcr:   r    r    r!   test_LinearConstraintZ   s2     rA   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y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
m} |tt jg  |tt jt dgdgt dgdgg d S )Nr9   r<   r   r   )r5   )r:   )r   r-   r   r#   r=   r5   r>   r?   r   r   r@   r:   r   )Zcombr5   r:   r    r    r!   test_LinearConstraint_combine   s    rB   ,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    )rR   rQ   rS   r    )rQ   rR   r!   _token_maker   s    rT   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    )rV   rW   )r'   nr    r    r!   r)      s    rM   rL   rK   z unrecognized token in constraintr   )join_opssortedr   rT   r   LPARENRPARENrV   Scannerscanr   r   )rQ   r   Z	lparen_reZ	rparen_reZop_reZnum_reZwhitespace_reZvariable_relexiconrP   tokensZleftoveroffsetr    r    r!   _tokenize_constraint   s(    

rg   c           
   C   s  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	}xft||D ]X\}}t|ts`t|j|d ksrt|jt	| |d |d kst|j
|d ksJtqJW ddlm} |tt ddg t ddg xNddgddgfD ]:}t d|}t|dkstdd |D dddgkstqW t ddg}t|dks<tdd |D d d!d"d#gks\td$d |D d%d!dd#gks|td S )&Nz2 * (a + b) = qr9   r<   q)rK   r   r   2)rH   r   r6   rH   r;      ()rL   rj      r9   )rE         rE   )rL   	   r7   r<   r7      ))rD         rD   )rL         rh   r   r   r   r6   )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    )rR   )r'   rw   r    r    r!   r)      s    rK   rH   rL   rC   c             S   s   g | ]
}|j qS r    )rv   )r'   rw   r    r    r!   r)      s    ri   )rg   r   r`   ra   zip
isinstancer#   rR   originr   rv   r@   r:   r   r   )codere   Z	expectedsgotexpectedr:   namesr    r    r!   test__tokenize_constraint   s6    
  r   c             C   s   t t| |ttS )N)r   rg   r^   _atomic)rQ   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)
)rL   r   )rK   r   )rE   r   )rG   r   )rE   r   )rG   r   )rH   r   )rJ   r   )rD   r   )rC   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   )tokenrv   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   rv   )r   r   r   r    r    r!   r     s    z_EvalConstraint._eval_numberc             C   s   |  |jd S )Nr   )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    r!   r     s    z!_EvalConstraint._eval_unary_minusc             C   s    |  |jd |  |jd  S )Nr   r   )r   r   )r   r   r    r    r!   r     s    z!_EvalConstraint._eval_binary_plusc             C   s    |  |jd |  |jd  S )Nr   r   )r   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 constraint)r   r   r   r   )r   r   r   r   r    r    r!   r   +  s    

z%_EvalConstraint._eval_binary_multiplyc             C   s   t |j}g }xDt|D ]8\}}|jdkr|| j|dd |jd|  ||< qW | |d }| |d }|d | j |d | j  }t|dkrt	d||d  |d  }	t
| j||	}
||
 t
|S )NrD   T)r,   r   r   z!no variables appear in constraintr   )r   r   	enumeraterR   appendr   r   r   r   r   r   r   r-   )r   r   r   r+   iargr   r   r   Zconstantr,   r    r    r!   r   6  s    



z_EvalConstraint._eval_binary_eqc             C   s6   | j |jd dd}| j |jd dd}t||gS )Nr   T)r,   r   )r   r   r   r-   )r   r   r   r   r    r    r!   r   J  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)rR   r   r   r   r#   ry   r   sizer   r   r   r   r   )r   r   r,   rZ   valr    r    r!   r   O  s     


z_EvalConstraint.evalN)F)r.   r/   r0   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	 }xt
t| D ]x\}\}}||kr||}n t |tjr|}ntd|f ||krtd|| f || d|||f< |||< qrW t|||S t | tr| g} t | tr| rt | d trg }	xN| D ]F}
t |
tsVtd|
f t|
|}t|}|	|j|dd	 q8W t|	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 %rT)r,   r   z#constraint tuple must have length 2)ry   r   r   r   r   r   r   r   r   setr   sixZ	iteritemsr   Zinteger_typesaddstrr   r   r   r   r   r-   tupler   )Zconstraint_liker   r   r   Zusedr   namevalueidxr+   r{   r   Z	evaluatorZcoefr    r    r!   linear_constrainte  sZ    








r   c             C   s   y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   )r5   r|   r}   )r=   r5   r>   r?   r   printr   r   r   r   r   r   r   )inputZvarnamesr   r   r5   r|   r}   r    r    r!   _check_lincon  s    


r   c              C   s  ddl m}  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   )r:   )OrderedDictr9   r<   r   r6   r   )r9   r   )r<   r6   )r   r   )r   r6   rh   )r9   r   r;   rj   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 + 1r7   r8      (   #   )
r@   r:   Zpatsy.compatr   r   r   r   r   r   Zarray)r:   r   rw   r    r    r!   test_linear_constraint  sl    *
 "" ."&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 )Nr9   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   ))Z
__future__r   __all__rV   collectionsr   r   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   rA   rB   r^   r   rT   rg   r   r   r   r   r   r   r   r   r    r    r    r!   <module>   sR   A%






$u>N