def cnn_convolve(patch_dim, num_features, images, W, b, zca_white, patch_mean):

    num_images = images.shape[3]
    image_dim = images.shape[0]
    image_channels = images.shape[2]

    #  Instructions:
    #    Convolve every feature with every large image here to produce the
    #    numFeatures x numImages x (imageDim - patchDim + 1) x (imageDim - patchDim + 1)
    #    matrix convolvedFeatures, such that
    #    convolvedFeatures(featureNum, imageNum, imageRow, imageCol) is the
    #    value of the convolved featureNum feature for the imageNum image over
    #    the region (imageRow, imageCol) to (imageRow + patchDim - 1, imageCol + patchDim - 1)
    #
    #  Expected running times:
    #    Convolving with 100 images should take less than 3 minutes
    #    Convolving with 5000 images should take around an hour
    #    (So to save time when testing, you should convolve with less images, as
    #    described earlier)

    convolved_features = np.zeros(shape=(num_features, num_images, image_dim - patch_dim + 1,
                                         image_dim - patch_dim + 1),
                                  dtype=np.float64)

    WT = W.dot(zca_white)
    bT = b - WT.dot(patch_mean)

    for i in range(num_images):
        for j in range(num_features):
            # convolution of image with feature matrix for each channel
            convolved_image = np.zeros(shape=(image_dim - patch_dim + 1, image_dim - patch_dim + 1),
                                       dtype=np.float64)

            for channel in range(image_channels):
                # Obtain the feature (patchDim x patchDim) needed during the convolution
                patch_size = patch_dim * patch_dim
                feature = WT[j, patch_size * channel:patch_size * (channel + 1)].reshape(patch_dim, patch_dim)

                # Flip the feature matrix because of the definition of convolution, as explained later
                feature = np.flipud(np.fliplr(feature))

                # Obtain the image
                im = images[:, :, channel, i]

                # Convolve "feature" with "im", adding the result to convolvedImage
                # be sure to do a 'valid' convolution
                convolved_image += scipy.signal.convolve2d(im, feature, mode='valid')

            # Subtract the bias unit (correcting for the mean subtraction as well)
            # Then, apply the sigmoid function to get the hidden activation
            convolved_image = sigmoid(convolved_image + bT[j])

            # The convolved feature is the sum of the convolved values for all channels
            convolved_features[j, i, :, :] = convolved_image

    return convolved_features
Returns the convolution of the features given by W and b with
dataset/ETHPy150Open jatinshah/ufldl_tutorial/cnn.py/cnn_convolve