def preprocessData(self, ys, u=None, computeMarginal=True):
        ys is not None

        ys = np.array(ys)
        if (ys.ndim == 2):
            ys = ys[None]
        else:
            assert ys.ndim == 3

        assert self.J1Emiss.shape[0] == ys.shape[2]

        self._T = ys.shape[1]

        # This is A.T @ sigInv @ y for each y, summed over each measurement
        self.hy = ys.dot(self._hy).sum(axis=0)

        # P( y | x ) ~ N( -0.5 * Jy, hy )
        self.computeMarginal = computeMarginal
        if (computeMarginal):
            print('self.Jy', self.Jy)
            print('self.hy', self.hy)
            partition = np.vectorize(
                lambda J, h: Normal.log_partition(nat_params=(-0.5 * J, h)),
                signature='(n,n),(n)->()')
            self.log_Zy = partition(self.Jy, self.hy)
        else:
            self.log_Zy = np.zeros(self.hy.shape[0])

        if (u is not None):
            assert u.shape == (self.T, self.D_latent)
            uMask = np.isnan(u)
            self.u = (u, uMask, None)
Beispiel #2
0
    def log_partition( cls, x=None, params=None, nat_params=None, split=False ):
        # Compute A( Ѳ ) - log( h( x ) )
        assert ( params is None ) ^ ( nat_params is None )

        # Need to multiply each partition by the length of each sequence!!!!
        A, sigma, C, R, mu0, sigma0 = params if params is not None else cls.natToStandard( *nat_params )
        A1, A2 = Regression.log_partition( params=( A, sigma ), split=True )
        A3, A4 = Regression.log_partition( params=( C, R ), split=True )
        A5, A6, A7 = Normal.log_partition( params=( mu0, sigma0 ), split=True )

        if( split == True ):
            return A1, A2, A3, A4, A5, A6, A7
        return A1 + A2 + A3 + A4 + A5 + A6 + A7
    def updateNatParams(self,
                        z,
                        n1Trans,
                        n2Trans,
                        n3Trans,
                        n1Emiss,
                        n2Emiss,
                        n3Emiss,
                        n1Init,
                        n2Init,
                        u=None,
                        ys=None,
                        computeMarginal=True):

        self._D_latent = n2Init.shape[0]
        self._D_obs = n1Emiss.shape[0]

        self.z = z

        self.J11s = [-2 * n for n in n1Trans]
        self.J12s = [-n.T for n in n3Trans]
        self.J22s = [-2 * n for n in n2Trans]
        self.log_Zs = [
            0.5 * np.linalg.slogdet(np.linalg.inv(J11))[1] for J11 in self.J11s
        ] if computeMarginal else [0 for _ in self.J11s]

        self.J1Emiss = -2 * n1Emiss
        self.Jy = -2 * n2Emiss
        self._hy = n3Emiss.T

        self.J0 = -2 * n1Init
        self.h0 = n2Init
        self.log_Z0 = Normal.log_partition(
            nat_params=(-2 * self.J0, self.h0)) if computeMarginal else 0

        if (ys is not None):
            self.preprocessData(ys, computeMarginal=computeMarginal)
        else:
            self._T = None

        if (u is not None):
            assert u.shape == (self.T, self.D_latent)
            uMask = np.isnan(u)
            self.u = (u, uMask, None)
        else:
            uMask = np.zeros(self.T, dtype=bool)
            self.u = (None, uMask, self.D_latent)
    def updateNatParams(self,
                        n1Trans,
                        n2Trans,
                        n3Trans,
                        n1Emiss,
                        n2Emiss,
                        n3Emiss,
                        n1Init,
                        n2Init,
                        u=None,
                        ys=None,
                        computeMarginal=True):
        # This doesn't exactly use natural parameters, but uses J = -2 * n1 and h = n2

        self._D_latent = n1Trans.shape[0]
        self._D_obs = n1Emiss.shape[0]

        self.J11 = -2 * n1Trans
        self.J12 = -n3Trans.T
        self.J22 = -2 * n2Trans
        self.log_Z = 0.5 * np.linalg.slogdet(np.linalg.inv(
            self.J11))[1] if computeMarginal else 0

        self.J1Emiss = -2 * n1Emiss
        self.Jy = -2 * n2Emiss
        self._hy = n3Emiss.T

        self.J0 = -2 * n1Init
        self.h0 = n2Init
        self.log_Z0 = Normal.log_partition(
            nat_params=(-2 * self.J0, self.h0)) if computeMarginal else 0

        if (ys is not None):
            self.preprocessData(ys, computeMarginal=computeMarginal)
        else:
            self._T = None

        if (u is not None):
            assert u.shape == (self.T, self.D_latent)
            uMask = np.isnan(u)
            self.u = (u, uMask, None)
        else:
            uMask = np.zeros(self.T, dtype=bool)
            self.u = (None, uMask, self.D_latent)

        self.fromNatural = True
    def emissionProb(self, t, forward=False, ys=None):

        # P( y_t | x_t ) as a function of x_t
        J = self.Jy

        if (ys is None):
            h = self.hy[t]
            log_Z = self.log_Zy[t]
        else:
            # A.T @ sigInv @ y
            h = np.einsum('ji,mj->i', self._hy, ys[:, t])
            log_Z = Normal.log_partition(nat_params=(-0.5 * self.Jy, h))

        if (forward):
            return J, h, np.array(log_Z)

        # Because this is before the integration step
        return self.alignOnUpper(J, h, log_Z)
 def log_marginalFromAlphaBeta(cls, alpha, beta):
     Ja, ha, log_Za = alpha
     Jb, hb, log_Zb = beta
     return Normal.log_partition(nat_params=(-0.5 * (Ja + Jb),
                                             (ha + hb))) - (log_Za + log_Zb)