Ejemplo n.º 1
0
    def gcn_layer_gen(self,
                      _input,
                      input_dim,
                      output_dim,
                      layer_name,
                      act_fun,
                      sparse_input=False,
                      record_vars=False):
        """
        GCN层计算图
        """
        with tf.variable_scope(layer_name):
            THWs = []

            if sparse_input:  #【如果使用了稀疏矩阵,则需去除特征向量中的空值】
                H = utils.sparse_dropout(
                    _input, 1 - self.dropout,
                    self.num_features_nonzero)  #【去除含空值之后维度不会出问题吗?】
            else:
                H = tf.nn.dropout(_input, 1 - self.dropout)

            for i, suport in enumerate(self.supports):
                W = inits.glorot([input_dim, output_dim],
                                 name=f'{layer_name}_weight_{i}')
                #【第一轮:名为:layer1 W为(1433*16) 第二轮:名为:layer2 W为(16*7)】
                if record_vars:
                    self.vars.append(W)
                HW = utils.dot(H, W, sparse=sparse_input)
                THW = utils.dot(suport, HW, sparse=True)
                THWs.append(THW)
            output = tf.add_n(THWs)  #【THW列表元素相加】
            # bias = inits.zeros([output_dim], name='bias')
            # output += bias
            output = act_fun(output)
        return output
Ejemplo n.º 2
0
    def castRay(self, origin, direction):
        material, intersect = self.sceneIntersect(origin, direction)
        
        if material is None:
            return self.currentColor

        lightDir = norm(sub(self.light.position, intersect.point))
        lightDistance = length(sub(self.light.position, intersect.point))
        
        offsetNormal = mul(intersect.normal, 1.1)
        shadowOrigin = sub(intersect.point, offsetNormal) if dot(lightDir, intersect.normal) < 0 else sum(intersect.point, offsetNormal)
        shadowMaterial, shadowIntersect = self.sceneIntersect(shadowOrigin, lightDir)
        shadowIntensity = 0

        if shadowMaterial and length(sub(shadowIntersect.point, shadowOrigin)) < lightDistance:
            shadowIntensity = 0.9

        intensity = self.light.intensity * max(0, dot(lightDir, intersect.normal)) * (1 - shadowIntensity)

        reflection = reflect(lightDir, intersect.normal)
        specularIntensity = self.light.intensity * (
            max(0, -dot(reflection, direction)) ** material.spec
        )

        diffuse = material.diffuse * intensity * material.albedo[0]
        specular = Color(255, 255, 255) * specularIntensity * material.albedo[1]
        return diffuse + specular
Ejemplo n.º 3
0
    def side(self, v0, v1, v2, origin, direction):
        v0v1 = sub(v1, v0)
        v0v2 = sub(v2, v0)

        N = cross(v0v1, v0v2)
        
        raydirection = dot(N, direction)

        if abs(raydirection) < 0.0001:
            return None
        
        d = dot(N, v0)
        
        t = (dot(N, origin) + d) / raydirection
        
        if t < 0:
            return None

        P = sum(origin, mul(direction, t))
        U, V, W = barycentric(v0, v1, v2, P)
        
        if U < 0 or V < 0 or W < 0:
            return None
        else: 
            return Intersect(distance = d,
                         point = P,
                         normal = norm(N))
Ejemplo n.º 4
0
    def call(self, inputs, training=False, **kwargs):
        x, support_ = inputs

        # dropout
        if training and self.is_sparse_inputs:
            x = self.sparse_dropout(x, 1 - self.dropout, self.num_features_nonzero)
        else:
            x = tf.nn.dropout(x, 1 - self.dropout)

        # convolve
        supports = list()
        for i in range(len(support_)):
            if not self.featureless:  # if it has features x
                pre_sup = dot(x, self.weights_[i], spares=self.is_sparse_inputs)
            else:
                pre_sup = self.weights_[i]
            support = dot(support_[i], pre_sup, spares=True)
            supports.append(support)
        output = tf.add_n(supports)

        # bias
        if self.bias:
            output += self.bias

        return self.activation(output)
Ejemplo n.º 5
0
def point_line_segment_distances2(points, linesA, linesB):
    n_p = points.shape[0]
    n_l = linesA.shape[0]

    dir_line = utils.normalize(linesB - linesA).unsqueeze(0).expand(
        n_p, -1, -1)
    vecA = points.unsqueeze(1).expand(
        -1, n_l, -1) - linesA.unsqueeze(0).expand(n_p, -1, -1)
    vecB = points.unsqueeze(1).expand(
        -1, n_l, -1) - linesB.unsqueeze(0).expand(n_p, -1, -1)

    # Distances to first endpoint
    dists2 = utils.norm2(vecA)

    # Distances to second endpoint
    dists2 = torch.min(dists2, utils.norm2(vecB))

    # Points within segment
    in_line = (utils.dot(dir_line, vecA) > 0) & (utils.dot(dir_line, vecB) < 0)

    # Distances to line
    line_dists2 = utils.norm2(
        utils.project_to_tangent(vecA[in_line], dir_line[in_line]))
    dists2[in_line] = line_dists2

    return dists2
Ejemplo n.º 6
0
def conmf_cost(Vs, Ws, Hs, weights, regu_weights, norm, method):
    """
    Calculate the value of cost function(Frobenius form) of CoNMF.
    Two parts of the cost function: factorization part and regularization part, are calculated seperately.
    """
    # Factorization part
    sum1 = 0
    for k in range(0, len(weights)):
        V, W, H = Vs[k], Ws[k], Hs[k]
        dot_WH = dot(W, H)
        R = V - dot_WH
        sum1 = sum1 + weights[k] * multiply(R, R).sum()

    # Regularization part
    sum2 = 0
    for k in range(0, len(weights)):
        for t in range(0, len(weights)):
            if k == t: continue
            if k < t: lambda_kt = regu_weights[k][t]
            if k > t: lambda_kt = regu_weights[t][k]
            if method == "pair-wise":
                R = Ws[k] - Ws[t]
                sum2 = sum2 + lambda_kt * multiply(R, R).sum()
            if method == "cluster-wise":
                R = dot(Ws[k].T, Ws[k]) - dot(Ws[t].T, Ws[t])
                sum2 = sum2 + lambda_kt * multiply(R, R).sum()

    return sum1 + sum2
Ejemplo n.º 7
0
    def castRay(self, origin, direction, recursion=0):
        material, intersect = self.sceneIntersect(origin, direction)

        if material is None or recursion >= MAX_RECURSION_DEPTH:
            return self.currentColor
            # Si el rayo no golpeo nada o si llego al limite de recursion

        lightDir = norm(sub(self.light.position, intersect.point))
        lightDistance = length(sub(self.light.position, intersect.point))

        offsetNormal = mul(intersect.normal, 1.1)
        shadowOrigin = sub(
            intersect.point,
            offsetNormal) if dot(lightDir, intersect.normal) < 0 else sum(
                intersect.point, offsetNormal)
        shadowMaterial, shadowIntersect = self.sceneIntersect(
            shadowOrigin, lightDir)
        shadowIntensity = 0

        if shadowMaterial and length(sub(shadowIntersect.point,
                                         shadowOrigin)) < lightDistance:
            shadowIntensity = 0.9

        intensity = self.light.intensity * max(
            0, dot(lightDir, intersect.normal)) * (1 - shadowIntensity)

        reflection = reflect(lightDir, intersect.normal)
        specularIntensity = self.light.intensity * (max(
            0, -dot(reflection, direction))**material.spec)

        if material.albedo[2] > 0:
            reflectDir = reflect(direction, intersect.normal)
            reflectOrigin = sub(intersect.point, offsetNormal) if dot(
                reflectDir, intersect.normal) < 0 else sum(
                    intersect.point, offsetNormal)
            reflectedColor = self.castRay(reflectOrigin, reflectDir,
                                          recursion + 1)
        else:
            reflectedColor = self.currentColor

        if material.albedo[3] > 0:
            refractDir = refract(direction, intersect.normal,
                                 material.refractionIndex)
            refractOrigin = sub(intersect.point, offsetNormal) if dot(
                refractDir, intersect.normal) < 0 else sum(
                    intersect.point, offsetNormal)
            refractedColor = self.castRay(refractOrigin, refractDir,
                                          recursion + 1)
        else:
            refractedColor = self.currentColor

        diffuse = material.diffuse * intensity * material.albedo[0]
        specular = Color(255, 255,
                         255) * specularIntensity * material.albedo[1]
        reflected = reflectedColor * material.albedo[2]
        refracted = refractedColor * material.albedo[3]

        return diffuse + specular + reflected + refracted
    def create_new_data_function(self):
        # self.z_test = sharedZeroMatrix(self.Q,1,'z_test')
        h_decoder  = softplus(dot(self.W_zh,self.z_test.T) + self.b_zh)
        if self.numHiddenLayers_decoder == 2:
            h_decoder = softplus(dot(self.W_hh, h_decoder) + self.b_hh)
        mu_decoder = dot(self.W_hy1, h_decoder) + self.b_hy1
        self.new_data_function = th.function([], mu_decoder, no_default_updates=True)

        return mu_decoder
