U
    U¹ f  ã                   @   s¤   d dl mZ d dlZd dlZd dddœZdd„ Zd"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ed!kr eƒ  dS )#é    ©Ú	euclideanNé   é   )ÚxÚyÚzc                 C   sF   t  | |¡}t  t  | | ¡¡}t  t  ||¡¡}|| }t  || ¡S ©N)ÚnpÚdotÚsqrtÚarccos)Úv1Úv2Ú	numeratorÚm1Úm2Údenominator© r   ún/home/dh_an3skk/arjun-chandrasekhar-teaching.com/tomato/backend/backend_plant_architecture/optimal_midpoint.pyÚangle_between_vectors   s
    r   r   c                 C   s   d S r	   r   )ÚvÚdimr   r   r   Úrotation_angle   s    r   c           	      C   sž   t | ƒt |ƒ  kr t |ƒks&n t‚t| dd… ƒ}t|dd… ƒ}t|dd… ƒ}t| ƒD ](\}}|||fD ]}||  |8  < qpq^t|ƒt|ƒt|ƒfS )z¶
    Takes three points (of any dimension) as input; translates the first point to be at
    the origin, and translates the other two points by the same amount in each dimension
    N)ÚlenÚAssertionErrorÚlistÚ	enumerateÚtuple)	Úp0Úp1ÚqÚp0_shiftÚp1_shiftÚq_shiftÚiÚcoordÚpointr   r   r   Útranslate_to_origin   s    &r(   c                 C   sD   t | ƒt |ƒkst‚g }tt | ƒƒD ]}| || | |  ¡ q$|S r	   )r   r   ÚrangeÚappend)r   r    Úmr%   r   r   r   Úslope_vector$   s
    r,   c                 C   sL   t | ƒt |ƒkst‚g }tt | ƒƒD ]}| | | || |  ¡ q$t|ƒS r	   )r   r   r)   r*   r   )r   r+   ÚtÚmidpointr%   r   r   r   r.   +   s
    r.   c                 C   s:   t ||ƒ}t ||ƒt | |ƒ | }|| d| |  }|S )Nr   r   )r   r!   r.   ÚalphaÚdrootÚwiringÚdelayÚcostr   r   r   Úmidpoint_cost4   s    
r4   c                 C   s°   g }| d || d   }d| |  | d|  |  }|d ||  |  }|d d| |  }|dkr¬| |d  d|  }	|  |	¡ |dkr¬| |d  d|  }
|  |
¡ |S )Nr   é   r   g      à?)r*   )r   r   r   ÚgammaÚcritical_valuesÚaÚbÚcZdeterminantÚt1Út2r   r   r   r7   :   s    

r7   c                 C   s<   t  | | ¡}t  || ¡}t  ||¡}d| d }||||fS )Nr   r   )r
   r   )r+   r!   r/   r   r   r   r6   r   r   r   Úintermediate_variablesM   s
    r=   c                 C   s°   t | ||ƒ\}}}ddg}t||ƒ}	t|	||ƒ\}
}}}t|
|||ƒ}tdd„ |ƒ}||7 }tdƒ}d }d }|D ]4}t| |	|ƒ}t| ||||ƒ}||k rp|}|}|}qp|||fS )Nr   r   c                 S   s   d|   kodkS   S ©Nr   r   r   )r   r   r   r   Ú<lambda>_   ó    z(optimal_midpoint_exact.<locals>.<lambda>Úinf)r(   r,   r=   r7   ÚfilterÚfloatr.   r4   )r   r    r!   r/   r0   r"   r#   r$   Zcandidate_timesr+   r   r   r   r6   Zcrit_valuesÚ	best_costÚbest_midpointÚ
best_deltaÚdeltaÚmpr3   r   r   r   Úoptimal_midpoint_exactU   s$    
rI   c                 C   sÎ   t | ƒt |ƒ  kr t |ƒks&n t‚t| |ƒ}d}tdƒ}d}d}	t dd| |¡D ]d}
d}|
dkrt| }t|
ƒ}
n"|
dkrŠ|}t|
ƒ}
n|| ||
ƒ}t| ||||ƒ}||k rV|}|}|
}	qVt|ƒ}|||	fS )aŽ  
    approximates the optimal point to insert a point onto a line segment. This method uses
    brute force to try all possible midpoints, within a certain granularity.

    p0, p1 - the points comprising a line segment

    q - the point that should be connected to the line segment

    alpha - the degree to  which we prioritize conduction delay or wiring cost.

    The wiring cost is the distance from q to our chosen midpoint. the conduction delay is
    the sum of the distance from q to our chosen midpoint and the distance from our chosen
    midpoint to p0.

    We want to (mimimize alpha * wiring cost) + ((1 - alpha) * conduction delay)
    g{®Gáz„?rA   Nr   r   )	r   r   r,   rC   r
   ÚarangeÚintr4   r   )r   r    r!   r/   r0   r+   rG   rD   rE   rF   r-   r.   rH   r3   r   r   r   Úoptimal_midpoint_approxp   s,    &


rL   c                 C   s   t | ||||ƒS r	   )rI   )r   r    r!   r/   r0   r   r   r   Úoptimal_midpoint¨   s    rM   c           
      C   sl   t | ||ƒ\}}}t||ƒ}t ||¡t ||¡ }|dk r@d}|dkrLd}t| ||ƒ}t||ƒ}	|	||fS r>   )r(   r,   r
   r   r.   r   )
r   r    r!   r"   r#   r$   r+   r-   rH   r3   r   r   r   Úoptimal_midpoint_alpha1«   s    

rN   c                  C   s    d} d}d}t t| ||ƒƒ d S )N)r   r   )r   r   )gffffffæ?g®Gázæ?)ÚprintrN   )r   r    r!   r   r   r   Úmain»   s    	rP   Ú__main__)r   )Úscipy.spatial.distancer   Únumpyr
   ÚrandomZDIMENSION_COORDr   r   r(   r,   r.   r4   r7   r=   rI   rL   rM   rN   rP   Ú__name__r   r   r   r   Ú<module>   s$   	
	8