<s> import numpy as np <EOL> from scipy . sparse import coo_matrix , csr_matrix , csc_matrix , issparse <EOL> def count_matrix ( arr , slices , m = None ) : <EOL> """<STR_LIT>""" <EOL> if not m : <EOL> m = arr . max ( ) <EOL> shape = ( m , len ( slices ) ) <EOL> data = np . ones_like ( arr ) <EOL> row_indices = arr <EOL> col_indices = np . empty_like ( arr ) <EOL> for i , s in enumerate ( slices ) : <EOL> col_indices [ s ] = i <EOL> return coo_matrix ( ( data , ( row_indices , col_indices ) ) , <EOL> shape = shape , dtype = np . int32 ) <EOL> def rand_pt_unit_sphere ( n , seed = None ) : <EOL> """<STR_LIT:U+0020>""" <EOL> np . random . seed ( seed ) <EOL> pt = np . random . normal ( size = n ) <EOL> pt = pt / np . dot ( pt , pt ) ** <NUM_LIT> <EOL> return pt <EOL> def naive_cconv ( v , w ) : <EOL> """<STR_LIT:U+0020>""" <EOL> out = np . empty_like ( v ) <EOL> for i in xrange ( v . shape [ <NUM_LIT:0> ] ) : <EOL> out [ i ] = np . dot ( v , np . roll ( w [ : : - <NUM_LIT:1> ] , i + <NUM_LIT:1> ) ) <EOL> return out <EOL> def scipy_cdist ( ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> from scipy . spatial . distance import cdist <EOL> def dist_fn ( P , Q ) : <EOL> P = P . astype ( np . float ) <EOL> Q = Q . astype ( np . float ) <EOL> if P . ndim < <NUM_LIT:2> : <EOL> P = P . reshape ( ( <NUM_LIT:1> , P . size ) ) <EOL> if Q . ndim < <NUM_LIT:2> : <EOL> Q = Q . reshape ( ( Q . size , <NUM_LIT:1> ) ) <EOL> out = cdist ( P , Q . T , ** kwargs ) <EOL> out = np . squeeze ( out ) <EOL> if out . ndim == <NUM_LIT:0> : <EOL> return out [ ( ) ] <EOL> return out <EOL> return dist_fn <EOL> def angle ( P , Q ) : <EOL> """<STR_LIT>""" <EOL> P = P . astype ( np . float ) <EOL> Q = Q . astype ( np . float ) <EOL> if P . ndim < <NUM_LIT:2> : <EOL> P = P . reshape ( ( <NUM_LIT:1> , P . size ) ) <EOL> if Q . ndim < <NUM_LIT:2> : <EOL> Q = Q . reshape ( ( Q . size , <NUM_LIT:1> ) ) <EOL> P /= np . sqrt ( ( P * P ) . sum ( <NUM_LIT:1> ) [ : , np . newaxis ] ) <EOL> Q /= np . sqrt ( ( Q * Q ) . sum ( <NUM_LIT:0> ) [ np . newaxis , : ] ) <EOL> cos_PQ = np . dot ( P , Q ) <EOL> cos_PQ [ ( cos_PQ > <NUM_LIT:1> ) ] = <NUM_LIT:1.> <EOL> cos_PQ [ ( cos_PQ < - <NUM_LIT:1> ) ] = - <NUM_LIT:1.> <EOL> out = np . arccos ( cos_PQ ) <EOL> out = np . squeeze ( out ) <EOL> if out . ndim == <NUM_LIT:0> : <EOL> return out [ ( ) ] <EOL> return out <EOL> def angle_sparse ( P , Q ) : <EOL> """<STR_LIT>""" <EOL> P = P . tocsc ( ) . astype ( np . float ) <EOL> Q = Q . tocsr ( ) . astype ( np . float ) <EOL> P_inv_norms = <NUM_LIT:1> / np . sqrt ( P . multiply ( P ) . sum ( <NUM_LIT:1> ) ) <EOL> Q_inv_norms = <NUM_LIT:1> / np . sqrt ( Q . multiply ( Q ) . sum ( <NUM_LIT:0> ) ) <EOL> P = P . multiply ( csc_matrix ( P_inv_norms ) ) <EOL> Q = Q . multiply ( csr_matrix ( Q_inv_norms ) ) <EOL> P = P . tocsr ( ) <EOL> Q = Q . tocsc ( ) <EOL> cos_PQ = P . dot ( Q ) . toarray ( ) <EOL> cos_PQ [ ( cos_PQ > <NUM_LIT:1> ) ] = <NUM_LIT:1.> <EOL> cos_PQ [ ( cos_PQ < - <NUM_LIT:1> ) ] = - <NUM_LIT:1.> <EOL> out = np . arccos ( cos_PQ ) <EOL> out = np . squeeze ( out ) <EOL> if out . ndim == <NUM_LIT:0> : <EOL> return out [ ( ) ] <EOL> return out <EOL> def H ( P ) : <EOL> """<STR_LIT>""" <EOL> P = P . astype ( np . float ) <EOL> if P . ndim < <NUM_LIT:2> : <EOL> P = P . reshape ( ( <NUM_LIT:1> , P . size ) ) <EOL> old_settings = np . seterr ( divide = '<STR_LIT:ignore>' ) <EOL> logP = np . log2 ( P ) <EOL> np . seterr ( ** old_settings ) <EOL> logP [ ( P == <NUM_LIT:0> ) ] = <NUM_LIT:0.> <EOL> out = - <NUM_LIT:1> * ( P * logP ) . sum ( <NUM_LIT:1> ) <EOL> out = np . squeeze ( out ) <EOL> if out . ndim == <NUM_LIT:0> : <EOL> return out [ ( ) ] <EOL> return out <EOL> def cross_H ( P , Q ) : <EOL> """<STR_LIT>""" <EOL> P = P . astype ( np . float ) <EOL> Q = Q . astype ( np . float ) <EOL> if P . ndim < <NUM_LIT:2> : <EOL> P = P . reshape ( ( <NUM_LIT:1> , P . size ) ) <EOL> if Q . ndim < <NUM_LIT:2> : <EOL> Q = Q . reshape ( ( Q . size , <NUM_LIT:1> ) ) <EOL> P_ = np . tile ( P . reshape ( P . shape [ <NUM_LIT:0> ] , P . shape [ <NUM_LIT:1> ] , <NUM_LIT:1> ) , ( <NUM_LIT:1> , <NUM_LIT:1> , Q . shape [ <NUM_LIT:1> ] ) ) <EOL> Q_ = np . tile ( Q . reshape ( <NUM_LIT:1> , Q . shape [ <NUM_LIT:0> ] , Q . shape [ <NUM_LIT:1> ] ) , ( P . shape [ <NUM_LIT:0> ] , <NUM_LIT:1> , <NUM_LIT:1> ) ) <EOL> old_settings = np . seterr ( divide = '<STR_LIT:ignore>' ) <EOL> logQ_ = np . tile ( np . log2 ( Q . reshape ( <NUM_LIT:1> , Q . shape [ <NUM_LIT:0> ] , Q . shape [ <NUM_LIT:1> ] ) ) , <EOL> ( P . shape [ <NUM_LIT:0> ] , <NUM_LIT:1> , <NUM_LIT:1> ) ) <EOL> np . seterr ( ** old_settings ) <EOL> out = ( P_ * logQ_ ) <EOL> P_zeros = ( P_ == <NUM_LIT:0> ) <EOL> Q_zeros = ( Q_ == <NUM_LIT:0> ) <EOL> PQ_zeros = np . bitwise_and ( P_zeros , Q_zeros ) <EOL> out [ PQ_zeros ] = <NUM_LIT:0.> <EOL> out = np . squeeze ( - <NUM_LIT:1> * out . sum ( <NUM_LIT:1> ) ) <EOL> if out . ndim == <NUM_LIT:0> : <EOL> return out [ ( ) ] <EOL> return out <EOL> def KL_div ( P , Q ) : <EOL> """<STR_LIT>""" <EOL> P = P . astype ( np . float ) <EOL> Q = Q . astype ( np . float ) <EOL> if P . ndim < <NUM_LIT:2> : <EOL> return np . squeeze ( cross_H ( P , Q ) - H ( P ) ) <EOL> out = np . squeeze ( cross_H ( P , Q ) - H ( P ) [ : , np . newaxis ] ) <EOL> if out . ndim == <NUM_LIT:0> : <EOL> return out [ ( ) ] <EOL> return out <EOL> def JS_div ( P , Q , metric = False ) : <EOL> """<STR_LIT>""" <EOL> P = P . astype ( np . float ) <EOL> Q = Q . astype ( np . float ) <EOL> if P . ndim < <NUM_LIT:2> : <EOL> P = P . reshape ( ( <NUM_LIT:1> , P . size ) ) <EOL> if Q . ndim < <NUM_LIT:2> : <EOL> Q = Q . reshape ( ( Q . size , <NUM_LIT:1> ) ) <EOL> P_ = np . tile ( P [ : , : , np . newaxis ] , ( <NUM_LIT:1> , <NUM_LIT:1> , Q . shape [ <NUM_LIT:1> ] ) ) <EOL> Q_ = np . tile ( Q [ np . newaxis , : , : ] , ( P . shape [ <NUM_LIT:0> ] , <NUM_LIT:1> , <NUM_LIT:1> ) ) <EOL> M_ = <NUM_LIT> * ( P_ + Q_ ) <EOL> old_settings = np . seterr ( divide = '<STR_LIT:ignore>' ) <EOL> logM_ = np . log2 ( M_ ) <EOL> np . seterr ( ** old_settings ) <EOL> P_zeros = ( P_ == <NUM_LIT:0> ) <EOL> Q_zeros = ( Q_ == <NUM_LIT:0> ) <EOL> PQ_zeros = np . bitwise_and ( P_zeros , Q_zeros ) <EOL> logM_ [ PQ_zeros ] = <NUM_LIT:0.> <EOL> HP = H ( P ) <EOL> HQ = H ( Q . T ) <EOL> PM_KLdiv = - <NUM_LIT:1> * ( P_ * logM_ ) . sum ( <NUM_LIT:1> ) - HP . reshape ( HP . size , <NUM_LIT:1> ) <EOL> QM_KLdiv = - <NUM_LIT:1> * ( Q_ * logM_ ) . sum ( <NUM_LIT:1> ) - HQ . reshape ( <NUM_LIT:1> , HQ . size ) <EOL> out = <NUM_LIT> * ( PM_KLdiv + QM_KLdiv ) <EOL> out [ out < <NUM_LIT:0> ] = <NUM_LIT:0.> <EOL> if metric : <EOL> out = np . sqrt ( out ) <EOL> out = np . squeeze ( out ) <EOL> if out . ndim == <NUM_LIT:0> : <EOL> return out [ ( ) ] <EOL> return out <EOL> def JS_dist ( P , Q ) : <EOL> """<STR_LIT>""" <EOL> return JS_div ( P , Q , metric = True ) </s>
