def t2l(arg): # projects a lie element in tensor form to a lie in lie basis form """ >>> from tjl_hall_numpy_lie import * >>> from tjl_dense_numpy_tensor import * >>> width = 2 >>> depth = 3 >>> t = tensor_log(stream2sigtensor(brownian(100, width), depth), depth) >>> print(np.sum(tensor_sub(l2t(t2l(t),width,depth), t)[2:]**2) < 1e-30) True >>> """ width = int(arg[0]) _layers = lambda bz: tjl_dense_numpy_tensor.layers(bz, width) _blob_size = lambda dep: tjl_dense_numpy_tensor.blob_size(width, dep) depth = _layers(len(arg)) ans = defaultdict(scalar_type) ibe = _blob_size(0) # just beyond the zero tensors ien = _blob_size(depth) for i in range(ibe, ien): t = index_to_tuple(i, width) if t: ## must normalise to get the dynkin projection to make it a projection add_into( ans, scale_into(rbraketing(t, width, depth), arg[i] / scalar_type(len(t))), ) return ans
def stream2sig(stream, signature_degree): """Computes the signature of a stream. Parameters ---------- array : array of shape (length, 2) Stream whose signature will be computed. signature_degree : int Signature degree. Returns ------- array Signature of the stream. Examples --------- >>> import tosig as ts >>> from tjl_dense_numpy_tensor import brownian >>> from esig import tosig as ets >>> width = 4 >>> depth = 4 >>> ts.sigkeys(width, depth) ' () (1) (2) (3) (4) (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) (4,1) (4,2) (4,3) (4,4) (1,1,1) (1,1,2) (1,1,3) (1,1,4) (1,2,1) (1,2,2) (1,2,3) (1,2,4) (1,3,1) (1,3,2) (1,3,3) (1,3,4) (1,4,1) (1,4,2) (1,4,3) (1,4,4) (2,1,1) (2,1,2) (2,1,3) (2,1,4) (2,2,1) (2,2,2) (2,2,3) (2,2,4) (2,3,1) (2,3,2) (2,3,3) (2,3,4) (2,4,1) (2,4,2) (2,4,3) (2,4,4) (3,1,1) (3,1,2) (3,1,3) (3,1,4) (3,2,1) (3,2,2) (3,2,3) (3,2,4) (3,3,1) (3,3,2) (3,3,3) (3,3,4) (3,4,1) (3,4,2) (3,4,3) (3,4,4) (4,1,1) (4,1,2) (4,1,3) (4,1,4) (4,2,1) (4,2,2) (4,2,3) (4,2,4) (4,3,1) (4,3,2) (4,3,3) (4,3,4) (4,4,1) (4,4,2) (4,4,3) (4,4,4) (1,1,1,1) (1,1,1,2) (1,1,1,3) (1,1,1,4) (1,1,2,1) (1,1,2,2) (1,1,2,3) (1,1,2,4) (1,1,3,1) (1,1,3,2) (1,1,3,3) (1,1,3,4) (1,1,4,1) (1,1,4,2) (1,1,4,3) (1,1,4,4) (1,2,1,1) (1,2,1,2) (1,2,1,3) (1,2,1,4) (1,2,2,1) (1,2,2,2) (1,2,2,3) (1,2,2,4) (1,2,3,1) (1,2,3,2) (1,2,3,3) (1,2,3,4) (1,2,4,1) (1,2,4,2) (1,2,4,3) (1,2,4,4) (1,3,1,1) (1,3,1,2) (1,3,1,3) (1,3,1,4) (1,3,2,1) (1,3,2,2) (1,3,2,3) (1,3,2,4) (1,3,3,1) (1,3,3,2) (1,3,3,3) (1,3,3,4) (1,3,4,1) (1,3,4,2) (1,3,4,3) (1,3,4,4) (1,4,1,1) (1,4,1,2) (1,4,1,3) (1,4,1,4) (1,4,2,1) (1,4,2,2) (1,4,2,3) (1,4,2,4) (1,4,3,1) (1,4,3,2) (1,4,3,3) (1,4,3,4) (1,4,4,1) (1,4,4,2) (1,4,4,3) (1,4,4,4) (2,1,1,1) (2,1,1,2) (2,1,1,3) (2,1,1,4) (2,1,2,1) (2,1,2,2) (2,1,2,3) (2,1,2,4) (2,1,3,1) (2,1,3,2) (2,1,3,3) (2,1,3,4) (2,1,4,1) (2,1,4,2) (2,1,4,3) (2,1,4,4) (2,2,1,1) (2,2,1,2) (2,2,1,3) (2,2,1,4) (2,2,2,1) (2,2,2,2) (2,2,2,3) (2,2,2,4) (2,2,3,1) (2,2,3,2) (2,2,3,3) (2,2,3,4) (2,2,4,1) (2,2,4,2) (2,2,4,3) (2,2,4,4) (2,3,1,1) (2,3,1,2) (2,3,1,3) (2,3,1,4) (2,3,2,1) (2,3,2,2) (2,3,2,3) (2,3,2,4) (2,3,3,1) (2,3,3,2) (2,3,3,3) (2,3,3,4) (2,3,4,1) (2,3,4,2) (2,3,4,3) (2,3,4,4) (2,4,1,1) (2,4,1,2) (2,4,1,3) (2,4,1,4) (2,4,2,1) (2,4,2,2) (2,4,2,3) (2,4,2,4) (2,4,3,1) (2,4,3,2) (2,4,3,3) (2,4,3,4) (2,4,4,1) (2,4,4,2) (2,4,4,3) (2,4,4,4) (3,1,1,1) (3,1,1,2) (3,1,1,3) (3,1,1,4) (3,1,2,1) (3,1,2,2) (3,1,2,3) (3,1,2,4) (3,1,3,1) (3,1,3,2) (3,1,3,3) (3,1,3,4) (3,1,4,1) (3,1,4,2) (3,1,4,3) (3,1,4,4) (3,2,1,1) (3,2,1,2) (3,2,1,3) (3,2,1,4) (3,2,2,1) (3,2,2,2) (3,2,2,3) (3,2,2,4) (3,2,3,1) (3,2,3,2) (3,2,3,3) (3,2,3,4) (3,2,4,1) (3,2,4,2) (3,2,4,3) (3,2,4,4) (3,3,1,1) (3,3,1,2) (3,3,1,3) (3,3,1,4) (3,3,2,1) (3,3,2,2) (3,3,2,3) (3,3,2,4) (3,3,3,1) (3,3,3,2) (3,3,3,3) (3,3,3,4) (3,3,4,1) (3,3,4,2) (3,3,4,3) (3,3,4,4) (3,4,1,1) (3,4,1,2) (3,4,1,3) (3,4,1,4) (3,4,2,1) (3,4,2,2) (3,4,2,3) (3,4,2,4) (3,4,3,1) (3,4,3,2) (3,4,3,3) (3,4,3,4) (3,4,4,1) (3,4,4,2) (3,4,4,3) (3,4,4,4) (4,1,1,1) (4,1,1,2) (4,1,1,3) (4,1,1,4) (4,1,2,1) (4,1,2,2) (4,1,2,3) (4,1,2,4) (4,1,3,1) (4,1,3,2) (4,1,3,3) (4,1,3,4) (4,1,4,1) (4,1,4,2) (4,1,4,3) (4,1,4,4) (4,2,1,1) (4,2,1,2) (4,2,1,3) (4,2,1,4) (4,2,2,1) (4,2,2,2) (4,2,2,3) (4,2,2,4) (4,2,3,1) (4,2,3,2) (4,2,3,3) (4,2,3,4) (4,2,4,1) (4,2,4,2) (4,2,4,3) (4,2,4,4) (4,3,1,1) (4,3,1,2) (4,3,1,3) (4,3,1,4) (4,3,2,1) (4,3,2,2) (4,3,2,3) (4,3,2,4) (4,3,3,1) (4,3,3,2) (4,3,3,3) (4,3,3,4) (4,3,4,1) (4,3,4,2) (4,3,4,3) (4,3,4,4) (4,4,1,1) (4,4,1,2) (4,4,1,3) (4,4,1,4) (4,4,2,1) (4,4,2,2) (4,4,2,3) (4,4,2,4) (4,4,3,1) (4,4,3,2) (4,4,3,3) (4,4,3,4) (4,4,4,1) (4,4,4,2) (4,4,4,3) (4,4,4,4)' >>> ts.logsigkeys(width, depth) ' 1 2 3 4 [1,2] [1,3] [1,4] [2,3] [2,4] [3,4] [1,[1,2]] [1,[1,3]] [1,[1,4]] [2,[1,2]] [2,[1,3]] [2,[1,4]] [2,[2,3]] [2,[2,4]] [3,[1,2]] [3,[1,3]] [3,[1,4]] [3,[2,3]] [3,[2,4]] [3,[3,4]] [4,[1,2]] [4,[1,3]] [4,[1,4]] [4,[2,3]] [4,[2,4]] [4,[3,4]] [1,[1,[1,2]]] [1,[1,[1,3]]] [1,[1,[1,4]]] [2,[1,[1,2]]] [2,[1,[1,3]]] [2,[1,[1,4]]] [2,[2,[1,2]]] [2,[2,[1,3]]] [2,[2,[1,4]]] [2,[2,[2,3]]] [2,[2,[2,4]]] [3,[1,[1,2]]] [3,[1,[1,3]]] [3,[1,[1,4]]] [3,[2,[1,2]]] [3,[2,[1,3]]] [3,[2,[1,4]]] [3,[2,[2,3]]] [3,[2,[2,4]]] [3,[3,[1,2]]] [3,[3,[1,3]]] [3,[3,[1,4]]] [3,[3,[2,3]]] [3,[3,[2,4]]] [3,[3,[3,4]]] [4,[1,[1,2]]] [4,[1,[1,3]]] [4,[1,[1,4]]] [4,[2,[1,2]]] [4,[2,[1,3]]] [4,[2,[1,4]]] [4,[2,[2,3]]] [4,[2,[2,4]]] [4,[3,[1,2]]] [4,[3,[1,3]]] [4,[3,[1,4]]] [4,[3,[2,3]]] [4,[3,[2,4]]] [4,[3,[3,4]]] [4,[4,[1,2]]] [4,[4,[1,3]]] [4,[4,[1,4]]] [4,[4,[2,3]]] [4,[4,[2,4]]] [4,[4,[3,4]]] [[1,2],[1,3]] [[1,2],[1,4]] [[1,2],[2,3]] [[1,2],[2,4]] [[1,2],[3,4]] [[1,3],[1,4]] [[1,3],[2,3]] [[1,3],[2,4]] [[1,3],[3,4]] [[1,4],[2,3]] [[1,4],[2,4]] [[1,4],[3,4]] [[2,3],[2,4]] [[2,3],[3,4]] [[2,4],[3,4]]' >>> stream = brownian(100, width) >>> print(np.max(np.abs(ets.stream2sig(stream,depth)-ts.stream2sig(stream,depth))) < 1e-12) True >>> print(np.max(np.abs(ets.stream2logsig(stream,depth)-ts.stream2logsig(stream,depth))) < 1e-12) True """ width = stream.shape[1] return te.stream2sigtensor(stream, signature_degree)[te.blob_size(width):]
def sigdim(signal_dimension, signature_degree): """Returns the length of the signature vector. Parameters ---------- signal_dimension : int Dimension of the underlying vector space. signature_degree : int Degree of the signature. Returns ------- int Length of the signature vector. """ return te.blob_size(signal_dimension, signature_degree) - te.blob_size(signal_dimension)
def index_to_tuple(i, width): # the shape of the tensor that contains # \sum t[k] index_to_tuple(k,width) is the tensor # None () (0) (1) ...(w-1) (0,0) ...(n1,...,nd) ... """ >>> from tjl_hall_numpy_lie import * >>> from tjl_dense_numpy_tensor import * >>> width = 2 >>> depth = 3 >>> t = arange(width, depth) >>> print(t) [ 2. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.] >>> for t1 in [t]: ... for k, coeff in enumerate(t1): ... print (coeff, index_to_tuple(k,width)) ... 2.0 None 1.0 () 2.0 (1,) 3.0 (2,) 4.0 (1, 1) 5.0 (1, 2) 6.0 (2, 1) 7.0 (2, 2) 8.0 (1, 1, 1) 9.0 (1, 1, 2) 10.0 (1, 2, 1) 11.0 (1, 2, 2) 12.0 (2, 1, 1) 13.0 (2, 1, 2) 14.0 (2, 2, 1) 15.0 (2, 2, 2) >>> """ _blob_size = lambda depth: tjl_dense_numpy_tensor.blob_size(width, depth) _layers = lambda bz: tjl_dense_numpy_tensor.layers(bz, width) bz = i + 1 d = _layers(bz) ## this index is in the d-tensors if _layers(bz) < 0: return j = bz - 1 - _blob_size(d - 1) ans = () ## remove initial offset to compute the index if j >= 0: for jj in range(d): ans = (1 + (j % width), ) + ans j = j // width return ans
def sigkeys(width, desired_degree): """ >>> from tjl_hall_numpy_lie import * >>> from tjl_dense_numpy_tensor import * >>> width = 2 >>> depth = 3 >>> from esig import tosig as ts >>> ts.sigkeys(width , depth) == sigkeys(width , depth) True >>> sigkeys(width , depth) ' () (1) (2) (1,1) (1,2) (2,1) (2,2) (1,1,1) (1,1,2) (1,2,1) (1,2,2) (2,1,1) (2,1,2) (2,2,1) (2,2,2)' >>> """ t_to_string(0, width) return " " + " ".join([ t_to_string(z, width) for z in range(1, blob_size(width, desired_degree)) ])
def expand(k, width, depth): _expand = lambda k: expand(k, width, depth) _tensor_multiply = lambda k1, k2: tjl_dense_numpy_tensor.tensor_multiply( k1, k2, depth) _tensor_sub = tjl_dense_numpy_tensor.tensor_sub if k: hall_set, degrees, degree_boundaries, reverse_map, width = hall_basis( width, depth) (k1, k2) = hall_set[k] if k1: return _tensor_sub( _tensor_multiply(_expand(k1), _expand(k2)), _tensor_multiply(_expand(k2), _expand(k1)), ) else: ans = tjl_dense_numpy_tensor.zero(width, 1) ans[blob_size(width, 0) - 1 + k2] = scalar_type( 1) ## recall k2 will never be zero return ans return tjl_dense_numpy_tensor.zero(width)