Ejemplo n.º 9
0
 def predict(self, point, y_hat=2):
     P_0 = 1 / (1 + utils.math.exp(utils.dot(self.w, point.x)))
     P_1 = 1 / (1 + utils.math.exp(-utils.dot(self.w, point.x)))
     if y_hat == 1:
         print("Pr(y^ = 1):", P_1)
     elif y_hat == 0:
         print("Pr(y^ = 0):", P_0)
     else:
         print("Pr(y^ = 0):", P_0)
         print("Pr(y^ = 1):", P_1)
    def reconstruct_test_datum(self):
        self.y_test = self.y(np.random.choice(self.N, 1))

        h_qX = softplus(plus(dot(self.W1_qX, self.y_test.T), self.b1_qX))
        mu_qX = plus(dot(self.W2_qX, h_qX), self.b2_qX)
        log_sigma_qX = mul( 0.5, plus(dot(self.W3_qX, h_qX), self.b3_qX))

        self.phi_test  = mu_qX.T  # [BxR]
        (self.Phi_test,self.cPhi_test,self.iPhi_test,self.logDetPhi_test) \
            = diagCholInvLogDet_fromLogDiag(log_sigma_qX)

        self.Xz_test = plus( self.phi_test, dot(self.cPhi_test, self.xi[0,:]))

        self.Kzz_test = kfactory.kernel(self.Xz_test, None,    self.log_theta)
        self.Kzu_test = kfactory.kernel(self.Xz_test, self.Xu, self.log_theta)

        self.A_test  = dot(self.Kzu_test, self.iKuu)
        self.C_test  = minus( self.Kzz_test, dot(self.A_test, self.Kzu_test.T))
        self.cC_test, self.iC_test, self.logDetC_test = cholInvLogDet(self.C_test, self.B, self.jitter)

        self.u_test  = plus( self.kappa, (dot(self.cKappa, self.alpha)))

        self.mu_test = dot(self.A_test, self.u_test)

        self.z_test  = plus(self.mu_test, (dot(self.cC_test, self.beta[0,:])))
Ejemplo n.º 11
0
    def reconstruct_test_datum(self):
        self.y_test = self.y(np.random.choice(self.N, 1))

        h_qX = softplus(plus(dot(self.W1_qX, self.y_test.T), self.b1_qX))
        mu_qX = plus(dot(self.W2_qX, h_qX), self.b2_qX)
        log_sigma_qX = mul(0.5, plus(dot(self.W3_qX, h_qX), self.b3_qX))

        self.phi_test = mu_qX.T  # [BxR]
        (self.Phi_test,self.cPhi_test,self.iPhi_test,self.logDetPhi_test) \
            = diagCholInvLogDet_fromLogDiag(log_sigma_qX)

        self.Xz_test = plus(self.phi_test, dot(self.cPhi_test, self.xi[0, :]))

        self.Kzz_test = kfactory.kernel(self.Xz_test, None, self.log_theta)
        self.Kzu_test = kfactory.kernel(self.Xz_test, self.Xu, self.log_theta)

        self.A_test = dot(self.Kzu_test, self.iKuu)
        self.C_test = minus(self.Kzz_test, dot(self.A_test, self.Kzu_test.T))
        self.cC_test, self.iC_test, self.logDetC_test = cholInvLogDet(
            self.C_test, self.B, self.jitter)

        self.u_test = plus(self.kappa, (dot(self.cKappa, self.alpha)))

        self.mu_test = dot(self.A_test, self.u_test)

        self.z_test = plus(self.mu_test, (dot(self.cC_test, self.beta[0, :])))
Ejemplo n.º 12
0
def conmf_update(Vs, Ws, Hs, weights, regu_weights, norm, method):
    """
    The iterative rules of CoNMF. Details in paper [1] Section 4.3 and 4.4.
    
    :param Vs (type: list<csr_matrix>). Data of each view.
    :param Ws (type: list<csr_matrix). W matrix of each view.
    :param Hs (type: list<csr_matrix). H matrix of each view.
    :param weights (type: list<int>). Regularization parameters \lambda_s.
    :param regu_weights (type: list, 2 dimension). Regularization parameters \lambda_st.
    :param norm (type: string). Normalization scheme in CoNMF initialization and factorization. Values can be 'l2', 'l1' and 'l0':
        'l2': each item vector is normalized by its euclidean length (i.e. l2 distance).
        'l1': each item vector is normalized by its sum of all elements (i.e. l1 distance). 
        'l0': the whole matrix is normalized by the sum of all elements (i.e. l1 normalization on the whole matrix).
    :param method (type: string). Regularization method of CoNMF. Currently support two ways:
    'pair-wise': pair-wise NMF, details in paper [1] Section 4.3
    'cluster-wise': cluster-wise NMF, details in paper [1] Section 4.4
    
    V = W H
    V: #item * #feature; 
    W: #item * #cluster
    H: #cluster * #feature
    """
    # Update Hs[k]
    Ws, Hs = conmf_normalize(Ws, Hs, norm, basis="W")
    # Update Hs[k] first. NMF, CoNMF(mutual, cluster) are same for this updates
    for k in range(0, len(weights)):
        V, W, H = Vs[k], Ws[k], Hs[k]
        up = dot(W.T, V)
        down = dot(dot(W.T, W), H)
        elop_div = elop(up, down, div)
        Hs[k] = multiply(H, elop_div)

    # Update Ws[k]
    for k in range(0, len(weights)):
        V, W, H = Vs[k], Ws[k], Hs[k]
        up = dot(V, H.T) * weights[k]
        down = dot(W, dot(H, H.T)) * weights[k]
        if method == "pair-wise":
            for t in range(0, len(weights)):
                if k == t: continue
                if k < t: lambda_kt = regu_weights[k][t]
                if k > t: lambda_kt = regu_weights[t][k]
                up = up + Ws[t] * lambda_kt
                down = down + W * lambda_kt
        if method == "cluster-wise":
            for t in range(0, len(weights)):
                if k == t: continue
                if k < t: lambda_kt = regu_weights[k][t]
                if k > t: lambda_kt = regu_weights[t][k]
                up = up + 2 * lambda_kt * dot(Ws[k], dot(Ws[t].T, Ws[t]))
                down = down + 2 * lambda_kt * dot(Ws[k], dot(Ws[k].T, Ws[k]))
        elop_div = elop(up, down, div)
        Ws[k] = multiply(W, elop_div)

    return Ws, Hs
