# Path: dsenser/svd/svdbase.py
# class SVDBaseSenser(NNBaseSenser):
#     """Abstract class for disambiguating relation senses.
# 
#     Attributes:
#       n_y (int): number of distinct classes
# 
#     """
# 
#     def _init_nn(self):
#         """Initialize neural network.
# 
#         """
#         self.intm_dim = max(MIN_DIM, self.ndim - (self.ndim - self.n_y) / 2)
#         # indices of word embeddings
#         self.W_INDICES_ARG1 = TT.ivector(name="W_INDICES_ARG1")
#         self.W_INDICES_ARG2 = TT.ivector(name="W_INDICES_ARG2")
#         # connective's index
#         self.CONN_INDEX = TT.iscalar(name="CONN_INDEX")
#         # initialize the matrix of word embeddings
#         self.init_w_emb()
#         # word embeddings of the arguments
#         self.EMB_ARG1 = self.W_EMB[self.W_INDICES_ARG1]
#         self.EMB_ARG2 = self.W_EMB[self.W_INDICES_ARG2]
#         # connective's embedding
#         self._init_conn_emb()
#         self.EMB_CONN = self.CONN_EMB[self.CONN_INDEX]
#         # perform matrix decomposition
#         _, _, self.ARG1 = TT.nlinalg.svd(self.EMB_ARG1,
#                                          full_matrices=True)
#         _, _, self.ARG2 = TT.nlinalg.svd(self.EMB_ARG2,
#                                          full_matrices=True)
#         self.ARG_DIFF = self.ARG1 - self.ARG2
#         # map decomposed matrices to the intermediate level
#         self.ARG_DIFF2I = theano.shared(value=HE_UNIFORM((self.ndim, 1)),
#                                         name="ARG_DIFF2I")
#         self.arg_diff_bias = theano.shared(value=HE_UNIFORM((1, self.ndim)),
#                                            name="arg_diff_bias")
#         self._params.extend([self.ARG_DIFF2I, self.arg_diff_bias])
#         self.ARGS = (TT.dot(self.ARG_DIFF, self.ARG_DIFF2I).T +
#                      self.arg_diff_bias).flatten()
#         # define final units
#         self.I = TT.concatenate((self.ARGS, self.EMB_CONN))
#         self.I2Y = theano.shared(value=HE_UNIFORM((self.n_y,
#                                                    self.ndim + self.intm_dim)),
#                                  name="I2Y")
#         self.y_bias = theano.shared(value=HE_UNIFORM((1, self.n_y)),
#                                     name="y_bias")
#         self._params.extend([self.I2Y, self.y_bias])
#         self.Y_pred = TT.nnet.softmax(TT.dot(self.I2Y, self.I).T + self.y_bias)
#         # initialize cost and optimization functions
#         self.Y_gold = TT.vector(name="Y_gold")
#         self._cost = TT.sum((self.Y_pred - self.Y_gold) ** 2)
#         self._dev_cost = TT.sum((self.Y_pred - self.Y_gold) ** 2)
#         self._pred_class = TT.argmax(self.Y_pred)
#         grads = TT.grad(self._cost, wrt=self._params)
#         self._init_funcs(grads)
# 
# MIN_DIM = 50
# 
# Path: dsenser/theano_utils.py
# def floatX(a_data, a_dtype=config.floatX):
# def rmsprop(tparams, grads, x, y, cost):
# MAX_ITERS = 150  # 450
# CONV_EPS = 1e-5
# DFLT_VDIM = 100
# _HE_NORMAL = HeNormal()
# HE_NORMAL = lambda x: floatX(_HE_NORMAL.sample(x))
# _HE_UNIFORM = HeUniform()
# HE_UNIFORM = lambda x: floatX(_HE_UNIFORM.sample(x))
# _HE_UNIFORM_RELU = HeUniform(gain=np.sqrt(2))
# HE_UNIFORM_RELU = lambda x: floatX(_HE_UNIFORM_RELU.sample(x))
# _RELU_ALPHA = 0.
# _HE_UNIFORM_LEAKY_RELU = HeUniform(
#     gain=np.sqrt(2. / (1 + (_RELU_ALPHA or 1e-6)**2)))
# HE_UNIFORM_LEAKY_RELU = lambda x: \
#     floatX(_HE_UNIFORM_LEAKY_RELU.sample(x))
# _ORTHOGONAL = Orthogonal()
# ORTHOGONAL = lambda x: floatX(_ORTHOGONAL.sample(x))
# TRNG = RandomStreams()


