#NEWLINE# def expectation_propagation( self , K , Y , likelihood , Y_metadata ) : #NEWLINE# #INDENT# ( num_data , data_dim ) = Y . shape #NEWLINE# assert ( data_dim == 1 ) , 'This EP methods only works for 1D outputs' #NEWLINE# mu = np . zeros ( num_data ) #NEWLINE# Sigma = K . copy ( ) #NEWLINE# diag . add ( Sigma , 1e-07 ) #NEWLINE# Y = Y . values . copy ( ) #NEWLINE# Z_hat = np . empty ( num_data , dtype = np . float64 ) #NEWLINE# mu_hat = np . empty ( num_data , dtype = np . float64 ) #NEWLINE# sigma2_hat = np . empty ( num_data , dtype = np . float64 ) #NEWLINE# tau_cav = np . empty ( num_data , dtype = np . float64 ) #NEWLINE# v_cav = np . empty ( num_data , dtype = np . float64 ) #NEWLINE# if ( self . old_mutilde is None ) : #NEWLINE# #INDENT# ( tau_tilde , mu_tilde , v_tilde ) = np . zeros ( ( 3 , num_data ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# assert ( self . old_mutilde . size == num_data ) , 'data size mis-match: did you change the data? try resetting!' #NEWLINE# ( mu_tilde , v_tilde ) = ( self . old_mutilde , self . old_vtilde ) #NEWLINE# tau_tilde = ( v_tilde / mu_tilde ) #NEWLINE# #UNINDENT# tau_diff = ( self . epsilon + 1.0 ) #NEWLINE# v_diff = ( self . epsilon + 1.0 ) #NEWLINE# tau_tilde_old = np . nan #NEWLINE# v_tilde_old = np . nan #NEWLINE# iterations = 0 #NEWLINE# while ( ( tau_diff > self . epsilon ) or ( v_diff > self . epsilon ) ) : #NEWLINE# #INDENT# update_order = np . random . permutation ( num_data ) #NEWLINE# for i in update_order : #NEWLINE# #INDENT# tau_cav [ i ] = ( ( 1.0 / Sigma [ ( i , i ) ] ) - ( self . eta * tau_tilde [ i ] ) ) #NEWLINE# v_cav [ i ] = ( ( mu [ i ] / Sigma [ ( i , i ) ] ) - ( self . eta * v_tilde [ i ] ) ) #NEWLINE# if ( Y_metadata is not None ) : #NEWLINE# #INDENT# Y_metadata_i = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# for key in Y_metadata . keys ( ) : #NEWLINE# #INDENT# Y_metadata_i [ key ] = Y_metadata [ key ] [ i , : ] #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# Y_metadata_i = None #NEWLINE# #UNINDENT# ( Z_hat [ i ] , mu_hat [ i ] , sigma2_hat [ i ] ) = likelihood . moments_match_ep ( Y [ i ] , tau_cav [ i ] , v_cav [ i ] , Y_metadata_i = Y_metadata_i ) #NEWLINE# delta_tau = ( ( self . delta / self . eta ) * ( ( 1.0 / sigma2_hat [ i ] ) - ( 1.0 / Sigma [ ( i , i ) ] ) ) ) #NEWLINE# delta_v = ( ( self . delta / self . eta ) * ( ( mu_hat [ i ] / sigma2_hat [ i ] ) - ( mu [ i ] / Sigma [ ( i , i ) ] ) ) ) #NEWLINE# tau_tilde [ i ] += delta_tau #NEWLINE# v_tilde [ i ] += delta_v #NEWLINE# ci = ( delta_tau / ( 1.0 + ( delta_tau * Sigma [ ( i , i ) ] ) ) ) #NEWLINE# DSYR ( Sigma , Sigma [ : , i ] . copy ( ) , ( - ci ) ) #NEWLINE# mu = np . dot ( Sigma , v_tilde ) #NEWLINE# #UNINDENT# tau_tilde_root = np . sqrt ( tau_tilde ) #NEWLINE# Sroot_tilde_K = ( tau_tilde_root [ : , None ] * K ) #NEWLINE# B = ( np . eye ( num_data ) + ( Sroot_tilde_K * tau_tilde_root [ None , : ] ) ) #NEWLINE# L = jitchol ( B ) #NEWLINE# ( V , _ ) = dtrtrs ( L , Sroot_tilde_K , lower = 1 ) #NEWLINE# Sigma = ( K - np . dot ( V . T , V ) ) #NEWLINE# mu = np . dot ( Sigma , v_tilde ) #NEWLINE# if ( iterations > 0 ) : #NEWLINE# #INDENT# tau_diff = np . mean ( np . square ( ( tau_tilde - tau_tilde_old ) ) ) #NEWLINE# v_diff = np . mean ( np . square ( ( v_tilde - v_tilde_old ) ) ) #NEWLINE# #UNINDENT# tau_tilde_old = tau_tilde . copy ( ) #NEWLINE# v_tilde_old = v_tilde . copy ( ) #NEWLINE# iterations += 1 #NEWLINE# #UNINDENT# mu_tilde = ( v_tilde / tau_tilde ) #NEWLINE# mu_cav = ( v_cav / tau_cav ) #NEWLINE# sigma2_sigma2tilde = ( ( 1.0 / tau_cav ) + ( 1.0 / tau_tilde ) ) #NEWLINE# Z_tilde = np . exp ( ( ( ( np . log ( Z_hat ) + ( 0.5 * np . log ( ( 2 * np . pi ) ) ) ) + ( 0.5 * np . log ( sigma2_sigma2tilde ) ) ) + ( ( 0.5 * ( ( mu_cav - mu_tilde ) ** 2 ) ) / sigma2_sigma2tilde ) ) ) #NEWLINE# return ( mu , Sigma , mu_tilde , tau_tilde , Z_tilde )