Littelmann path software in Java written by Allen Knutson, 2/16/96 -------------------------------- GNU public license. This is a rudimentary collection of routines with which to play with Peter Littelmann's path model of representation theory. The test programs to actually play with them are documented elsewhere. The basic objects in this theory are piecewise-linear paths in a certain vector space starting at the origin, the dual of the Lie algebra of the maximal torus of a symmetrizable Kac-Moody algebra. Littelmann defines "raising" and "lowering" operators on the space of paths, mysteriously analogous to the ones on the weight vectors in a representation. They take a path and simple root, and (sometimes) produce a new path whose endpoint has been shifted by the simple root. Sometimes they are declared inapplicable. Among Littelmann's results: if one starts with a path contained entirely in the positive Weyl chamber ending at an integral weight lambda, and takes the closure under the lowering operators, one gets a set of paths whose endpoints are exactly the weight vectors in the irreducible representation with high weight lambda, with the correct multiplicities. ***I should include the references here*** The Java classes in this directory are Path - naturally Arrow - the steps in a Path Szam - a class for doing rational arithmetic ("number" in Hungarian, pronounced "Sahm") CompostHeap - a trivial memory manager The initial implementation made Arrow a list of Szamok (the plural). Unfortunately Java is too slow, particularly in memory management, to make this practical, and Arrow now does its rational arithmetic itself. Szamok are still very useful for storing things like dot products, and Path still thinks in terms of them. N.B. This being a computer, we can only have Paths with rational steps. But these are the only ones of interest in the literature anyway. By default the CompostHeap is not used, as it paradoxically causes memory to be leaked _faster_. Perhaps I will rip it out entirely some day. Methods found all over the place -------------------------------- public void debug(int i, String s) public void dbgalloc(int i,String s) public String th(int i) public String toString() debug and dbgalloc are called throughout the programs to spew debugging information. The int i is supposedly the level of sophistication of the thing being reported. That is to say, if things are really badly broken, you should set debug to print out even the really low-level stuff. dbgalloc is specific to testing memory allocation. th(int i) is a silly method to make the debugging information produce nice-looking ordinal numbers: "1st","2nd","3rd", otherwise n"th". toString is implemented differently in each class; it controls how the object looks when printed out (usually via a call to debug). Path's variables ---------------- int dimension; what dimensional space it lives in Vector step; a list of the Arrows Arrow endPt; explained in endPoint() below static Path compost; static boolean composting; static CompostHeap compostHeap; all explained in newPath() below Path's methods -------------- public Path() public Path(Arrow arrow) public Path(Path pathToCopy) static public Path newPath(Path pathToCopy) public void free() The first three are constructors. You make a new Path out of nothing, in which case it won't be initialized. The second is to make a one-step Path. The third makes an auxiliary copy of a Path - all internal things are copied, so you won't affect your old copy. The fourth and fifth are part of the attempt at internal memory management. newPath() checks to see if there are any Paths lying around in Path's CompostHeap. If so, the new Path given is actually just an old one. Otherwise it actually makes a new one. free() dumps a no-longer-used Path in the CompostHeap. public void copy(Path pathToCopy) Much like the Path(Path) constructor above (which calls this, actually), without allocating a new one. public Path thenDo(Path p) p.thenDo(q) is the concatenation of p and q. public boolean coalesce(int where) Checks to see if the whereth step in your Path is parallel (and not antiparallel) to the following edge, in which case they are coalesced into one. This is called all over the place, for example in thenDo(). It is safe to call this recklessly, with where out of bounds. All methods in Path assume that the Paths they deal with have been fully coalesced, and if so will only produce fully coalesced paths. public boolean LittelArrow(Arrow root, int where) This flips (part of) the whereth arrow, enough to shift the endpoint by root if possible, otherwise to move it as far as possible. It then operates destructively on root, replacing it by the amount left to move. The return value is whether a coalescing occured between the reflected segment and the previous part of the Path. public boolean LittelPiece(Arrow root, Step Where, Step WhereNext) "Where" is supposed to be the step in the Path furthest in the direction of root, WhereNext either the following furthest step or -1 (in which case LittelPiece calculates WhereNext itself). This is for future developments such as animation, when one will want to apply LittelPiece with very small roots and Where/WhereNext won't usually need to be recalculated. LittelPiece is the heart of the Littelmann path operation. It flips as much of the Path between Where and WhereNext as is allowed, using LittelArrow, and then recurses with LittelPiece(remaining amount to flip, WhereNext, -1). This acts destructively on the current Path, producing the answer. The boolean value is whether the root operator was in fact applicable. public int findFurthest(Arrow root) This is to find the initial Where to call LittelPiece. public boolean Littelmann(Arrow root) This is the least-input version of the Littelmann path operation. It calls findFurthest and LittelPiece. Like LittelPiece, it is destructive. The boolean value is whether the root operator was in fact applicable. public boolean Littelmen(Arrow root, boolean first) This doesn't work yet; it will be for the animation procedure. public boolean equals(Path p) Check two paths for equality. Since they're both coalesced this just involves recursing to Arrow's comparison. public Arrow endPoint() Recalculate the endpoint. This should never be different than the variable endPt, so naturally calling endPt is faster. But if things are broken' put in checks to see if endPt.equals(endPoint()). public void draw(Graphics g, double curx, double cury, double scale, Color col) Draw in an applet window, starting from curx, cury. Arrow's variables ----------------- int dimension; long cuurd[][]; Color color; static CompostHeap compostHeap; The dimension is again that of the vector space the Arrow lives in. cuurd[dimension][2] is the numerators ([][0]) and denominators ([][1]) of the coordinates. (Originally this was an array of Szamok, but that was abandoned as too inefficient.) The color variable is not used for much and will probably be removed entirely - unfortunately one generally wants to color not the whole Arrow but just a segment. The compostHeap is as described in Path. public Arrow() {} public Arrow(int d) public Arrow(Arrow toCopy) static public Arrow newArrow(int d) public void free() These are three actual constructors, producing an essentially uninitialized Arrow, the zero Arrow, and a copy of another Arrow, just as in Path. The last two are the attempt at memory management in Arrow; see the corresponding spot in Path above for slightly more description. public Szam coord(int i) This returns the ith coordinate as an actual Szam, by taking the ratio cuurd[i][0]/cuurd[i][1]. public void getCoord(int i, Szam become) The same thing, but puts the value in an already initialized Szam - this is the preferred method if you have a palimpsest Szam around. public void setCoord(int i, Szam value) Pulls the numerator and denominator of a Szam into cuurd[i][]. public void reduceCuurd(int i) This probably shouldn't be public - it's part of the rational arithmetic Arrow does itself, dividing top and bottom by +/-GCD. public void zeroOutArrow() Resets an Arrow to zero. public boolean isZero() Tests whether it's zero. public void copy(Arrow w) Copies another Arrow into yours. public boolean dimensionAgrees(Arrow w) If you're being good you should check that the dimensions agree before adding two Arrows, etc. If I were being good I'd throw exceptions all over the place if you didn't. public Arrow plus(Arrow w) public Arrow minus(Arrow w) public Arrow reflectedThrough(Arrow w) public Arrow scaleBy(Szam scale) Nondestructive Arrow arithmetic, returning a+w, a-w, a - 2/ w, and a*scale, not actually changing a. As such they have to allocate new Arrows. public void add(Arrow w) Destructive: a = a+w. But no Arrow need be allocated. public Szam dotProd(Arrow w) public void getDotProd(Arrow w, Szam dotprod) The first calculates a dot product and returns the answer as a Szam; the second puts the answer in a palimpsest Szam, and is thus preferred when possible. public boolean equals(Arrow other) public boolean posPropTo(Arrow other) Test the relation between two Arrows. The second is to see whether the two Arrows can be coalesced into a single Arrow (it is not enough that they be proportional, but must be proportional by a positive constant). public Szam over(Arrow other) If your Arrow is a multiple of other, this will return that multiple, as a Szam. If it isn't, you have no business calling this routine, and will be returned a random number! Says how to print out Arrows. Szam's variables ---------------- long numerator, denominator; static Szam ZERO = new Szam(0,1); static Szam ONE = new Szam(1,1); static Szam TWO = new Szam(2,1); static CompostHeap compostHeap; These are self-explanatory, except for compostHeap, which you can read about in Path. The constants are just around for convenience, so you don't allocate a new Szam every time you need ONE or TWO. public Szam(long A, long B) public Szam(Szam szamToCopy) static public Szam newSzam(Szam szamToCopy) static public Szam newSzam(long A, long B) public void free() Much like the constructors in Path and Arrow. The first takes the numerator and denominator, and divides them by their GCD, negating to make the denominator positive. The others are the memory management thingy. public void becomesRatio(long A, long B) public void copy(Szam szamToCopy) Reset your Szam to A/B, or to the value of another Szam. static public long GCD(long A, long B) Euclid's algorithm. Uses nothing about your Szam, which is why it's been made public. Arrow uses it to do its own rational arithmetic. public Szam plus(Szam other) public Szam times(Szam other) public Szam minus(Szam other) public Szam over(Szam other) Nondestructive arithmetic. public double value() Casts the rational to a double. public boolean lessThan(Szam other) public boolean lessThanEq(Szam other) public boolean equals(Szam other) For comparing Szamok. Presumably I should bother to include moreThan and moreThanEq, but obviously they're not strictly necessary.