Ejemplo n.º 13
0
    def create_new_data_function(self):
        # self.z_test = sharedZeroMatrix(self.Q,1,'z_test')
        h_decoder = softplus(dot(self.W_zh, self.z_test.T) + self.b_zh)
        if self.numHiddenLayers_decoder == 2:
            h_decoder = softplus(dot(self.W_hh, h_decoder) + self.b_hh)
        mu_decoder = dot(self.W_hy1, h_decoder) + self.b_hy1
        self.new_data_function = th.function([],
                                             mu_decoder,
                                             no_default_updates=True)

        return mu_decoder
    def KL_qp(self):

        if self.continuous:
            kappa_outer = dot(self.kappa, self.kappa.T, 'kappa_outer')
            AtA = dot(self.A.T, self.A)
            KL = 0.5*self.Q*trace(self.C) + 0.5*trace(dot(AtA,kappa_outer)) \
                + 0.5*self.Q+trace(dot(AtA,self.Kappa)) - 0.5*self.Q*self.B - 0.5*self.Q*self.logDetC
            KL.name = 'KL_qp'
        else:
            raise RuntimeError("Case not implemented")

        return KL
Ejemplo n.º 15
0
    def KL_qp(self):

        if self.continuous:
            kappa_outer = dot(self.kappa, self.kappa.T, 'kappa_outer')
            AtA = dot(self.A.T, self.A)
            KL = 0.5*self.Q*trace(self.C) + 0.5*trace(dot(AtA,kappa_outer)) \
                + 0.5*self.Q+trace(dot(AtA,self.Kappa)) - 0.5*self.Q*self.B - 0.5*self.Q*self.logDetC
            KL.name = 'KL_qp'
        else:
            raise RuntimeError("Case not implemented")

        return KL
Ejemplo n.º 16
0
 def log_r_X_z(self):
     X_m_tau = minus(self.Xz, self.tau)
     X_m_tau_vec = T.reshape(X_m_tau, [self.B * self.R, 1])
     X_m_tau_vec.name = 'X_m_tau_vec'
     if self.Tau_isDiagonal:
         log_rX_z = -0.5 * self.R * self.B * log2pi - 0.5 * self.R * self.logDetTau \
         - 0.5 * trace(dot(X_m_tau_vec.T, div(X_m_tau_vec,self.Tau)))
     else:
         log_rX_z = -0.5 * self.R * self.B * log2pi - 0.5 * self.R * self.logDetTau \
         - 0.5 * trace(dot(X_m_tau_vec.T, dot(self.iTau, X_m_tau_vec)))
     log_rX_z.name = 'log_rX_z'
     return log_rX_z
Ejemplo n.º 17
0
    def _k_intersect(self, other):
        u2 = utils.dot(self.direction, self.direction)
        v2 = utils.dot(other.direction, other.direction)
        uv = utils.dot(self.direction, other.direction)

        AC = utils.vector(self.point, other.point)
        AC_u = utils.dot(AC, self.direction)
        AC_v = utils.dot(AC, other.direction)

        lower = u2 * v2 - uv * uv
        if lower == 0:
            return None
        return (AC_u * v2 - AC_v * uv) / lower
Ejemplo n.º 18
0
def conmf_normalize(Ws, Hs, norm="l2", basis="H"):
    """
    Normalization strategy of CoNMF, details in [1] Section 4.3.2.     
    
    :param basis (type: string). Indicate which matrix to use for calculating the norm factors. Values can be 'H' and 'W':
        'H':First calculating norm factors from H (rows), then
            1. Normalize W;
            2. Normalize H (row)
        'W':First calculating norm factors from W (cols), then
            1. Normalize H;
            2. Normalize W (col)
    """
    if norm == "none":
        return Ws, Hs

    if basis not in ["W", "H"]:
        print "Error! Input basis is not 'W' or 'H'!"

    if basis == "H":
        for k in range(len(Hs)):
            W, H = Ws[k], Hs[k]
            if norm == "l1" or norm == "l0":
                S = np.squeeze(np.asarray(H.sum(axis=1)))  #Type: np.array
            if norm == "l2":
                S = np.squeeze(np.asarray(multiply(H, H).sum(axis=1)))
                S = np.sqrt(S)

            D, D_inv = sparse.lil_matrix((len(S), len(S))), sparse.lil_matrix(
                (len(S), len(S)))
            D.setdiag(S)
            D_inv.setdiag(1.0 / S)
            Ws[k] = dot(W, D)
            Hs[k] = dot(D_inv, H)

    if basis == "W":
        for k in range(len(Hs)):
            W, H = Ws[k], Hs[k]
            if norm == "l1" or norm == "l0":
                S = np.squeeze(np.asarray(W.sum(axis=0)))  #Type: np.array
            if norm == "l2":
                S = np.squeeze(np.asarray(multiply(W, W).sum(axis=0)))
                S = np.sqrt(S)

            D, D_inv = sparse.lil_matrix((len(S), len(S))), sparse.lil_matrix(
                (len(S), len(S)))
            D.setdiag(S)
            D_inv.setdiag(1.0 / S)
            Hs[k] = dot(D, H)
            Ws[k] = dot(W, D_inv)

    return Ws, Hs
Ejemplo n.º 19
0
    def constrain(self, other_item, center):
        AB = utils.vector(self.point, other_item.line.point)

        n = self.normal
        if utils.dot(utils.vector(self.point, center), n) < 0:
            n = (-n[0], -n[1])

        v_n = utils.dot(other_item.line.direction, n)
        AB_n = utils.dot(AB, n)

        if v_n > 0:
            other_item.k.set_min(-AB_n / v_n)
        if v_n < 0:
            other_item.k.set_max(-AB_n / v_n)
Ejemplo n.º 20
0
    def testJacobian(self):
        import pybullet as p

        clid = p.connect(p.SHARED_MEMORY)
        if (clid < 0):
            p.connect(p.DIRECT)

        time_step = 0.001
        gravity_constant = -9.81

        urdfs = [
            "TwoJointRobot_w_fixedJoints.urdf",
            "TwoJointRobot_w_fixedJoints.urdf", "kuka_iiwa/model.urdf",
            "kuka_lwr/kuka.urdf"
        ]
        for urdf in urdfs:
            p.resetSimulation()
            p.setTimeStep(time_step)
            p.setGravity(0.0, 0.0, gravity_constant)

            robotId = p.loadURDF(urdf, useFixedBase=True)
            p.resetBasePositionAndOrientation(robotId, [0, 0, 0], [0, 0, 0, 1])
            numJoints = p.getNumJoints(robotId)
            endEffectorIndex = numJoints - 1

            # Set a joint target for the position control and step the sim.
            self.setJointPosition(robotId,
                                  [0.1 * (i % 3) for i in range(numJoints)])
            p.stepSimulation()

            # Get the joint and link state directly from Bullet.
            mpos, mvel, mtorq = self.getMotorJointStates(robotId)

            result = p.getLinkState(robotId,
                                    endEffectorIndex,
                                    computeLinkVelocity=1,
                                    computeForwardKinematics=1)
            link_trn, link_rot, com_trn, com_rot, frame_pos, frame_rot, link_vt, link_vr = result
            # Get the Jacobians for the CoM of the end-effector link.
            # Note that in this example com_rot = identity, and we would need to use com_rot.T * com_trn.
            # The localPosition is always defined in terms of the link frame coordinates.

            zero_vec = [0.0] * len(mpos)
            jac_t, jac_r = p.calculateJacobian(robotId, endEffectorIndex,
                                               com_trn, mpos, zero_vec,
                                               zero_vec)

            assert (allclose(dot(jac_t, mvel), link_vt))
            assert (allclose(dot(jac_r, mvel), link_vr))
        p.disconnect()
