<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-2416938867494003223</id><updated>2009-05-12T17:03:08.186-07:00</updated><title type='text'>rlm-blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/-/sage'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/search/label/sage'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-835077612165050559</id><published>2008-09-14T00:44:00.000-07:00</published><updated>2008-09-14T01:07:49.930-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Double cosets implemented</title><content type='html'>I have finally implemented the "missing link" for doing canonical augmentation right. This is the question of computing double-coset type problems. Suppose you have two properties P_L and P_R which form subgroups of a permutation group G (i.e. this is true of the elements for which these hold), and a third property P. Further suppose that if P holds for any permutation in G, then it forms both a left coset of P_L and a right coset of P_R. This is the kind of problem the double-coset approach tackles.&lt;br /&gt;&lt;br /&gt;In particular, this is a more efficient method of isomorphism than the usual "canonical label times two" approach. Essentially, only one tree structure is traversed (instead of two), and worse case performance is when this one traversal takes about the same time. So the best case will be a little more than half the time of the other approach.&lt;br /&gt;&lt;br /&gt;I have implemented randomized testing of the new code on graphs only thus far, but everything now seems to be working, and what I have is posted &lt;a href="http://trac.sagemath.org/sage_trac/ticket/4115"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This was the last obstacle before canonical augmentation itself could be tackled. Currently, in the code which implements augmentation for binary codes, the step which should be accomplished by a double-coset approach is farmed out to GAP, in an inefficient way. Essentially, GAP computes a group intersection and a coset traversal, in order to find whether (C,P) ~ (C,M). Instead, using refinements for each structure in the pair, we can adapt the (flexible, thanks to the generalized framework) new double coset program to compute this very efficiently. In practice, GAP can take up to 70% of cpu time when being used in this way, where the new approach is expected to be a much smaller fraction of computation time. This should speed up the classification under way &lt;a href="http://rlmiller.org/de_codes/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-835077612165050559?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/835077612165050559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=835077612165050559' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/835077612165050559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/835077612165050559'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/09/double-cosets-implemented.html' title='Double cosets implemented'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-3316892871629895905</id><published>2008-09-02T13:49:00.000-07:00</published><updated>2008-09-02T13:56:26.446-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Hypergraphs</title><content type='html'>Also known as incidence structures, nonlinear binary codes, block designs and (0,1)-matrices... The object is a collection of points P, and a collection of blocks, which are subsets of P. The action of S_P induces an action on subsets of P, and the subgroup of S_P which takes blocks to blocks is the automorphism group of the incidence structure.&lt;br /&gt;&lt;br /&gt;This is the latest application of the generalized partition backtrack methods for computing automorphism groups and canonical labels. It is implemented with surprising similarity to the linear case (for example, the exact same refinement procedure is used). In fact, one of the optimizations Leon uses is to take some subset of the words of a linear binary code, and use them for refinement. With this new code in place, it will be trivial to implement such an optimization. However, choosing which subset of blocks, and then finding them all, is not a simple problem -- his approach is to simply take the set of words of minimum weight. This does reduce the time taken to refine each partition substantially, but it may have unexpected adverse effects of enlarging the search tree, depending on the specific code.&lt;br /&gt;&lt;br /&gt;Currently the code is valgrinding to find the usual segfaults and other human errata. Then there should be a patch appearing soon on trac. Thanks again to Google for funding all this!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-3316892871629895905?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/3316892871629895905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=3316892871629895905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/3316892871629895905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/3316892871629895905'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/09/hypergraphs.html' title='Hypergraphs'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-1479153299060161948</id><published>2008-08-20T17:13:00.001-07:00</published><updated>2008-08-20T17:35:10.217-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>How not to write a paper, part I</title><content type='html'>I have been reading over Jeffrey Leon's paper on partition backtrack methods, titled&lt;br /&gt;&lt;br /&gt;Permutation Group Algorithms Based on Partitions, I: Theory and Algorithms.&lt;br /&gt;&lt;br /&gt;What Leon accomplishes in this paper is as powerful as it is incomprehensible, and in reading it I have had so much difficulty that I have decided to use it as a model for how not to write a paper, much in the spirit of a lecture by Serre I once saw on video.&lt;br /&gt;&lt;br /&gt;First of all, it is a very bad idea to put "part I" in the title of a paper. I have titled this blog that way, because I am pretty certain that I will be posting a follow-up list. Leon never submitted a follow up paper to this one, and in fact references this non-existent paper several times in the paper I am reading.&lt;br /&gt;&lt;br /&gt;This paper is truly a maze of which a minotaur would be jealous. Every definition refers back to Definition XX or Notation XX of Section YY. This is no fault of Leon's, since the editors of the Journal of Symbolic Computation control the headers of the article, but you never know what section you are in anyway, so these references are already difficult to follow. To make matters worse (yes, that's right, Notation is on the same footing as Definition and Theorem), here is an example progression of his numbering from section 6:&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;Definition 19&lt;br /&gt;Example 6&lt;br /&gt;Definitions 20-22&lt;br /&gt;Lemma 9&lt;br /&gt;Definition 23&lt;br /&gt;Proposition 4&lt;br /&gt;Definition 24&lt;br /&gt;Proposition 5&lt;br /&gt;Definition 25&lt;br /&gt;Proposition 6&lt;br /&gt;Corollary&lt;br /&gt;Definition 26&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;That's correct, corollaries are only referenced as "the corollary to Proposition 6" or something like it.&lt;br /&gt;&lt;br /&gt;Another good idea if you are trying to win the journal equivalent of an obfuscated C contest is to use lots of notation. Leon starts his article with at least three pages of notation, and to make matters worse, for a large part of the notation, one reads "Notation not specified above may be found in Gorenstein (1968) or in Wielandt (1964)." As if one more table of notation would hurt!&lt;br /&gt;&lt;br /&gt;More on notation: no latin letters are ever used for notation, except for groups. Everything is either Greek, Fraktur, or some monstrous calligraphication of Fraktur. More on that: your typos can get pretty interesting when your paper is structured this way. An "R"-base is defined as a sequence of things, ("A_1", ..., "A_{n-1}"), where "" means some kind of Fraktur notation. In this definition, another set of notations is defined, and yet a third sequence of things ("U_1", ..., "U_{n-1}") is referenced to in the "such that" clause that never comes up again. After struggle, the reader (if one has not already jumped off the cliff) realizes that the "U_i" and "A_i" are actually the same object, and the scriptyness of the fonts being used has had the reader thinking that those were "A"s, when in fact they were "U"s all along. The "U_i" were actually a typo of not being hard enough to read, using regular Fraktur instead of super scripty Fraktur!&lt;br /&gt;&lt;br /&gt;Now keep in mind, we have almost made it through half the paper, and most of what we've been presented with have been definitions of notation, and complicated concepts with what I find to be simple English explanations (lacking in the paper of course). We haven't even gotten to the "Theory and Algorithms" yet!&lt;br /&gt;&lt;br /&gt;All this aside, I should mention that Leon's work in this paper is very important, and I wouldn't be struggling with it so hard if anyone else had published anything like it. We also owe him a bit of thanks for releasing his code under GPL, so that when I eventually go crazy over his notation, I can just look at his source code (written in ASCII, with no weird alphabets) to see what he means. Thanks also to Google, once again, for paying me for this self-torture.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-1479153299060161948?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/1479153299060161948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=1479153299060161948' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/1479153299060161948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/1479153299060161948'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/08/how-not-to-write-paper-part-i.html' title='How not to write a paper, part I'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-6232147374203537450</id><published>2008-08-18T14:48:00.000-07:00</published><updated>2008-08-18T16:30:11.070-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Double cosets</title><content type='html'>I'm now turning to the task of canonical augmentation, or orderly generation. More simply, the question of generating unique isomorphism representatives of a certain class of finite objects, where the notion of isomorphism comes from the action of some finite permutation group.&lt;br /&gt;&lt;br /&gt;One key step in the algorithm is to discover whether or not two pairs of objects are isomorphic via the same isomorphism. More specifically, it needs to be computed whether (P, C) ~ (M, g(C)), where g(C) is the canonical relabeling of C (a superobject of P), and M is defined to be the "canonical parent." This means, is there a permutation h such that h(P) = M and h(C) = g(C). First, this means that P and M must be isomorphic, let's say via d: M = d(P). So once we know d, we can say that we are looking for some permutation which is in the coset dAut(P) and also in the coset gAut(C).&lt;br /&gt;&lt;br /&gt;There are two places in the code in Sage which does this, in generating graphs and in generating binary codes. Both are currently implemented ad hoc- graphs are written in Python in a pretty naive implementation, and binary codes actually farm the work out to Gap, which takes over half the CPU time.&lt;br /&gt;&lt;br /&gt;This is an example of a double-coset problem, which is one of the types of algorithms I was planning on implementing. Since this can also be used to solve the isomorphism problem substantially faster (at least in the negative-answer case; when they are isomorphic the runtime is the same), I have decided to tackle this problem next.&lt;br /&gt;&lt;br /&gt;Once more, thanks to Google for funding my work over the summer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-6232147374203537450?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/6232147374203537450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=6232147374203537450' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/6232147374203537450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/6232147374203537450'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/08/double-cosets.html' title='Double cosets'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-6025360264697191186</id><published>2008-07-29T13:50:00.000-07:00</published><updated>2008-07-29T14:09:42.921-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Binary Codes</title><content type='html'>I'm currently working on refactoring the binary code part of sage into the &lt;a href="http://trac.sagemath.org/sage_trac/ticket/3676"&gt;new framework&lt;/a&gt;, and I'm trying to get my head clear on exactly what is to be done. I'll be rewriting a binary code class/struct where degree is arbitrary (the underlying implementation will use bitsets for the basis). In order to retain focus, I won't be tying this in to Sage's general linear codes until after my work for Google is done, keeping my work in the newly created &lt;tt&gt;sage/groups/perm_gps/partn_ref&lt;/tt&gt; module.&lt;br /&gt;&lt;br /&gt;To adapt incidence structures to the algorithm in general, the standard procedure is to produce a bipartite graph whose vertices are divided into two sets: points and lines of the incidence structure. However, the automorphism group of an incidence structure is a permutation group acting on the points of the structure, which induces an action on the lines. Binary codes are an example of incidence structures, with additional linear structure.&lt;br /&gt;&lt;br /&gt;However, the bipartite graph approach can be more expensive-- this is in essence the solution to the riddle (item 4 &lt;a href="http://wiki.rlmiller.org/PartitionRefinement"&gt;here&lt;/a&gt;) of the projective planes of order 16 (which I will confirm experimentally later, once the machinery is there). Instead, the refinement tree only needs to be partitions of the points. Although it will be handy to keep the partition of the words of the code around, this need not be in the main algorithm, since it will only be used on refinement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-6025360264697191186?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/6025360264697191186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=6025360264697191186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/6025360264697191186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/6025360264697191186'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/07/binary-codes.html' title='Binary Codes'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-7401343912495243619</id><published>2008-07-22T15:36:00.000-07:00</published><updated>2008-07-22T15:59:47.766-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Adinkras</title><content type='html'>&lt;a href = "http://www.welltempered.net/adinkra/"&gt;Adinkras&lt;/a&gt; are visual symbols ("originally created by the Akan of Ghana and the Gyaman of Cote d'Ivoire in West Africa" - wikipedia) representing different concepts. In the &lt;a href="http://arxiv.org/abs/hep-th/0408004"&gt;paper&lt;/a&gt; by Faux and Gates, the term "Adinkra" was used to refer to an edge-colored bipartite graph with height assignments on the vertices which contains all the data of a certain type of representation of the &lt;a href="http://en.wikipedia.org/wiki/Supersymmetry_algebra"&gt;supersymmetry algebra&lt;/a&gt;. They look like this:&lt;br /&gt;&lt;br /&gt;&lt;img width=240 height=200 src="http://www.kaleidoscope.net/greg/math/The%20Adinkramat_files/14641.jpg"&gt;&lt;br /&gt;&lt;br /&gt;In classifying the off-shell representations of the supersymmetry algebra, Adinkras are a key tool. I have spent the last few days applying the &lt;a href="http://trac.sagemath.org/sage_trac/ticket/3676"&gt;new Google-funded code&lt;/a&gt; to classify (undashed) Adinkras, for a paper in preparation. On the first day, other than writing up a rather naive implementation of a classification algorithm, I spent most of my time hunting for &lt;a href="http://trac.sagemath.org/sage_trac/ticket/3703"&gt;this bug&lt;/a&gt;. The second day, today, was spent optimizing the algorithm (from 173.54 secs to 88.74 secs for all N=5 Adinkras).&lt;br /&gt;&lt;br /&gt;Here is how to compute the canonical label and automorphism group of an undashed Adinkra. An isomorphism of Adinkras is a map of the vertices which leaves the heights unchanged, which is a graph isomorphism on the underlying graph with the option of permuting the colors which label the edges. Thus we form a partition of the vertices by height. Next, an edge u,v with color c becomes a triple of edges. One new vertex is inserted to represent the edge, and two edges come from this vertex to the vertices incident with the original edge. The third edge goes from a vertex representing the original edge to a vertex representing the color c. The partition then gets a cell consisting of the edges, and a cell consisting of the colors. Thus the edges may permute amongst themselves and the colors may permute amongst themselves.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-7401343912495243619?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/7401343912495243619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=7401343912495243619' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/7401343912495243619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/7401343912495243619'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/07/adinkras.html' title='Adinkras'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-720688254662354614</id><published>2008-07-18T15:41:00.000-07:00</published><updated>2008-07-22T15:36:49.817-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Patch #1</title><content type='html'>I submitted a patch to trac today. In it, there is a new module, &lt;tt&gt;sage.groups.perm_gps.partn_ref&lt;/tt&gt;, which has a module for generic partition backtrack, &lt;tt&gt;tree_traversal&lt;/tt&gt;, and a module for graph isomorphism/automorphism groups, &lt;tt&gt;refinement_graphs&lt;/tt&gt;. The function &lt;tt&gt;search_tree&lt;/tt&gt; in &lt;tt&gt;refinement_graphs&lt;/tt&gt; is meant to ultimately replace the function of the same name in &lt;tt&gt;graph_isom&lt;/tt&gt;, which should eventually become obsolete and removed. All tests that the original passes, the replacement now also passes. This is my first &lt;a href="http://wstein.org/grants/google08/google.pdf"&gt;Google sponsored&lt;/a&gt; patch!&lt;br /&gt;&lt;br /&gt;I'd like to add two notes. There were two places in &lt;tt&gt;graph_isom.pyx&lt;/tt&gt; where I wasn't exactly sure what was going on, and I now have explanations for both of them:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;# TODO: investigate the following line&lt;br /&gt;if nu.k == -1: nu.k = 0 # not in BDM,&lt;br /&gt;# broke at G = Graph({0:[], 1:[]}),&lt;br /&gt;# Pi = [[0,1]], lab=False&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Resolved! In fact, k should never be -1 here, and this was a false fix for a different bug (since squished). I've verified in the new version that this never ever happens.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;# TODO: investigate why, in practice, the&lt;br /&gt;# same does not seem to be true for hzf &lt; k...&lt;br /&gt;# BDM had !=, not &lt;, and this broke at&lt;br /&gt;# G = Graph({0:[],1:[],2:[]}), Pi = [[0,1,2]]&lt;br /&gt;if nu.k &lt; hzf: state = 8; continue&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Resolved! This is similar to the last "fix"- the comments in graph_isom.pyx are wrong. hzf is the length for which &lt;i&gt;indicator&lt;/i&gt; values line up, so for there to be an automorphism, nu must line up with zeta all the way, exactly.  I've verified in the new version that &lt;tt&gt;!=&lt;/tt&gt; here instead does work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-720688254662354614?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/720688254662354614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=720688254662354614' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/720688254662354614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/720688254662354614'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/07/patch-1.html' title='Patch #1'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-7885904817115705259</id><published>2008-07-16T16:14:00.000-07:00</published><updated>2008-07-16T16:20:52.295-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Graph Isomorphism</title><content type='html'>I have just reproduced some of the graph isomorphism doctests with the new partition refinement code. Of the two files meant to replace &lt;tt&gt;graph_isom.pyx&lt;/tt&gt;, one is over a thousand lines and one is around 300 lines. The graph-specific parts become the 300 lines, and the generic stuff is most of it. I'm currently scraping &lt;tt&gt;graph_isom.pyx&lt;/tt&gt; for useful tests of this new software. In a day or two, I should have a complete replacement for the current graph isomorphism code, which will show up on trac as a patch. I'm particularly excited to demonstrate some nontrivial calculations using the new software, such as the sizes of the automorphism groups of the dodecahedron and the cube (&lt;tt&gt;search_tree_old&lt;/tt&gt; is a function with the same signature as the function in &lt;tt&gt;graph_isom.pyx&lt;/tt&gt; which uses the new architecture):&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;sage: import sage.groups.perm_gps.partn_ref.refinement_graphs&lt;br /&gt;sage: st = sage.groups.perm_gps.partn_ref.refinement_graphs.search_tree_old&lt;br /&gt;&lt;br /&gt;sage: G = graphs.DodecahedralGraph()&lt;br /&gt;sage: Pi = [range(20)]&lt;br /&gt;sage: st(G, Pi, order=True)[2]&lt;br /&gt;120&lt;br /&gt;&lt;br /&gt;sage: G = graphs.CubeGraph(3)&lt;br /&gt;sage: G.relabel()&lt;br /&gt;sage: Pi = [G.vertices()]&lt;br /&gt;sage: st(G, Pi, order=True)[2]&lt;br /&gt;48&lt;br /&gt;&lt;/tt&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-7885904817115705259?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/7885904817115705259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=7885904817115705259' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/7885904817115705259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/7885904817115705259'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/07/graph-isomorphism.html' title='Graph Isomorphism'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-2141871979465731421</id><published>2008-07-11T12:26:00.000-07:00</published><updated>2008-07-11T14:29:23.715-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Phase 1 Complete</title><content type='html'>Again, grateful thanks to Google for funding my summer work.&lt;br /&gt;&lt;br /&gt;"Phase 1," by which I mean rewriting the common parts of &lt;tt&gt;sage.graphs.graph_isom&lt;/tt&gt; and &lt;tt&gt;sage.coding.binary_code&lt;/tt&gt;, is now finished. All of the variable names are logically labeled, so that in fact many of the comments in the original &lt;tt&gt;sage.graphs.graph_isom&lt;/tt&gt; code have been simply removed. Now, reading the code itself is much like reading the comments in the original.&lt;br /&gt;&lt;br /&gt;I have also tested the code written so far with valgrind, and fixed the errors that were found. For each of the problem specific functions, I have implemented a trivial version, which essentially does nothing. The first, which refines partitions, returns the partition given. The second, which allows for determining that all the nodes below the current position, always returns false. The third, which compares structures under a permutation, always returns true, i.e. that the permutation is an isomorphism of the structure in question. Basically, this means that given a partition with blocks of size n(1), ..., n(k), the algorithm just computes S&lt;sub&gt;n(1)&lt;/sub&gt; x ... x S&lt;sub&gt;n(k)&lt;/sub&gt;.&lt;br /&gt;&lt;br /&gt;In theory, this should be ready for arbitrary refinement functions and structures, so Phase 2 of my project will be to implement as many specific such things as possible. I'd like to try graphs, block designs (including binary codes), computing the automorphism group of a matrix (permuting columns such that the set of rows is preserved), reflexive polytopes (perhaps using some of the functionality of PALP, perhaps not...), &lt;a href="http://arxiv.org/abs/hep-th/0408004"&gt;Adinkras&lt;/a&gt;, and certain kinds of combinatorial species.&lt;br /&gt;&lt;br /&gt;On a side note, I've said a few times to people that it's nice to be getting funding for "what I'd be doing anyway," but I have to admit that it has been making me much more productive in my work than I might have been otherwise. Thanks again, Google!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-2141871979465731421?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/2141871979465731421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=2141871979465731421' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/2141871979465731421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/2141871979465731421'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/07/phase-1-complete.html' title='Phase 1 Complete'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-2376281313463679934</id><published>2008-07-09T18:00:00.000-07:00</published><updated>2008-07-11T13:37:47.966-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Partition Refinement Snapshot</title><content type='html'>I've just passed the thousand line mark on the &lt;a href="http://wiki.rlmiller.org/PartitionRefinement"&gt;partition backtrack code&lt;/a&gt; I'm writing this summer (thanks to the support of Google!), so I thought I'd take a &lt;a href="http://rlmiller.org/snap1.txt"&gt;snapshot&lt;/a&gt; of the work done so far and post it. As you can see, I've taken care of the datastructures, supporting functions, memory management, and I'm through the main loop itself. The naming conventions are better, the code is much more self-explanatory, and the loop is structured in a logical way, instead of a mazelike circuit of GOTOs. You can continue to watch my progress through the guts of NICE &lt;a href="http://wiki.rlmiller.org/PartitionRefinement/Refactor"&gt;here&lt;/a&gt;, as I am trying to keep it current with what I am doing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-2376281313463679934?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/2376281313463679934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=2376281313463679934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/2376281313463679934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/2376281313463679934'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/07/partition-refinement-snapshot.html' title='Partition Refinement Snapshot'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-985573022523709782</id><published>2008-07-06T12:59:00.000-07:00</published><updated>2008-07-11T13:37:34.945-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Variable names, people!</title><content type='html'>Once again thanks go to Google for funding my summer work!&lt;br /&gt;&lt;br /&gt;If you've ever been frustrated with unhelpful variable names, perhaps you'll appreciate the planned changes for the partition backtrack algorithm I'm working on currently:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;Theta -&gt; orbits_of_subgroup&lt;br /&gt;index -&gt; subgroup_primary_orbit_size&lt;br /&gt;size -&gt; subgroup_size&lt;br /&gt;L -&gt; max_len_of_fp_and_mcr&lt;br /&gt;l -&gt; index_in_fp_and_mcr&lt;br /&gt;Phi -&gt; fixed_points_of_generators&lt;br /&gt;Omega -&gt; minimal_cell_reps_of_generators&lt;br /&gt;W -&gt; vertices_to_split&lt;br /&gt;nu -&gt; current_ps&lt;br /&gt;zeta -&gt; first_ps&lt;br /&gt;rho -&gt; label_ps&lt;br /&gt;h -&gt; first_meets_current&lt;br /&gt;hb -&gt; label_meets_current&lt;br /&gt;hh -&gt; current_kids_are_same&lt;br /&gt;ht -&gt; first_kids_are_same&lt;br /&gt;Lambda -&gt; current_indicators&lt;br /&gt;zf -&gt; first_indicators&lt;br /&gt;zb -&gt; label_indicators&lt;br /&gt;hzf -&gt; first_and_current_indicator_same&lt;br /&gt;hzb -&gt; label_and_current_indicator_same&lt;br /&gt;&lt;/tt&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-985573022523709782?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/985573022523709782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=985573022523709782' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/985573022523709782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/985573022523709782'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/07/variable-names-people.html' title='Variable names, people!'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-5591760598865908616</id><published>2008-06-25T09:57:00.000-07:00</published><updated>2008-07-11T13:28:24.659-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google Summer and Partition Backtrack</title><content type='html'>First of all I would like to thank Google for funding my summer work on Sage.&lt;br /&gt;&lt;br /&gt;The algorithm used in &lt;span style="font-family: courier new; font-weight: bold;"&gt;sage.coding.binary_code&lt;/span&gt; and &lt;span style="font-family: courier new; font-weight: bold;"&gt;sage.graphs.graph_isom&lt;/span&gt; is based on Brendan McKay's masters thesis. The algorithm computes, amongst other things, the automorphism group of the combinatorial structure in question. The method of the algorithm is to traverse a tree consisting of successively finer partitions (e.g. ({0,1},{2,3},{4}) is finer than ({0,1,2,3},{4})...) whose leaves are discrete partitions (such as ({1},{0},{3},{2},{4})). The two key steps are refinement and pruning. Refinement is how you get from one node in the tree to any of its successors (i.e. how to go from a given partition to one finer). For example, one way (what we do in the above modules) would be to pick a vertex of the graph, put it in its own partition, and use the number of edges between cells in the partition to further refine the partition. Pruning is making use of the observation that symmetries of the object being studied translate into symmetries of the tree being traversed, so that large chunks of the tree need not be searched, being equivalent to parts already searched.&lt;br /&gt;&lt;br /&gt;My first goal is to generalize this algorithm by making the refinement method one of the arguments to the function. This would replace two copies of the same algorithm in different places with one copy that would be much easier to plug other questions into. For example, the algorithm would work with any "subgroup type problem," in which one has a permutation group G, and a property P of permutations of G such that the permutations in G satisfying P are a subgroup (for the automorphism group of a graph, G = S_n and P is obvious). This would allow us to find set stabilizers, centralizers and normalizers of elements, upper central series, group intersections, and automorphism groups. The algorithm would also work with "canonical representative type problems," such as finding a unique representative of a conjugacy class or an orbit of some group action.&lt;br /&gt;&lt;br /&gt;Once the algorithm is generalized, other refinement procedures can also be implemented, even for the same familiar problem of graphs. For example, the technique described in &lt;a href="http://arxiv.org/abs/0804.4881"&gt;this paper&lt;/a&gt; always chooses the optimal refinement, which makes the actual refinement process much longer at each step, but the search tree exponentially smaller for certain classes of sparse graphs for which nauty's performance is bad. The strategy described &lt;a href="http://vlsicad.eecs.umich.edu/BK/SAUCY/saucy-dac08.pdf"&gt;here&lt;/a&gt; works well when the symmetries themselves are sparse, which is to "check for the condition that all the differences between partitions exist... only in the singletons, and [to] short-circuit... paths to leaf nodes when the condition" holds, which it does frequently for graphs with sparse symmetry.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-5591760598865908616?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/5591760598865908616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=5591760598865908616' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/5591760598865908616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/5591760598865908616'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/06/google-summer-and-partition-backtrack.html' title='Google Summer and Partition Backtrack'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-5194792679737288350</id><published>2008-02-09T08:02:00.000-08:00</published><updated>2008-02-09T10:47:27.293-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><title type='text'>Fast sparse graphs</title><content type='html'>&lt;span style="font-family:arial;"&gt;From the hotel room at &lt;a href="http://wiki.sagemath.org/days7"&gt;Sage Days 7: Combinatorics&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When I discussed the base implementation of graph datatypes with the NetworkX developers, I was surprised when they told me that they found the current Python dict-of-dict's approach faster than even any C implementations. Perhaps the missing ingredient was Cython, which allowed me to beat out the dicts in under twenty four &lt;/span&gt;&lt;span style="font-family:arial;"&gt;hours. The underlying implementation is an adjacency list, achieved by an array of custom made hash tables, whose buckets are rudimentary binary trees. There is an option to specify at run time the expected degree of the graph-- these tests were done on random cubic graphs. The vertical axis is number of vertices, the horizontal is a single edge access, in secs x 10000000.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;sage: G = graphs.RandomRegular(3,100)&lt;br /&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 464px; height: 284px;" src="http://bp1.blogger.com/_70vU0Zh0t7s/R63zcyJrSQI/AAAAAAAAAAM/wm4Y-oX5rJY/s320/tmp_0.jpg" alt="" id="BLOGGER_PHOTO_ID_5165052023488071938" border="0" /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-5194792679737288350?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/5194792679737288350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=5194792679737288350' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/5194792679737288350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/5194792679737288350'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2008/02/fast-sparse-graphs.html' title='Fast sparse graphs'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_70vU0Zh0t7s/R63zcyJrSQI/AAAAAAAAAAM/wm4Y-oX5rJY/s72-c/tmp_0.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2416938867494003223.post-3598991473009382329</id><published>2007-12-13T10:50:00.000-08:00</published><updated>2007-12-13T15:48:52.857-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sage'/><title type='text'>Sage TA</title><content type='html'>I have been hired by the college of Arts and Sciences, at the University of Washington,  to work on and help people with Sage. This is the first position of this kind, so I don't know what to expect. My plan is to hold some office hours in the Sage lab, and help with getting releases out.&lt;br /&gt;&lt;br /&gt;Title: Arts &amp;amp; Sciences Mathematical Computing GSA&lt;br /&gt;&lt;br /&gt;Description: This position will be focused on providing support for computing-based research across the campus. The GSA will hold office hours where the focus will be on assisting undergraduate and graduate students, researchers and faculty from all areas of the sciences and engineering with the use of software designed for mathematical computation.  In particular, the GSA will assist with the development and implementation of &lt;span class="nfakPe"&gt;Sage&lt;/span&gt;, which is an open source mathematical software development project sponsored by the University of Washington.  The &lt;span class="nfakPe"&gt;TA&lt;/span&gt; will also devote time to answering email queries in this area.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2416938867494003223-3598991473009382329?l=rlmill.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rlmill.blogspot.com/feeds/3598991473009382329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=2416938867494003223&amp;postID=3598991473009382329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/3598991473009382329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2416938867494003223/posts/default/3598991473009382329'/><link rel='alternate' type='text/html' href='http://rlmill.blogspot.com/2007/12/sage-ta.html' title='Sage TA'/><author><name>Robert L. Miller</name><uri>http://www.blogger.com/profile/00214381485849784713</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07443535694551311299'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>