# Storing Computations -- caching scheme for jets computations

In many cases, the jets method will store its results inside a CacheTable in the base object. When the method is called again with the same or a lower jets order, the result is pulled from the cache.

For polynomial rings, data is stored under *.jet.

 i1 : R= QQ[x,y] o1 = R o1 : PolynomialRing i2 : R.?jet o2 = false i3 : jets(3,R) o3 = QQ[x0, y0][x1, y1][x2, y2][x3, y3] o3 : PolynomialRing i4 : R.?jet o4 = true i5 : peek R.jet o5 = CacheTable{jetsMaxOrder => 3 } jetsRing => QQ[x0, y0][x1, y1][x2, y2][x3, y3]

Note also that rings of jets are built as towers from lower to higher jets orders. Therefore it is possible to store a single ring of the highest order computed thus far.

For ideals, data is stored under *.cache.jet. A single matrix is stored containing generators for the highest order of jets computed thus far. Generators for lower orders are recovered from this matrix without additional computations.

 i6 : I= ideal (x^2 - y) 2 o6 = ideal(x - y) o6 : Ideal of R i7 : I.cache.?jet o7 = false i8 : elapsedTime jets(3,I) -- 0.0989431 seconds elapsed 2 2 o8 = ideal (2x0*x3 - y3 + 2x1*x2, 2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) o8 : Ideal of QQ[x0, y0][x1, y1][x2, y2][x3, y3] i9 : I.cache.?jet o9 = true i10 : peek I.cache.jet o10 = CacheTable{jetsMatrix => | 2x0x3-y3+2x1x2 |} | 2x0x2-y2+x1^2 | | 2x0x1-y1 | | x0^2-y0 | jetsMaxOrder => 3 i11 : elapsedTime jets(3,I) -- 0.00518438 seconds elapsed 2 2 o11 = ideal (2x0*x3 - y3 + 2x1*x2, 2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) o11 : Ideal of QQ[x0, y0][x1, y1][x2, y2][x3, y3] i12 : elapsedTime jets(2,I) -- 0.00382195 seconds elapsed 2 2 o12 = ideal (2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) o12 : Ideal of QQ[x0, y0][x1, y1][x2, y2]

For quotient rings, data is stored under *.jet. Each jets order gives rise to a different quotient that is stored separately under *.jet.jetsRing (order zero jets are always included by default).

 i13 : Q= R/I o13 = Q o13 : QuotientRing i14 : Q.?jet o14 = false i15 : jets(3,Q) QQ[x0, y0][x1, y1][x2, y2][x3, y3] o15 = ---------------------------------------------------------------- 2 2 (2x0*x3 - y3 + 2x1*x2, 2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) o15 : QuotientRing i16 : Q.?jet o16 = true i17 : peek Q.jet.jetsRing QQ[x0, y0][x1, y1][x2, y2][x3, y3] o17 = CacheTable{3 => ----------------------------------------------------------------} 2 2 (2x0*x3 - y3 + 2x1*x2, 2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) QQ[x0, y0] 0 => ---------- 2 x0 - y0 i18 : jets(2,Q) QQ[x0, y0][x1, y1][x2, y2] o18 = ------------------------------------------ 2 2 (2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) o18 : QuotientRing i19 : peek Q.jet.jetsRing QQ[x0, y0][x1, y1][x2, y2][x3, y3] o19 = CacheTable{3 => ----------------------------------------------------------------} 2 2 (2x0*x3 - y3 + 2x1*x2, 2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) QQ[x0, y0][x1, y1][x2, y2] 2 => ------------------------------------------ 2 2 (2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) QQ[x0, y0] 0 => ---------- 2 x0 - y0

For ring homomorphisms, data is stored under *.cache.jet. A single matrix is stored describing the map for the highest order of jets computed thus far. Lower orders map are recovered from this matrix without additional computations.

 i20 : S= QQ[t] o20 = S o20 : PolynomialRing i21 : f= map(S,Q,{t,t^2}) 2 o21 = map (S, Q, {t, t }) o21 : RingMap S <--- Q i22 : isWellDefined f o22 = true i23 : f.cache.?jet o23 = false i24 : elapsedTime jets(3,f) -- 0.0652982 seconds elapsed QQ[x0, y0][x1, y1][x2, y2][x3, y3] 2 2 o24 = map (QQ[t0][t1][t2][t3], ----------------------------------------------------------------, {t3, 2t0*t3 + 2t1*t2, t2, 2t0*t2 + t1 , t1, 2t0*t1, t0, t0 }) 2 2 (2x0*x3 - y3 + 2x1*x2, 2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) QQ[x0, y0][x1, y1][x2, y2][x3, y3] o24 : RingMap QQ[t0][t1][t2][t3] <--- ---------------------------------------------------------------- 2 2 (2x0*x3 - y3 + 2x1*x2, 2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) i25 : f.cache.?jet o25 = true i26 : peek f.cache.jet o26 = CacheTable{jetsMatrix => | t3 2t0t3+2t1t2 |} | t2 2t0t2+t1^2 | | t1 2t0t1 | | t0 t0^2 | jetsMaxOrder => 3 i27 : elapsedTime jets(2,f) -- 0.0027911 seconds elapsed QQ[x0, y0][x1, y1][x2, y2] 2 2 o27 = map (QQ[t0][t1][t2], ------------------------------------------, {t2, 2t0*t2 + t1 , t1, 2t0*t1, t0, t0 }) 2 2 (2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) QQ[x0, y0][x1, y1][x2, y2] o27 : RingMap QQ[t0][t1][t2] <--- ------------------------------------------ 2 2 (2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0)

Projective jets data is stored separately under *.projet or *.cache.projet to accommodate for the different grading.

 i28 : jets(2,I,Projective=>true) 2 2 o28 = ideal (2x0*x2 - y2 + x1 , 2x0*x1 - y1, x0 - y0) o28 : Ideal of QQ[x0, y0][x1, y1][x2, y2] i29 : peek I.cache.projet o29 = CacheTable{jetsMatrix => {-2} | 2x0x2-y2+x1^2 |} {-1} | 2x0x1-y1 | {0} | x0^2-y0 | jetsMaxOrder => 2 i30 : peek R.projet o30 = CacheTable{jetsMaxOrder => 2 } jetsRing => QQ[x0, y0][x1, y1][x2, y2]

## Caveat

No data is cached when computing jets of affine varieties and (hyper)graphs, radicals, or principal components.