Ejemplo n.º 21
0
def transform_on_q(q, options, constants, timeseries, particles,
                   fourier_length):
    o, c = options, constants
    if o['debug']:
        print('Computing intensities for q = [{}, {}, {}]'.format(
            q[0], q[1], q[2]))

    # Sets the length to the next power of 2, for speed
    I_aa = np.zeros((3, int(fourier_length / 2)), dtype=np.dtype('complex128'))
    t_0 = 1

    for z in range(0, 3):
        for tablename, table in timeseries.items():
            particle = particles.get_atom_from_tablename(tablename)
            if type(table) is np.ndarray:
                positions = table
            else:
                positions = np.array(
                    [table.cols.pos_x, table.cols.pos_y, table.cols.pos_z],
                    dtype=np.complex128)

            q_dot_lattice = cmath.exp(1j * dot(q, particle.lattice_position))

            # Do the fourier transform and add it to the I_aa matrix
            I_aa[z, :] += np.fft.fft(q_dot_lattice * positions[z].T[t_0:], n=fourier_length) \
                            .reshape((fourier_length,))[:int(fourier_length/2)]

        ic_sum = 0
        for tablename, table in timeseries.items():
            particle = particles.get_atom_from_tablename(tablename)
            if type(table) is np.ndarray:
                positions = table
            else:
                positions = np.array(
                    [table.cols.pos_x, table.cols.pos_y, table.cols.pos_z],
                    dtype=np.complex128)

            ic_sum += cmath.exp(
                -1j * dot(q, particle.lattice_position)) * positions[z, t_0]

        I_aa[z, :] *= ic_sum
        I_aa[z, :] = np.power(np.abs(I_aa[z, :]), 2)
        # I_aa[z, :] = np.real(I_aa[z, :])

    frequencies = np.fft.fftfreq(fourier_length,
                                 o['dt'])[:int(fourier_length / 2)]
    energies = c['Hz_to_meV'] * frequencies

    return I_aa, energies, frequencies
Ejemplo n.º 22
0
def generate_coords(points_pos, query_triangles_pos):

    EPS = 1e-6

    # First, compute and remove the normal component
    area_normals = 0.5 * torch.cross(
        query_triangles_pos[:, :, 1, :] - query_triangles_pos[:, :, 0, :],
        query_triangles_pos[:, :, 2, :] - query_triangles_pos[:, :, 0, :],
        dim=-1)

    areas = utils.norm(area_normals) + EPS  # (B, Q)
    normals = area_normals / areas.unsqueeze(-1)  # (B, Q, 3)
    barycenters = torch.mean(query_triangles_pos, dim=2)  # (B, Q, 3)
    centered_neighborhood = points_pos - barycenters.unsqueeze(2)
    normal_comp = utils.dot(normals.unsqueeze(2), centered_neighborhood)
    neighborhood_planar = points_pos - normals.unsqueeze(
        2) * normal_comp.unsqueeze(-1)

    # Compute barycentric coordinates in plane
    def coords_i(i):
        point_area = 0.5 * utils.dot(
            normals.unsqueeze(2),
            torch.cross(query_triangles_pos[:, :,
                                            (i + 1) % 3, :].unsqueeze(2) -
                        neighborhood_planar,
                        query_triangles_pos[:, :,
                                            (i + 2) % 3, :].unsqueeze(2) -
                        neighborhood_planar,
                        dim=-1))

        area_frac = (point_area + EPS / 3.) / areas.unsqueeze(-1)
        return area_frac

    BARY_MAX = 5.
    u = torch.clamp(coords_i(0), -BARY_MAX, BARY_MAX)
    v = torch.clamp(coords_i(1), -BARY_MAX, BARY_MAX)
    w = torch.clamp(coords_i(2), -BARY_MAX, BARY_MAX)

    # Compute cartesian coordinates with the x-axis along the i --> j edge
    basisX = utils.normalize(query_triangles_pos[:, :, 1, :] -
                             query_triangles_pos[:, :, 0, :])
    basisY = utils.normalize(torch.cross(normals, basisX))
    x_comp = utils.dot(basisX.unsqueeze(2), centered_neighborhood)
    y_comp = utils.dot(basisY.unsqueeze(2), centered_neighborhood)

    coords = torch.stack((x_comp, y_comp, normal_comp, u, v, w), dim=-1)

    return coords
Ejemplo n.º 23
0
def backpropagate(network, input_vector, targets):
    # ???
    hidden_outputs, outputs = network_output(network, input_vector)

    # s'(t) = s(t) * (1 - s(t)), where s(t) = 1 / (1 + e^(-t))
    output_deltas = [
        output * (1 - output) * (output - target)
        for output, target in zip(outputs, targets)
    ]

    # adjust weights for output layer, one neuron at a time
    for i, output_neuron in enumerate(network[-1]):
        # focus on the ith output layer neuron
        for j, hidden_output in enumerate(hidden_outputs + [1]):
            # adjust the jth weight based on both
            # this neuron's delta and its jth input
            output_neuron[j] -= output_deltas[i] * hidden_output

    # back-propagate errors to hidden layer
    hidden_deltas = [
        hidden_output * (1 - hidden_output) *
        dot(output_deltas, [n[i] for n in network[-1]])
        for i, hidden_output in enumerate(hidden_outputs)
    ]

    for i, hidden_neuron in enumerate(network[0]):
        for j, input in enumerate(input_vector + [1]):
            hidden_neuron[j] -= hidden_deltas[i] * input
Ejemplo n.º 24
0
    def take_RK4_step(self, b_rand):
        o, c = self.options, self.constants
        # Get the current position
        p = self.current_position()

        # Calculate partial Runge Kutta steps
        k1 = self.calculate_function_value(p)
        k2 = self.calculate_function_value(
            p + k1 * o['dt'] / 2)  # Needs B_eff with spins p+k1
        k3 = self.calculate_function_value(p + k2 * o['dt'] / 2)
        k4 = self.calculate_function_value(p + k3 * o['dt'])

        # Calculate the total difference in the spin
        d_spin = (k1 + 2 * k2 + 2 * k3 + k4) * o['dt'] / 6

        # Calculate the random energy added
        # This is based on temperature
        d_spin_rand = c['gamma'] * cross(p, b_rand)

        # Calculate new position and normalise the vector
        p += d_spin + d_spin_rand
        p = p / math.sqrt(dot(p, p))

        # Save the data to the atom
        self.set_position(p)

        return self.id, p
Ejemplo n.º 25
0
  def safe_to_move(self, dist_to_left, dist_to_rght, 
    robot_to_left, robot_to_rght):


  def move_to_loc(self, robot_coord, target_coord, style, reverse_dir=0):
    """
    @brief Moves the robot to a target coordinate by calling the 
    motor_worker function. Returns the thread running motor_worker so 
    the calling function can check if the motor is still moving with
    the 'moving' field

    @param robot_loc The current location of the robot in a Point object
    @param target_loc The desired location for the robot in a Point object
    @param style SINGLE: Standard steps
                 DOUBLE: Two coils on, more power and more strength
                 INTERLEAVE: Mix of single and double
                 MICROSTEP: More precise, gives 8x more steps to motor
    @param reverse_dir Whether or not to reverse the direction of the
    motor, perhaps because of a change in mounting orientation

    """

    if self.moving = True:
        print "Cannot move motor when motor is already moving"
        return

    #Distances of the robot from the left or right rails, respectively
    dist_to_left = utils.get_pt2pt_dist(robot_coord, self.left_rail_coord)
    dist_to_rght = utils.get_pt2pt_dist(robot_coord, self.rght_rail_coord)
    dist_to_trgt = utils.get_pt2pt_dist(robot_coord, target_coord)
    #Real distance to target in cm
    real_dist_to_trgt = dist_to_trgt/self.scaled_ovr_real

    #Compute direction in which the robot needs to move
    #Point object is used as a vector in this case to use utils.dot
    #Vector from robot to left rail
    robot_to_left = Point(self.left_rail_coord.x-self.robot_coord.x,
                          self.left_rail_coord.y-self.robot_coord.y)
    #Vector from robot to target
    robot_to_trgt = Point(target_coord.x-self.robot_coord.x,
                          target_coord.y-self.robot_coord.y)
    #Use dot product to find if the direction is towards left or right
    #Direction: -1->left, 1->right

    direction = -1
    if utils.dot(robot_to_left, robot_to_trgt) < 0:
        direction = 1
    if reverse_dir is 1:
        direction = direction * -1
    motor_dir = direction

    #Compute how many steps the motor should move
    steps = (real_dist_to_trgt/gear_circum)*self.motor_steps


    #Create the thread controlling the motor and run it
    motor_thread = threading.Thread(target=motor_worker, 
                            args=(self.motor, steps, motor_dir))
    self.moving = True
    motor_thread.start()
