
    Di                     <   d dl Z d dlmZ d dlmc mZ d dlmZ  G d dej                        Z	 G d dej                        Z
edk(  rdZd	Zd
ZdZdZ ed        ede de d        ede de de         e         e	eee      Z e j&                  ee      Z ee      \  ZZ edej.                           edej.                           ededd          e        ej1                  eee      Z edej.                           e         e
eeee      Z ee      Z edej.                           e        e j8                  j;                  ej=                         d      ZejA                         Z!e!jE                           ed        edejF                  jH                  jJ                  du         edejF                  j,                  jJ                  du         edejL                  jH                  jJ                  du        yy)     N)Optionalc            	            e Zd ZdZ	 ddedededef fdZd Zdej                  fd	Z
	 	 ddej                  d
ee   dee   fdZ xZS )LinearWithBandwidtha  
    A custom linear layer that outputs both feature values and per-node bandwidth parameters.
    
    The bandwidth information allows reshaping the output for Conv2D operations by providing
    spatial structure information for each neuron.
    
    Args:
        in_features: Size of each input sample
        out_features: Number of output features (neurons)
        bandwidth_dim: Spatial dimension for bandwidth (height/width of the output grid)
        use_bias: If True, includes a bias term for the linear transformation
    in_featuresout_featuresbandwidth_dimuse_biasc                    t         |           || _        || _        || _        t        j                  t        j                  ||            | _	        |r.t        j                  t        j                  |            | _        n| j                  dd        t        j                  t        j                  |            | _        | j                          y )Nbias)super__init__r   r   r   nn	Parametertorchrandnweightzerosr   register_parameterones	bandwidthreset_parameters)selfr   r   r   r	   	__class__s        ;/home/per/Documents/python/deep entropy/bandwidth_linear.pyr   zLinearWithBandwidth.__init__   s     	&(* ll5;;|[#IJU[[%>?DI##FD1 ejj&>?    c                    t         j                  j                  | j                  d       | j                  )t         j                  j                  | j                         t         j                  j                  | j                         y)z3Initialize parameters using Kaiming initialization.gw@)aN)r   initkaiming_uniform_r   r   zeros_ones_r   )r   s    r   r   z$LinearWithBandwidth.reset_parameters.   sO    
   799 GGNN499%
dnn%r   xc                 t    t        j                  || j                  | j                        }|| j                  fS )aK  
        Forward pass.
        
        Args:
            x: Input tensor of shape (batch_size, in_features)
            
        Returns:
            Tuple of (features, bandwidth) where:
                - features: shape (batch_size, out_features)
                - bandwidth: shape (out_features,) - shared across batch
        )Flinearr   r   r   )r   r"   featuress      r   forwardzLinearWithBandwidth.forward6   s-     88At{{DII6''r   target_heighttarget_widthc           
          | |      \  }}|j                   d   }| |||z  | j                  k\  sJ d       ||}}nt        t        j                  t        j
                  t        j                  | j                  t        j                                          x}}||z  | j                  k  r|dz  }||z  | j                  k  rd}	t        j                  ||	|||j                  |j                        }
t        | j                        D ]:  }||z  }||z  }||k  s||k  s|dd|f   | j                  |   z  |
ddd||f<   < |
S )a  
        Forward pass that reshapes output for Conv2D compatibility.
        
        Args:
            x: Input tensor of shape (batch_size, in_features)
            target_height: Height of the output grid (optional)
            target_width: Width of the output grid (optional)
            
        Returns:
            Reshaped tensor of shape (batch_size, channels, height, width)
            where bandwidth information is used to structure the output
        r   Nz'Grid size must be at least out_features)dtype   )devicer+   )shaper   intr   ceilsqrttensorfloatr   r-   r+   ranger   )r   r"   r(   r)   r&   r   
batch_sizehwchannelsoutputirowcols                 r   forward_reshapedz$LinearWithBandwidth.forward_reshapedE   sX   $ #1g)WWQZ
 $)A </43D3DD :9:D ,qA 

5::ell4;L;LTYT_T_.`#abccAa%$+++Q a%$+++ Z1aPQPWPWX t(() 	LAq&Ca%CQw37)1!Q$$..:K)Kq!S#~&	L r   )T)NN)__name__
__module____qualname____doc__r/   boolr   r   r   Tensorr'   r   r=   __classcell__r   s   @r   r   r      s    $      	 
  2&( ($ (,&*	,<<,  }, sm	,r   r   c                   T     e Zd ZdZdedededef fdZdej                  fdZ xZ	S )	ConvAfterLinearaP  
    Example module showing how to use LinearWithBandwidth followed by Conv2D.
    
    Args:
        in_features: Input feature size
        hidden_features: Hidden layer size (output of linear with bandwidth)
        grid_size: Spatial dimension for reshaping (height/width)
        out_channels: Number of Conv2D output channels
    r   hidden_features	grid_sizeout_channelsc                     t         |           t        |||      | _        t	        j
                  d|dd      | _        || _        y )N)r   r   r   r,      )in_channelsrJ   kernel_sizepadding)r   r   r   	linear_bwr   Conv2dconvrI   )r   r   rH   rI   rJ   r   s        r   r   zConvAfterLinear.__init__   sL     	,#(#
 II%	
	 #r   r"   c                     | j                   j                  || j                  | j                        }| j                  |      }|S )z
        Args:
            x: Input tensor of shape (batch_size, in_features)
            
        Returns:
            Output tensor of shape (batch_size, out_channels, grid_size, grid_size)
        )r(   r)   )rP   r=   rI   rR   )r   r"   reshapedouts       r   r'   zConvAfterLinear.forward   sC     >>22.. 3 
 ii!
r   )
r>   r?   r@   rA   r/   r   r   rC   r'   rD   rE   s   @r   rG   rG   t   sC    ## # 	#
 #0 r   rG   __main__      @         z#=== LinearWithBandwidth Example ===zInput: (z, )zHidden: z, Grid: r"   zFeatures shape: zBandwidth shape: zBandwidth values:    zReshaped for Conv2D: zFinal output shape: gMbP?)lrzGradient check:z  weight.grad: z  bandwidth.grad: z  conv.weight.grad: )'r   torch.nnr   torch.nn.functional
functionalr$   typingr   Moduler   rG   r>   r5   r   rH   rI   rJ   printlayerr   r"   r&   r   r.   r=   rT   modelrU   optimAdam
parameters	optimizersumlossbackwardrP   r   gradrR    r   r   <module>rp      s-       j")) jZ4bii 4n zJKOIL	
/0	HZL;-q
12	H_%Xi[)
EF	G  _iHEJ,A(Hi	X^^,
-.	ioo.
/0	y!}o
./	G %%aI>H	!(..!1
23	G K)\RE
(C	 
,-	G   !1!1!3 >I779DMMO	
	OEOO2277tCD
EF	u88==TIJ
KL	 !2!2!7!7t!C D
EFU r   