[docs]defget_factor_list(factors):'''Get sorted factor list. Parameters ---------- factors : list of int list List of factor id pairs, indicating the row and column factors of each matrix. Please follow the convention that factors are numbered consecutively and starting from 0. There must exist a matrix with its factors numbered as [0, 1]. Returns ------- factor_list : list List of sorted factor ids. '''factor_list=[]forfinfactors:factor_list.extend(f)factor_list=sorted(list(set(factor_list)))returnfactor_list
[docs]defget_matrices(factors):'''List of related matrices given factors. This is the reversion of 'factors', the list of related factors given matrices. '''factor_list=get_factor_list(factors)matrices=[]forfinfactor_list:matrix_list=[]fori,fsinenumerate(factors):iffinfs:matrix_list.append(i)matrices.append(matrix_list)returnmatrices
[docs]defget_factor_dims(Xs,factors):'''The dimensions of each factor. '''factor_list=get_factor_list(factors)matrices=get_matrices(factors)factor_dims=[]forfinfactor_list:m=matrices[f][0]# pick 1 related matrixd=factors[m].index(f)# 0 or 1dim=Xs[m].shape[d]factor_dims.append(dim)returnfactor_dims
[docs]defget_factor_starts(Xs,factors):'''The starting point of each factor when multiple factors Us are concatenated into a pair of row and column factor U. '''rows,cols=split_factor_list(factors=factors)factor_dims=get_factor_dims(Xs,factors)heights=[factor_dims[r]forrinrows]widths=[factor_dims[c]forcincols]row_starts=[0]+list(accumulate(heights))col_starts=[0]+list(accumulate(widths))factor_starts=[row_starts,col_starts]returnfactor_starts
[docs]defget_dummy_factor_info(Xs,factors):'''Get dummy factor_info for collective matrices. '''factor_list=get_factor_list(factors)factor_dims=get_factor_dims(Xs,factors)factor_info=[]fori,finenumerate(factor_list):dim=factor_dims[i]f_order=np.arange(dim).astype(int)f_idmap=np.arange(dim).astype(int)f_alias=np.arange(dim).astype(str)f_info=(f_order,f_idmap,f_alias)factor_info.append(f_info)returnfactor_info
[docs]defsplit_factor_list(factors):'''Classify factors into row and column factors. Please follow the convention that factors are numbered consecutively and starting from 0. There must exist a matrix with its factors numbered as [0, 1]. Factor 0 and those on the same side as 0 are regraded as row factors. Factor 1 and those on the same side as 1 are regraded as column factors. List `f` stores the type of each factor with 0 for unclassified, 1 for row factor and 2 for column factor. '''factor_list=get_factor_list(factors)f=[0]*len(factor_list)f[0],f[1]=1,2foriinrange(len(factors)):a,b=factors[i]iff[a]+f[b]!=3:f[a]=3-f[b]iff[a]==0elsef[a]f[b]=3-f[a]iff[b]==0elsef[b]row_factors=sorted([ifori,vinenumerate(f)ifv==1])col_factors=sorted([ifori,vinenumerate(f)ifv==2])returnrow_factors,col_factors