Ejemplo n.º 26
0
    def take_RK2_step(self, b_rand):
        o, c = self.options, self.constants
        # Get the current position
        p = self.current_position()

        # Calculate partial Runge Kutta steps
        k1 = self.calculate_function_value(p)
        self.set_position(p + k1 * o['dt'])
        # self.combine_neighbours # We need to call this, but then we have to call from particles

        k2 = self.calculate_function_value(self.pos)

        # Calculate the total difference in the spin
        # d_spin = (k1 + k2)/2*o['dt']
        d_spin = k2 * o['dt']

        # Calculate the random energy added
        # This is based on temperature
        d_spin_rand = c['gamma'] * cross(p, b_rand)

        # Calculate new position and normalise the vector
        p += d_spin + d_spin_rand
        p = p / math.sqrt(dot(p, p))

        # Save the data to the atom
        self.set_position(p)

        return self.id, p
Ejemplo n.º 27
0
    def __init__(self, point_item):
        self.vertices = set()
        if not point_item.is_bounded():
            return

        # Compute segments edges
        for other in point_item.others:
            v1, v2 = other.vertices()
            for v in [v1, v2]:
                EPSILON = 1e-4
                distances = list(utils.distance2(v, i) for i in self.vertices)
                if len(distances) == 0 or min(distances) > EPSILON:
                    self.vertices |= {v}

        # Sort vertices to make the shape convex
        self.vertices = list(self.vertices)
        OA = utils.vector(point_item.point, self.vertices[0])
        len_OA = utils.length(OA)
        t = {(self.vertices[0], 0)}
        for vertex in self.vertices[1:]:
            OB = utils.vector(point_item.point, vertex)
            len_OB = utils.length(OB)
            cos_angle = utils.dot(OA, OB) / (len_OA * len_OB)
            if cos_angle < -1:
                cos_angle = -1
            elif cos_angle > 1:
                cos_angle = 1

            angle = math.acos(cos_angle)
            if utils.cross(OA, OB) < 0:  # sign of sin
                angle = 2 * math.pi - angle
            t |= {(vertex, angle)}
        self.vertices = list(vertex
                             for vertex, _ in sorted(t, key=lambda x: x[1]))
Ejemplo n.º 28
0
    def rayIntersect(self, orig, dir):
        # t = (( position - origRayo) dot normal) / (dirRayo dot normal)

        denom = dot(dir, self.normal)

        if abs(denom) > 0.0001:
            t = dot(self.normal, sub(self.position, orig)) / denom
            if t > 0:
                # P = O + tD
                hit = sum(orig, mul(dir, t))

                return Intersect(distance = t,
                                 point = hit,
                                 normal = self.normal)

        return None
Ejemplo n.º 29
0
    def take_ad_bs_step(self, b_rand):
        # Grab the constants
        o, c = self.options, self.constants
        pos = self.current_position()

        # Gradually increase steps in the Adams Bashforth method
        if self.spos4 is None:
            d_spos = self.first_ad_bs_step(pos)
            d_fpos = d_spos
        elif self.spos3 is None:
            d_spos, d_fpos = self.second_ad_bs_step(pos)
        elif self.spos2 is None:
            d_spos, d_fpos = self.third_ad_bs_step(pos)
        elif self.spos1 is None:
            d_spos, d_fpos = self.fourth_ad_bs_step(pos)
        else:
            d_spos, d_fpos = self.fifth_ad_bs_step(pos)

        # Move the values along so we keep continuing
        self.spos4, self.spos3, self.spos2, self.spos1 = d_fpos, self.spos4, self.spos3, self.spos2

        # Calculate the random energy added
        # This is based on temperature
        d_spin_rand = c['gamma'] * cross(pos, b_rand)

        # Take the step and calculate the final position and normalise the vector
        pos = pos + d_spos * o['dt'] + d_spin_rand
        pos = pos / math.sqrt(dot(pos, pos))

        # Save the data to the atom
        self.set_position(pos)

        return self.id, pos
Ejemplo n.º 30
0
def dist_triangle_probs_to_sampled_surface(surf_pos, surf_normals, gen_verts, gen_faces, gen_face_probs, n_sample_pts=5000):
    if gen_faces.shape[0] == 0:
        return torch.tensor(0., device=surf_verts.device)

    # get a characteristic length
    char_len = utils.norm(surf_pos - torch.mean(surf_pos, dim=0, keepdim=True)).mean()

    # Sample points on the generated triangulation
    samples, face_inds, _ = mesh_utils.sample_points_on_surface(
        gen_verts, gen_faces, n_sample_pts, return_inds_and_bary=True)

    # Likelihoods associated with each point
    point_probs = gen_face_probs[face_inds]

    # Measure the distance to the surface
    knn_dist, neigh = knn.find_knn(samples, surf_pos, k=1)
    neigh_pos = surf_pos[neigh.squeeze(1), :]

    if len(surf_normals) == 0 :
        dists = knn_dist
    else:
        neigh_normal = surf_normals[neigh.squeeze(1), :]
        vecs = neigh_pos - samples
        dists = torch.abs(utils.dot(vecs, neigh_normal))
    
    # Expected distance integral
    exp_dist = torch.mean(dists * point_probs)

    return exp_dist / char_len
Ejemplo n.º 31
0
 def getLogLiklihood(self):
     lnL = 0
     for p in self.data.points:
         lnL_j = -utils.math.log(1 + utils.math.exp(-p.y *
                                                    utils.dot(self.w, p.x)))
         lnL += lnL_j
     return lnL
Ejemplo n.º 32
0
  def testJacobian(self):
    import pybullet as p

    clid = p.connect(p.SHARED_MEMORY)
    if (clid < 0):
      p.connect(p.DIRECT)

    time_step = 0.001
    gravity_constant = -9.81

    urdfs = [
        "TwoJointRobot_w_fixedJoints.urdf", "TwoJointRobot_w_fixedJoints.urdf",
        "kuka_iiwa/model.urdf", "kuka_lwr/kuka.urdf"
    ]
    for urdf in urdfs:
      p.resetSimulation()
      p.setTimeStep(time_step)
      p.setGravity(0.0, 0.0, gravity_constant)

      robotId = p.loadURDF(urdf, useFixedBase=True)
      p.resetBasePositionAndOrientation(robotId, [0, 0, 0], [0, 0, 0, 1])
      numJoints = p.getNumJoints(robotId)
      endEffectorIndex = numJoints - 1

      # Set a joint target for the position control and step the sim.
      self.setJointPosition(robotId, [0.1 * (i % 3) for i in range(numJoints)])
      p.stepSimulation()

      # Get the joint and link state directly from Bullet.
      mpos, mvel, mtorq = self.getMotorJointStates(robotId)

      result = p.getLinkState(robotId,
                              endEffectorIndex,
                              computeLinkVelocity=1,
                              computeForwardKinematics=1)
      link_trn, link_rot, com_trn, com_rot, frame_pos, frame_rot, link_vt, link_vr = result
      # Get the Jacobians for the CoM of the end-effector link.
      # Note that in this example com_rot = identity, and we would need to use com_rot.T * com_trn.
      # The localPosition is always defined in terms of the link frame coordinates.

      zero_vec = [0.0] * len(mpos)
      jac_t, jac_r = p.calculateJacobian(robotId, endEffectorIndex, com_trn, mpos, zero_vec,
                                         zero_vec)

      assert (allclose(dot(jac_t, mvel), link_vt))
      assert (allclose(dot(jac_r, mvel), link_vr))
    p.disconnect()
Ejemplo n.º 33
0
    def item_that_contains(self, point):
        for point_item in self.point_items:
            if not point_item.is_bounded():
                continue

            skip = False
            for other in point_item.others:
                edge_normal = utils.orthogonal(other.line.direction)
                A, B = other.vertices()
                AO = utils.vector(A, point_item.point)
                AP = utils.vector(A, point)
                if utils.dot(AO, edge_normal) * utils.dot(AP, edge_normal) < 0:
                    skip = True
                    break
            if not skip:
                return point_item
        raise Exception("PointSet.item_that_contains: not found")
