def testLevel1(self): m = 1 d = 2 path = numpy.random.uniform(size=(10, d)) rightSig = path[-1, :] - path[0, :] s = iisignature.prepare(d, m, "cosx2") self.assertLess(diff(iisignature.sig(path, m), rightSig), 0.0000001) for type_ in ("C", "O", "S", "X", "A"): self.assertLess(diff(iisignature.logsig(path, s, type_), rightSig), 0.0000001, type_) self.assertLess(diff(rightSig, iisignature.logsigtosig(rightSig, s)), 0.000001) derivs = numpy.array([2.1, 3.2]) pathderivs = numpy.zeros_like(path) pathderivs[-1] = derivs pathderivs[0] = -derivs self.assertLess( diff(iisignature.logsigbackprop(derivs, path, s), pathderivs), 0.00001) self.assertLess( diff(iisignature.logsigbackprop(derivs, path, s, "X"), pathderivs), 0.00001) self.assertLess( diff(iisignature.sigbackprop(derivs, path, m), pathderivs), 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 test_batch(self): numpy.random.seed(734) d = 2 m = 2 n = 15 paths = [numpy.random.uniform(-1, 1, size=(6, d)) for i in range(n)] pathArray15 = stack(paths) pathArray1315 = numpy.reshape(pathArray15, (1, 3, 1, 5, 6, d)) sigs = [iisignature.sig(i, m) for i in paths] sigArray = stack(sigs) sigArray15 = iisignature.sig(pathArray15, m) sigArray1315 = iisignature.sig(pathArray1315, m) siglength = iisignature.siglength(d, m) self.assertEqual(sigArray1315.shape, (1, 3, 1, 5, siglength)) self.assertTrue( numpy.allclose(sigArray1315.reshape(n, siglength), sigs)) self.assertEqual(sigArray15.shape, (15, siglength)) self.assertTrue(numpy.allclose(sigArray15, sigs)) backsigs = [ iisignature.sigbackprop(i, j, m) for i, j in zip(sigs, paths) ] backsigArray = stack(backsigs) backsigs1315 = iisignature.sigbackprop(sigArray1315, pathArray1315, m) self.assertEqual(backsigs1315.shape, (1, 3, 1, 5, 6, d)) self.assertTrue( numpy.allclose(backsigs1315.reshape(n, 6, 2), backsigArray)) data = [numpy.random.uniform(size=(d, )) for i in range(n)] dataArray1315 = stack(data).reshape((1, 3, 1, 5, d)) joined = [iisignature.sigjoin(i, j, m) for i, j in zip(sigs, data)] joined1315 = iisignature.sigjoin(sigArray1315, dataArray1315, m) self.assertEqual(joined1315.shape, (1, 3, 1, 5, siglength)) self.assertTrue( numpy.allclose(joined1315.reshape(n, -1), stack(joined))) backjoined = [ iisignature.sigjoinbackprop(i, j, k, m) for i, j, k in zip(joined, sigs, data) ] backjoinedArrays = [ stack([i[j] for i in backjoined]) for j in range(2) ] backjoined1315 = iisignature.sigjoinbackprop(joined1315, sigArray1315, dataArray1315, m) self.assertEqual(backjoined1315[0].shape, sigArray1315.shape) self.assertEqual(backjoined1315[1].shape, dataArray1315.shape) self.assertTrue( numpy.allclose(backjoined1315[0].reshape(n, -1), backjoinedArrays[0])) self.assertTrue( numpy.allclose(backjoined1315[1].reshape(n, -1), backjoinedArrays[1])) dataAsSigs = [ iisignature.sig(numpy.row_stack([numpy.zeros((d, )), i]), m) for i in data ] dataArray13151 = dataArray1315[:, :, :, :, None, :] dataArray13151 = numpy.repeat(dataArray13151, 2, 4) * [[0.0], [1.0]] dataArrayAsSigs1315 = iisignature.sig(dataArray13151, m) combined1315 = iisignature.sigcombine(sigArray1315, dataArrayAsSigs1315, d, m) self.assertEqual(joined1315.shape, combined1315.shape) self.assertTrue(numpy.allclose(joined1315, combined1315)) backcombined1315 = iisignature.sigcombinebackprop( joined1315, sigArray1315, dataArrayAsSigs1315, d, m) backcombined = [ iisignature.sigcombinebackprop(i, j, k, d, m) for i, j, k in zip(joined, sigs, dataAsSigs) ] backcombinedArrays = [ stack([i[j] for i in backcombined]) for j in range(2) ] self.assertEqual(backcombined1315[0].shape, sigArray1315.shape) self.assertEqual(backcombined1315[1].shape, sigArray1315.shape) self.assertTrue(numpy.allclose(backjoined1315[0], backcombined1315[0])) self.assertTrue( numpy.allclose(backcombined1315[0].reshape(n, -1), backcombinedArrays[0])) self.assertTrue( numpy.allclose(backcombined1315[1].reshape(n, -1), backcombinedArrays[1])) scaled = [iisignature.sigscale(i, j, m) for i, j in zip(sigs, data)] scaled1315 = iisignature.sigscale(sigArray1315, dataArray1315, m) self.assertEqual(scaled1315.shape, (1, 3, 1, 5, siglength)) self.assertTrue( numpy.allclose(scaled1315.reshape(n, -1), stack(scaled))) backscaled = [ iisignature.sigscalebackprop(i, j, k, m) for i, j, k in zip(scaled, sigs, data) ] backscaledArrays = [ stack([i[j] for i in backscaled]) for j in range(2) ] backscaled1315 = iisignature.sigscalebackprop(scaled1315, sigArray1315, dataArray1315, m) self.assertEqual(backscaled1315[0].shape, sigArray1315.shape) self.assertEqual(backscaled1315[1].shape, dataArray1315.shape) self.assertTrue( numpy.allclose(backscaled1315[0].reshape(n, -1), backscaledArrays[0])) self.assertTrue( numpy.allclose(backscaled1315[1].reshape(n, -1), backscaledArrays[1])) s_s = (iisignature.prepare(d, m, "cosax2"), iisignature.prepare(d, m, "cosahx2")) for type in ("c", "o", "s", "x", "a", "ch", "oh", "sh", "ah"): s = s_s[1 if "h" in type else 0] logsigs = [iisignature.logsig(i, s, type) for i in paths] logsigArray = stack(logsigs) logsigArray1315 = iisignature.logsig(pathArray1315, s, type) self.assertEqual(logsigArray1315.shape, (1, 3, 1, 5, logsigs[0].shape[0]), type) self.assertTrue( numpy.allclose(logsigArray1315.reshape(n, -1), logsigArray), type) if type in ("s", "x", "sh"): backlogs = stack([ iisignature.logsigbackprop(i, j, s, type) for i, j in zip(logsigs, paths) ]) backlogs1315 = iisignature.logsigbackprop( logsigArray1315, pathArray1315, s, type) self.assertEqual(backlogs1315.shape, backsigs1315.shape) self.assertTrue( numpy.allclose(backlogs1315.reshape(n, 6, d), backlogs), type) for s in s_s: logsigs1315 = iisignature.logsig(pathArray1315, s) logsigs = [iisignature.logsig(p, s) for p in paths] sigsFromLogSigs1315 = iisignature.logsigtosig(logsigs1315, s) self.assertEqual(sigsFromLogSigs1315.shape, sigArray1315.shape) self.assertTrue(numpy.allclose(sigsFromLogSigs1315, sigArray1315)) backls2s = stack([ iisignature.logsigtosigbackprop(i, j, s) for i, j in zip(sigs, logsigs) ]) backls2s1315 = iisignature.logsigtosigbackprop( sigArray1315, logsigs1315, s) self.assertEqual(backls2s1315.shape, logsigs1315.shape) self.assertTrue( numpy.allclose(backls2s1315.reshape(-1, logsigs[0].shape[0]), backls2s)) a = iisignature.rotinv2dprepare(m, "a") rots = stack([iisignature.rotinv2d(i, a) for i in paths]) rots1315 = iisignature.rotinv2d(pathArray1315, a) self.assertEqual(rots1315.shape, (1, 3, 1, 5, rots.shape[1])) self.assertTrue(numpy.allclose(rots1315.reshape(n, -1), rots))