# Path: emolga/utils/theano_utils.py
# def shared_zeros(shape, dtype=theano.config.floatX, name=None):
#     return sharedX(np.zeros(shape), dtype=dtype, name=name)
# 
# def shared_scalar(val=0., dtype=theano.config.floatX, name=None):
#     return theano.shared(np.cast[dtype](val), name=name)
# 
# def floatX(X):
#     return np.asarray(X, dtype=theano.config.floatX)
# 
# Path: emolga/utils/generic_utils.py
# def get_from_module(identifier, module_params, module_name, instantiate=False, kwargs=None):
#     if isinstance(identifier, six.string_types):
#         res = module_params.get(identifier)
#         if not res:
#             raise Exception('Invalid ' + str(module_name) + ': ' + str(identifier))
#         if instantiate and not kwargs:
#             return res()
#         elif instantiate and kwargs:
#             return res(**kwargs)
#         else:
#             return res
#     return identifier


import theano
import sys
import theano.tensor as T
import logging
from theano.sandbox.rng_mrg import MRG_RandomStreams
from emolga.utils.theano_utils import shared_zeros, shared_scalar, floatX
from emolga.utils.generic_utils import get_from_module
from six.moves import zip
from copy import copy, deepcopy
        grads = self.get_gradients(loss, params)
        accumulators = [shared_zeros(p.get_value().shape) for p in params]
        self.updates = []

        for p, g, a, c in zip(params, grads, accumulators, constraints):
            new_a = a + g ** 2  # update accumulator
            self.updates.append((a, new_a))
            new_p = p - self.lr * g / T.sqrt(new_a + self.epsilon)
            self.updates.append((p, c(new_p)))  # apply constraints
        return self.updates

    def get_config(self):
        return {"name": self.__class__.__name__,
                "lr": float(self.lr.get_value()),
                "epsilon": self.epsilon}


class Adadelta(Optimizer):
    '''
        Reference: http://arxiv.org/abs/1212.5701
    '''
    def __init__(self, lr=0.1, rho=0.95, epsilon=1e-6, *args, **kwargs):
        super(Adadelta, self).__init__(**kwargs)
        self.__dict__.update(locals())
        self.lr = shared_scalar(lr)
        self.iterations = shared_scalar(0)

    def get_updates(self, params, loss):
        grads = self.get_gradients(loss, params)
        accumulators = [shared_zeros(p.get_value().shape) for p in params]

# Path: emolga/utils/theano_utils.py
# def shared_zeros(shape, dtype=theano.config.floatX, name=None):
#     return sharedX(np.zeros(shape), dtype=dtype, name=name)
# 
# def shared_scalar(val=0., dtype=theano.config.floatX, name=None):
#     return theano.shared(np.cast[dtype](val), name=name)
# 
# def floatX(X):
#     return np.asarray(X, dtype=theano.config.floatX)
# 
# Path: emolga/utils/generic_utils.py
# def get_from_module(identifier, module_params, module_name, instantiate=False, kwargs=None):
#     if isinstance(identifier, six.string_types):
#         res = module_params.get(identifier)
#         if not res:
#             raise Exception('Invalid ' + str(module_name) + ': ' + str(identifier))
#         if instantiate and not kwargs:
#             return res()
#         elif instantiate and kwargs:
#             return res(**kwargs)
#         else:
#             return res
#     return identifier


# Path: emolga/basic/optimizers.py
import theano
import sys
import theano.tensor as T
import logging
from theano.sandbox.rng_mrg import MRG_RandomStreams
from emolga.utils.theano_utils import shared_zeros, shared_scalar, floatX
from emolga.utils.generic_utils import get_from_module
from six.moves import zip
from copy import copy, deepcopy

        grads = self.get_gradients(loss, params)
        accumulators = [shared_zeros(p.get_value().shape) for p in params]
        self.updates = []

        for p, g, a, c in zip(params, grads, accumulators, constraints):
            new_a = a + g ** 2  # update accumulator
            self.updates.append((a, new_a))
            new_p = p - self.lr * g / T.sqrt(new_a + self.epsilon)
            self.updates.append((p, c(new_p)))  # apply constraints
        return self.updates

    def get_config(self):
        return {"name": self.__class__.__name__,
                "lr": float(self.lr.get_value()),
                "epsilon": self.epsilon}


class Adadelta(Optimizer):
    '''
        Reference: http://arxiv.org/abs/1212.5701
    '''
    def __init__(self, lr=0.1, rho=0.95, epsilon=1e-6, *args, **kwargs):
        super(Adadelta, self).__init__(**kwargs)
        self.__dict__.update(locals())
        self.lr = shared_scalar(lr)
        self.iterations = shared_scalar(0)

    def get_updates(self, params, loss):
        grads = self.get_gradients(loss, params)
        accumulators = [shared_zeros(p.get_value().shape) for p in params]

        delta_accumulators = [shared_zeros(p.get_value().shape) for p in params]