Ejemplo n.º 34
0
 def test(self, test_data, quiet=True):
     E = 0
     for p in test_data.points:
         E += (p.y - utils.dot(self.w, p.x))**2
     E /= len(test_data.points)
     if not quiet:
         print("Mean Test Error : " + str(E)[:6])
     return E
Ejemplo n.º 35
0
def step_line_search(f, x, gradient, wolfe_const1=0.1, step_max=10, factor=0.3):
    """Backtracking line search which finds a step length,
    satisfying the first condition of Wolfe for sufficient decrease."""
    step = step_max
    while f(descent_step(x, gradient, step)) > \
            f(x) + wolfe_const1 * step * -dot(gradient, gradient):
        step *= factor
    return step
    def log_p_y_z(self):

        if self.continuous:
            h_decoder  = softplus(dot(self.W_zh,self.z.T) + self.b_zh)
            if self.numHiddenLayers_decoder == 2:
                h_decoder = softplus(dot(self.W_hh, h_decoder) + self.b_hh)
            mu_decoder = dot(self.W_hy1, h_decoder) + self.b_hy1
            log_sigma_decoder = 0.5*(dot(self.W_hy2, h_decoder) + self.b_hy2)
            log_pyz    = T.sum( -(0.5 * np.log(2 * np.pi) + log_sigma_decoder) \
                                - 0.5 * ((self.y_miniBatch.T - mu_decoder) / T.exp(log_sigma_decoder))**2 )

            log_sigma_decoder.name = 'log_sigma_decoder'
            mu_decoder.name        = 'mu_decoder'
            h_decoder.name         = 'h_decoder'
            log_pyz.name           = 'log_p_y_z'
        else:
            h_decoder = tanh(dot(self.W_zh, self.z) + self.b_zh)
            if self.numHiddenLayers_decoder == 2:
                h_decoder = softplus(dot(W_hh, h_decoder) + self.b_hh)
            y_hat     = sigmoid(dot(self.W_hy1, h_decoder) + self.b_hy1)
            log_pyz   = -T.nnet.binary_crossentropy(y_hat, self.y_miniBatch).sum()
            h_decoder.name = 'h_decoder'
            y_hat.name     = 'y_hat'
            log_pyz.name   = 'log_p_y_z'

        return log_pyz
def backpropagate(network, input_vector, targets):
    # ???
    hidden_outputs, outputs = network_output(network, input_vector)

    # s'(t) = s(t) * (1 - s(t)), where s(t) = 1 / (1 + e^(-t))
    output_deltas = [output * (1 - output) * (output - target)
                     for output, target in zip(outputs, targets)]

    # adjust weights for output layer, one neuron at a time
    for i, output_neuron in enumerate(network[-1]):
        # focus on the ith output layer neuron
        for j, hidden_output in enumerate(hidden_outputs + [1]):
            # adjust the jth weight based on both
            # this neuron's delta and its jth input
            output_neuron[j] -= output_deltas[i] * hidden_output

    # back-propagate errors to hidden layer
    hidden_deltas = [hidden_output * (1 - hidden_output) *
                     dot(output_deltas, [n[i] for n in network[-1]])
                     for i, hidden_output in enumerate(hidden_outputs)]

    for i, hidden_neuron in enumerate(network[0]):
        for j, input in enumerate(input_vector + [1]):
            hidden_neuron[j] -= hidden_deltas[i] * input
Ejemplo n.º 38
0
 def hamil(xs, J):
     return dot(xs, hs) + J * (sum([xi * xj for (xi, xj) in pairs(xs)]))
Ejemplo n.º 39
0
    def get_trajectory_list(self, color=colors.Cyan):
      """
      @brief Gets best fit traj from n-previous points and predicts bounces

      Uses np.polyfit with dimension 1. Creates line from two points. Points
      are generated using closest point to most recent frame (x1,y1) and 
      a point (x1 + 1.0, y2). This works as a line can be represented by any
      arbitrary two points along it. The actual points do not matter here or
      for the goalie, unless specified/calculated otherwise.

      self.traj is always the farthest-predicted line between the last impact
      point or object location and the robot axis

      self.traj_list contains, from oldest to farthest predicted, a list of 
      Lines representing each bounce. The lines go obj->wall, wall->wall, ...,
      wall->robot_axis.

      @param color The color to be used in the trajectory lines

      @return list of Line objects representing trajectory path
      """
      # Not enough frames collected
      if None in self.pt_list:
        return []

      # reset and get best fit line
      self.traj_list = []
      ln = self.get_best_fit_line()

      # get trajectory towards robot axis, line from obj to axis
      # if trajectory not moving towards robot axis, no prediction
      if not self.traj_dir_toward_line(self.robot_axis):
        ln = None
      start_pt = self.pt_list[self.curr_index]
      traj_int_pt = utils.line_intersect(ln, self.robot_axis) # Point object
      traj = utils.get_line(start_pt, traj_int_pt, color=colors.Blue)
      self.traj = traj

      # return straight-line trajectory (as a 1-elem list for consistency) if
      # no bounces to be predicted
      if self.bounce is 0: # no bounce prediction
        self.traj_list.append(self.traj)
        return self.traj_list


      #### BOUNCE (broken) ####
      for wall in self.walls:
        # Determine where bounce occurs and add line up to bounce
        bounce_pt = utils.line_segment_intersect(self.traj, wall)
        if bounce_pt is None:
          continue

        bounce_ln = utils.get_line(self.pt_list[self.curr_index],
          bounce_pt, color=colors.Blue)
        self.traj_list.append(bounce_ln)
        self.debug_pt = bounce_pt


        ### THIS IS BROKEN 
        # Reflect line across wall and project to next wall or axis
        # incoming d, normal n: outgoing r = d - 2(d dot n)*n
        normal_dx = -wall.dy*1.0
        normal_dy = wall.dx*1.0
        normal_len = math.sqrt(normal_dx*normal_dx + normal_dy*normal_dy)

        d = shapes.Point(bounce_ln.dx, bounce_ln.dy)
        n = shapes.Point(normal_dx/normal_len, normal_dy/normal_len)
        self.debug_line = shapes.Line(x1=bounce_pt.x, y1=bounce_pt.y,
          x2=bounce_pt.x+n.x*20,y2=bounce_pt.y+n.y*20,color=colors.Red)

        reflect_dx = (d.x - 2 * utils.dot(d, n) * n.x)
        reflect_dy = (d.y - 2 * utils.dot(d, n) * n.y)


        #### ONCE NEW DX AND DY ARE FOND, IT WORKS. GETTING DX/DY FAILS ####
        new_x = bounce_pt.x + reflect_dx * 0.001
        new_y = bounce_pt.y + reflect_dy * 0.001
        new_pt = shapes.Point(new_x, new_y)

        new_ln = utils.get_line(bounce_pt, new_pt) # small line
        final_int = utils.line_intersect(new_ln, self.robot_axis)
        final_ln = shapes.Line(
          x1=bounce_pt.x, y1=bounce_pt.y,
          x2=final_int.x, y2=final_int.y, color=colors.Cyan)

        self.traj = final_ln
        self.traj_list.append(final_ln)

        # only one bounce
        break

      return self.traj_list
def neuron_output(inputs, weights):
    return sigmoid(dot(inputs, weights))
Ejemplo n.º 41
0
    magic_ball.speed = BALL_SPEED * random_vector()

    result = [magic_ball]
    for x in (-1, 0, 1):
        for y in (-1, 0, 1):
            if x == 0 and y == 0:
                continue
            result.append(Ball(BALL_POS + Vec2d(150 * x, 150 * y), random.randint(10, 40)))

    return result

balls_list = create_balls()

Ep0 = 0
for ball in balls_list:
    Ep0 -= dot(GRAVITY, ball.pos)

megapoly = Polygon([Vec2d(300, 250), Vec2d(400, 300), Vec2d(350, 450), Vec2d(200, 400), Vec2d(200, 300)])


def create_rects(x_count, y_count):
    result = []
    w, h = backyblacky.dims

    step_x = w // x_count
    step_y = h // y_count

    half_rect_w = step_x // 4
    half_rect_h = step_y // 4
    half_extents = Vec2d(half_rect_w, half_rect_h)
    offset = backyblacky.pos + half_extents
