.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/matrix.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_matrix.py: Matrix multiplication and Kronecker product. ============================================ .. GENERATED FROM PYTHON SOURCE LINES 5-184 .. raw:: html
%3 outer_cluster_87 cluster_87 outer_cluster_88 cluster_88 outer_cluster_39 cluster_39 outer_cluster_64 cluster_64 outer_cluster_81 cluster_81 outer_cluster_15 cluster_15 outer_cluster_49 cluster_49 outer_cluster_33 cluster_33 outer_cluster_32 cluster_32 outer_cluster_66 cluster_66 outer_cluster_16 cluster_16 outer_cluster_55 cluster_55 outer_cluster_5 cluster_5 outer_cluster_74 cluster_74 outer_cluster_76 cluster_76 outer_cluster_13 cluster_13 outer_cluster_77 cluster_77 outer_cluster_75 cluster_75 outer_cluster_String-11528348156020970404 cluster_String-11528348156020970404 outer_cluster_String-3202650155014948485 cluster_String-3202650155014948485 outer_cluster_String-14222418042678926385 cluster_String-14222418042678926385 outer_cluster_String-16306764408138076702 cluster_String-16306764408138076702 outer_cluster_String-16397460090742139346 cluster_String-16397460090742139346 outer_cluster_String-11699616173846259658 cluster_String-11699616173846259658 ncols-9405279736398950097:s->MMul-18345483942329882714 MMul-18345483942329882714:s->MMul-18345483942329882714 MMul-18345483942329882714:s->MMul-11099957881801664042 ncols-2546176790493825425:s->Kron-113215578715265317 Kron-113215578715265317:s->MMul-14773350977755607829 Kron-113215578715265317:s->Id-6859102945905124672 ncols-1714775736476281168:s->Kron-4775599672430715124 Kron-4775599672430715124:s->NamedMat-11699616173846259658 Kron-4775599672430715124:s->NamedMat-14222418042678926385 ncols-14289738803621830331:s->Kron-6490375408906996292 Kron-6490375408906996292:s->Id-7638530371481476275 Kron-6490375408906996292:s->MMul-12688178645860814480 ncols-155920885323577962:s->Kron-16845183915948535765 Kron-16845183915948535765:s->MMul-351222034075905962 Kron-16845183915948535765:s->MMul-15182381807913447251 Times-11162027824455326108:s->NamedDim-11528348156020970404 Times-11162027824455326108:s->NamedDim-16306764408138076702 NamedDim-11528348156020970404:s->String-11528348156020970404 NamedDim-16306764408138076702:s->String-16306764408138076702 Times-11937194103459949105:s->ncols-9301332479516564789 Times-11937194103459949105:s->ncols-3429551472952562336 ncols-9301332479516564789:s->NamedMat-11699616173846259658 ncols-3429551472952562336:s->NamedMat-14222418042678926385 nrows-1714775736476281168:s->Kron-4775599672430715124 nrows-14289738803621830331:s->Kron-6490375408906996292 nrows-2546176790493825425:s->Kron-113215578715265317 nrows-155920885323577962:s->Kron-16845183915948535765 ncols-16108461796980496807:s->Kron-12047071565334446820 Kron-12047071565334446820:s->Id-14445659688945408293 Kron-12047071565334446820:s->NamedMat-3202650155014948485 Times-5282742591830199048:s->NamedDim-16397460090742139346 Times-5282742591830199048:s->ncols-10236680790416494354 NamedDim-16397460090742139346:s->String-16397460090742139346 ncols-10236680790416494354:s->Id-14445659688945408293 nrows-9405279736398950097:s->MMul-13678838702042704301 MMul-13678838702042704301:s->Kron-16845183915948535765 MMul-13678838702042704301:s->Kron-12047071565334446820 nrows-16108461796980496807:s->Kron-12047071565334446820 NamedMat-11699616173846259658:s->String-11699616173846259658 ncols-11016108215992845957:s->Id-7638530371481476275 Id-7638530371481476275:s->ncols-11016108215992845957 nrows-9301332479516564789:s->MMul-14773350977755607829 MMul-14773350977755607829:s->NamedMat-11699616173846259658 MMul-14773350977755607829:s->MMul-351222034075905962 nrows-11016108215992845957:s->MMul-351222034075905962 MMul-351222034075905962:s->Id-7638530371481476275 MMul-351222034075905962:s->MMul-351222034075905962 NamedMat-14222418042678926385:s->String-14222418042678926385 ncols-9353306107957757443:s->Id-6859102945905124672 Id-6859102945905124672:s->ncols-9353306107957757443 nrows-3429551472952562336:s->MMul-12688178645860814480 MMul-12688178645860814480:s->NamedMat-14222418042678926385 MMul-12688178645860814480:s->MMul-15182381807913447251 nrows-9353306107957757443:s->MMul-15182381807913447251 MMul-15182381807913447251:s->Id-6859102945905124672 MMul-15182381807913447251:s->MMul-15182381807913447251 Id-14445659688945408293:s->ncols-10912160959110460649 ncols-10912160959110460649:s->NamedMat-3202650155014948485 NamedMat-3202650155014948485:s->String-3202650155014948485 nrows-10912160959110460649:s->NamedMat-3202650155014948485 nrows-10236680790416494354:s->Id-14445659688945408293 MMul-2058493544491062523:s->Kron-16845183915948535765 MMul-2058493544491062523:s->MMul-2058493544491062523 MMul-11099957881801664042:s->Kron-16845183915948535765 MMul-11099957881801664042:s->MMul-11099957881801664042 MMul-14666065604032454919:s->MMul-2058493544491062523 MMul-14666065604032454919:s->MMul-10613007590827118942 MMul-10613007590827118942:s->MMul-11099957881801664042 MMul-10613007590827118942:s->MMul-10613007590827118942 MMul-9625780688837368324:s->Kron-6490375408906996292 MMul-9625780688837368324:s->Kron-12047071565334446820 MMul-14032557786918583467:s->MMul-18345483942329882714 MMul-14032557786918583467:s->MMul-2058493544491062523 ncols-9405279736398950097 ·.ncols MMul-18345483942329882714 (· @ ·) ncols-2546176790493825425 ·.ncols Kron-113215578715265317 kron ncols-1714775736476281168 ·.ncols Kron-4775599672430715124 kron ncols-14289738803621830331 ·.ncols Kron-6490375408906996292 kron ncols-155920885323577962 ·.ncols Kron-16845183915948535765 kron Times-11162027824455326108 (· * ·) NamedDim-11528348156020970404 Dim.named NamedDim-16306764408138076702 Dim.named Times-11937194103459949105 (· * ·) ncols-9301332479516564789 ·.ncols ncols-3429551472952562336 ·.ncols nrows-1714775736476281168 ·.nrows nrows-14289738803621830331 ·.nrows nrows-2546176790493825425 ·.nrows nrows-155920885323577962 ·.nrows ncols-16108461796980496807 ·.ncols Kron-12047071565334446820 kron Times-5282742591830199048 (· * ·) NamedDim-16397460090742139346 Dim.named ncols-10236680790416494354 ·.ncols nrows-9405279736398950097 ·.nrows MMul-13678838702042704301 (· @ ·) nrows-16108461796980496807 ·.nrows String-16306764408138076702 "m" NamedMat-11699616173846259658 Matrix.named ncols-11016108215992845957 ·.ncols Id-7638530371481476275 Matrix.identity nrows-9301332479516564789 ·.nrows MMul-14773350977755607829 (· @ ·) nrows-11016108215992845957 ·.nrows MMul-351222034075905962 (· @ ·) String-11528348156020970404 "n" NamedMat-14222418042678926385 Matrix.named ncols-9353306107957757443 ·.ncols Id-6859102945905124672 Matrix.identity nrows-3429551472952562336 ·.nrows MMul-12688178645860814480 (· @ ·) nrows-9353306107957757443 ·.nrows MMul-15182381807913447251 (· @ ·) String-16397460090742139346 "p" Id-14445659688945408293 Matrix.identity ncols-10912160959110460649 ·.ncols NamedMat-3202650155014948485 Matrix.named nrows-10912160959110460649 ·.nrows nrows-10236680790416494354 ·.nrows String-11699616173846259658 "B" String-14222418042678926385 "A" MMul-2058493544491062523 (· @ ·) MMul-11099957881801664042 (· @ ·) MMul-14666065604032454919 (· @ ·) MMul-10613007590827118942 (· @ ·) String-3202650155014948485 "C" MMul-9625780688837368324 (· @ ·) MMul-14032557786918583467 (· @ ·)


