
    hJ                     f    S r SSKrSSKJr  SSKrSSKJr  S rS r	 " S S\R                  5      rg)u+   Single Echo State Network layer tuned to φ    N)INV_PHIc                 <   [        U [        R                  5      (       a,  U R                  5       R	                  5       R                  5       n [        R                  R                  U 5      n[        [        R                  " [        R                  " U5      5      5      $ )z6Compute spectral radius (largest eigenvalue magnitude))
isinstancetorchTensordetachcpunumpynplinalgeigvalsfloatmaxabs)Weigenvaluess     3/home/james-whalen/eden_hybrid_phi/phi_esn_layer.pyspectral_radiusr      s_    !U\\""HHJNN""$))##A&K{+,--    c                 6    [        U 5      nUS:X  a  U $ XU-  -  $ )z(Rescale matrix to target spectral radiusr   )r   )r   	target_sr
current_srs      r   rescale_to_target_srr      s&     #JQJ&''r   c                   H   ^  \ rS rSrSr SU 4S jjrS rS	S jrS rSr	U =r
$ )
PhiESNLayer   u:   Echo State Network layer with fixed spectral radius = 1/φc                   > [         T
U ]  5         Xl        X l        X0l        X@l        X`l        [        R                  " [        R                  " X!5      S-  SS9U l        [        R                  " X"5      n[        R                  " X"5      U:  nXxR                  5       -  n[        UR                  5       [         5      n	[        R                  " [        R"                  " U	5      R                  5       SS9U l        [        R&                  " X#5      U l        U R+                  S[        R,                  " SU5      5        U R/                  U5        g )Ng      ?F)requires_gradstate   )super__init__
input_sizereservoir_sizeoutput_size	leak_ratedevicenn	Parameterr   randnW_inrandr   r   r
   r   
from_numpyW_recLinearreadoutregister_bufferzerosto)selfr#   r$   r%   r&   sparsityr'   r   maskW_np	__class__s             r   r"   PhiESNLayer.__init__   s    $,&" LLKK3c9
	 KK7zz.9HD

 $AGGIw7\\T"((*

 yy= 	Wekk!^&DEr   c                    UR                   S   nU R                  R                   S   U:w  a>  [        R                  " X R                  5      R                  U R                  5      U l        [        R                  " XR                  R                  5       5      n[        R                  " U R                  U R                  R                  5       5      n[        R                  " X4-   5      nSU R                  -
  U R                  -  U R                  U-  -   U l        U R                  U R                  5      nX`R                  4$ )z'Process input: x is [batch, input_size]r   r    )shaper   r   r2   r$   r3   r'   matmulr+   tr.   tanhr&   r0   )r4   x
batch_sizeinput_contribrecurrent_contrib	new_stateoutputs          r   forwardPhiESNLayer.forward<   s    WWQZ
::A*,Z1D1DEHHUDJ Q		6!LLTZZ\\^DJJ}@A	$..(DJJ6)9SS
 djj)zz!!r   c                     [         R                  " XR                  5      R                  U R                  5      U l        g)zReset reservoir stateN)r   r2   r$   r3   r'   r   )r4   r@   s     r   reset_statePhiESNLayer.reset_stateO   s'    [[-@-@ADDT[[Q
r   c                 ,    [        U R                  5      $ )zGet current spectral radius)r   r.   )r4   s    r   get_spectral_radiusPhiESNLayer.get_spectral_radiusS   s    tzz**r   )	r+   r.   r'   r#   r&   r%   r0   r$   r   )g      ?g?r	   )r    )__name__
__module____qualname____firstlineno____doc__r"   rE   rH   rK   __static_attributes____classcell__)r8   s   @r   r   r      s&    D 6;"H"&R+ +r   r   )rQ   r   torch.nnr(   r
   r   phi_constantsr   r   r   Moduler    r   r   <module>rX      s0    1    !.(@+")) @+r   