# Path: pynet/datasets/mnist.py
# class Mnist(SingleBlock):
# 
#     def __init__(self, **kwargs):
# 
#         im_dir = os.environ['PYNET_DATA_PATH'] + '/mnist/'
# 
#         train_X = read_mnist_images(im_dir + 'train-images-idx3-ubyte', dtype='float32')
#         train_y = read_mnist_labels(im_dir + 'train-labels-idx1-ubyte')
# 
#         test_X = read_mnist_images(im_dir + 't10k-images-idx3-ubyte', dtype='float32')
#         test_y = read_mnist_labels(im_dir + 't10k-labels-idx1-ubyte')
# 
#         train_X = train_X.reshape(train_X.shape[0], train_X.shape[1] * train_X.shape[2])
#         test_X = test_X.reshape(test_X.shape[0], test_X.shape[1] * test_X.shape[2])
# 
#         X = np.concatenate((train_X, test_X), axis=0)
# 
#         train_y_tmp = np.zeros((train_X.shape[0], 10), dtype=theano.config.floatX)
#         test_y_tmp = np.zeros((test_X.shape[0], 10), dtype=theano.config.floatX)
# 
#         for i in xrange(train_X.shape[0]):
#             train_y_tmp[i, train_y[i]] = 1
# 
#         for i in xrange(test_X.shape[0]):
#             test_y_tmp[i, test_y[i]] = 1
# 
#         train_y = train_y_tmp
#         test_y = test_y_tmp
# 
#         y = np.concatenate((train_y, test_y), axis=0)
# 
#         super(Mnist, self).__init__(X=X, y=y, **kwargs)
# 
# Path: pynet/datasets/preprocessor.py
# class GCN(Preprocessor):
# 
#     """
#     Adapted from pylearn2
#     Global contrast normalizes by (optionally) subtracting the mean
#     across features and then normalizes by either the vector norm
#     or the standard deviation (across features, for each example).
# 
#     Parameters
#     ----------
#     X : ndarray, 2-dimensional
#         Design matrix with examples indexed on the first axis and
#         features indexed on the second.
# 
#     scale : float, optional
#         Multiply features by this const.
# 
#     subtract_mean : bool, optional
#         Remove the mean across features/pixels before normalizing.
#         Defaults to `False`.
# 
#     use_std : bool, optional
#         Normalize by the per-example standard deviation across features
#         instead of the vector norm.
# 
#     sqrt_bias : float, optional
#         Fudge factor added inside the square root. Defaults to 0.
# 
#     min_divisor : float, optional
#         If the divisor for an example is less than this value,
#         do not apply it. Defaults to `1e-8`.
#     """
# 
#     def __init__(self, scale=1., subtract_mean=False, use_std=False,
#                 sqrt_bias=0., min_divisor=1e-8):
# 
#         self.scale = scale
#         self.subtract_mean = subtract_mean
#         self.use_std = use_std
#         self.sqrt_bias = sqrt_bias
#         self.min_divisor = min_divisor
# 
#     def apply(self, X):
#         """
#         Returns
#         -------
#         Xp : ndarray, 2-dimensional
#             The contrast-normalized features.
# 
#         Notes
#         -----
#         `sqrt_bias` = 10 and `use_std = True` (and defaults for all other
#         parameters) corresponds to the preprocessing used in [1].
# 
#         .. [1] A. Coates, H. Lee and A. Ng. "An Analysis of Single-Layer
#            Networks in Unsupervised Feature Learning". AISTATS 14, 2011.
#            http://www.stanford.edu/~acoates/papers/coatesleeng_aistats_2011.pdf
#         """
#         assert X.ndim == 2, "X.ndim must be 2"
#         scale = float(self.scale)
#         # Note: this is per-example mean across pixels, not the
#         # per-pixel mean across examples. So it is perfectly fine
#         # to subtract this without worrying about whether the current
#         # object is the train, valid, or test set.
#         if self.subtract_mean:
#             self.mean = X.mean(axis=1)[:, np.newaxis]
#             X = X - self.mean  # Makes a copy.
#         else:
#             X = X.copy()
#         if self.use_std:
#             # ddof=1 simulates MATLAB's var() behaviour, which is what Adam
#             # Coates' code does.
#             self.normalizers = np.sqrt(self.sqrt_bias + X.var(axis=1, ddof=1)) / scale
#         else:
#             self.normalizers = np.sqrt(self.sqrt_bias + (X ** 2).sum(axis=1)) / scale
#         # Don't normalize by anything too small.
#         self.normalizers[self.normalizers < self.min_divisor] = 1.
#         X /= self.normalizers[:, np.newaxis]  # Does not make a copy.
#         return X
# 
#     def invert(self, X):
#         try:
#             if self.subtract_mean:
#                 X = X + self.mean
#             rval = X * self.normalizers[:, np.newaxis]
#             return rval
#         except AttributeError:
#             print 'apply() needs to be used before invert()'
#         except:
#             print "Unexpected error:", sys.exc_info()[0]


import os
from pynet.datasets.mnist import Mnist
from pynet.datasets.preprocessor import GCN



os.environ['PYNET_DATA_PATH'] = '/Volumes/Storage/Dropbox/CodingProjects/pynet/data/'


data = Mnist()
train = data.get_train()
proc = GCN()
out = proc.apply(train.X)

