SheavesMaking math concrete with Sage
http://sheaves.github.io
Distributive Laws<p>I’ve been participating in the <a href="http://www.math.jhu.edu/~eriehl/kanII/">Kan Extension Seminar II</a>, and this week it’s my turn to <a href="https://golem.ph.utexas.edu/category/2017/02/distributive_laws.html">post about Jon Beck’s “Distributive Laws”</a> at the <a href="https://golem.ph.utexas.edu/category/">n-Category Cafe</a>!</p>
<p>The post uses lots of string diagrams for monads, resulting in pictures like the following:</p>
<p><img src="/distributive/comp_assoc.png" alt="" title="Associativity of the composite monad" /></p>
<p>See you <a href="https://golem.ph.utexas.edu/category/2017/02/distributive_laws.html">there</a>!</p>
Sat, 18 Feb 2017 00:00:00 +0000
http://sheaves.github.io/Distributive-Laws/
http://sheaves.github.io/Distributive-Laws/Noncommutative Algebras in Sage<p>In this post, I’ll demonstrate 3 ways to define non-commutative rings in Sage. They’re essentially different ways of expressing the non-commutative relations in the ring:</p>
<ol>
<li><a href="http://doc.sagemath.org/html/en/reference/algebras/sage/algebras/free_algebra.html#sage.algebras.free_algebra.FreeAlgebra_generic.g_algebra" target="_blank">Via <code class="highlighter-rouge">g_algebra</code></a>: define the relations directly</li>
<li><a href="http://www.sagemath.org/documentation/html/en/reference/polynomial_rings/sage/rings/polynomial/plural.html" target="_blank">Via <code class="highlighter-rouge">NCPolynomialRing_plural</code></a>: define a pair of structural matrices</li>
<li><a href="http://doc.sagemath.org/html/en/reference/rings/sage/rings/quotient_ring.html" target="_blank">Via a quotient of a letterplace ring</a>: define the ideal generated by the relations (only works for homogeneous relations)</li>
</ol>
<!--more-->
<p>As far as I know, all 3 methods rely on Sage’s interface with <a href="https://www.singular.uni-kl.de/index.php" target="_blank">Singular</a> and its non-commutative extension <a href="https://www.singular.uni-kl.de/Manual/4-0-2/sing_469.htm" target="_blank">Plural</a>.</p>
<p>In addition to all the documentation linked above, I also relied heavily on Greuel and Pfister’s <a href="http://www.cimpa-icpam.org/archivesecoles/20130130100834/singularbuch1-210.pdf" target="_blank"><em>A Singular Introduction to
Commutative Algebra</em></a>. Despite the title, it does have a pretty substantial section (1.9) devoted to non-commutative $G$-algebras.</p>
<h2 id="umathfraksl_2-and-its-homogenization">$U(\mathfrak{sl}_2)$ and its homogenization</h2>
<p>The running example throughout this post will be the universal enveloping algebra $U(\mathfrak{sl}_2)$ over $\mathbb{Q}$.</p>
<p>We’ll define this to be the (non-commutative) $\mathbb{Q}$-algebra $U$ with generators $e,f,h$ subject to the relations</p>
<script type="math/tex; mode=display">[e,f] = h, \qquad [h,e] = 2e, \qquad [h,f] = -2f.</script>
<p>If we set $e,f,h$ to have degree 1, these relations are not homogeneous. Their left-hand sides only have degree 2 terms, while their right-hand sides have degree 1 terms as well. This is fine with the first two methods, but won’t work for method 3 (which requires homogeneous relations).</p>
<p>To demonstrate the third method, we’ll define the $\mathbb{Q}$-algebra $H$ with generators $e,f,h,t$ subject to the homogeneous relations</p>
<script type="math/tex; mode=display">[t,e] = [t,f] = [t,h] = 0,</script>
<script type="math/tex; mode=display">[e,f] = ht, \qquad [h,e] = 2et, \qquad [h,f] = -2ft.</script>
<p>We can obtain $U$ both as a quotient and a localization of $H$:</p>
<script type="math/tex; mode=display">H/(1-t) \;\;\cong\;\; U \;\;\cong\;\; H[t^{-1}]_0.</script>
<h2 id="g-algebras">$G$-algebras</h2>
<p>Using the <a href="http://doc.sagemath.org/html/en/reference/algebras/sage/algebras/free_algebra.html#sage.algebras.free_algebra.FreeAlgebra_generic.g_algebra" target="_blank"><code class="highlighter-rouge">g_algebra</code></a> method of Sage’s <code class="highlighter-rouge">FreeAlgebra</code> class, we can simply plug our noncommutative relations in, and get our non-commutative ring. This is about as easy as it gets:</p>
<div class="sage">
<script type="text/x-sage">
F.<e,f,h> = FreeAlgebra(QQ,3)
U = F.g_algebra({f*e: e*f - h, h*e: e*h + 2*e, h*f: f*h-2*f})
U
</script>
</div>
<p>Let’s unravel what’s going on here.</p>
<h3 id="monomial-orderings-and-pbw-basis">Monomial orderings and PBW basis</h3>
<p>Most algorithms for commutative and non-commutative rings require an ordering on the generators. In our case, let’s use the ordering</p>
<script type="math/tex; mode=display">e \leq f \leq h.</script>
<p>This is implicitly stated in our code: we wrote <code class="highlighter-rouge">F.<e,f,h></code> instead of <code class="highlighter-rouge">F.<h,e,f></code>, for example.</p>
<p>A <em>standard word</em> is a monomial of the form</p>
<script type="math/tex; mode=display">e^if^jh^k, \qquad i,j,k \in \mathbb{N}</script>
<p>In the polynomial ring $\mathbb{Q}[e,f,h]$, every monomial can be expressed in this form, so the set of standard words forms a $\mathbb{Q}$-basis for $\mathbb{Q}[e,f,h]$.</p>
<p>In a non-commutative ring, whether or not the standard words form a basis depends on what relations we have. Such a basis, if it exists, is called a <a href="https://en.wikipedia.org/wiki/Poincar%C3%A9%E2%80%93Birkhoff%E2%80%93Witt_theorem" target="_blank">PBW basis</a>.</p>
<p>The free algebra $F = \mathbb{Q}\langle e,f,h\rangle$ has no relations, so does not have a PBW basis. Fortunately, our algebra $U$ does have a PBW basis.</p>
<p>This means that we can always express a non-standard monomial (e.g. $fe$) as a sum of standard monomials (e.g. $ef - h$). The non-commutative relations that define $U$ can thus be thought of as an algorithm for turning non-standard words into sums of standard words.</p>
<p>To do this in Sage, we define a <a href="https://docs.python.org/2/tutorial/datastructures.html#dictionaries" target="_blank">dictionary</a> whose keys are non-standard words and values are the standard words they become.</p>
<p>In the above example, our dictionary was short enough to fit into one line, but we could also define a dictionary separately and pass it into <code class="highlighter-rouge">g_algebra</code>:</p>
<div class="sage">
<script type="text/x-sage">
F.<e,f,h> = FreeAlgebra(QQ,3)
U_relations = {
f*e : e*f - h,
h*e : e*h + 2*e,
h*f : f*h - 2*f
}
U = F.g_algebra(U_relations)
U
</script>
</div>
<p>It’s very important that the keys are non-standard words and the values are sums of standard words. Mathematically, the relation $fe = ef - h$ is the same as $ef = fe + h$, but if we replace <code class="highlighter-rouge">f*e : e*f - h</code> with <code class="highlighter-rouge">e*f : f*e + h</code> in the code, we’ll get an error (try it!).</p>
<h3 id="what-are-g-algebras">What are $G$-algebras?</h3>
<p>The reason why $U$ has a PBW basis is because it is a $G$-algebra. Briefly, $G$-algebras are algebras whose relations satisfy certain non-degeneracy conditions that make the algebra nice to work with.</p>
<p>For a full definition of $G$-algebras, refer to <a href="http://www.cimpa-icpam.org/archivesecoles/20130130100834/singularbuch1-210.pdf" target="_blank"><em>A Singular Introduction to Commutative Algebra</em></a> or the <a href="https://www.singular.uni-kl.de/Manual/4-0-2/sing_534.htm#SEC573" target="_blank">Plural manual</a>.</p>
<p>If $A$ is a $G$-algebra, then it has a PBW basis, is left and right Noetherian, and is an integral domain. More importantly (for this site at least!), it means that we can define $A$ in Singular/Plural, and hence in Sage.</p>
<h2 id="structural-matrices-for-a-g-algebra">Structural matrices for a $G$-algebra</h2>
<p>Another way of writing our non-commutative relations is</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{pmatrix}
0 & fe & he \\
0 & 0 & hf \\
0 & 0 & 0
\end{pmatrix}
=
\begin{pmatrix}
0 & 1 & 1 \\
0 & 0 & 1 \\
0 & 0 & 0
\end{pmatrix}
*
\begin{pmatrix}
0 & ef & eh \\
0 & 0 & fh \\
0 & 0 & 0
\end{pmatrix}
+
\begin{pmatrix}
0 & -h & 2e \\
0 & 0 & -2f \\
0 & 0 & 0
\end{pmatrix}, %]]></script>
<p>where $ * $ denotes element-wise multiplication (so there isn’t any linear algebra going on here; we’re just using matrices to organize the information). Let $N,C,S,D$ be the matrices above, in that order, so that $N = C*S + D$.</p>
<p>If we let $x_1 = e, x_2 = f, x_3 = h$ (so that $x_i \leq x_j$ if $i \leq j$) then for $i < j$</p>
<script type="math/tex; mode=display">n_{ij} = x_j x_i, \qquad s_{ij} = x_i x_j.</script>
<p>In other words, $N$ contains the non-standard words that we’re trying to express in terms of the standard words in $S$.</p>
<p>The matrices $C$ and $D$ are called the <em>structural matrices</em> of the $G$-algebra, and their entries are such that our relations may be written</p>
<script type="math/tex; mode=display">% <![CDATA[
x_jx_i = c_{ij} x_i x_j + d_{ij}, \qquad i < j %]]></script>
<p>with zeros everywhere else ($i \geq j$). If $C = D = 0$, the resulting algebra will be commutative.</p>
<p>We can use the structural matrices $C$ and $D$ to define our algebra via Sage’s <a href="http://www.sagemath.org/documentation/html/en/reference/polynomial_rings/sage/rings/polynomial/plural.html" target="_blank"><code class="highlighter-rouge">NCPolynomialRing_plural</code></a> function (note that Python uses zero-indexing for matrices):</p>
<div class="sage">
<script type="text/x-sage">
from sage.rings.polynomial.plural import NCPolynomialRing_plural
R = QQ['e','f','h']
R.inject_variables()
C = matrix(R,3)
D = matrix(R,3)
C[0,1] = 1
C[0,2] = 1
C[1,2] = 1
D[0,1] = -h
D[0,2] = 2*e
D[1,2] = -2*f
show(C)
show(D)
U.<e,f,h> = NCPolynomialRing_plural(QQ, c = C, d = D, order = TermOrder('lex',3), category = Algebras(QQ))
U
</script>
</div>
<p>Note that <code class="highlighter-rouge">R</code> is a commutative polynomial ring. In fact, up till the point where we call <code class="highlighter-rouge">NCPolynomialRing_plural</code>, even the variables <code class="highlighter-rouge">e,f,h</code> are treated as commutative variables.</p>
<p>This method of defining $U$ is considerably longer and more prone to mistakes than using <code class="highlighter-rouge">g_algebra</code>. As stated in the <a href="http://www.sagemath.org/documentation/html/en/reference/polynomial_rings/sage/rings/polynomial/plural.html" target="_blank">documentation</a>, this is not intended for use! I’m including it here because this is essentially how one would go about defining a $G$-algebra in Singular. In fact, the Sage method <code class="highlighter-rouge">g_algebra</code> calls <code class="highlighter-rouge">NCPolynomialRing_plural</code>, which in turn calls Singular.</p>
<h2 id="quotients-of-letterplace-rings">Quotients of letterplace rings</h2>
<p>Our final method for defining non-commutative rings makes use of <a href="http://doc.sagemath.org/html/en/reference/algebras/sage/algebras/letterplace/free_algebra_letterplace.html" target="_blank">Sage’s implementation of Singular’s letterplace rings</a>.</p>
<p>As mentioned at the start of this post, this method requires the relations to be homogeneous, so we’ll work with $H$ instead of $U$.</p>
<p>Let $\mathbb{Q}\langle e,f,h,t \rangle$ be the free algebra on 4 variables. Consider the two-sided ideal $I$ generated by the relations for $H$:</p>
<script type="math/tex; mode=display">I = (te - et, tf - ft, th - ht, ef - fe - ht, he - eh - 2et, hf - fh + 2ft)</script>
<p>Then</p>
<script type="math/tex; mode=display">H = \mathbb{Q}\langle e,f,h,t \rangle/I.</script>
<p>This can be expressed Sage-ly:</p>
<div class="sage">
<script type="text/x-sage">
F.<e,f,h,t> = FreeAlgebra(QQ, implementation='letterplace')
I = [
t*e - e*t,
t*f - f*t,
t*h - h*t,
e*f - f*e - h*t,
h*e - e*h - 2*e*t,
h*f - f*h + 2*f*t
]
H = F.quotient(F * I * F)
H
</script>
</div>
<p>The expression <code class="highlighter-rouge">F*I*F</code> is the two-sided ideal generated by elements in the list <code class="highlighter-rouge">I</code>.</p>
<p>Although $U$ cannot be defined using this method, $H$ can be defined using all three methods. As a (fun?) exercise, try defining $H$ using the other two methods.</p>
<h2 id="difficulties">Difficulties</h2>
<p>These methods can be used to define many non-commutative algebras such as the Weyl algebra and various enveloping algebras of Lie algebras. One can also define these algebras over fields other than $\mathbb{Q}$, such as $\mathbb{C}$ or $\mathbb{F}_p$.</p>
<p>However, we cannot define algebras over $\mathbb{Q}(q)$, the fraction field of $\mathbb{Q}[q]$:</p>
<div class="sage">
<script type="text/x-sage">
Qq =QQ['q'].fraction_field()
Qq.inject_variables()
F.<x,y> = FreeAlgebra(Qq,2)
F.g_algebra({y*x : q*x*y})
</script>
</div>
<p>This is a problem if we want to define rings with relations such as</p>
<script type="math/tex; mode=display">yx = qxy.</script>
<p>Such relations occur frequently when studying quantum groups, for example.</p>
<p>This is suprising, because one can easily define $\mathbb{Q}(q)$ and non-commutative $\mathbb{Q}(q)$-algebras in Singular/Plural, which is what Sage is using. It seems that the problem is in Sage’s wrapper for Singular/Plural, because Sage can’t even pass the ring $\mathbb{Q}(q)$ to Singular.</p>
<p>There’s a <a href="http://trac.sagemath.org/ticket/14886" target="_blank">trac ticket</a> for this problem, but until it gets resolved, we’ll just have to define such rings directly in Singular/Plural. Thanks to the amazing capabilities of the <a href="https://sagecell.sagemath.org/" target="_blank">Sage Cell Server</a>, <del>we’ll do this in the next post</del>!</p>
Thu, 03 Mar 2016 00:00:00 +0000
http://sheaves.github.io/Noncommutative-Sage/
http://sheaves.github.io/Noncommutative-Sage/The Weyl Algebra and $\mathfrak{sl}_2$<!--more-->
<p>I’ve been away from this blog for quite a while - almost a year, in fact! My excuses are my wedding and the prelims (a.k.a. quals), as well as all the preparation that had to go into them (although, to be honest, those things only occupied me till September last year!).</p>
<p>Looking back at my previous posts, I’ve realized that in attempting to teach <em>both</em> math and code, I probably ended up doing neither. This is really not the best place to learn representation theory (for example) - there are better books and blogs out there. Also, most of the code that I wrote to illustrate those posts feels contrived, and neither highlights Sage’s strengths nor reflects how I normally use Sage for my assignments and projects.</p>
<p>I’ve thus decided to write shorter posts with code that I actually use (on <a href="https://cloud.sagemath.com/" target="_blank">SageMathCloud</a>), along with some explanations of the code. Lately, I’ve been writing code for non-commutative algebra and combinatorics, so today I’ll start with a simple example of a non-commutative algebra.</p>
<h2 id="the-weyl-algebra">The Weyl Algebra</h2>
<p>The $1$-dim. Weyl algebra is the (non-commutative) algebra generated by $x, \partial_x$ subject to the relations</p>
<script type="math/tex; mode=display">x \partial_x = \partial_x x - 1.</script>
<p>If we treat $x$ as “multiplication by $x$” and $\partial_x$ as “differentiation w.r.t. $x$”, this relation is really just an application of the chain rule:</p>
<script type="math/tex; mode=display">\partial_x (x (f(x)) = f(x) + x \partial_x f(x)</script>
<p>We can generalize to higher dimensions: the $n$-dim. Weyl algebra is the algebra generated by $x_1,\dots,x_n,\partial_{x_1},\dots,\partial_{x_n}$ quotiented by the relations that arise from treating them as the obvious operators on $\mathbb{F}[x_1,\dots,x_n]$.</p>
<h3 id="weyl-algebras-in-sage">Weyl algebras in Sage</h3>
<p>It’s easy to <a href="http://doc.sagemath.org/html/en/reference/algebras/sage/algebras/weyl_algebra.html" target="_blank">define the Weyl algebra in Sage</a>:</p>
<div class="linked">
<script type="text/x-sage">
# 3-dim Weyl algebra over QQ[x,y,z]
R.<x,y,z> = QQ[]
W = DifferentialWeylAlgebra(R)
W.inject_variables()
</script>
</div>
<p>Calling <code class="highlighter-rouge">inject_variables</code> allows us to use the operators <code class="highlighter-rouge">x,y,z,dx,dy,dz</code> in subsequent code (where <code class="highlighter-rouge">dx</code> denotes $\partial_x$, etc).</p>
<p>One can do rather complicated computations:</p>
<div class="linked">
<script type="text/x-sage">
dx * dy * dz * (x + y + z)^2
</script>
</div>
<p>By default, Sage chooses to represent monomials with <code class="highlighter-rouge">x,y,z</code> in front of <code class="highlighter-rouge">dx,dy,dz</code>:</p>
<div class="linked">
<script type="text/x-sage">
dx*x
</script>
</div>
<p>Keep in mind that <code class="highlighter-rouge">x</code> does not refer to the polynomial $x \in \mathbb{F}[x]$, so one should not expect <code class="highlighter-rouge">dx*x</code> to be <code class="highlighter-rouge">1</code>.</p>
<p>(For some reason <code class="highlighter-rouge">show</code> does not give the right output. Try <code class="highlighter-rouge">show(x)</code> or <code class="highlighter-rouge">show(x*dx)</code>, for example.)</p>
<h2 id="representations-of-mathfraksl_2">Representations of $\mathfrak{sl}_2$</h2>
<p>It turns out that the $1$-dim. Weyl algebra gives a representation of $\mathfrak{sl}_2(\mathbb{F})$.</p>
<p>The Lie algebra $\mathfrak{sl}_2(\mathbb{F})$ is generated by $E,F,H$ subject to the relations</p>
<script type="math/tex; mode=display">[H,E] = 2E, \qquad [H,F] = -2F, \qquad [E,F] = H.</script>
<p>Define the following elements of the $1$-dim. Weyl algebra:</p>
<script type="math/tex; mode=display">E = x \partial_x^2,\qquad F = -x,\qquad H = -2x\partial_x.</script>
<p>We can use Sage to quickly verify that these elements indeed satisfy the relations for $\mathfrak{sl}_2$ (using the commutator as the Lie bracket i.e. $[A,B] = AB - BA$):</p>
<div class="sage">
<script type="text/x-sage">
R.<x> = QQ[]
W = DifferentialWeylAlgebra(R)
W.inject_variables()
E = x*dx^2
F = -x
H = -2*x*dx
print H*E - E*H == 2*E
print H*F - F*H == -2*F
print E*F - F*E == H
</script>
</div>
<p>Working over $\mathbb{C}$, this action of $\mathfrak{sl}_2(\mathbb{C})$ makes $\mathbb{C}[x]$ a Verma module of highest weight $0$.</p>
<p>In fact, we can make $\mathbb{C}[x]$ a Verma module of highest weight $c$ for any $c \in \mathbb{C}$ by using:</p>
<script type="math/tex; mode=display">E = (x \partial_x - c)\partial_x,\qquad F = -x,\qquad H = -2x\partial_x + c.</script>
<p>We verify this again in Sage:</p>
<div class="sage">
<script type="text/x-sage">
Fc.<c> = CC[] # This allows c to be a complex indeterminate
R.<x> = Fc[]
W = DifferentialWeylAlgebra(R)
W.inject_variables()
E = (x*dx-c)*dx
F = -x
H = -2*x*dx + c
print H*E - E*H == 2*E
print H*F - F*H == -2*F
print E*F - F*E == H
</script>
</div>
<p>In subsequent posts, I’ll talk more about defining other non-commutative algebras in Sage and Singular.</p>
Wed, 17 Feb 2016 00:00:00 +0000
http://sheaves.github.io/Weyl-Algebra/
http://sheaves.github.io/Weyl-Algebra/Character Theory Basics<p>This post illustrates some of SageMath’s character theory functionality, as well as some basic results about characters of finite groups.</p>
<!--more-->
<h2 id="basic-definitions-and-properties">Basic Definitions and Properties</h2>
<p>Given a representation $(V,\rho)$ of a group $G$, its <a href="http://en.wikipedia.org/wiki/Character_theory" target="_blank"><strong>character</strong></a> is a map $ \chi: G \to \mathbb{C}$ that returns the <a href="http://en.wikipedia.org/wiki/Trace_(linear_algebra)" target="_blank">trace</a> of the matrices given by $\rho$:</p>
<script type="math/tex; mode=display">\chi(g) = \text{trace}(\rho(g)).</script>
<p>A character $\chi$ is <strong>irreducible</strong> if the corresponding $(V,\rho)$ is <a href="/Representation-Theory-Irreducibility-Indecomposability/" target="_blank">irreducible</a>.</p>
<p>Despite the simplicity of the definition, the (irreducible) characters of a group contain a surprising amount of information about the group. Some <a href="http://en.wikipedia.org/wiki/Character_theory#Applications" target="_blank">big theorems</a> in group theory depend heavily on character theory.</p>
<p>Let’s calculate the character of the permutation representation of $D_4$. For each $g \in G$, we’ll display the pairs:</p>
<script type="math/tex; mode=display">[\rho(g),\chi(g)]</script>
<p><em>(The Sage cells in this post are linked, so things may not work if you don’t execute them in order.)</em></p>
<div class="linked">
<script type="text/x-sage">
# Define group and its permutation representation
G = DihedralGroup(4)
def rho(g):
return g.matrix()
# Define a function that returns the character of a representation
def character(rho):
def chi(g):
return rho(g).trace()
return chi
# Compute the character
chi = character(rho)
for g in G:
show([rho(g),chi(g)])
</script>
</div>
<p>Many of the following properties of characters can be deduced from properties of the trace:</p>
<ol>
<li>The <strong>dimension</strong> of a character is the dimension of $V$ in $(V,\rho)$. Since $\rho(\text{Id})$ is always the identity matrix, the dimension of $\chi$ is $\chi(\text{Id})$.</li>
<li>Because the trace is <a href="http://en.wikipedia.org/wiki/Similarity_invariance" target="_blank">invariant under similarity transformations</a>, $\chi(hgh^{-1}) = \chi(g)$ for all $g,h \in G$. So characters are constant on conjugacy classes, and are thus <a href="http://en.wikipedia.org/wiki/Class_function" target="_blank"><strong>class functions</strong></a>.</li>
<li>Let $\chi_V$ denote the character of $(V,\rho)$. Recalling the definitions of <a href="/Representation-Theory-Sums-Products/" target="_blank">direct sums and tensor products</a>, we see that</li>
</ol>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align*}
\chi_{V_1 \oplus V_2} &= \chi_{V_1} + \chi_{V_2} \\
\chi_{V_1 \otimes V_2} &= \chi_{V_1} \times \chi_{V_2}
\end{align*} %]]></script>
<h2 id="the-character-table">The Character Table</h2>
<p>Let’s ignore the representation $\rho$ for now, and just look at the character $\chi$:</p>
<div class="linked">
<script type="text/x-sage">
print "chi g"
table([[chi(g),g] for g in G])
</script>
</div>
<p>This is succinct, but we can make it even shorter. From point 2 above, $\chi$ is constant on conjugacy classes of $G$, so we don’t lose any information by just looking at the values of $\chi$ on each conjugacy class:</p>
<div class="linked">
<script type="text/x-sage">
print "chi conjugacy class"
table([[chi(C[0]),C.list()] for C in G.conjugacy_classes()])
</script>
</div>
<p>Even shorter, let’s just display the values of $\chi$:</p>
<div class="linked">
<script type="text/x-sage">
[chi(g) for g in G.conjugacy_classes_representatives()]
</script>
</div>
<p>This single row of numbers represents the character of <em>one</em> representation of $G$. If we knew all the irreducible representations of $G$ and their corresponding characters, we could form a table with one row for each character. This is called the <a href="http://en.wikipedia.org/wiki/Character_table" target="_blank"><strong>character table</strong></a> of $G$.</p>
<p>Remember how we had to define our representations by hand, one by one? We don’t have to do that for characters, because SageMath has the <a href="http://www.sagemath.org/doc/constructions/rep_theory.html" target="_blank">character tables of small groups built-in</a>:</p>
<div class="linked">
<script type="text/x-sage">
char_table = G.character_table()
char_table
</script>
</div>
<p>This just goes to show how important the character of a group is. We can also access individual characters as a functions. Let’s say we want the last one:</p>
<div class="linked">
<script type="text/x-sage">
c = G.character(char_table[4])
print "c(g) for each g in G:"
print [c(g) for g in G]
print "c(g) for each conjugacy class:"
print [c(g) for g in G.conjugacy_classes_representatives()]
</script>
</div>
<p>Notice that the character we were playing with, $[4,2,0,0,0]$, is not in the table. This is because its representation $\rho$ is not irreducible. At the end of the post on <a href="/Representation-Theory-Decomposing-Representations/" target="_blank">decomposing representations</a>, we saw that $\rho$ splits into two $1$-dimensional irreducible representations and one $2$-dimensional one. It’s not hard to see that the character of $\rho$ is the sum of rows 1,4 and 5 in our character table:</p>
<div class="linked">
<script type="text/x-sage">
c1 = G.character(char_table[0])
c4 = G.character(char_table[3])
c5 = G.character(char_table[4])
c = c1 + c4 + c5
print "c1 + c4 + c5:"
print [c(g) for g in G.conjugacy_classes_representatives()]
print "chi:"
print [chi(g) for g in G.conjugacy_classes_representatives()]
</script>
</div>
<p>Just as we could decompose every representation of $G$ into a sum of irreducible representations, we can express any character as a sum of irreducible characters.</p>
<p>The next post discusses how to do this easily, by making use of the <a href="http://en.wikipedia.org/wiki/Schur_orthogonality_relations">Schur orthogonality relations</a>. These are really cool relations among the rows and columns of the character table. Apart from decomposing representations into irreducibles, we’ll also be able to prove that the character table is always square!</p>
<p><strong>Edit:</strong> The promised “next post” about these topics never happened. Maybe sometime in the far future, I might come back to these topics, but no promises for now!</p>
Fri, 20 Mar 2015 00:00:00 +0000
http://sheaves.github.io/Character-Theory/
http://sheaves.github.io/Character-Theory/Animated GIFs<p>I really should be posting about character theory, but I got distracted making some aesthetic changes to this blog (new icon and favicon!) and creating animations like this:</p>
<p><img src="/images/harmonograph_loop.gif" alt="harmonograph" /></p>
<!--more-->
<div class="no_out">
<script type="text/x-sage">
d,c,p,k = [0.01, 0.05, -0.15, 0.05]
x(t,u) = (sin(t*2*pi) + sin((1-c + u*c*2)*t*2*pi) + p*pi)*exp(-d*t)
y(t,u) = (sin((1-c+ 0.55*c*2)*t*2*pi + k*(1-u)*pi) + cos((1-c + 0.9*c*2)*t*2*pi) + p*pi)*exp(-d*t)
a = animate([parametric_plot((x(t,u),y(t,u)),(t,0,30),color = [u,1-u,0.52], axes= False, plot_points = 200) for u in [0.48+0.45*sin(v) for v in srange(0,2*pi,0.1)]])
a.gif(savefile='my_animation.gif', delay=20, iterations=0)
</script>
</div>
<p>I’m not putting this in a SageCell because this could take quite a while, especially if you increase the number of frames (by changing the parameters in <code class="highlighter-rouge">srange</code>), but feel free to try it out on your own copy of Sage. It saves an animated GIF that loops forever (<code class="highlighter-rouge">iterations = 0</code>) at the location specified by <code class="highlighter-rouge">savefile</code>.</p>
<p>For more information, checkout the <a href="http://www.sagemath.org/doc/reference/plotting/sage/plot/animate.html">Sage reference for animated plots</a>.</p>
Thu, 12 Mar 2015 00:00:00 +0000
http://sheaves.github.io/Animations/
http://sheaves.github.io/Animations/The Group Ring and the Regular Representation<p>In the <a href="/Representation-Theory-Decomposing-Representations/" target="_blank">previous post</a>, we saw how to decompose a given group representation into irreducibles. But we still don’t know much about the irreducible representations of a (finite) group. What do they look like? How many are there? Infinitely many?</p>
<p>In this post, we’ll construct the <a href="http://en.wikipedia.org/wiki/Group_ring" target="_blank">group ring</a> of a group. Treating this as a vector space, we get the <a href="http://en.wikipedia.org/wiki/Regular_representation" target="_blank">regular representation</a>, which turns out to contain <em>all</em> the irreducible representations of $G$!</p>
<!--more-->
<h2 id="the-group-ring-fg">The group ring $FG$</h2>
<p>Given a (finite) group $G$ and a field $F$, we can treat each element of $G$ as a basis element of a vector space over $F$. The resulting vector space generated by $g \in G$ is</p>
<script type="math/tex; mode=display">FG := \left\{\sum_{g\in G} \alpha_g g: \alpha_g \in F \right\}.</script>
<p>Let’s do this is Sage with the group $G = D_4$ and the field $F = \mathbb{Q}$:</p>
<p><em>(The Sage cells in this post are linked, so things may not work if you don’t execute them in order.)</em></p>
<div class="linked">
<script type="text/x-sage">
G = DihedralGroup(4)
F = QQ
FG = GroupAlgebra(G,F)
v = FG.an_element()
v
</script>
</div>
<p>We can view $v \in FG$ as vector in $F^n$, where $n$ is the size of $G$ :</p>
<div class="linked">
<script type="text/x-sage">
v.to_vector()
</script>
</div>
<p>Here, we’re treating each $g \in G$ as a basis element of $FG$</p>
<div class="linked">
<script type="text/x-sage">
for g in G:
g = FG(g)
print "{} = {}".format(g.to_vector(),g)
</script>
</div>
<p>Vectors in $FG$ are added component-wise:</p>
<script type="math/tex; mode=display">\left(\sum_{g \in G} \alpha_g g\right) + \left(\sum_{g\in G} \beta_g g\right) = \sum_{g \in G} (\alpha_g+\beta_g) g.</script>
<div class="linked">
<script type="text/x-sage">
w = FG.random_element()
print 'w = {}'.format(w.to_vector())
print 'v + w = {}'.format((v + w).to_vector())
</script>
</div>
<h2 id="multiplication-as-a-linear-transformation">Multiplication as a linear transformation</h2>
<p>In fact $FG$ is also a <em>ring</em> (called the <a href="http://en.wikipedia.org/wiki/Group_ring" target="_blank"><strong>group ring</strong></a>), because we can multiply vectors using the multiplication rule of the group $G$:</p>
<script type="math/tex; mode=display">\left(\sum_{h \in G} \alpha_h h\right) \left(\sum_{g\in G} \beta_g g\right) = \sum_{h,g \in G} (\alpha_h \beta_g) hg.</script>
<div class="linked">
<script type="text/x-sage">
print 'v * w = {}'.format((v * w).to_vector())
</script>
</div>
<p>That wasn’t very illuminating. However, treating multiplication by $v \in FG$ as a function</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align*}
T_v: FG &\to FG \\
w &\mapsto vw,
\end{align*} %]]></script>
<p>one can check that each $T_v$ is a linear transformation! We can thus represent $T_v$ as a matrix whose columns are $T_v(g), g \in G$:</p>
<div class="linked">
<script type="text/x-sage">
for g in G:
g = FG(g)
print "v*{} = {}".format(g.to_vector(),(v*g).to_vector())
T = matrix([(v*FG(g)).to_vector() for g in G]).transpose()
show(T)
</script>
</div>
<h2 id="the-regular-representation">The regular representation</h2>
<p>We’re especially interested in $T_g, g \in G$. These are invertible, with inverse $T_{g^{-1}}$, and their matrices are all permutation matrices, because multiplying by $g \in G$ simply permutes elements of $G$:</p>
<div class="linked">
<script type="text/x-sage">
for v in G:
v = FG(v)
show(matrix([(v*FG(g)).to_vector() for g in G]).transpose())
</script>
</div>
<p>Define a function $\rho_{FG}$ which assigns to each $g\in G$ the corresponding $T_g$:</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align*}
\rho_{FG}: G &\to \mathrm{GL}(FG) \\
g &\mapsto T_g
\end{align*} %]]></script>
<p>Then $(FG,\rho_{FG})$ is the <a href="http://en.wikipedia.org/wiki/Regular_representation" target="_blank"><strong>regular representation</strong></a> of $G$ over $F$.</p>
<p>The regular representation of any non-trivial group is not irreducible. In fact, it is a direct sum of <em>all</em> the irreducible representations of $G$! What’s more, if $(V,\rho)$ is an irreducible representation of $G$ and $\dim V = k$, then $V$ occurs $k$ times in the direct-sum decomposition of $FG$!</p>
<p>Let’s apply the decomposition algorithm in the <a href="/Representation-Theory-Decomposing-Representations/" target="_blank">previous post</a> to $(FG,\rho_{FG})$ (this might take a while to run):</p>
<div class="sage">
<script type="text/x-sage">
# Define group and its regular representation
G = DihedralGroup(4)
FG = GroupAlgebra(G,QQbar)
def rho(h):
h = FG(h)
return matrix([(h*FG(g)).to_vector() for g in G]).transpose()
# Decomposition algorithms
import numpy as np
def is_irreducible(rho,G, n= None):
"""
If rho is irreducible, returns (True, I) where I is the n-by-n identity matrix, n = dimension of rho.
Otherwise, returns (False, H) where H is a non-scalar matrix that commutes with rho(G).
"""
# Compute the dimension of the representation
if n is None:
n = rho(G.identity()).dimensions()[0]
# Run through all r,s = 1,2,...,n
for r in range(n):
for s in range(n):
# Define H_rs
H_rs = matrix.zero(QQbar,n)
if r == s:
H_rs[r,s] = 1
elif r > s:
H_rs[r,s] = 1
H_rs[s,r] = 1
else: # r < s
H_rs[r,s] = I
H_rs[s,r] = -I
# Compute H
H = sum([rho(g).conjugate_transpose()*H_rs*rho(g) for g in G])/G.cardinality()
# Check if H is scalar
if H[0,0]*matrix.identity(n) != H:
return False,H
# If all H are scalar
return True, matrix.identity(n)
def decompose(rho,G,H):
"""
Uses the eigenspaces of H to decompose G into subrepresentations.
Returns a change of basis matrix P and the indices of the block-decomposition of rho in this basis.
"""
# Compute J,P such that H = PJP^(-1)
J,P = H.jordan_form(QQbar,transformation=True)
# Compute block subdivisions
edges = []
for g in G:
edges += (P.conjugate_transpose()*rho(g)*P).nonzero_positions()
graph = Graph(edges, multiedges = False, loops = False)
subrep_indices = sorted(graph.connected_components(), key=lambda x: x[0])
return P,subrep_indices
def irr_decompose(rho,G,index = None):
"""
Decomposes rho into irreducible representations of G.
Returns a change of basis matrix P and the indices of the block-decomposition of rho in this basis.
"""
n = rho(G.identity()).dimensions()[0]
if index is None:
index = range(n)
# Test for irreducibility
is_irred, H = is_irreducible(rho,G,n)
if is_irred:
subrep_indices = list(np.array(index)[range(n)])
return H, [subrep_indices]
else:
P, subrep_indices = decompose(rho,G,H)
print [list(np.array(index)[subrep_index]) for subrep_index in subrep_indices]
new_subrep_indices = []
new_P_list = []
for subrep_index in subrep_indices:
def subrep(g):
return (P.inverse()*rho(g)*P)[subrep_index,subrep_index]
new_P, new_indices = irr_decompose(subrep,G, list(np.array(index)[subrep_index]))
new_subrep_indices += new_indices
new_P_list += [new_P]
return P*block_diagonal_matrix(new_P_list), new_subrep_indices
def show_irreps(rho,G,P,irrep_indices):
subdivisions = [i for subrep_index in irrep_indices for i in subrep_index][1:]
for subrep in irrep_indices:
for i in subrep[1:]:
subdivisions.remove(i)
# Display rho in block-diagonal form
for g in G:
M = P.inverse()*rho(g)*P
M == M*1 # Just for aesthetics
M.subdivide(subdivisions, subdivisions)
show(M)
# Execute!
P,irrep_indices = irr_decompose(rho,G)
print irrep_indices
show_irreps(rho,G,P,irrep_indices)
</script>
</div>
<p>So the regular representation of $D_4$ decomposes into four (distinct) $1$-dim representations and two (isomorphic) $2$-dim ones.</p>
<h2 id="building-character">Building character</h2>
<p>We’ve spent a lot of time working directly with representations of a group. While more concrete, the actual matrix representations themselves tend to be a little clumsy, especially when the groups in question get large.</p>
<p>In the next few posts, I’ll switch gears to <a href="http://en.wikipedia.org/wiki/Character_theory" target="_blank">character theory</a>, which is a simpler but more powerful way of working with group representations.</p>
Sun, 15 Feb 2015 00:00:00 +0000
http://sheaves.github.io/Group-Ring-Regular-Representation/
http://sheaves.github.io/Group-Ring-Regular-Representation/Decomposing Representations<p>In this post, we’ll implement an algorithm for decomposing representations that <a href="http://www.ams.org/journals/mcom/1970-24-111/S0025-5718-1970-0280611-6/S0025-5718-1970-0280611-6.pdf" target="_blank">Dixon published in 1970</a>.</p>
<!--more-->
<p>As a motivating example, I’ll use the permutation matrix representation of $D_4$ that we saw in an <a href="/Representation-Theory-Intro/" target="_blank">earlier post</a>. To make the code more generally applicable, let’s call the group $G$ and the representation $\rho$:</p>
<p><em>(The Sage cells in this post are linked, so things may not work if you don’t execute them in order.)</em></p>
<div class="linked">
<script type="text/x-sage">
G = DihedralGroup(4)
# Defining the permutation representation
def rho(g):
return g.matrix()
g = G.an_element()
show(rho(g))
</script>
</div>
<p>We’ll see that this is decomposable, and find out what its irreducible components are.</p>
<h3 id="unitary-representations">Unitary representations</h3>
<p>A short remark before we begin: The algorithm assumes that $\rho$ is a <a href="http://en.wikipedia.org/wiki/Unitary_representation" target="_blank">unitary representation</a></p>
<p>i.e. for all $g \in G$,</p>
<script type="math/tex; mode=display">\rho(g)^* \rho(g) = \rho(g) \rho(g)^* = I,</script>
<p>where $A*$ is the <a href="http://en.wikipedia.org/wiki/Conjugate_transpose" target="_blank">conjugate transpose</a> of a matrix $A$.
For $G$ a finite group, all representations can be made unitary under an appropriate change of basis, so we need not be too concerned about this. In any case, permutation representations are always unitary, so we can proceed with our example.</p>
<h2 id="finding-non-scalar-commuting-matrices">Finding non-scalar, commuting matrices</h2>
<p>At the end of the <a href="/Representation-Theory-Irreducibility-Indecomposability/" target="_blank">previous post</a> we saw that in order to decompose a representation $(V,\rho)$, it is enough to find a non-scalar matrix $T$ that commutes with $\rho(g)$ for every $g \in G$. This first step finds a <a href="http://en.wikipedia.org/wiki/Hermitian_matrix" target="_blank">Hermitian</a> non-scalar $H$ that commutes with $\rho(G)$ (if there is one to be found).</p>
<p>Let $E_{rs}$ denote the $n \times n$ matrix with a $1$ in the $(r,s)$th entry and zeros everywhere else. Here $n$ is the dimension of $V$ in the representation $(V,\rho)$. Define</p>
<script type="math/tex; mode=display">% <![CDATA[
H_{rs} = \begin{cases}
E_{rr} &\text{if } r = s \\
E_{rs} + E_{sr} &\text{if } r > s \\
i(E_{rs} - E_{sr}) &\text{if } r < s,
\end{cases} %]]></script>
<p>then the set of matrices $H_{rs}$ forms a Hermitian basis for the $n \times n$ matrices over $\mathbb{C}$.</p>
<p>Now for each $r,s$, compute the sum</p>
<script type="math/tex; mode=display">H = \frac{1}{|G|} \sum_{g \in G} \,\, \rho(g)^* \, H_{rs} \, \rho(g).</script>
<p>Observe that $H$ has the following properties:</p>
<ul>
<li>it is hermitian</li>
<li>it commutes with $\rho(g)$ for all $g \in G$</li>
</ul>
<p>If $\rho$ is irreducible, then $H$ is a scalar matrix for all $r,s$. Otherwise, it turns out that there <strong>will</strong> be some $r,s$ such that $H$ is non-scalar (this is due to the fact that the $H_{rs}$ matrices form a basis of the $n \times n$ matrices$).</p>
<p>Let’s test this algorithm on our permutation representation of $D_4$:</p>
<div class="linked">
<script type="text/x-sage">
def is_irreducible(rho,G, n= None):
"""
If rho is irreducible, returns (True, I) where I is the n-by-n identity matrix, n = dimension of rho.
Otherwise, returns (False, H) where H is a non-scalar matrix that commutes with rho(G).
"""
# Compute the dimension of the representation
if n is None:
n = rho(G.identity()).dimensions()[0]
# Run through all r,s = 1,2,...,n
for r in range(n):
for s in range(n):
# Define H_rs
H_rs = matrix.zero(QQbar,n)
if r == s:
H_rs[r,s] = 1
elif r > s:
H_rs[r,s] = 1
H_rs[s,r] = 1
else: # r < s
H_rs[r,s] = I
H_rs[s,r] = -I
# Compute H
H = sum([rho(g).conjugate_transpose()*H_rs*rho(g) for g in G])/G.cardinality()
# Check if H is scalar
if H[0,0]*matrix.identity(n) != H:
return False,H
# If all H are scalar
return True, matrix.identity(n)
is_irred,H = is_irreducible(rho,G)
show(is_irred)
show(H)
</script>
</div>
<p>We get a non-scalar $H$! So the permutation representation of $D_4$ is reducible!</p>
<h2 id="using-h-to-decompose-rho">Using $H$ to decompose $\rho$</h2>
<p>Our next step is to use the eigenspaces of $H$ to decompose $\rho$. At the end of the <a href="/Representation-Theory-Irreducibility-Indecomposability/" target="_blank">previous post</a>, we saw that $\rho(g)$ preserves the eigenspaces of $H$, so we need only find the eigenspaces of $H$ to decompose $\rho$.</p>
<p>Since $H$ is hermitian, it is <a href="http://en.wikipedia.org/wiki/Diagonalizable_matrix" target="_blank">diagonalizable</a>, so its eigenvectors form a basis of $V$. In fact, the eigenbasis can be chosen to be orthonormal.</p>
<p>We can find this basis by computing the <a href="http://en.wikipedia.org/wiki/Jordan_normal_form" target="_blank">Jordan decomposition</a> of $H$, and then orthonormalizing it:</p>
<div class="linked">
<script type="text/x-sage">
# Compute J,P such that H = PJP^(-1)
J,P = H.jordan_form(QQbar,transformation=True)
P = P.transpose().gram_schmidt(orthonormal=True)[0].transpose()
show(P)
</script>
</div>
<p>It’s important that we orthonormalize $P$ so that $P$ becomes unitary. This will ensure that the subrepresentations remain unitary.</p>
<p>Observe that $P^{-1} \rho(g) P$ has the same block-diagonal form for each $g \in G$:</p>
<div class="linked">
<script type="text/x-sage">
# Compute block subdivisions (just for aesthetics)
edges = []
for g in G:
edges += (P.conjugate_transpose()*rho(g)*P).nonzero_positions()
graph = Graph(edges, multiedges = False, loops = False)
subrep_indices = graph.connected_components()
subdivisions = graph.vertices()[1:]
for l in subrep_indices:
for i in l[1:]:
subdivisions.remove(i)
# Display rho in block-diagonal form
for g in G:
M = P.inverse()*rho(g)*P
M.subdivide(subdivisions, subdivisions)
show(M)
</script>
</div>
<p>We have thus decomposed $\rho$ into two 1-dimensional representations and one 2-dimensional one!</p>
<h2 id="decomposing-into-irreducibles">Decomposing into irreducibles</h2>
<p>Finally, to get a decomposition into irreducibles, we can apply the algorithm recursively on each of the subrepresentations to see if they further decompose.</p>
<p>Here’s a stand-alone script that decomposes a representation into its irreducible components:</p>
<div class="sage">
<script type="text/x-sage">
# Define group and representation here
G = DihedralGroup(4)
def rho(g):
return g.matrix()
# Algorithms
import numpy as np
def is_irreducible(rho,G, n= None):
"""
If rho is irreducible, returns (True, I) where I is the n-by-n identity matrix, n = dimension of rho.
Otherwise, returns (False, H) where H is a non-scalar matrix that commutes with rho(G).
"""
# Compute the dimension of the representation
if n is None:
n = rho(G.identity()).dimensions()[0]
# Run through all r,s = 1,2,...,n
for r in range(n):
for s in range(n):
# Define H_rs
H_rs = matrix.zero(QQbar,n)
if r == s:
H_rs[r,s] = 1
elif r > s:
H_rs[r,s] = 1
H_rs[s,r] = 1
else: # r < s
H_rs[r,s] = I
H_rs[s,r] = -I
# Compute H
H = sum([rho(g).conjugate_transpose()*H_rs*rho(g) for g in G])/G.cardinality()
# Check if H is scalar
if H[0,0]*matrix.identity(n) != H:
return False,H
# If all H are scalar
return True, matrix.identity(n)
def decompose(rho,G,H):
"""
Uses the eigenspaces of H to decompose G into subrepresentations.
Returns a change of basis matrix P and the indices of the block-decomposition of rho in this basis.
"""
# Compute J,P such that H = PJP^(-1)
J,P = H.jordan_form(QQbar,transformation=True)
P = P.transpose().gram_schmidt(orthonormal=True)[0].transpose()
# Compute block subdivisions
edges = []
for g in G:
edges += (P.conjugate_transpose()*rho(g)*P).nonzero_positions()
graph = Graph(edges, multiedges = False, loops = False)
subrep_indices = sorted(graph.connected_components(), key=lambda x: x[0])
return P,subrep_indices
def irr_decompose(rho,G,index = None):
"""
Decomposes rho into irreducible representations of G.
Returns a change of basis matrix P and the indices of the block-decomposition of rho in this basis.
"""
n = rho(G.identity()).dimensions()[0]
if index is None:
index = range(n)
# Test for irreducibility
is_irred, H = is_irreducible(rho,G,n)
if is_irred:
subrep_indices = list(np.array(index)[range(n)])
return H, [subrep_indices]
else:
P, subrep_indices = decompose(rho,G,H)
print [list(np.array(index)[subrep_index]) for subrep_index in subrep_indices]
new_subrep_indices = []
new_P_list = []
for subrep_index in subrep_indices:
def subrep(g):
return (P.inverse()*rho(g)*P)[subrep_index,subrep_index]
new_P, new_indices = irr_decompose(subrep,G, list(np.array(index)[subrep_index]))
new_subrep_indices += new_indices
new_P_list += [new_P]
return P*block_diagonal_matrix(new_P_list), new_subrep_indices
def show_irreps(rho,G,P,irrep_indices):
subdivisions = [i for subrep_index in irrep_indices for i in subrep_index][1:]
for subrep in irrep_indices:
for i in subrep[1:]:
subdivisions.remove(i)
# Display rho in block-diagonal form
for g in G:
M = P.inverse()*rho(g)*P
M.subdivide(subdivisions, subdivisions)
show(M)
# Execute!
P,irrep_indices = irr_decompose(rho,G)
show_irreps(rho,G,P,irrep_indices)
</script>
</div>
<h2 id="getting-all-irreducible-representations">Getting all irreducible representations</h2>
<p>Now we know how to test for irreducibility and decompose reducible representations. But we still don’t know how many irreducible representations a group has.</p>
<p>It turns out that finite groups have finitely many irreducible representations! In the <a href="/Group-Ring-Regular-Representation/">next post</a>, we’ll construct a representation for any finite group $G$ that contains <em>all</em> the irreducible representations of $G$.</p>
Mon, 02 Feb 2015 00:00:00 +0000
http://sheaves.github.io/Representation-Theory-Decomposing-Representations/
http://sheaves.github.io/Representation-Theory-Decomposing-Representations/Irreducible and Indecomposable Representations<p>Following up from the questions I asked at the end of the <a href="/Representation-Theory-Sums-Products/" target="_blank">previous post</a>, I’ll define (ir)reducible and (in)decomposable representations, and discuss how we might detect them. Unlike previous posts, this post will have just text, and no code. This discussion will form the basis of the algorithm in the next post.</p>
<!--more-->
<h2 id="decomposability">Decomposability</h2>
<p>In the previous post, I showed how to form the direct sum $(V_1 \oplus V2,\rho)$ of two representations $(V_1,\rho_1)$ and $(V_2,\rho_2)$. The matrices given by $\rho$ looked like this:</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{pmatrix}
\rho_1(g) & 0 \\
0 & \rho_2(g)
\end{pmatrix}. %]]></script>
<p>A representation $(V,\rho)$ is <strong>decomposable</strong> if there is a basis of $V$ such that each $\rho(g)$ takes this block diagonal form. If $(V,\rho)$ does not admit such a decomposition, it is <strong>indecomposable</strong>.</p>
<p>Equivalently, $(V,\rho)$ is decomposable if there is an invertible matrix $P$ such that for all $g\in G$,</p>
<script type="math/tex; mode=display">% <![CDATA[
P^{-1}\rho(g)P =
\begin{pmatrix}
\rho_1(g) & 0 \\
0 & \rho_2(g)
\end{pmatrix}, %]]></script>
<p>and indecomposable otherwise. Here, $P$ is a change of basis matrix and conjugating by $P$ changes from the standard basis to the basis given by the columns of $P$.</p>
<h2 id="reducibility">Reducibility</h2>
<p>Notice that if $\rho(g)$ were block diagonal, then writing $v \in V$ as ${v_1 \choose v_2}$, where $v_1$ and $v_2$ are vectors whose dimensions agree with the blocks of $\rho(g)$, we see that</p>
<script type="math/tex; mode=display">% <![CDATA[
\rho(g)v =
\begin{pmatrix}
\rho_1(g) & 0 \\
0 & \rho_2(g)
\end{pmatrix}{v_1 \choose v_2}
= {\rho_1(g) v_1 \choose \rho_2(g) v_2}. %]]></script>
<p>Let $V_1$ be the subspace of $V$ corresponding to vectors of the form ${v_1 \choose 0}$, and $V_2$ be the subspace of vectors of the form ${0 \choose v_2}$. Then for all $g \in G, v \in V_i$,</p>
<script type="math/tex; mode=display">\rho(g) v = \rho_i(g) v_i \in V_i.</script>
<p>Now suppose instead that for all $g \in G, \rho(g)$ has the block upper-triangular form</p>
<script type="math/tex; mode=display">% <![CDATA[
\rho(g) =
\begin{pmatrix}
\rho_1(g) & * \\
0 & \rho_2(g)
\end{pmatrix}, %]]></script>
<p>where $ * $ represents an arbitrary matrix (possibly different for each $g \in G$). If $*$ is not the zero matrix for some $g$, then we will still have $\rho(g) v \in V_1 \,\, \forall v \in V_1$, but we no longer have $\rho(g) v \in V_2 \,\, \forall v \in V_2$. In this case, we say that $V_1$ is a subrepresentation of $V$ whereas $V_2$ is not.</p>
<p>Formally, if we have a subspace $W \subset V$ such that for all $g \in G, w \in W$,</p>
<script type="math/tex; mode=display">\rho(g)w \in W,</script>
<p>then $W$ is a $G$-<strong>invariant</strong> subspace of $V$, and $(W,\rho)$ is a <strong>subrepresentation</strong> of $(V,\rho)$.</p>
<p>Any representation $(V,\rho)$ has at least two subrepresentations: $(0,\rho)$ and $(V,\rho)$. If there are no other subrepresentations, then $(V,\rho)$ is <a href="http://en.wikipedia.org/wiki/Irreducible_representation" target="_blank"><strong>irreducible</strong></a>. Otherwise, it is <strong>reducible</strong>.</p>
<p>Equivalently, $(V,\rho)$ is reducible if there is an invertible matrix $P$ such that for all $g \in G$,</p>
<script type="math/tex; mode=display">% <![CDATA[
P^{-1}\rho(g)P =
\begin{pmatrix}
\rho_1(g) & * \\
0 & \rho_2(g)
\end{pmatrix}, %]]></script>
<p>and irreducible otherwise.</p>
<h2 id="maschkes-theorem">Maschke’s Theorem</h2>
<p>Note that a decomposable representation is also reducible, but the converse is not generally true.
(Equivalently: an irreducible representation is also indecomposable, but the converse is not generally true.)
<a href="http://en.wikipedia.org/wiki/Maschke%27s_theorem" target="_blank">Maschke’s Theorem</a> tells us that the converse is true over fields of characteristic zero! In other words:</p>
<blockquote>
<p>Suppose $V$ is a vector space over a field of characteristic zero, say $\mathbb{C}$, and $(V,\rho)$ has a subrepresentation $(W_1,\rho)$. Then there is a subspace $W_2$ (called the direct complement of $W_1$) such that $V = W_1 \oplus W_2$.</p>
</blockquote>
<p>Since we will be working over $\mathbb{C}$, we can thus treat (in)decomposability as equivalent to (ir)reducibility. To understand representations of $G$, we need only understand its irreducible representations, because any other representation can be decomposed into a direct sum of irreducibles.</p>
<h2 id="schurs-lemma">Schur’s Lemma</h2>
<p>How may we detect (ir)reducible representations? We’ll make use of the following linear algebraic properties:</p>
<p>Given an eigenvalue $\lambda$ of a matrix $A \in \mathbb{C}^{n \times n}$, its $\lambda$-eigenspace is</p>
<script type="math/tex; mode=display">E_\lambda = \{v \in \mathbb{C}^n: Av = \lambda v \}.</script>
<p>Clearly, each eigenspace is an invariant subspace of $A$. If we have another matrix $B \in \mathbb{C}^{n \times n}$ such that $AB = BA$, then $B$ preserves the eigenspaces of $A$ as well. To see this, take $v \in E_\lambda$, then</p>
<script type="math/tex; mode=display">A(Bv) = B(Av) = B(\lambda v) = \lambda (Bv),</script>
<p>so $E_\lambda$ is also an invariant subspace of $B$!</p>
<p>Now suppose we have a representation $(V,\rho)$ and a linear map $T:V \to V$ such that for all $g \in G, v \in V$,</p>
<script type="math/tex; mode=display">\rho(g)(Tv) = T \rho(g)(v).</script>
<p>Treating $T$ as a matrix, this is equivalent to saying that $\rho(g)T = T\rho(g)$ for all $g \in G$. In that case, the eigenspaces of $T$ are $G$-invariant subspaces, and will yield decompositions of $(V,\rho)$ if they are not the whole of $V$. But if $E_\lambda = V$, then $Tv = \lambda v$ for all $v \in V$, so in fact $T = \lambda I$, where $I$ is the identity matrix. We have thus shown a variant of <a href="http://en.wikipedia.org/wiki/Schur%27s_lemma" target="_blank">Schur’s lemma</a>:</p>
<blockquote>
<p>If $(V,\rho)$ is irreducible, and $\rho(g) T = T \rho(g)$ for all $g \in G$, then $T =\lambda I$ for some $\lambda$.</p>
</blockquote>
<p>We already know that scalar matrices (i.e. matrices of the form $\lambda I$) commute with all matrices. If $(V,\rho)$ is irreducible, this result says that there are no other matrices that commute with all $\rho(g)$. The converse is also true:</p>
<blockquote>
<p>If $(V,\rho)$ is a reducible, then there is some $T \neq \lambda I$ such that $\rho(g) T = T\rho(g)$ for all $g \in G$.</p>
</blockquote>
<p>I won’t prove this, but note that if $V$ has a decomposition $W_1 \oplus W_2$, then the projection onto either $W_i$ will have the desired properties. If we have such a $T$, then its eigenspaces will give a decomposition of $(V,\rho)$. This will be the subject of the <a href="/Representation-Theory-Decomposing-Representations/">next post</a>.</p>
Mon, 26 Jan 2015 00:00:00 +0000
http://sheaves.github.io/Representation-Theory-Irreducibility-Indecomposability/
http://sheaves.github.io/Representation-Theory-Irreducibility-Indecomposability/Direct Sums and Tensor Products<p>In this short post, we will show two ways of combining existing representations to obtain new representations.</p>
<!--more-->
<h2 id="recall">Recall</h2>
<p>In the <a href="/Representation-Theory-Intro/" target="_blank">previous post</a>, we saw two representations of $D_4$: the permutation representation, and the representation given in this <a href="http://en.wikipedia.org/wiki/Dihedral_group#Matrix_representation" target="_blank">Wikipedia example</a>. Let’s first define these in Sage:</p>
<p><em>(The Sage cells in this post are linked, so things may not work if you don’t execute them in order.)</em></p>
<div class="linked">
<script type="text/x-sage">
D4 = DihedralGroup(4)
# Defining the permutation representation
def perm(g):
return g.matrix()
# Defining the representation in the Wikipedia example
r,s = D4.gens()
D4_dict = {}
for i in range(4):
for j in range(2):
D4_dict[r^i * s^j] = (i,j)
def wiki_rep(g):
i,j = D4_dict[g]
return matrix([[0,-1],[1,0]])^i * matrix([[1,0],[0,-1]])^j
# See what they look like
g = D4.an_element()
show(perm(g))
show(wiki_rep(g))
</script>
</div>
<h2 id="direct-sums">Direct Sums</h2>
<p>If $(V_1,\rho_1), (V_2,\rho_2)$ are representations of $G$, the <a href="http://groupprops.subwiki.org/wiki/Direct_sum_of_linear_representations" target="_blank">direct sum</a> of these representations is $(V_1 \oplus V_2, \rho)$, where $\rho$ sends $g \in G$ to the <a href="http://en.wikipedia.org/wiki/Block_matrix#Block_diagonal_matrices" target="_blank">block diagonal matrix</a></p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{pmatrix}
\rho_1(g) & 0 \\
0 & \rho_2(g)
\end{pmatrix} %]]></script>
<p>Here $\rho_1(g), \rho_2(g)$ and the “zeros” are all <em>matrices</em>.</p>
<p>It’s best to illustrate with an example. We can define a function <code class="highlighter-rouge">direct_sum</code> in Sage that takes two representations and returns their direct sum.</p>
<div class="linked">
<script type="text/x-sage">
def direct_sum(rep1,rep2):
def new_rep(g):
return block_diagonal_matrix(rep1(g),rep2(g))
return new_rep
# Form the direct sum of perm and wiki_rep
sum_rep = direct_sum(perm,wiki_rep)
# See what it looks like
show(sum_rep(g))
</script>
</div>
<h2 id="tensor-products">Tensor products</h2>
<p>We can also form the <a href="http://groupprops.subwiki.org/wiki/Tensor_product_of_linear_representations" target="_blank">tensor product</a> $(V_1 \otimes V_2,\rho)$, where $\rho$ sends $g \in G$ to the <a href="http://en.wikipedia.org/wiki/Kronecker_product" target="_blank">Kronecker product</a> of the matrices $\rho_1(g)$ and $\rho_2(g)$.</p>
<p>We define a function <code class="highlighter-rouge">tensor_prod</code> that takes two representations and returns their tensor product.</p>
<div class="linked">
<script type="text/x-sage">
def tensor_prod(rep1,rep2):
def new_rep(g):
return rep1(g).tensor_product(rep2(g))
return new_rep
# Form the tensor product of perm and wiki_rep
prod_rep = tensor_prod(perm,wiki_rep)
# See what it looks like
show(prod_rep(g))
</script>
</div>
<p>Observe that</p>
<ul>
<li>$\dim V_1 \oplus V_2 = \dim V_1 + \dim V_2$,</li>
<li>$\dim V_1 \otimes V_2 = \dim V_1 \times \dim V_2$,</li>
</ul>
<p>which motivates the terms direct <em>sum</em> and tensor <em>product</em>.</p>
<p>We can keep taking direct sums and tensor products of existing representations to obtain new ones:</p>
<div class="linked">
<script type="text/x-sage">
new_rep = direct_sum(perm,tensor_prod(perm,wiki_rep))
show(new_rep(g))
</script>
</div>
<h2 id="decomposing-representations">Decomposing representations</h2>
<p>Now we know how to build new representations out of old ones. One might be interested in the inverse questions:</p>
<ol>
<li>Is a given representation a direct sum of smaller representations?</li>
<li>Is a given representation a tensor product of smaller representations?</li>
</ol>
<p>It turns out that Q1 is a much more interesting question to ask than Q2.</p>
<p>A (very poor) analogy of this situation is the problem of “building up” natural numbers. We have two ways of building up new integers from old: we can either add numbers, or multiply them. Given a number $n$, it’s easy (and not very interesting) to find smaller numbers that add up to $n$. However, <a href="http://en.wikipedia.org/wiki/Integer_factorization" target="_blank">finding numbers whose product is $n$</a> is <em>much much</em> harder (especially for large $n$) and much more <a href="http://en.wikipedia.org/wiki/Algebraic_number_theory" target="_blank">rewarding</a>. Prime numbers also play a special role in the latter case: every positive integer has a unique factorization into primes.</p>
<p>The analogy is a poor one (not least because the roles of “sum” and “product” are switched!). However, it motivates the question</p>
<ul>
<li>What are the analogues of “primes” for representations?</li>
</ul>
<p>We’ll try to answer this last question and Q1 in the <a href="/Representation-Theory-Irreducibility-Indecomposability/">next few posts</a>, and see what it means for us when working with representations in Sage.</p>
Sat, 24 Jan 2015 00:00:00 +0000
http://sheaves.github.io/Representation-Theory-Sums-Products/
http://sheaves.github.io/Representation-Theory-Sums-Products/Representation Theory in Sage - Basics<p>This is the first of a series of posts about working with group representations in Sage.</p>
<!--more-->
<h2 id="basic-definitions">Basic Definitions</h2>
<p>Given a group $G$, a linear representation of $G$ is a group homomorphism $\rho: G \to \mathrm{GL}(V)$.</p>
<p>For our purposes, we will assume that $G$ is a finite group and $V$ is an $n$-dimensional vector space over $\mathbb{C}$. Then $\mathrm{GL}(V)$ is isomorphic to the invertible $n \times n$ matrices over $\mathbb{C}$, which we will denote $\mathrm{GL}_n \mathbb{C}$.</p>
<p>So a representation is just a function that takes group elements and returns invertible matrices, such that</p>
<script type="math/tex; mode=display">\rho(g h) = \rho(g) \rho(h) \,\, \forall g,h \in G,</script>
<p>where we have matrix multiplication on the right-hand side.</p>
<p>Various authors refer to the map $\rho$, the vector space $V$, or the tuple $(V,\rho)$ as a representation; this shouldn’t cause any confusion, as it’s usually clear from context whether we are referring to a map or a vector space. When I need to be extra precise, I’ll use $(V,\rho)$.</p>
<h2 id="some-simple-examples">Some simple examples</h2>
<h3 id="trivial-representation">Trivial representation</h3>
<p>The simplest representation is just the trivial representation that sends every element of $G$ to the identity matrix (of some fixed dimension $n$). Let’s do this for the symmetric group $S_3$:</p>
<p><em>(The Sage cells in this post are linked, so things may not work if you don’t execute them in order.)</em></p>
<div class="linked">
<script type="text/x-sage">
G = SymmetricGroup(3)
n = 3
def triv(g):
return matrix.identity(n)
g = G.an_element()
show(triv(g))
</script>
</div>
<p>We can verify that this is indeed a group homomorphism (warning: There are 6 elements in $S_3$, which means we have to check $6^2 = 36$ pairs!):</p>
<div class="linked">
<script type="text/x-sage">
for g in G:
for h in G:
print triv(g*h) == triv(g)*triv(h)
</script>
</div>
<h3 id="permutation-representation">Permutation representation</h3>
<p>This isn’t very interesting. However, we also know that $S_3$ is the group of permutations of the 3-element set {$1,2,3$}. We can associate to each permutation a <a href="http://mathworld.wolfram.com/PermutationMatrix.html" target="_blank">permutation matrix</a>. Sage already has this implemented for us, via the method <code class="highlighter-rouge">matrix()</code> for a group element <code class="highlighter-rouge">g</code>:</p>
<div class="linked">
<script type="text/x-sage">
def perm(g):
return g.matrix()
g = G.an_element()
show(perm(g))
</script>
</div>
<p><em>Qn: From the permutation matrix, can you tell which permutation $g$ corresponds to?</em></p>
<p>We can again verify that this is indeed a representation. Let’s not print out all the output; instead, we’ll only print something if it is <em>not</em> a representation. If nothing pops up, then we’re fine:</p>
<div class="linked">
<script type="text/x-sage">
for g in G:
for h in G:
if triv(g*h) != triv(g)*triv(h):
print "This is not a representation!"
</script>
</div>
<h3 id="defining-a-representation-from-generators">Defining a representation from generators</h3>
<p>We could define permutation representations so easily only because Sage has them built in. But what if we had some other representation that we’d like to work with in Sage? Take the <a href="http://en.wikipedia.org/wiki/Dihedral_group" target="_blank">dihedral group</a> $D_4$. Wikipedia tells us that this group has <a href="http://en.wikipedia.org/wiki/Dihedral_group#Matrix_representation" target="_blank">a certain matrix representation</a>. How can we recreate this in Sage?</p>
<p>We could hard-code the relevant matrices in our function definition. However, typing all these matrices can be time-consuming, especially if the group is large.</p>
<p>But remember that representations are group homomorphisms. If we’ve defined $\rho(g)$ and $\rho(h)$, then we can get $\rho(gh)$ simply by multiplying the matrices $\rho(g)$ and $\rho(h)$! If we have a <a href="http://en.wikipedia.org/wiki/Generating_set_of_a_group" target="_blank">set of generators</a> of a group, then we only need to define $\rho$ on these generators. Let’s do that for the generators of $D_4$:</p>
<div class="linked">
<script type="text/x-sage">
D4 = DihedralGroup(4)
D4.gens()
</script>
</div>
<p>We see that $D_4$ has a generating set of 2 elements (note: the method <code class="highlighter-rouge">gens()</code> need not return a <em>minimal</em> generating set, but in this case, we do get a minimal generating set). Let’s call these $r$ and $s$. We know that elements of $D_4$ can be written $r^is^j$, where $i = 0,1,2,3$ and $j = 0,1$. We first run through all such pairs $(i,j)$ to create a <a href="https://docs.python.org/2/tutorial/datastructures.html#dictionaries" target="_blank">dictionary</a> that tells us which group elements are given by which $(i,j)$:</p>
<div class="linked">
<script type="text/x-sage">
r,s = D4.gens()
D4_dict = {}
# Populate dictionary
for i in range(4):
for j in range(2):
D4_dict[r^i * s^j] = (i,j)
# Check!
for g in D4:
show(D4_dict[g])
</script>
</div>
<p>Now for $g = r^i s^j \in D_4$, we can define $\rho(g) = \rho(r)^i \rho(s)^j$ and we will get a representation of $D_4$. We need only choose the matrices we want for $\rho(r)$ and $\rho(s)$.</p>
<p>$r$ and $s$ correspond to $R_1$ and $S_0$, resp., in the <a href="http://en.wikipedia.org/wiki/Dihedral_group#Matrix_representation" target="_blank">Wikipedia example</a>, so let’s use their matrix representations to generate our representation:</p>
<div class="linked">
<script type="text/x-sage">
def wiki_rep(g):
i,j = D4_dict[g]
return matrix([[0,-1],[1,0]])^i * matrix([[1,0],[0,-1]])^j
# Check!
for g in D4:
show(wiki_rep(g))
</script>
</div>
<p>One can verify that this does indeed give the same matrices as the Wikipedia example, albeit in a different order.</p>
<h2 id="we-can-do-better">We can do better!</h2>
<p>All the representations we’ve defined so far aren’t very satisfying! For the last example, we required the special property that all elements in $D_4$ have the form $r^i s^j$. In general, it isn’t always easy to express a given group element in terms of the group’s generators (this is known as the <a href="http://en.wikipedia.org/wiki/Word_problem_for_groups" target="_blank">word problem</a>).</p>
<p>We’ve also been constructing representations in a rather ad-hoc manner. Is there a more general way to construct representations? And how many are representations are there?</p>
<p>In the <a href="/Representation-Theory-Sums-Products/">next post</a>, I’ll run through two simple ways of combining existing representations to get new ones: the direct sum and the tensor product. I’ll also define <em>irreducible</em> representations, and state some results that will shed some light on the above questions.</p>
Tue, 20 Jan 2015 00:00:00 +0000
http://sheaves.github.io/Representation-Theory-Intro/
http://sheaves.github.io/Representation-Theory-Intro/