% SPECIFICATION OF: liealgebra class lafree
% ----------------
% 
% SUMMARY: liealgebra class lafree
% -------
%         Based on:
%         --------
%            class liealgebra
% 
%         Properties:
%         ----------
%            Free liealgebra generated by s symbols, by all commutators up to
%            order q.
% 
% PURPOSE:
% -------
%    This class is doing computations on symbolic commutators such
%    as e.g. [1,[1,2]] and [2,1], where the integers are placeholders
%    for elements in some concrete liealgebra. By systematically
%    employing the rules:
%       1) [i,i] = 0
%       2) [i,j] = -[j,i]
%       3) [i,j+k] = [i,j] + [i,k]
%       4) [i,[j,k]] + [j,[k,i]] + [k,[i,j]]
%    we can reduce all commutators to a standard basis. We have chosen
%    the so-called HALL basis, described in Bourbaki. Other choices are
%    possible.
% 
%    By doing a symbolic computation, we may systematically eliminate
%    all linearly dependent commutators, and derive a result in a reduced
%    form. Once the reduced form is derived, we may evaluate the result in
%    a concrete Lie algebra.
% 
%    Example: Suppose a computation yields the result:
%       r = 3*[1] + 4*[2] - 6*[1,2]
%    Let lalist = {a,b} where a and b are elements in a concrete Lie algebra,
%    say 'laso'. We may employ the function 'eval' to evaluate the
%    symbolic expression r in laso:
%       c = eval(r,lalist)
%    yields the same result as:
%       c = 3*a + 4*b - 6*[a,b]
% 
%    The advantage of using the class lafree is that the number of commutator
%    computations are minimized.
% 
%    The DEGREE of a commutator is the number of elements in it, so
%    [1,2] has degree 2, while [[1,2],[1,2,3]] has degree 5.
% 
%    The ORDER of a commutator is a number that can be set for the free
%    basis elements by the user, and which behaves additively under
%    commutation. E.g. if we set the order of [1], [2] and [3] to be
%    1, 2 and 3 respectively, we have that [1,2] has order 3, while
%    [[1,2],[1,2,3]] has order 9. The order of the basis elements must
%    always be positive integers. The order can be thought of as measuring
%    the size of an element (e.g. in differential equations we talk about
%    order p if the size of an object is ~ h^p).
% 
%    The order q defines the highest order any element in lafree should have. If
%    any element of higher order is generated by a computation, it is
%    set to 0.
% 
%    The SHAPE information of a free Liealgebra is a cell array of
%    the following form:
%       shape = {[s,q],[o1,o2,o3,...,os]}
%    where s is the number of elements, q is the maximal order of terms,
%    and [o1,...,os] is the order of the basis elements. If the shape is
%    set as:
%       shape = {[s,q]},
%    then [o1,...,os] is taken to be [1,1,...,1], and in this case
%    ORDER = DEGREE for all elements.
% 
%    Example: Suppose we have a function a(t), and we want to compute
%       expressions involving the function sampled at different times:
%          ai = h*a(ci*h), i=1,...,s,
%       for some 'small' h. If we want to compute all terms up to some
%       order q in h, we have that all ai has order 1. Thus we can work
%       with the algebra with shape={[s,q]}. This algebra
%       may turn out to be very large. As an alternative, we may introduce
%       a Taylor basis for the space spanned by ai,
%          a1 = q1 + c1*q2 + c1^2*q3 + ... + c1^s*qs
%          a2 = q1 + c2*q2 + c2^2*q3 + ... + c2^s*qs
%          ...
%          as = q1 + cs*q2 + cs^2*q3 + ... + cs^s*qs
%       thus, if the qi are our free elements instead of ai, we work
%       with the algebra with shape={[s,q],[1,2,...,s]}, which can be
%       MUCH smaller. We have:
%          dimension(lafree({[3,6]}) == 196
%       while
%          dimension(lafree({[3,6],[1,2,3]}) == 15
%       Needless to say, the resulting expressions are tremendously simpler
%       in the qi's than in the ai's.
% 
% IMPLEMENTATION:
% --------------
%    The current implementation of this class starts by computing a complete
%    basis for the free Lie algebra. This makes the functions fast if the
%    dimension is not terribly big, say up to 10000 or so. In some cases,
%    the free algebra is much bigger than this, while we during the
%    computations only will span a small part of the full algebra. In this
%    case the current implementation is not good, and should be replaced by
%    another implementation which is not depending on knowing the full
%    algebra.
% 
%    When a new algebra is defined, the basis and other information is
%    computed. This data is stored in a global variable LAFREEDATA.
%    This datastructure may grow quite large, and is not deleted until
%    one quits MatLab. This is done to save space and time, but it
%    is a non-elegant hack that should be corrected in the future.
% 
% DESCRIPTION:
% -----------
%    Types:
%    -----
%       Laf = lafree; % free Lie algebra
%       LafShape;     % shape information, see 'setshape' for info
%       LafData;      % same as vec in current implementation.
%       LalgList;     % 1-D array of lie algebra elements, created
%                     % by e.g. cat() or array() commands
%       int;          % integers
%       vec;          % real or complex vectors
%       mat;          % real or complex matrix
%       bool;         % 0 for false, 1 for true
% 
% 
%    Operations:
%    ----------
%    Constructors:
%       function [a] = lafree(varargin)
%       Result:
%          No argument:
%             a = lafree; % returns a template element, with no shape.
% 
%          Single argument from same class:
%             a = lafree(arg); isa(arg,'lafree') == 1;
%          This sets a to have the same liealgebra as arg, but the data
%          in a is undefined. If arg has shape information, this is copied
%          to a.
% 
%          Single argument with shape information:
%             a = lafree({[s,q],[o1,...,os]})
%          Sets a to be a lafree object with the given shape. The
%          data in a is undefined.
% 
%    Observers:
%       dimension : Laf->int
%       function [d] = dimension(g)
%          Result: returns the dimension of the vectorspace underlying Laf
% 
%       getVector    : Laf->vec
%       function [v] = getvector(g)
%          Result: returns a (column) vector which represents the element g,
%             wrt. a chosen ordering of the Hall basis.
% 
%       getData      : Laf->LafData
%       function [v] = getdata(g)
%          Result: returns data that represents an element g.
%          More precisely: In the current implementation, this function is
%             identical to getvector.
% 
%       isAbelian    : Laf->bool
%       function [i] = isabelian(g)
%          Result: Returns 0.
% 
%       hasMatrix    : Laf->bool
%       function [i] = hasmatrix(g)
%          Result: Returns 0.
% 
%       hasShape    : Laf->bool
%       function [i] = hasshape(g)
%          Result: Returns 1.
% 
%       isMatrix     : Laf,mat->bool
%       function [i] = ismatrix(g,m)
%          Result: Returns 0.
% 
%       isData     : Laf,LafData->bool
%       function [i] = isdata(g,m)
%          Result: checks if m could be data for an element in Laf.
% 
%       sameShape     : Laf,Laf->bool
%       function [i] = sameshape(g,h)
%          Result: Checks if free algebras g and h have the same shape
% 
%     --- optional ---
%       getShape     : Laf->LafShape
%       function [sh] = getshape(g)
%          Result: The shape of a free liealgebra is a 1-by-2 double
%             array consisting of the integers:
%                sh = [s,q]
%             where s is the number of symbols and q is the maximal order.
% 
%       degree     : Laf->int
%       function [d] = degree(g)
%          Result: The degree of a commutator [i1,[i2,i3]] is 3.
% 
%       order     : Laf->int
%       function [p] = order(g)
%          Result: The order of a commutator [i1,[i2,i3]] is
%             order([i1])+order([i2])+order([i3]). The order of the
%             basis elements is set by the 'setshape' command.
% 
%    Generators:
%       .+. : Laf,Laf->Laf
%       function [c] = plus(a,b)
%          Result: addition in the algebra
% 
%       .-. : Laf,Laf->Laf
%       function [c] = minus(a,b)
%          Result: subtraction in the algebra
% 
%       -. : Laf->Laf
%       function [c] = uminus(a)
%          Result: unary minus
% 
%       .*. : Laf,F->Laf,    .*. : F,Laf->Laf
%       function [c] = mtimes(a,b)
%          Result: scalar multiplication
% 
%       0 :  Laf->Laf
%       function [z] = zero(g)
%          Result: returns the zero element in the algebra defined by g.
% 
%       [.,.]  :  Laf,Laf->Laf
%       function [c] = horzcat(a,b)
%          Result: Lie bracket.
% 
%       dexp : Laf,Laf,int->Laf
%       function [d] = dexp(a,b,n)
%          Result: The differential of the exponential mapping, approximated
%             to order n.
%          Note: We assume that the tangentspace TG is trivialized by
%             right multiplication, and hence dexp is a mapping from
%             the Lie algebra to itself.
%          More precisely: In the case of matrix Lie algebras, we have:
%             exp'(a,b) = dexp(a,b)*exp(a)
%       ==> To be implemented!
% 
%       dexpinv : Laf,Laf,int->Laf
%       function [d] = dexpinv(a,b,n)
%          Result: The inverse differential of the exponential mapping,
%             approximated to order n.
%          Note: We assume that the tangentspace TG is trivialized by
%             right multiplication, and hence dexpinv is a mapping from
%             the Lie algebra to itself.
%          More precisely:
%             b == dexpinv(a,dexp(a,b));
%             c == dexp(a,dexpinv(a,c));
%       ==> To be implemented!
% 
%       setVector    : Laf,vec->Laf
%       function [] = setvector(upd g,v)
%          Result: sets v to be the vector data of g
% 
%       setData      : Laf,LafData->Laf
%       function [] = setdata(g,d)
%          Result: sets data that represents an element g. The specific
%          form of this data depends on the particular case.
%          More precisely: In the current implementation, this function is
%             identical to set vector.
% 
%     --- optional ---
%       basis : Laf,int->Laf
%       function [b] = basis(a,i)
%          Result: Returns the i'th basis vector in the algebra.
% 
%       setShape     : Laf,LafShape->Laf
%       function [] = setshape(upd g,sh)
%          Result: sets shape information in g.
%          More precisely: The shape of a free liealgebra is a cell
%             array of the following form:
%                sh = {[s,q],[o1,o2,...,os]}
%             where s is the number of symbols, q is the maximal order, and
%             o1,...,os is the order of the basis elements. If [o1,...,os]
%             is not given, they are all set to 1.
% 
%       eval : Laf,LalgList -> Lalg
%       function [c] = eval(r,lalist)
%          Result: Apply the expression r to the elements of a Lie algebra
%             given in lalist. 
%          Example: Suppose a computation yields the result:
%             r = 3*[1] + 4*[2] - 6*[1,2]
%             Let a and b be elements in a concrete Lie algebra,
%             e.g. 'laso'. We may employ the function 'eval' to evaluate the
%             symbolic expression r in laso:
%                c = eval(r,cat(1,a,b))
%             yields the same result as:
%                c = 3*a + 4*b - 6*[a,b]
% 
%    Conventions:
%       See also QUICKSTART.

% Written   by: Hans Munthe-Kaas, 10/10-97
% Revised   by:
% Validated by:
% Accepted  by:
