code: def max_pool(images, imgshp, maxpoolshp):
      """Implements a max pooling layer
  
      Takes as input a 2D tensor of shape batch_size x img_size and
      performs max pooling.  Max pooling downsamples by taking the max
      value in a given area, here defined by maxpoolshp. Outputs a 2D
      tensor of shape batch_size x output_size.
  
      :param images: 2D tensor containing images on which to apply convolution.
                     Assumed to be of shape batch_size x img_size
      :param imgshp: tuple containing image dimensions
      :param maxpoolshp: tuple containing shape of area to max pool over
  
      :return: out1, symbolic result (2D tensor)
      :return: out2, logical shape of the output
      """
      poolsize = np.int64(np.prod(maxpoolshp))
  
      # imgshp contains either 2 entries (height,width) or 3 (nfeatures,h,w)
      # in the first case, default nfeatures to 1
      if np.size(imgshp) == 2:
          imgshp = (1,) + imgshp
  
      # construct indices and index pointers for sparse matrix, which,
      # when multiplied with input images will generate a stack of image
      # patches
      (
          indices,
          indptr,
          spmat_shape,
          sptype,
          outshp,
      ) = convolution_indices.conv_eval(
          imgshp, maxpoolshp, maxpoolshp, mode="valid"
      )
  
      #    print 'XXXXXXXXXXXXXXXX MAX POOLING LAYER XXXXXXXXXXXXXXXXXXXX'
      #    print 'imgshp = ', imgshp
      #    print 'maxpoolshp = ', maxpoolshp
      #    print 'outshp = ', outshp
  
      # build sparse matrix, then generate stack of image patches
      csc = theano.sparse.CSM(sptype)(
          np.ones(indices.size), indices, indptr, spmat_shape
      )
      patches = sparse.structured_dot(csc, images.T).T
  
      pshape = tensor.stack(
          [
              images.shape[0] * tensor.as_tensor(np.prod(outshp)),
              tensor.as_tensor(imgshp[0]),
              tensor.as_tensor(poolsize),
          ]
      )
      patch_stack = tensor.reshape(patches, pshape, ndim=3)
  
      out1 = tensor.max(patch_stack, axis=2)
  
      pshape = tensor.stack(
          [
              images.shape[0],
              tensor.as_tensor(np.prod(outshp)),
              tensor.as_tensor(imgshp[0]),
          ]
      )
      out2 = tensor.reshape(out1, pshape, ndim=3)
  
      out3 = tensor.DimShuffle(out2.broadcastable, (0, 2, 1))(out2)
  
      return tensor.flatten(out3, 2), outshp
  
file_path: Theano/theano/sparse/sandbox/sp.py
imports: from __future__ import absolute_import, print_function, division
  import numpy
  import scipy
  from scipy import sparse
  from six.moves import xrange
  import theano
  import theano.sparse
  from theano import sparse, gof, Op, tensor
  from theano.sparse.basic import Remove0, remove0
  from theano.sparse import SpSum, sp_sum, ColScaleCSC, RowScaleCSC, col_scale, row_scale, Diag, diag, SquareDiagonal, square_diagonal, EnsureSortedIndices, ensure_sorted_indices, clean
label_desc: Use image node_id 3 for calling a global function with example usage: max_pool(images, imgshp, maxpoolshp) and returns: tensor,  outshp