From 4df4f92456122a67197163572284f051968d6a18 Mon Sep 17 00:00:00 2001 From: Julian Peeters Date: Wed, 24 Jan 2024 21:16:54 -0800 Subject: [PATCH] Basic support for tensor of three monomials --- README.md | 10 +++-- docs/readme.md | 3 +- .../scala/polynomial/mermaid/Mermaid.scala | 12 +++--- .../scala/polynomial/morphism/PolyMap.scala | 6 ++- .../polynomial/morphism/methods/andThen.scala | 41 ++++++++++++++----- .../scala/polynomial/product/Tensor.scala | 8 +++- 6 files changed, 55 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index b111884..a645a21 100644 --- a/README.md +++ b/README.md @@ -74,17 +74,19 @@ be printed, with titles and labels in the following formats: import polynomial.`object`.Monomial.{Store, Interface} import polynomial.mermaid.{Format, Mermaid, given} import polynomial.morphism.~> +import polynomial.product.⊗ -type F[Y] = (Store[Boolean, _] ~> Interface[Int, Int, _])[Y] +type F[Y] = ((Store[Boolean, _] ⊗ Store[Boolean, _]) ~> (Interface[Int, Int, _] ⊗ Interface[Int, Int, _]))[Y] val M: Mermaid[F] = summon[Mermaid[F]] -// M: Mermaid[F] = polynomial.mermaid.Mermaid$$anon$1@56887c6 +// M: Mermaid[F] = polynomial.mermaid.Mermaid$$anon$5@1264038d println(M.showTitledGraph(titleFmt = Format.Generic, graphFmt = Format.Generic)) // ```mermaid // graph LR; -// TitleStart[ ]:::hidden~~~TitleBody[S𝑦SB𝑦A]:::title~~~TitleEnd[ ]:::hidden -// A:::hidden---|A|S[S]---|B|B:::hidden; +// TitleStart[ ]:::hidden~~~TitleBody[S1𝑦S1S2𝑦S2B1𝑦A1B2𝑦A2]:::title~~~TitleEnd[ ]:::hidden +// A1:::hidden---|A1|S1[S1]---|B1|B1:::hidden; +// A2:::hidden---|A2|S2[S2]---|B2|B2:::hidden; // // classDef empty fill:background; // classDef point width:0px, height:0px; diff --git a/docs/readme.md b/docs/readme.md index 155e492..579758e 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -74,8 +74,9 @@ be printed, with titles and labels in the following formats: import polynomial.`object`.Monomial.{Store, Interface} import polynomial.mermaid.{Format, Mermaid, given} import polynomial.morphism.~> +import polynomial.product.⊗ -type F[Y] = (Store[Boolean, _] ~> Interface[Int, Int, _])[Y] +type F[Y] = ((Store[Boolean, _] ⊗ Store[Boolean, _]) ~> (Interface[Int, Int, _] ⊗ Interface[Int, Int, _]))[Y] val M: Mermaid[F] = summon[Mermaid[F]] diff --git a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala index de52035..381a528 100644 --- a/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala +++ b/modules/mermaid/shared/src/main/scala/polynomial/mermaid/Mermaid.scala @@ -401,12 +401,12 @@ object Mermaid: Q2: MermaidQ[Monomial.Interface[A2, B2, _]], ): Mermaid[PolyMap[Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _], Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _], _]] = new Mermaid[PolyMap[Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _], Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _], _]]: - private val labelS1 = "S1" - private val labelS2 = "S2" - private val labelA1 = "A1" - private val labelA2 = "A2" - private val labelB1 = "B1" - private val labelB2 = "B2" + private val labelS1 = "S1" + private val labelS2 = "S2" + private val labelA1 = "A1" + private val labelA2 = "A2" + private val labelB1 = "B1" + private val labelB2 = "B2" private val nodeS1 = "S1" private val nodeS2 = "S2" private val nodeA1 = "A1" diff --git a/modules/poly/shared/src/main/scala/polynomial/morphism/PolyMap.scala b/modules/poly/shared/src/main/scala/polynomial/morphism/PolyMap.scala index c262540..0f3b755 100644 --- a/modules/poly/shared/src/main/scala/polynomial/morphism/PolyMap.scala +++ b/modules/poly/shared/src/main/scala/polynomial/morphism/PolyMap.scala @@ -24,7 +24,7 @@ object PolyMap: type Phi[P[_], Q[_], Y] = (P[Y], Q[Y]) match case (Binomial.Interface[a1, b1, a2, b2, Y], Binomial.Interface[a3, b3, a4, b4, Y]) => (b1 => b3, b2 => b4) - case (Binomial.Interface[a1, b1, a2, b2, Y], Monomial.Interface[a3, b3, Y]) => (b1 => b3, b2 => b3) + case (Binomial.Interface[a1, b1, a2, b2, Y], Monomial.Interface[a3, b3, Y]) => (b1 => b3, b2 => b3) case (Monomial.Interface[a1, b1, Y], Binomial.Interface[a3, b3, a4, b4, Y]) => (b1 => b3, b1 => b4) case (Monomial.Interface[a1, b1, Y], Monomial.Interface[a2, b2, Y]) => b1 => b2 case (PolyMap[p, q, Y], Binomial.Interface[a3, b3, a4, b4, Y]) => Phi[p, Binomial.Interface[a3, b3, a4, b4, _], Y] @@ -33,10 +33,11 @@ object PolyMap: case (Monomial.Store[s, Y], Binomial.Interface[a1, b1, a2, b2, Y]) => (s => b1, s => b2) case (Monomial.Store[s, Y], Monomial.Interface[a, b, Y]) => s => b case (Monomial.Store[s, Y], Composition[p, q, Y]) => (Phi[Monomial.Store[s, _], p, Y], Phi[p, q, Y]) + case (Tensor[p, q, Y], Monomial.Store[s1, Y]) => Phi[Tensor.DayConvolution[p, q, _], Monomial.Store[s1, _], Y] case (Tensor[p, q, Y], Monomial.Interface[a1, b1, Y]) => Phi[Tensor.DayConvolution[p, q, _], Monomial.Interface[a1, b1, _], Y] case (Tensor[p, q, Y], Binomial.Interface[a1, b1, a2, b2, Y]) => Phi[Tensor.DayConvolution[p, q, _], Binomial.Interface[a1, b1, a2, b2, _], Y] case (Tensor[o, p, Y], Tensor[q, r, Y]) => Phi[Tensor.DayConvolution[o, p, _], Tensor.DayConvolution[q, r, _], Y] - + type PhiSharp[P[_], Q[_], Y] = (P[Y], Q[Y]) match case (Binomial.Interface[a1, b1, a2, b2, Y], Binomial.Interface[a3, b3, a4, b4, Y]) => ((b1, a3) => a1, (b2, a4) => a2) case (Binomial.Interface[a1, b1, a2, b2, Y], Monomial.Interface[a3, b3, Y]) => ((b1, a3) => a1, (b2, a3) => a2) @@ -50,4 +51,5 @@ object PolyMap: case (PolyMap[o, p, Y], Tensor[q, r, Y]) => PhiSharp[o, Tensor[q, r, _], Y] case (Tensor[p, q, Y], Binomial.Interface[a1, b1, a2, b2, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], Binomial.Interface[a1, b1, a2, b2, _], Y] case (Tensor[p, q, Y], Monomial.Interface[a1, b1, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], Monomial.Interface[a1, b1, _], Y] + case (Tensor[p, q, Y], Monomial.Store[s1, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], Monomial.Store[s1, _], Y] case (Tensor[o, p, Y], Tensor[q, r, Y]) => PhiSharp[Tensor.DayConvolution[o, p, _], Tensor.DayConvolution[q, r, _], Y] \ No newline at end of file diff --git a/modules/poly/shared/src/main/scala/polynomial/morphism/methods/andThen.scala b/modules/poly/shared/src/main/scala/polynomial/morphism/methods/andThen.scala index 2f8ea88..afcdbeb 100644 --- a/modules/poly/shared/src/main/scala/polynomial/morphism/methods/andThen.scala +++ b/modules/poly/shared/src/main/scala/polynomial/morphism/methods/andThen.scala @@ -70,7 +70,7 @@ object andThen: def φ: PolyMap.Phi[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _]) ~> (Monomial.Interface[(A, B), C, _] ⊗ Monomial.Interface[C, B, _]), Monomial.Interface[A, A => C, _], Y] = p.φ.andThen(w.φ) def `φ#`: PolyMap.PhiSharp[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _]) ~> (Monomial.Interface[(A, B), C, _] ⊗ Monomial.Interface[C, B, _]), Monomial.Interface[A, A => C, _], Y] = - (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) + (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) extension [S1, S2, A1, B1, A2, B2, Y] (p: PolyMap[Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _], Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _], Y]) @scala.annotation.targetName("andThenTensoredStoreTensoredMonoToTensoredMono") @@ -87,19 +87,40 @@ object andThen: @scala.annotation.targetName("andThenTensorStoreTensorBiToBi") def andThen( w: PolyMap[Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _], Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _], Y], - f: S2 => A3, - g: S1 => A4, - h: B1 => A3, - i: B2 => A4 + // f: S2 => A3, + // g: S1 => A4, + // h: B1 => A3, + // i: B2 => A4 ): PolyMap[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _]), (Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]), _], Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _], Y] = new PolyMap[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _]), (Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]), _], Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _], Y]: def φ: PolyMap.Phi[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _]), (Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]), _], Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _], Y] = ( - s => a1 => p.φ._1(p.`φ#`._1(s, (a1, h(p.φ._1(s)._1))))._2, - s => a2 => p.φ._2(p.`φ#`._2(s, (a2, i(p.φ._2(s)._1))))._2 + p.φ._1.andThen(w.φ._1), + p.φ._2.andThen(w.φ._2), + // s => a1 => p.φ._1(p.`φ#`._1(s, (a1, h(p.φ._1(s)._1))))._2, + // s => a2 => p.φ._2(p.`φ#`._2(s, (a2, i(p.φ._2(s)._1))))._2 ) def `φ#`: PolyMap.PhiSharp[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _]), (Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]), _], Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _], Y] = ( - (s: (S1, S2), a1: A1) => p.`φ#`._1(s, (a1, f(s._2))), - (s: (S1, S2), a2: A2) => p.`φ#`._2(s, (a2, g(s._1))) - ) \ No newline at end of file + (s, a) => p.`φ#`._1(s, w.`φ#`._1(p.φ._1(s), a)), + (s, a) => p.`φ#`._2(s, w.`φ#`._2(p.φ._2(s), a)), + // (s: (S1, S2), a1: A1) => p.`φ#`._1(s, (a1, f(s._2))), + // (s: (S1, S2), a2: A2) => p.`φ#`._2(s, (a2, g(s._1))) + ) + + extension [S1, S2, S3, A1, B1, A2, B2, A3, B3, A4, B4, Y] ( + p: PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _] ⊗ Monomial.Store[S3, _]), (Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]), Y] + ) + @scala.annotation.targetName("andThenMsMsMstoMiMiMi") + def andThen( + w: PolyMap[(Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]), Monomial.Interface[Unit, Unit => Unit, _], Y], + f: S1 => A1, + g: S2 => A2, + h: S3 => A3, + ): PolyMap[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _] ⊗ Monomial.Store[S3, _]), (Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]), _], Monomial.Interface[Unit, Unit => Unit, _], Y] = + new PolyMap[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _] ⊗ Monomial.Store[S3, _]), (Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]), _], Monomial.Interface[Unit, Unit => Unit, _], Y]: + def φ: PolyMap.Phi[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _] ⊗ Monomial.Store[S3, _]), (Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]), _], Monomial.Interface[Unit, Unit => Unit, _], Y] = + p.φ.andThen(w.φ) + def `φ#`: PolyMap.PhiSharp[PolyMap[(Monomial.Store[S1, _] ⊗ Monomial.Store[S2, _] ⊗ Monomial.Store[S3, _]), (Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]), _], Monomial.Interface[Unit, Unit => Unit, _], Y] = + (s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a)) + // (s, _) => p.`φ#`(s, ((f(s._1._1), g(s._1._2)), h(s._2))) diff --git a/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala b/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala index 9ee4c56..3dd4f90 100644 --- a/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala +++ b/modules/poly/shared/src/main/scala/polynomial/product/Tensor.scala @@ -1,7 +1,7 @@ package polynomial.product -import polynomial.`object`.{Binomial, Monomial} import polynomial.morphism.PolyMap +import polynomial.`object`.{Binomial, Monomial} type ⊗[P[_], Q[_]] = Tensor[P, Q, _] @@ -10,6 +10,10 @@ object Tensor: type DayConvolution[P[_], Q[_], Y] = (P[Y], Q[Y]) match case (Binomial.Interface[a1, b1, a2, b2, Y], Binomial.Interface[a3, b3, a4, b4, Y]) => Binomial.Interface[(a1, a3), (b1, b3), (a2, a4), (b2, b4), Y] + case (Monomial.Interface[a1, b1, Y], Binomial.Interface[a2, b2, a3, b3, Y]) => Binomial.Interface[(a1, a2), (b1, b2), (a1, a3), (b1, b3), Y] case (Monomial.Interface[a1, b1, Y], Monomial.Interface[a2, b2, Y]) => Monomial.Interface[(a1, a2), (b1, b2), Y] case (Monomial.Store[s1, Y], Monomial.Store[s2, Y]) => Monomial.Store[(s1, s2), Y] - case (PolyMap[o, p, Y], PolyMap[q, r, Y]) => PolyMap[DayConvolution[o, q, _], DayConvolution[p, r, _], Y] \ No newline at end of file + case (PolyMap[o, p, Y], PolyMap[q, r, Y]) => PolyMap[DayConvolution[o, q, _], DayConvolution[p, r, _], Y] + case (Tensor[o, p, Y], Binomial.Interface[a1, b1, a2, b2, Y]) => DayConvolution[DayConvolution[o, p, _], Binomial.Interface[a1, b1, a2, b2, _], Y] + case (Tensor[o, p, Y], Monomial.Interface[a1, b1, Y]) => DayConvolution[DayConvolution[o, p, _], Monomial.Interface[a1, b1, _], Y] + case (Tensor[o, p, Y], Monomial.Store[s1, Y]) => DayConvolution[DayConvolution[o, p, _], Monomial.Store[s1, _], Y] \ No newline at end of file