from dsenser.svd.svdbase import SVDBaseSenser, MIN_DIM
from dsenser.theano_utils import HE_UNIFORM, TT, floatX
from mock import patch, MagicMock
from pytest import fixture
from unittest import TestCase
from theano.tensor.var import TensorVariable
import dsenser
import numpy as np
import theano
        import sys


##################################################################
# Test Classes
class TestSVDBaseSenser(TestCase):
    @fixture(autouse=True)
    def set_svd(self):
        with patch.object(dsenser.nnbase, "Word2Vec",
                          MagicMock(ndim=300)):
            self.svd = SVDBaseSenser(a_w2v=True)
            self.svd.w_i = 50
            self.svd.n_y = 20
            self.svd._init_nn()

    def test_svd_0(self):
        # check that the variables are of the right size
        assert self.svd.intm_dim >= MIN_DIM
        assert isinstance(self.svd.W_INDICES_ARG1,
                          TensorVariable)
        assert self.svd.W_INDICES_ARG1.type.ndim == 1
        assert isinstance(self.svd.W_INDICES_ARG2,
                          TensorVariable)
        assert self.svd.CONN_INDEX.type.ndim == 0

    def test_svd_1(self):
        # compile function that takes preliminary inout and outputs SVD
        get_svd = theano.function([self.svd.EMB_ARG1], self.svd.ARG1,
                                  name="get_svd")
        ret = get_svd(floatX(np.random.randn(20, 30)))
        print(ret.size, ret.shape, file=sys.stderr)

