def infer_shape(self,node,shapes): #d=shapes[0][-1] s,method=_prepared_obeject_store[node.inputs[1].get_value()] m=iisignature.info(s)["level"] d=iisignature.info(s)["dimension"] if "x" in method or "X" in method: length=iisignature.siglength(d,m) else: length=iisignature.logsiglength(d,m) return [shapes[0][:-2]+(length,)]
def consistency(self, coropa, dim, level): #numpy.random.seed(21) s = iisignature.prepare(dim,level,"coshx" if coropa else "cosx") myinfo = {"level":level, "dimension":dim, "methods": ("COSAX" if level <= 2 else "COSX"), "basis":("Standard Hall" if coropa else "Lyndon")} self.assertEqual(iisignature.info(s),myinfo) path = numpy.random.uniform(size=(10,dim)) basis = iisignature.basis(s) logsig = iisignature.logsig(path,s) sig = iisignature.sig(path,level) #check lengths self.assertEqual(len(basis),iisignature.logsiglength(dim,level)) self.assertEqual((len(basis),),logsig.shape) self.assertEqual(sig.shape,(iisignature.siglength(dim,level),)) #calculate a signature from logsig expanded_logsig = [numpy.zeros(dim ** m) for m in range(1,level + 1)] for coeff, expression in zip(logsig,basis): values, depth = valueOfBracket(expression,dim) expanded_logsig[depth - 1]+=values * coeff calculated_sig = numpy.concatenate(exponentiateTensor(expanded_logsig)) self.assertLess(diff(sig,calculated_sig),0.00001) #calculate a log signature from sig fullLogSig = numpy.concatenate(logTensor(splitConcatenatedTensor(sig,dim,level))) fullLogSigLib = iisignature.logsig(path,s,"x") diff1 = numpy.max(numpy.abs(fullLogSigLib - fullLogSig)) #print #(numpy.vstack([fullLogSig,fullLogSigLib,numpy.abs(fullLogSigLib-fullLogSig)]).transpose()) self.assertLess(diff1,0.00001) basisMatrix = [] zeros = [numpy.zeros(dim ** m) for m in range(1,level + 1)] for expression in basis: values, depth = valueOfBracket(expression, dim) temp = zeros[depth - 1] zeros[depth - 1] = values basisMatrix.append(numpy.concatenate(zeros)) zeros[depth - 1] = temp calculatedLogSig = lstsq(numpy.transpose(basisMatrix),fullLogSig)[0] diff2 = numpy.max(numpy.abs(logsig - calculatedLogSig)) self.assertLess(diff2,0.00001) #check consistency of methods slowLogSig = iisignature.logsig(path,s,"o") diffs = numpy.max(numpy.abs(slowLogSig - calculatedLogSig)) self.assertLess(diffs,0.00001) sigLogSig = iisignature.logsig(path,s,"s") diffs = numpy.max(numpy.abs(sigLogSig - calculatedLogSig)) self.assertLess(diffs,0.00001) if level < 3: areaLogSig = iisignature.logsig(path,s,"a") diffs = numpy.max(numpy.abs(areaLogSig - calculatedLogSig)) self.assertLess(diffs,0.00001)
def doL2S(self, coropa): numpy.random.seed(212) d = 3 m = 6 path = numpy.random.uniform(size=(12, d)) sig = iisignature.sig(path, m) s = iisignature.prepare(d, m, "S2H" if coropa else "S2") self.assertTrue(iisignature.info(s)["logsigtosig_supported"]) logsig = iisignature.logsig(path, s) sig_ = iisignature.logsigtosig(logsig, s) self.assertEqual(sig.shape, sig_.shape) self.assertTrue(numpy.allclose(sig, sig_)) #Like the other iisig functions, we check that derivatives #of logsigtosig allow sum(logsigtosig) to be backproped correctly #This is a boring thing to calculate, because after the first level #each of the log signature elements is a lie bracket and so #contributes a net total of 0 to the signature derivsOfSum = numpy.ones((sig.shape[0], ), dtype="float64") bumpedLogSig = 1.01 * logsig calculated = iisignature.logsigtosigbackprop(derivsOfSum, logsig, s) #wantedbackprop = allSensitivities(logsig, lambda l: iisignature.logsigtosig(l,s).sum()) manualChange = fdDeriv(lambda x: iisignature.logsigtosig(x, s), logsig, bumpedLogSig - logsig, 6) calculatedChange = numpy.sum((bumpedLogSig - logsig) * calculated) self.assertLess(numpy.abs(manualChange - calculatedChange), 0.00001) #beyond the first level, all zero if m > 1: self.assertLess(numpy.max(numpy.abs(calculated[d:])), 0.00001) self.assertEqual(calculated.shape, logsig.shape) #Now for a better test, we backprop sum(random*logsigtosig) #specifically calculate the change in it caused by bump two ways random = numpy.random.uniform(size=sig.shape[0], ) derivsOfSum = random calculated = iisignature.logsigtosigbackprop(derivsOfSum, logsig, s) manualChange = fdDeriv( lambda x: iisignature.logsigtosig(x, s) * random, logsig, bumpedLogSig - logsig, 4) calculatedChange = numpy.sum((bumpedLogSig - logsig) * calculated) self.assertLess(numpy.abs(manualChange - calculatedChange), 0.00001) self.assertEqual(calculated.shape, logsig.shape)
def getMatrices(s): info=iisignature.info(s) m=info["level"] d=info["dimension"] values=[[] for i in range(m)] for exp in iisignature.basis(s): vec,level = valueOfBracket(exp,d) values[level-1].append(vec) out=[] for v in values: def f(x,y): return numpy.inner(v[x],v[y]) out.append(numpy.fromfunction( numpy.vectorize(f),(len(v),len(v)),dtype=int)) # store=[] # for x1 in v: # store.append([]) # for x2 in v: # store[-1].append(numpy.inner(x1,x2)) # out.append(numpy.array(store)) return out