Ejemplo n.º 42
0
import utils as ut

if __name__ == '__main__':
	vecs = [[0, 0, 0], [1, 1, 1], [0, -1, 2.0]]

	print(ut.vadd(vecs[0], vecs[1])) # [1, 1,  1]
	print(ut.vadd(vecs[0], vecs[2])) # [0, -1, 2.0]
	print(ut.vadd(vecs[2], vecs[1])) # [1, 0,  3.0]
	print(ut.vadd(vecs[1], vecs[2])) # [1, 0,  3.0]

	print(ut.smult(10, vecs[1]))

	print(ut.vzero(10))

	print(ut.vneg(vecs[1])) # [-1, -1, -1]
	print(ut.vneg(vecs[2])) # [0, 1, -2.0]

	print(ut.dot(vecs[1], vecs[2])) # 1
	
	print(ut.sbasis(-1, 5))	# [0, 0, 0, 0, 0]
	print(ut.sbasis(2, 5))  # [0, 1, 0, 0, 0]

	print(ut.vsum(vecs))    # [1, 0, 3.0]



Ejemplo n.º 43
0
    def __init__(self,
                 numberOfInducingPoints,  # Number of inducing ponts in sparse GP
                 batchSize,              # Size of mini batch
                 dimX,                   # Dimensionality of the latent co-ordinates
                 dimZ,                   # Dimensionality of the latent variables
                 data,                   # [NxP] matrix of observations
                 kernelType='ARD',
                 encoderType_qX='FreeForm2',  # 'MLP', 'Kernel'.
                 encoderType_rX='FreeForm2',  # 'MLP', 'Kernel'
                 Xu_optimise=False,
                 numberOfEncoderHiddenUnits=10
                 ):

        self.numTestSamples = 5000

        # set the data
        data = np.asarray(data, dtype=precision)
        self.N = data.shape[0]  # Number of observations
        self.P = data.shape[1]  # Dimension of each observation
        self.M = numberOfInducingPoints
        self.B = batchSize
        self.R = dimX
        self.Q = dimZ
        self.H = numberOfEncoderHiddenUnits

        self.encoderType_qX = encoderType_qX
        self.encoderType_rX = encoderType_rX
        self.Xu_optimise = Xu_optimise

        self.y = th.shared(data)
        self.y.name = 'y'

        if kernelType == 'RBF':
            self.numberOfKernelParameters = 2
        elif kernelType == 'RBFnn':
            self.numberOfKernelParameters = 1
        elif kernelType == 'ARD':
            self.numberOfKernelParameters = self.R + 1
        else:
            raise RuntimeError('Unrecognised kernel type')

        self.lowerBound = -np.inf  # Lower bound

        self.numberofBatchesPerEpoch = int(np.ceil(np.float32(self.N) / self.B))
        numPad = self.numberofBatchesPerEpoch * self.B - self.N

        self.batchStream = srng.permutation(n=self.N)
        self.padStream   = srng.choice(size=(numPad,), a=self.N,
                                       replace=False, p=None, ndim=None, dtype='int32')

        self.batchStream.name = 'batchStream'
        self.padStream.name = 'padStream'

        self.iterator = th.shared(0)
        self.iterator.name = 'iterator'

        self.allBatches = T.reshape(T.concatenate((self.batchStream, self.padStream)), [self.numberofBatchesPerEpoch, self.B])
        self.currentBatch = T.flatten(self.allBatches[self.iterator, :])

        self.allBatches.name = 'allBatches'
        self.currentBatch.name = 'currentBatch'

        self.y_miniBatch = self.y[self.currentBatch, :]
        self.y_miniBatch.name = 'y_miniBatch'

        self.jitterDefault = np.float64(0.0001)
        self.jitterGrowthFactor = np.float64(1.1)
        self.jitter = th.shared(np.asarray(self.jitterDefault, dtype='float64'), name='jitter')

        kfactory = kernelFactory(kernelType)

        # kernel parameters
        self.log_theta = sharedZeroMatrix(1, self.numberOfKernelParameters, 'log_theta', broadcastable=(True,False)) # parameters of Kuu, Kuf, Kff
        self.log_omega = sharedZeroMatrix(1, self.numberOfKernelParameters, 'log_omega', broadcastable=(True,False)) # parameters of Kuu, Kuf, Kff
        self.log_gamma = sharedZeroMatrix(1, self.numberOfKernelParameters, 'log_gamma', broadcastable=(True,False)) # parameters of Kuu, Kuf, Kff

        # Random variables
        self.xi    = srng.normal(size=(self.B, self.R), avg=0.0, std=1.0, ndim=None)
        self.alpha = srng.normal(size=(self.M, self.Q), avg=0.0, std=1.0, ndim=None)
        self.beta  = srng.normal(size=(self.B, self.Q), avg=0.0, std=1.0, ndim=None)
        self.xi.name    = 'xi'
        self.alpha.name = 'alpha'
        self.beta.name  = 'beta'

        self.sample_xi    = th.function([], self.xi)
        self.sample_alpha = th.function([], self.alpha)
        self.sample_beta  = th.function([], self.beta)

        self.sample_batchStream = th.function([], self.batchStream)
        self.sample_padStream   = th.function([], self.padStream)

        self.getCurrentBatch = th.function([], self.currentBatch, no_default_updates=True)

        # Compute parameters of q(X)
        if self.encoderType_qX == 'FreeForm1' or self.encoderType_qX == 'FreeForm2':
            # Have a normal variational distribution over location of latent co-ordinates

            self.phi_full = sharedZeroMatrix(self.N, self.R, 'phi_full')
            self.phi = self.phi_full[self.currentBatch, :]
            self.phi.name = 'phi'

            if encoderType_qX == 'FreeForm1':

                self.Phi_full_sqrt = sharedZeroMatrix(self.N, self.N, 'Phi_full_sqrt')

                Phi_batch_sqrt = self.Phi_full_sqrt[self.currentBatch][:, self.currentBatch]
                Phi_batch_sqrt.name = 'Phi_batch_sqrt'

                self.Phi = dot(Phi_batch_sqrt, Phi_batch_sqrt.T, 'Phi')

                self.cPhi, _, self.logDetPhi = cholInvLogDet(self.Phi, self.B, 0)

                self.qX_vars = [self.Phi_full_sqrt, self.phi_full]

            else:

                self.Phi_full_logdiag = sharedZeroArray(self.N, 'Phi_full_logdiag')

                Phi_batch_logdiag = self.Phi_full_logdiag[self.currentBatch]
                Phi_batch_logdiag.name = 'Phi_batch_logdiag'

                self.Phi, self.cPhi, _, self.logDetPhi \
                    = diagCholInvLogDet_fromLogDiag(Phi_batch_logdiag, 'Phi')

                self.qX_vars = [self.Phi_full_logdiag, self.phi_full]

        elif self.encoderType_qX == 'MLP':

            # Auto encode
            self.W1_qX = sharedZeroMatrix(self.H, self.P, 'W1_qX')
            self.W2_qX = sharedZeroMatrix(self.R, self.H, 'W2_qX')
            self.W3_qX = sharedZeroMatrix(1, self.H, 'W3_qX')
            self.b1_qX = sharedZeroVector(self.H, 'b1_qX', broadcastable=(False, True))
            self.b2_qX = sharedZeroVector(self.R, 'b2_qX', broadcastable=(False, True))
            self.b3_qX = sharedZeroVector(1, 'b3_qX', broadcastable=(False, True))

            # [HxB] = softplus( [HxP] . [BxP]^T + repmat([Hx1],[1,B]) )
            h_qX = softplus(plus(dot(self.W1_qX, self.y_miniBatch.T), self.b1_qX), 'h_qX' )
            # [RxB] = sigmoid( [RxH] . [HxB] + repmat([Rx1],[1,B]) )
            mu_qX = plus(dot(self.W2_qX, h_qX), self.b2_qX, 'mu_qX')
            # [1xB] = 0.5 * ( [1xH] . [HxB] + repmat([1x1],[1,B]) )
            log_sigma_qX = mul( 0.5, plus(dot(self.W3_qX, h_qX), self.b3_qX), 'log_sigma_qX')

            self.phi  = mu_qX.T  # [BxR]
            self.Phi, self.cPhi, self.iPhi,self.logDetPhi \
                = diagCholInvLogDet_fromLogDiag(log_sigma_qX, 'Phi')

            self.qX_vars = [self.W1_qX, self.W2_qX, self.W3_qX, self.b1_qX, self.b2_qX, self.b3_qX]

        elif self.encoderType_qX == 'Kernel':

            # Draw the latent coordinates from a GP with data co-ordinates
            self.Phi = kfactory.kernel(self.y_miniBatch, None, self.log_gamma, 'Phi')
            self.phi = sharedZeroMatrix(self.B, self.R, 'phi')
            (self.cPhi, self.iPhi, self.logDetPhi) = cholInvLogDet(self.Phi, self.B, self.jitter)

            self.qX_vars = [self.log_gamma]

        else:
            raise RuntimeError('Unrecognised encoding for q(X): ' + self.encoderType_qX)

        # Variational distribution q(u)
        self.kappa = sharedZeroMatrix(self.M, self.Q, 'kappa')
        self.Kappa_sqrt = sharedZeroMatrix(self.M, self.M, 'Kappa_sqrt')
        self.Kappa = dot(self.Kappa_sqrt, self.Kappa_sqrt.T, 'Kappa')

        (self.cKappa, self.iKappa, self.logDetKappa) \
                    = cholInvLogDet(self.Kappa, self.M, 0)
        self.qu_vars = [self.Kappa_sqrt, self.kappa]

        # Calculate latent co-ordinates Xf
        # [BxR]  = [BxR] + [BxB] . [BxR]
        self.Xz = plus( self.phi, dot(self.cPhi, self.xi), 'Xf' )
        # Inducing points co-ordinates
        self.Xu = sharedZeroMatrix(self.M, self.R, 'Xu')

        # Kernels
        self.Kzz = kfactory.kernel(self.Xz, None,    self.log_theta, 'Kff')
        self.Kuu = kfactory.kernel(self.Xu, None,    self.log_theta, 'Kuu')
        self.Kzu = kfactory.kernel(self.Xz, self.Xu, self.log_theta, 'Kfu')
        self.cKuu, self.iKuu, self.logDetKuu = cholInvLogDet(self.Kuu, self.M, self.jitter)

        # Variational distribution
        # A has dims [BxM] = [BxM] . [MxM]
        self.A = dot(self.Kzu, self.iKuu, 'A')
        # L is the covariance of conditional distribution q(z|u,Xf)
        self.C = minus( self.Kzz, dot(self.A, self.Kzu.T), 'C')
        self.cC, self.iC, self.logDetC = cholInvLogDet(self.C, self.B, self.jitter)

        # Sample u_q from q(u_q) = N(u_q; kappa_q, Kappa )  [MxQ]
        self.u  = plus(self.kappa, (dot(self.cKappa, self.alpha)), 'u')
        # compute mean of z [QxB]
        # [BxQ] = [BxM] * [MxQ]
        self.mu = dot(self.A, self.u, 'mu')
        # Sample f from q(f|u,X) = N( mu_q, C )
        # [BxQ] =
        self.z  = plus(self.mu, (dot(self.cC, self.beta)), 'z')

        self.qz_vars = [self.log_theta]

        self.iUpsilon = plus(self.iKappa, dot(self.A.T, dot(self.iC, self.A) ), 'iUpsilon')
        _, self.Upsilon, self.negLogDetUpsilon = cholInvLogDet(self.iUpsilon, self.M, self.jitter)

        if self.encoderType_rX == 'MLP':

            self.W1_rX = sharedZeroMatrix(self.H, self.Q+self.P, 'W1_rX')
            self.W2_rX = sharedZeroMatrix(self.R, self.H, 'W2_rX')
            self.W3_rX = sharedZeroMatrix(self.R, self.H, 'W3_rX')
            self.b1_rX = sharedZeroVector(self.H, 'b1_rX', broadcastable=(False, True))
            self.b2_rX = sharedZeroVector(self.R, 'b2_rX', broadcastable=(False, True))
            self.b3_rX = sharedZeroVector(self.R, 'b3_rX', broadcastable=(False, True))

            # [HxB] = softplus( [Hx(Q+P)] . [(Q+P)xB] + repmat([Hx1], [1,B]) )
            h_rX = softplus(plus(dot(self.W1_rX, T.concatenate((self.z.T, self.y_miniBatch.T))), self.b1_rX), 'h_rX')
            # [RxB] = softplus( [RxH] . [HxB] + repmat([Rx1], [1,B]) )
            mu_rX = plus(dot(self.W2_rX, h_rX), self.b2_rX, 'mu_rX')
            # [RxB] = 0.5*( [RxH] . [HxB] + repmat([Rx1], [1,B]) )
            log_sigma_rX = mul( 0.5, plus(dot(self.W3_rX, h_rX), self.b3_rX), 'log_sigma_rX')

            self.tau = mu_rX.T

            # Diagonal optimisation of Tau
            self.Tau_isDiagonal = True
            self.Tau = T.reshape(log_sigma_rX, [self.B * self.R, 1])
            self.logDetTau = T.sum(log_sigma_rX)
            self.Tau.name = 'Tau'
            self.logDetTau.name = 'logDetTau'

            self.rX_vars = [self.W1_rX, self.W2_rX, self.W3_rX, self.b1_rX, self.b2_rX, self.b3_rX]

        elif self.encoderType_rX == 'Kernel':

            self.tau = sharedZeroMatrix(self.B, self.R, 'tau')

            # Tau_r [BxB] = kernel( [[BxQ]^T,[BxP]^T].T )
            Tau_r = kfactory.kernel(T.concatenate((self.z.T, self.y_miniBatch.T)).T, None, self.log_omega, 'Tau_r')
            (cTau_r, iTau_r, logDetTau_r) = cholInvLogDet(Tau_r, self.B, self.jitter)

            # self.Tau  = slinalg.kron(T.eye(self.R), Tau_r)
            self.cTau = slinalg.kron(cTau_r, T.eye(self.R))
            self.iTau = slinalg.kron(iTau_r, T.eye(self.R))

            self.logDetTau = logDetTau_r * self.R
            self.tau.name  = 'tau'
            # self.Tau.name  = 'Tau'
            self.cTau.name = 'cTau'
            self.iTau.name = 'iTau'
            self.logDetTau.name = 'logDetTau'

            self.Tau_isDiagonal = False
            self.rX_vars = [self.log_omega]

        else:
            raise RuntimeError('Unrecognised encoding for r(X|z)')

        # Gradient variables - should be all the th.shared variables
        # We always want to optimise these variables
        if self.Xu_optimise:
            self.gradientVariables = [self.Xu]
        else:
            self.gradientVariables = []

        self.gradientVariables.extend(self.qu_vars)
        self.gradientVariables.extend(self.qz_vars)
        self.gradientVariables.extend(self.qX_vars)
        self.gradientVariables.extend(self.rX_vars)

        self.lowerBounds = []

        self.condKappa = myCond()(self.Kappa)
        self.condKappa.name = 'condKappa'
        self.Kappa_conditionNumber = th.function([], self.condKappa, no_default_updates=True)

        self.condKuu = myCond()(self.Kuu)
        self.condKuu.name = 'condKuu'
        self.Kuu_conditionNumber = th.function([], self.condKuu, no_default_updates=True)

        self.condC = myCond()(self.C)
        self.condC.name = 'condC'
        self.C_conditionNumber = th.function([], self.condC, no_default_updates=True)

        self.condUpsilon = myCond()(self.Upsilon)
        self.condUpsilon.name = 'condUpsilon'
        self.Upsilon_conditionNumber = th.function([], self.condUpsilon, no_default_updates=True)

        self.Xz_get_value = th.function([], self.Xz, no_default_updates=True)