# Path: dsenser/svd/svdbase.py
# class SVDBaseSenser(NNBaseSenser):
#     """Abstract class for disambiguating relation senses.
# 
#     Attributes:
#       n_y (int): number of distinct classes
# 
#     """
# 
#     def _init_nn(self):
#         """Initialize neural network.
# 
#         """
#         self.intm_dim = max(MIN_DIM, self.ndim - (self.ndim - self.n_y) / 2)
#         # indices of word embeddings
#         self.W_INDICES_ARG1 = TT.ivector(name="W_INDICES_ARG1")
#         self.W_INDICES_ARG2 = TT.ivector(name="W_INDICES_ARG2")
#         # connective's index
#         self.CONN_INDEX = TT.iscalar(name="CONN_INDEX")
#         # initialize the matrix of word embeddings
#         self.init_w_emb()
#         # word embeddings of the arguments
#         self.EMB_ARG1 = self.W_EMB[self.W_INDICES_ARG1]
#         self.EMB_ARG2 = self.W_EMB[self.W_INDICES_ARG2]
#         # connective's embedding
#         self._init_conn_emb()
#         self.EMB_CONN = self.CONN_EMB[self.CONN_INDEX]
#         # perform matrix decomposition
#         _, _, self.ARG1 = TT.nlinalg.svd(self.EMB_ARG1,
#                                          full_matrices=True)
#         _, _, self.ARG2 = TT.nlinalg.svd(self.EMB_ARG2,
#                                          full_matrices=True)
#         self.ARG_DIFF = self.ARG1 - self.ARG2
#         # map decomposed matrices to the intermediate level
#         self.ARG_DIFF2I = theano.shared(value=HE_UNIFORM((self.ndim, 1)),
#                                         name="ARG_DIFF2I")
#         self.arg_diff_bias = theano.shared(value=HE_UNIFORM((1, self.ndim)),
#                                            name="arg_diff_bias")
#         self._params.extend([self.ARG_DIFF2I, self.arg_diff_bias])
#         self.ARGS = (TT.dot(self.ARG_DIFF, self.ARG_DIFF2I).T +
#                      self.arg_diff_bias).flatten()
#         # define final units
#         self.I = TT.concatenate((self.ARGS, self.EMB_CONN))
#         self.I2Y = theano.shared(value=HE_UNIFORM((self.n_y,
#                                                    self.ndim + self.intm_dim)),
#                                  name="I2Y")
#         self.y_bias = theano.shared(value=HE_UNIFORM((1, self.n_y)),
#                                     name="y_bias")
#         self._params.extend([self.I2Y, self.y_bias])
#         self.Y_pred = TT.nnet.softmax(TT.dot(self.I2Y, self.I).T + self.y_bias)
#         # initialize cost and optimization functions
#         self.Y_gold = TT.vector(name="Y_gold")
#         self._cost = TT.sum((self.Y_pred - self.Y_gold) ** 2)
#         self._dev_cost = TT.sum((self.Y_pred - self.Y_gold) ** 2)
#         self._pred_class = TT.argmax(self.Y_pred)
#         grads = TT.grad(self._cost, wrt=self._params)
#         self._init_funcs(grads)
# 
# MIN_DIM = 50
# 
# Path: dsenser/theano_utils.py
# def floatX(a_data, a_dtype=config.floatX):
# def rmsprop(tparams, grads, x, y, cost):
# MAX_ITERS = 150  # 450
# CONV_EPS = 1e-5
# DFLT_VDIM = 100
# _HE_NORMAL = HeNormal()
# HE_NORMAL = lambda x: floatX(_HE_NORMAL.sample(x))
# _HE_UNIFORM = HeUniform()
# HE_UNIFORM = lambda x: floatX(_HE_UNIFORM.sample(x))
# _HE_UNIFORM_RELU = HeUniform(gain=np.sqrt(2))
# HE_UNIFORM_RELU = lambda x: floatX(_HE_UNIFORM_RELU.sample(x))
# _RELU_ALPHA = 0.
# _HE_UNIFORM_LEAKY_RELU = HeUniform(
#     gain=np.sqrt(2. / (1 + (_RELU_ALPHA or 1e-6)**2)))
# HE_UNIFORM_LEAKY_RELU = lambda x: \
#     floatX(_HE_UNIFORM_LEAKY_RELU.sample(x))
# _ORTHOGONAL = Orthogonal()
# ORTHOGONAL = lambda x: floatX(_ORTHOGONAL.sample(x))
# TRNG = RandomStreams()


# Path: tests/svd/test_svd_base.py
from dsenser.svd.svdbase import SVDBaseSenser, MIN_DIM
from dsenser.theano_utils import HE_UNIFORM, TT, floatX
from mock import patch, MagicMock
from pytest import fixture
from unittest import TestCase
from theano.tensor.var import TensorVariable
import dsenser
import numpy as np
import theano
        import sys



##################################################################
# Test Classes
class TestSVDBaseSenser(TestCase):
    @fixture(autouse=True)
    def set_svd(self):
        with patch.object(dsenser.nnbase, "Word2Vec",
                          MagicMock(ndim=300)):
            self.svd = SVDBaseSenser(a_w2v=True)
            self.svd.w_i = 50
            self.svd.n_y = 20
            self.svd._init_nn()

    def test_svd_0(self):
        # check that the variables are of the right size
        assert self.svd.intm_dim >= MIN_DIM
        assert isinstance(self.svd.W_INDICES_ARG1,
                          TensorVariable)
        assert self.svd.W_INDICES_ARG1.type.ndim == 1
        assert isinstance(self.svd.W_INDICES_ARG2,
                          TensorVariable)
        assert self.svd.CONN_INDEX.type.ndim == 0

    def test_svd_1(self):
        # compile function that takes preliminary inout and outputs SVD
        get_svd = theano.function([self.svd.EMB_ARG1], self.svd.ARG1,
                                  name="get_svd")
        ret = get_svd(floatX(np.random.randn(20, 30)))
        print(ret.size, ret.shape, file=sys.stderr)

        a = ret.dot(ret.T)