# Path: pynet/datasets/mnist.py
# class Mnist(SingleBlock):
# 
#     def __init__(self, **kwargs):
# 
#         im_dir = os.environ['PYNET_DATA_PATH'] + '/mnist/'
# 
#         train_X = read_mnist_images(im_dir + 'train-images-idx3-ubyte', dtype='float32')
#         train_y = read_mnist_labels(im_dir + 'train-labels-idx1-ubyte')
# 
#         test_X = read_mnist_images(im_dir + 't10k-images-idx3-ubyte', dtype='float32')
#         test_y = read_mnist_labels(im_dir + 't10k-labels-idx1-ubyte')
# 
#         train_X = train_X.reshape(train_X.shape[0], train_X.shape[1] * train_X.shape[2])
#         test_X = test_X.reshape(test_X.shape[0], test_X.shape[1] * test_X.shape[2])
# 
#         X = np.concatenate((train_X, test_X), axis=0)
# 
#         train_y_tmp = np.zeros((train_X.shape[0], 10), dtype=theano.config.floatX)
#         test_y_tmp = np.zeros((test_X.shape[0], 10), dtype=theano.config.floatX)
# 
#         for i in xrange(train_X.shape[0]):
#             train_y_tmp[i, train_y[i]] = 1
# 
#         for i in xrange(test_X.shape[0]):
#             test_y_tmp[i, test_y[i]] = 1
# 
#         train_y = train_y_tmp
#         test_y = test_y_tmp
# 
#         y = np.concatenate((train_y, test_y), axis=0)
# 
#         super(Mnist, self).__init__(X=X, y=y, **kwargs)
# 
# Path: pynet/datasets/preprocessor.py
# class GCN(Preprocessor):
# 
#     """
#     Adapted from pylearn2
#     Global contrast normalizes by (optionally) subtracting the mean
#     across features and then normalizes by either the vector norm
#     or the standard deviation (across features, for each example).
# 
#     Parameters
#     ----------
#     X : ndarray, 2-dimensional
#         Design matrix with examples indexed on the first axis and
#         features indexed on the second.
# 
#     scale : float, optional
#         Multiply features by this const.
# 
#     subtract_mean : bool, optional
#         Remove the mean across features/pixels before normalizing.
#         Defaults to `False`.
# 
#     use_std : bool, optional
#         Normalize by the per-example standard deviation across features
#         instead of the vector norm.
# 
#     sqrt_bias : float, optional
#         Fudge factor added inside the square root. Defaults to 0.
# 
#     min_divisor : float, optional
#         If the divisor for an example is less than this value,
#         do not apply it. Defaults to `1e-8`.
#     """
# 
#     def __init__(self, scale=1., subtract_mean=False, use_std=False,
#                 sqrt_bias=0., min_divisor=1e-8):
# 
#         self.scale = scale
#         self.subtract_mean = subtract_mean
#         self.use_std = use_std
#         self.sqrt_bias = sqrt_bias
#         self.min_divisor = min_divisor
# 
#     def apply(self, X):
#         """
#         Returns
#         -------
#         Xp : ndarray, 2-dimensional
#             The contrast-normalized features.
# 
#         Notes
#         -----
#         `sqrt_bias` = 10 and `use_std = True` (and defaults for all other
#         parameters) corresponds to the preprocessing used in [1].
# 
#         .. [1] A. Coates, H. Lee and A. Ng. "An Analysis of Single-Layer
#            Networks in Unsupervised Feature Learning". AISTATS 14, 2011.
#            http://www.stanford.edu/~acoates/papers/coatesleeng_aistats_2011.pdf
#         """
#         assert X.ndim == 2, "X.ndim must be 2"
#         scale = float(self.scale)
#         # Note: this is per-example mean across pixels, not the
#         # per-pixel mean across examples. So it is perfectly fine
#         # to subtract this without worrying about whether the current
#         # object is the train, valid, or test set.
#         if self.subtract_mean:
#             self.mean = X.mean(axis=1)[:, np.newaxis]
#             X = X - self.mean  # Makes a copy.
#         else:
#             X = X.copy()
#         if self.use_std:
#             # ddof=1 simulates MATLAB's var() behaviour, which is what Adam
#             # Coates' code does.
#             self.normalizers = np.sqrt(self.sqrt_bias + X.var(axis=1, ddof=1)) / scale
#         else:
#             self.normalizers = np.sqrt(self.sqrt_bias + (X ** 2).sum(axis=1)) / scale
#         # Don't normalize by anything too small.
#         self.normalizers[self.normalizers < self.min_divisor] = 1.
#         X /= self.normalizers[:, np.newaxis]  # Does not make a copy.
#         return X
# 
#     def invert(self, X):
#         try:
#             if self.subtract_mean:
#                 X = X + self.mean
#             rval = X * self.normalizers[:, np.newaxis]
#             return rval
#         except AttributeError:
#             print 'apply() needs to be used before invert()'
#         except:
#             print "Unexpected error:", sys.exc_info()[0]


# Path: test/test.py
import os
from pynet.datasets.mnist import Mnist
from pynet.datasets.preprocessor import GCN




os.environ['PYNET_DATA_PATH'] = '/Volumes/Storage/Dropbox/CodingProjects/pynet/data/'


data = Mnist()
train = data.get_train()
proc = GCN()
out = proc.apply(train.X)

inv = proc.invert(out)