def sig_scale_depth_ratio(sig, dim, depth, scalefactor): """ sig is a numpy array corresponding to the signature of a stream, computed by esig, of dimension dim and truncated to level depth. The input scalefactor can be any float. The returned output is a numpy array of the same shape as sig. Each entry in the returned array is the corresponding entry in sig multiplied by r^k, where k is the level of sig to which the entry belongs. If the input depth is 0, an error message is returned since the scaling will always leave the level zero entry of a signature as 1. """ if depth == 0: return print( "Error: Depth 0 term of a signature is always 1 and will not be changed by scaling" ) else: e = [] e.append(sig[0]) for j in range(1, dim + 1): e.append(scalefactor * sig[j]) if depth >= 2: for k in range(dim + 1, ts.sigdim(dim, 2)): e.append((scalefactor**2) * sig[k]) for i in range(2, depth): for a in range(ts.sigdim(dim, i), ts.sigdim(dim, i + 1)): e.append((scalefactor**(i + 1)) * sig[a]) E = np.array(e) return E
def changeofbasis(dimension, degree): liebasis = ts.logsigkeys(dimension, degree) tensorbasis = ts.sigkeys(dimension, degree) n = ts.logsigdim(dimension, degree) m = ts.sigdim(dimension, degree) matrix = np.zeros((n, m)) pos = tensorbasis.split() columnindex = [] pos[0] = '(0)' for row in pos: row = row.strip('(') row = row.strip(')') row = row.split(',') row = [int(i) for i in row] columnindex.append(row) #print(columnindex) rowindex = liebasis.split() expand = [] for i in range(n): B = Lietotensor(rowindex[i]) #print(B) for j in B: for k in range(m): #print(type(j[1])) #print(type(k)) if j[1] == columnindex[k]: matrix[i][k] = matrix[i][k] + j[0] return matrix
def find_dim(N): if N == 0: return 0 if N == 1: return 3 return tosig.sigdim(2, N)
def signature(path, depth): """return signature of a path up to level depth""" assert isinstance(depth, int), 'Argument of wrong type' assert depth > 1, 'depth must be > 1' width = path.shape[1] length = path.shape[0] if length <= 1: return np.array([0.]*(tosig.sigdim(width, depth)-1)) return iisignature.sig(path, depth)
def siglen(dim,deg,islog): dim = int(dim) deg = int(deg) islog = int(islog) if (islog): return(ts.logsigdim(dim,deg)) else: return(ts.sigdim(dim,deg)) end
def categorical_path_sig(node_index, mol, adjacent_matrix, index_map, L, cat_dim, sig_deg, flag): """function will output the signatures/logsignatures of categorical path of a node up to radius L input: node_index adjacent matrix mol:molecule information dictionary index_map: a dictionary assign atom labels to each index of categorical path L: radius around the node cat_dim: number of atom types sig_deg:degree of signature flag: 0 return signature, 1 return log-signature output: signatures/logsignatures of the all categorical paths of the node up to length L has shape (m,n), m depends on the number of paths at each L, n depends on the cat_dim and sig_deg """ sig_dim = ts.sigdim(cat_dim, sig_deg) logsig_dim = ts.logsigdim(cat_dim, sig_deg) signatures = None log_signatures = None if (flag == 0): for i in range(L): paths = get_paths(node_index, adjacent_matrix, i + 1) num_path = len(paths) paths_sig = np.zeros([num_path, sig_dim], dtype=float) k = 0 for path in paths: mat = categorical_path(path, mol, cat_dim, index_map, i) paths_sig[k, ] = ts.stream2sig(np.transpose(mat), sig_deg) k = k + 1 if signatures is None: signatures = paths_sig else: signatures = np.concatenate(([signatures, paths_sig]), axis=0) return (signatures) elif (flag == 1): for i in range(L): paths = get_paths(node_index, adjacent_matrix, i + 1) num_path = len(paths) paths_logsig = np.zeros([num_path, logsig_dim], dtype=float) k = 0 for path in paths: mat = categorical_path(path, mol, cat_dim, index_map, i) paths_logsig[k, ] = ts.stream2logsig(np.transpose(mat), sig_deg) k = k + 1 if log_signatures is None: log_signatures = paths_logsig else: log_signatures = np.concatenate( ([log_signatures, paths_logsig]), axis=0) return log_signatures
def coordinate_path_sig(node_index, mol, adjacent_matrix, L, sig_deg, flag): """ function will output the signatures/logsignatures of coordinate path of a node up to radius L Input: node_index: starting node adjacent_matrix: the matrix shows the connection between atoms mol:molecule information dictionary L: length of path sig_deg: degree of signature flag: 0 return signature, 1 return log_signature output: signatures/logsignatures of the all coordinate paths of the node up to length L has shape (m,n), m depends on the number of paths at each L, n= sig_dim/logsig_dim """ sig_dim = ts.sigdim(3, sig_deg) logsig_dim = ts.logsigdim(3, sig_deg) signatures = None log_signatures = None if (flag == 0): for i in range(L): paths = get_paths(node_index, adjacent_matrix, i + 1) num_path = len(paths) paths_sig = np.zeros([num_path, sig_dim]) #paths_logsig = np.zeros([num_path, logsig_dim]) k = 0 for path in paths: temp = np.zeros([len(path), 3]) for j in range(len(path)): temp[j, :] = mol['atoms'][path[j]].features paths_sig[k, ] = ts.stream2sig(temp, sig_deg) #paths_logsig[k,] = ts.stream2logsig(temp, sig_deg) k = k + 1 if signatures is None: signatures = paths_sig else: signatures = np.concatenate(([signatures, paths_sig]), axis=0) return (signatures) if (flag == 1): for i in range(L): paths = get_paths(node_index, adjacent_matrix, i + 1) num_path = len(paths) paths_logsig = np.zeros([num_path, logsig_dim]) k = 0 for path in paths: temp = np.zeros([len(path), 3]) for j in range(len(path)): temp[j, :] = mol['atoms'][path[j]].features paths_logsig[k, ] = ts.stream2logsig(temp, sig_deg) k = k + 1 if log_signatures is None: log_signatures = paths_logsig else: log_signatures = np.concatenate( ([log_signatures, paths_logsig]), axis=0) return log_signatures
def sig_dim(self, dimension, depth): """ Get the number of elements in the signature """ return tosig.sigdim(dimension, depth)