.. code-block:: Python from __future__ import annotations from egglog import * egraph = EGraph() @egraph.class_ class Dim(Expr): """ A dimension of a matix. >>> Dim(3) * Dim.named("n") Dim(3) * Dim.named("n") """ @egraph.method(egg_fn="Lit") def __init__(self, value: i64Like) -> None: ... @egraph.method(egg_fn="NamedDim") @classmethod def named(cls, name: StringLike) -> Dim: # type: ignore[empty-body] ... @egraph.method(egg_fn="Times") def __mul__(self, other: Dim) -> Dim: # type: ignore[empty-body] ... a, b, c, n = vars_("a b c n", Dim) i, j = vars_("i j", i64) egraph.register( rewrite(a * (b * c)).to((a * b) * c), rewrite((a * b) * c).to(a * (b * c)), rewrite(Dim(i) * Dim(j)).to(Dim(i * j)), rewrite(a * b).to(b * a), ) @egraph.class_(egg_sort="MExpr") class Matrix(Expr): @egraph.method(egg_fn="Id") @classmethod def identity(cls, dim: Dim) -> Matrix: # type: ignore[empty-body] """ Create an identity matrix of the given dimension. """ ... @egraph.method(egg_fn="NamedMat") @classmethod def named(cls, name: StringLike) -> Matrix: # type: ignore[empty-body] """ Create a named matrix. """ ... @egraph.method(egg_fn="MMul") def __matmul__(self, other: Matrix) -> Matrix: # type: ignore[empty-body] """ Matrix multiplication. """ ... @egraph.method(egg_fn="nrows") def nrows(self) -> Dim: # type: ignore[empty-body] """ Number of rows in the matrix. """ ... @egraph.method(egg_fn="ncols") def ncols(self) -> Dim: # type: ignore[empty-body] """ Number of columns in the matrix. """ ... @egraph.function(egg_fn="Kron") def kron(a: Matrix, b: Matrix) -> Matrix: # type: ignore[empty-body] """ Kronecker product of two matrices. https://en.wikipedia.org/wiki/Kronecker_product#Definition """ ... A, B, C, D = vars_("A B C D", Matrix) egraph.register( # The dimensions of a kronecker product are the product of the dimensions rewrite(kron(A, B).nrows()).to(A.nrows() * B.nrows()), rewrite(kron(A, B).ncols()).to(A.ncols() * B.ncols()), # The dimensions of a matrix multiplication are the number of rows of the first # matrix and the number of columns of the second matrix. rewrite((A @ B).nrows()).to(A.nrows()), rewrite((A @ B).ncols()).to(B.ncols()), # The dimensions of an identity matrix are the input dimension rewrite(Matrix.identity(n).nrows()).to(n), rewrite(Matrix.identity(n).ncols()).to(n), ) egraph.register( # Multiplication by an identity matrix is the same as the other matrix rewrite(Matrix.identity(n) @ A).to(A), rewrite(A @ Matrix.identity(n)).to(A), # Matrix multiplication is associative rewrite(A @ (B @ C)).to((A @ B) @ C), rewrite((A @ B) @ C).to(A @ (B @ C)), # Kronecker product is associative rewrite(kron(A, kron(B, C))).to(kron(kron(A, B), C)), rewrite(kron(kron(A, B), C)).to(kron(A, kron(B, C))), # Kronecker product distributes over matrix multiplication rewrite(kron(A @ C, B @ D)).to(kron(A, B) @ kron(C, D)), rewrite(kron(A, B) @ kron(C, D)).to( kron(A @ C, B @ D), # Only when the dimensions match eq(A.ncols()).to(C.nrows()), eq(B.ncols()).to(D.nrows()), ), ) egraph.register( # demand rows and columns when we multiply matrices rule(eq(C).to(A @ B)).then( let("demand1", A.ncols()), let("demand2", A.nrows()), let("demand3", B.ncols()), let("demand4", B.nrows()), ), # demand rows and columns when we take the kronecker product rule(eq(C).to(kron(A, B))).then( let("demand1", A.ncols()), let("demand2", A.nrows()), let("demand3", B.ncols()), let("demand4", B.nrows()), ), ) # Define a number of dimensions n = egraph.let("n", Dim.named("n")) m = egraph.let("m", Dim.named("m")) p = egraph.let("p", Dim.named("p")) # Define a number of matrices A = egraph.let("A", Matrix.named("A")) B = egraph.let("B", Matrix.named("B")) C = egraph.let("C", Matrix.named("C")) # Set each to be a square matrix of the given dimension egraph.register( union(A.nrows()).with_(n), union(A.ncols()).with_(n), union(B.nrows()).with_(m), union(B.ncols()).with_(m), union(C.nrows()).with_(p), union(C.ncols()).with_(p), ) # Create an example which should equal the kronecker product of A and B ex1 = egraph.let("ex1", kron(Matrix.identity(n), B) @ kron(A, Matrix.identity(m))) rows = egraph.let("rows", ex1.nrows()) cols = egraph.let("cols", ex1.ncols()) egraph.run(20) egraph.check(eq(B.nrows()).to(m)) egraph.check(eq(kron(Matrix.identity(n), B).nrows()).to(n * m)) # Verify it matches the expected result simple_ex1 = egraph.let("simple_ex1", kron(A, B)) egraph.check(eq(ex1).to(simple_ex1)) ex2 = egraph.let("ex2", kron(Matrix.identity(p), C) @ kron(A, Matrix.identity(m))) egraph.run(10) # Verify it is not simplified egraph.check_fail(eq(ex2).to(kron(A, C))) egraph .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.073 seconds) .. _sphx_glr_download_auto_examples_matrix.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: matrix.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: matrix.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_