def generate( cls, measurements=4, T=5, D_latent=3, D_obs=2, size=1, stabilize=False ): A, sigma = MatrixNormalInverseWishart.generate( D_in=D_latent, D_out=D_latent ) C, R = MatrixNormalInverseWishart.generate( D_in=D_latent, D_out=D_obs ) mu0, sigma0 = NormalInverseWishart.generate( D=D_latent ) dummy = LDSState( A=A, sigma=sigma, C=C, R=R, mu0=mu0, sigma0=sigma0 ) return dummy.isample( measurements=measurements, T=T, size=size, stabilize=stabilize, computeMarginal=False )
def natToStandard(cls, n1, n2, n3, n6, n7, n8, n11, n12, n4, n5, n9, n10, n13, n14, n15): # The order of the inputs to this function is important because it has the partition values at the end M_trans, V_trans, psi_trans, nu_trans, Q1 = MatrixNormalInverseWishart.natToStandard( n1, n2, n3, n4, n5) M_emiss, V_emiss, psi_emiss, nu_emiss, Q2 = MatrixNormalInverseWishart.natToStandard( n6, n7, n8, n9, n10) mu_0, kappa_0, psi_0, nu_0, Q0 = NormalInverseWishart.natToStandard( n11, n12, n13, n14, n15) return M_trans, V_trans, psi_trans, nu_trans, Q1, M_emiss, V_emiss, psi_emiss, nu_emiss, Q2, mu_0, kappa_0, psi_0, nu_0, Q0
def standardToNat(cls, M_trans, V_trans, psi_trans, nu_trans, Q1, M_emiss, V_emiss, psi_emiss, nu_emiss, Q2, mu_0, kappa_0, psi_0, nu_0, Q0): n1, n2, n3, n4, n5 = MatrixNormalInverseWishart.standardToNat( M_trans, V_trans, psi_trans, nu_trans, Q1) n6, n7, n8, n9, n10 = MatrixNormalInverseWishart.standardToNat( M_emiss, V_emiss, psi_emiss, nu_emiss, Q2) n11, n12, n13, n14, n15 = NormalInverseWishart.standardToNat( mu_0, kappa_0, psi_0, nu_0, Q0) return n1, n2, n3, n6, n7, n8, n11, n12, n4, n5, n9, n10, n13, n14, n15
def log_partitionGradient(cls, params=None, nat_params=None, split=False): # Derivative w.r.t. natural params. Also the expected sufficient stat assert (params is None) ^ (nat_params is None) n1, n2, n3, n6, n7, n8, n11, n12, n4, n5, n9, n10, n13, n14, n15 = nat_params if nat_params is not None else cls.standardToNat( *params) d1, d2, d3, d4, d5 = MatrixNormalInverseWishart.log_partitionGradient( nat_params=(n1, n2, n3, n4, n5)) d6, d7, d8, d9, d10 = MatrixNormalInverseWishart.log_partitionGradient( nat_params=(n6, n7, n8, n9, n10)) d11, d12, d13, d14, d15 = NormalInverseWishart.log_partitionGradient( nat_params=(n11, n12, n13, n14, n15)) if (split == False): return d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15 return ((d1, d2, d3, d6, d7, d8, d11, d12), (d4, d5, d9, d10, d13, d14, d15))
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) M_trans, V_trans, psi_trans, nu_trans, Q1, M_emiss, V_emiss, psi_emiss, nu_emiss, Q2, mu_0, kappa_0, psi_0, nu_0, Q0 = params if params is not None else cls.natToStandard( *nat_params) A1 = MatrixNormalInverseWishart.log_partition(x=x, params=(M_trans, V_trans, psi_trans, nu_trans, Q1), split=split) A2 = MatrixNormalInverseWishart.log_partition(x=x, params=(M_emiss, V_emiss, psi_emiss, nu_emiss, Q2), split=split) A3 = NormalInverseWishart.log_partition(x=x, params=(mu_0, kappa_0, psi_0, nu_0, Q0), split=split) return A1 + A2 + A3
def log_likelihood(cls, x, params=None, nat_params=None): # Compute P( x | Ѳ; α ) assert (params is None) ^ (nat_params is None) A, sigma, C, R, mu0, sigma0 = x M_trans, V_trans, psi_trans, nu_trans, Q1, M_emiss, V_emiss, psi_emiss, nu_emiss, Q2, mu_0, kappa_0, psi_0, nu_0, Q0 = params if params is not None else cls.natToStandard( *nat_params) ans1 = MatrixNormalInverseWishart.log_likelihood( (A, sigma), params=(M_trans, V_trans, psi_trans, nu_trans, Q1)) ans2 = MatrixNormalInverseWishart.log_likelihood( (C, R), params=(M_emiss, V_emiss, psi_emiss, nu_emiss, Q2)) ans3 = NormalInverseWishart.log_likelihood( (mu0, sigma0), params=(mu_0, kappa_0, psi_0, nu_0, Q0)) # print( '\nans1', ans1 ) # print( 'ans2', ans2 ) # print( 'ans3', ans3 ) ans = ans1 + ans2 + ans3 # print( 'ans', ans ) return ans
def sample(cls, params=None, nat_params=None, size=1): # Sample from P( x | Ѳ; α ) assert (params is None) ^ (nat_params is None) M_trans, V_trans, psi_trans, nu_trans, Q1, M_emiss, V_emiss, psi_emiss, nu_emiss, Q2, mu_0, kappa_0, psi_0, nu_0, Q0 = params if params is not None else cls.natToStandard( *nat_params) A, sigma = MatrixNormalInverseWishart.sample(params=(M_trans, V_trans, psi_trans, nu_trans, Q1), size=size) C, R = MatrixNormalInverseWishart.sample(params=(M_emiss, V_emiss, psi_emiss, nu_emiss, Q2), size=size) mu0sigma0 = NormalInverseWishart.sample(params=(mu_0, kappa_0, psi_0, nu_0, Q0), size=size) mu0, sigma0 = mu0sigma0 ans = (A, sigma, C, R, mu0, sigma0) cls.checkShape(ans) return ans