def __init__(self, theano_warning='raise', hessian=True):
        
        theanofunction = lazytheanofunc('warn', mode='FAST_RUN')
        theanofunction_silent = lazytheanofunc('ignore', mode='FAST_RUN')
        
        # Create theano expressions
        w, x, z = ndict.ordereddicts(self.variables())
        self.var_w, self.var_x, self.var_z, = w, x, z
        
        # Helper variables
        A = T.dmatrix('A')
        self.var_A = A
        
        # Get gradient symbols
        self.allvars = w.values()  + x.values() + z.values() + [A] # note: '+' concatenates lists
        self.allvars_keys = w.keys() + x.keys() + z.keys() + ['A']
        
        if False:
            # Put test values
            # needs fully implemented gen_xz(), which is not always the case
            # Also, the FD has no test values
            theano.config.compute_test_value = 'raise'
            _w = self.init_w()
            for i in _w: w[i].tag.test_value = _w[i]
            _x, _z, _ = self.gen_xz(_w, {}, {}, 10)
            _x, _z = self.xz_to_theano(_x, _z)
            for i in _x: x[i].tag.test_value = _x[i]
            for i in _z: z[i].tag.test_value = _z[i]
        
        # TODO: more beautiful/standardized way of setting distributions
        # (should be even simpler then this) 
        self.dist_px = {}
        self.dist_pz = {}
        
        logpw, logpx, logpz = self.factors(w, x, z, A)
        self.var_logpw, self.var_logpx, self.var_logpz = logpw, logpx, logpz
        
        # Complete-data likelihood estimate
        logpxz = logpx.sum() + logpz.sum()
        self.f_logpxz = theanofunction(self.allvars, [logpx, logpz])
        
        dlogpxz_dwz = T.grad(logpxz, w.values() + z.values())
        self.f_dlogpxz_dwz = theanofunction(self.allvars, [logpx, logpz] + dlogpxz_dwz)
        #self.f_dlogpxz_dw = theanofunction(allvars, [logpxz] + dlogpxz_dw)
        #self.f_dlogpxz_dz = theanofunction(allvars, [logpxz] + dlogpxz_dz)
        
        # prior
        dlogpw_dw = T.grad(logpw, w.values(), disconnected_inputs='ignore')
        self.f_logpw = theanofunction(w.values(), logpw)
        self.f_dlogpw_dw = theanofunction(w.values(), [logpw] + dlogpw_dw)
        
        if False:
            # MC-LIKELIHOOD
            logpx_max = logpx.max()
            logpxmc = T.log(T.exp(logpx - logpx_max).mean()) + logpx_max
            self.f_logpxmc = theanofunction(self.allvars, logpxmc)
            dlogpxmc_dw = T.grad(logpxmc, w.values(), disconnected_inputs=theano_warning)
            self.f_dlogpxmc_dw = theanofunction(self.allvars, [logpxmc] + dlogpxmc_dw)
        
        if True and len(z) > 0:
            # Fisher divergence (FD)
            gz = T.grad(logpxz, z.values())
            gz2 = [T.dmatrix() for _ in gz]
            fd = 0
            for i in range(len(gz)):
                fd += T.sum((gz2[i]-gz[i])**2)
            dfd_dw = T.grad(fd, w.values())
            self.f_dfd_dw = theanofunction(self.allvars + gz2, [logpx, logpz, fd] + dfd_dw)
            
        if False and hessian:
            # Hessian of logpxz wrt z (works best with n_batch=1)
            hessian_z = theano.gradient.hessian(logpxz, z_concat)
            self.f_hessian_z = theanofunction(self.allvars, hessian_z)
        
    # NOTE: IT IS ESSENTIAL THAT DICTIONARIES OF SYMBOLIC VARS AND RESPECTIVE NUMPY VALUES HAVE THE SAME KEYS
    # (OTHERWISE FUNCTION ARGUMENTS ARE IN INCORRECT ORDER)
dataset/ETHPy150Open dpkingma/nips14-ssl/anglepy/BNModel.py/BNModel.__init__/swapped operands of `-`