# Path: DeepFried2/utils.py
# def expand(tup, ndim, name=None, expand_nonnum=False):
#     if isinstance(tup, (tuple, list)) and len(tup) == ndim:
#         return tup
# 
#     if isinstance(tup, _Number) or expand_nonnum:
#         return (tup,) * ndim
# 
#     if not expand_nonnum:
#         return tup
# 
#     raise ValueError("Bad number of dimensions{}: is {} but should be {}.".format((" for " + name) if name else "", len(tup), ndim))


import DeepFried2 as df
import numpy as np
from DeepFried2.utils import expand
from theano.tensor.nnet import conv3d2d

class SpatialConvolution(df.Module):
    def __init__(self, nchan_in, nchan_out, filter_size, stride=1, border='valid', mode='cross', init=df.init.xavier(), bias=0, imshape=None):
        # See `SpatialConvolutionCUDNN` comment for the `mode` parameter. Only works in 2D
        df.Module.__init__(self)
        self.nchan_in = nchan_in
        self.nchan_out = nchan_out
        self.filter_size = filter_size
        self.mode = mode

# Path: DeepFried2/utils.py
# def expand(tup, ndim, name=None, expand_nonnum=False):
#     if isinstance(tup, (tuple, list)) and len(tup) == ndim:
#         return tup
# 
#     if isinstance(tup, _Number) or expand_nonnum:
#         return (tup,) * ndim
# 
#     if not expand_nonnum:
#         return tup
# 
#     raise ValueError("Bad number of dimensions{}: is {} but should be {}.".format((" for " + name) if name else "", len(tup), ndim))


# Path: DeepFried2/layers/SpatialConvolution.py
import DeepFried2 as df
import numpy as np
from DeepFried2.utils import expand
from theano.tensor.nnet import conv3d2d


class SpatialConvolution(df.Module):
    def __init__(self, nchan_in, nchan_out, filter_size, stride=1, border='valid', mode='cross', init=df.init.xavier(), bias=0, imshape=None):
        # See `SpatialConvolutionCUDNN` comment for the `mode` parameter. Only works in 2D
        df.Module.__init__(self)
        self.nchan_in = nchan_in
        self.nchan_out = nchan_out
        self.filter_size = filter_size
        self.mode = mode

        self.imshape = expand(imshape, len(filter_size), 'imshape', expand_nonnum=True)