B
    `Z                 @   s   d Z ddlmZ ddlmZ ddlmZ ddlm  mZ ddl	m
Z
 dgZdddZdd	d
ejdfddZdd Zdd Zdd Zdd ZdS )z)Functions for framing `conv` as `matmul`.    )absolute_import)division)print_functionN)prefer_staticim2row   r   NHWCVALIDc       
   	   C   s   t |p
d t|}t|}|dkr*n|dkr<tdndsDtt| }t|||||\}}tj	|dd dd	ggd
d}	t j
t | |	|d
d} t | |S Q R X dS )a'  Rearrange image blocks into rows.

  This function can be used to implement 2D convolution as a `matml`, e.g.,

  `tf.nn.conv2d(x, k) = tf.matmul(im2row(x), tf.reshape(k, [-1, out_size]))`.

  Args:
    x: Rank 3 (or more) Tensor representing 2D images.
    block_shape: Length-2 vector representing the block or "filter" shape.
    slice_step: Length-2 vector specifying the convolution stride length.
      Default value: `(1, 1)`.
    data_format: One of `'NHWC'` or `'NCHW'` (case insensitive).
      Default value: `'NHWC'`.
    padding: One of `'VALID'` or `'SAME'` (case insensitive).
      Default value: `'VALID'`.
    name: Python `str` used to describe ops created by this function.
      Default value: `None` (i.e., `'im2col'`).

  Returns:
    im2row_x: batch of matrices representing subblock copies of `x`.
      Same batch shape as `x` but with rightmost shape:
      `batch_shape + [oh * ow, block_shape[0] * block_shape[1] * channels]`,
      where `oh = (h - block_shape[0] + 1) // slice_step[0]` and
      `ow = (w - block_shape[1] + 1) // slice_step[1]` when `padding = 'VALID'`
      and `oh = h` and `ow = w` when `padding = 'SAME'`.
    shape: shape `Tensor` equivalent to:
      `batch_shape + [oh, ow, block_shape[0] * block_shape[1] * channels]` where
      `oh, ow` are defined as above.
  r   r
   SAMEz(Argument padding="SAME" not implemented.FNr   r   )ZpaddingsZconstant_values)axis)tf
name_scope_validate_data_format_validate_paddingNotImplementedErrorAssertionErrorr   shape_im2row_indexpadZgatherreshape)
xblock_shape
slice_stepdata_formatpaddingnameZx_shapeidxsZ
flat_shape r!   h/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow_probability/python/experimental/nn/util/im2row.pyr      s     #
c          	   C   s  t |p
d tjt| t jddddgd\}}}	}
t|\}}t|\}}t|}t|}|dkr|d |	d |
d   }}}t	tj
|| | || |dtj
|| ||dtj
|d|dg}nt|dkr4|d |	d |
d   }}}t	tj
|| | || |dtj
|| ||dtj
|d|dg}n
d	s>t|d
kr|| d }|| d }t	tj
|| || |dtj
|||dg}|dkr||9 }|| }|| }n
d	stt	||g}|||| | g}tj||gdd}||fS Q R X dS )z>Computes indexes into a flattened image for building `im2col`.Zim2row_indexr   r   )num_or_size_splitsr	   r   )deltadtypeNCHWFr
   )r   N)r   r   r   splitcastint32_split_pairr   r   _cartesian_addranger   concat)Zinput_shaper   r   r   r   r%   r   Zbatch_shapeZs3s2s1fhfwshswhwcZ	start_idxehewZ
offset_idxZohZowr   Z	new_shaper!   r!   r"   r   _   sH    





r   c             C   s6   t j| tjd} t j| ddgd\}}|d |d fS )z,Splits a length two vector into two scalars.)r%   r   )r#   r   )r   r(   r   r)   r'   )r   abr!   r!   r"   r*      s    r*   c                s   t  fddt D S )z=Adds a list of vectors by cumulatively expanding a dimension.c             3   s8   | ]0\}}t j|d gdgt d |   dV  qdS )r   r   )r   N)r   r   len).0ir   )xsr!   r"   	<genexpr>   s   z!_cartesian_add.<locals>.<genexpr>)sum	enumerate)r>   r!   )r>   r"   r+      s    r+   c             C   s*   t |  }|dkr|S td| dS )z-Verify correctness of `data_format` argument.>   r	   r&   z_Argument data_format="{}" not recognized; must be one of {{"NHWC", "NCHW"}} (case insensitive).N)strupper
ValueErrorformat)r   Zdata_format_r!   r!   r"   r      s    r   c             C   s*   t |  }|dkr|S td| dS )z)Verify correctness of `padding` argument.>   r   r
   z\Argument padding="{}" not recognized; must be one of {{"VALID", "SAME"}} (case insensitive).N)rB   rC   rD   rE   )r   Zpadding_r!   r!   r"   r      s    r   )r   r	   r
   N)__doc__
__future__r   r   r   Ztensorflow.compat.v2compatZv2r   Z&tensorflow_probability.python.internalr   __all__r   int64r   r*   r+   r   r   r!   r!   r!   r"   <module>   s&      
=8
