Modern fork of the Symmetrica library from the
[SageMath](https://www.sagemath.org/) team.

About Symmetrica
================

Symmetrica is a C library developed by Lehrstuhl Mathematik II of the
University of Bayreuth. It has routines for the following applications,
among many others:

  * ordinary representation theory of the symmetric group and related groups
    * ordinary representations of the symmetric group
      * semi normal representation
      * orthogonal representation
      * integer representation (Boerner)
      * integer representation (Rutherford)
      * integer representation (Specht)
      * Specht polynomials
    * table of characters of the symmetric group
    * table of characters of the alternating group
    * table of characters of the wreath product of symmetric groups
    * decomposition of characters of the symmetric group
    * Littlewood Richardson rule
    * scalar product of characters of the symmetric group
    * character polynomials of the symmetric group
    * computation in the group algebra
    * class sums of the symmetric group
      * single coefficient in the product of conjugacy classes
      * complete expansion of the product of conjugacy classes
  * ordinary representation theory of the classical groups
    * dimension of the irreducible representations of GL(n)
    * dimension of the irreducible representations of Sp(n)
    * dimension of the irreducible representations of SO(n)
    * characters of the classical groups
    * standard tableaux for the classical groups
    * representations for the classical groups
  * modular representation theory of the symmetric group
    * modular representations of the symmetric group
    * decomposition numbers of the symmetric group
    * Brauer characters
    * modular dimensions
  * projective representation theory of the symmetric group
    * projective representations of the symmetric group
  * combinatorics of tableaux
    * generate all tableaux with given properties
    * compute the number of tableaux with given properties
    * Jeu de taquin
    * Schensted algorithm
    * shifted tableaux
    * skew tableaux
  * symmetric functions and polynomials
    * Schur functions
    * power sums
    * product of monomial symmetric functions
    * product of Schur functions
    * skew Schur function
    * change of bases
    * Hall Littlewood polynomials
    * plethysm
      * plethysm of a complete symmetric function with a Schur function
      * plethysm of a power symmetric function with a Schur function
      * plethysm of a elementary symmetric function with a Schur function
      * plethysm of two Schur functions
      * plethysm of two complete symmetric functions
    * zonal polynomials
  * commutative and non commutative Schubert polynomials
    * redball compute Schubert polynomials
    * product of Schubert polynomials
    * compute double Schubert polynomials
    * compute non commutative Schubert polynomials
  * operations of finite groups
    * cycle index polynomials
      * symmetric group
      * alternating group
      * cyclic group
      * dihedral group
      * permutation group given by generators
    * group reduction function
      * symmetric group
      * alternating group
      * cyclic group
      * dihedral group
      * permutation group given by generators
    * permutational isomers
    * graphs
    * orbits
    * codes
  * ordinary representation theory of Hecke algebras of type A<sub>n</sub>
    * ordinary irreducible representations

The University of Bayreuth maintains its own page of information about
symmetrica, of mostly historical interest now, at
http://www.algorithm.uni-bayreuth.de/en/research/SYMMETRICA/

About the fork
--------------
This is a fork of symmetrica-2.0, maintained by the
[SageMath](https://www.sagemath.org/) development team. The original
developers of symmetrica at the University of Bayreuth are no longer
active, but symmetrica is still in use in SageMath and elsewhere. This
fork was created to modernize the codebase, and to resume making
releases with the fixes that have accrued over the years.

Building a release
==================
If you are building from the release tarball, the standard

```
./configure
make
make install
```

should suffice to build and install the library. Afterwards, the test
suite can be run with

```
make check
```

to ensure that everything went as planned. In addition to the standard
`./configure` flags controlling the installation directories, the
following flags are also supported:

  * `--enable-doc`: install the API documentation


Using the library
=================

To use the symmetrica library in your program, you first have to
install it. You could follow the "Building a release" instructions,
but we recommend using your distribution's package manager to install
symmetrica if you're running Linux. After the library and headers are
installed, you can use the library by including the `symmetrica.h`
header in your own C program. For example,

```c
#include <symmetrica.h>

SYM_BEGIN
scan(PARTITION,a);
scan(INTEGER,b);
compute_schur_with_alphabet(a,b,c);
println(c);
SYM_END
```

If your program is called `example.c`, then you can compile it
and link it against the symmetrica library with something like
the following (the exact command depends on your system):

```sh
gcc example.c -lsymmetrica
```

The full API documentation for symmetrica can be found in the `doc`
subdirectory of each release, and is likely installed for you by your
distribution.

The fundamental object type in a symmetrica program is, appropriately,
called `object`. Most functions take pointers to these object
structures using the alias `OP` (object pointer). Objects consist of
two pieces of data, a "kind" (type `OBJECTKIND`) and a "self" (type
`OBJECTSELF`). The stored `OBJECTKIND` tells you what type of object
(integer, vector, et cetera) is being represented and the `OBJECTSELF`
is a reference to the thing itself (integer, vector, et cetera). This
allows for a sort of polymorphism.

Typically functions will return an integer to indicate success or
failure, and the real return value (if there is one) is returned by
reference. For example, the factorial function is declared as,

```c
INT fakul(OP n, OP d)
```

The input is a pointer `n` to an integer object whose factorial you
want to compute, and the output is stored in another object pointed to
by `d`. The `INT` return value is there to indicate what went wrong if
some intermediate computation failed. The `INT` type is itself an
alias, for `int32_t`, a fixed-width integer of 32 bits.

Much of the code that you'll write is boilerplate to create, modify,
access, and destroy objects. To create one, you would use the
`callocobject` function, and to "destroy" one (i.e. free its
resources), you should use `freeall`. In between, there are a large
collection of tersely-named modifier and accessor functions such as
`m_i_i`, for "make int integer", because it makes a symmetrica integer
object from a C `INT`. Similarly there are `s_i_i` and `c_i_i` for
"select int integer" and "change int integer", to get or change the
value of an existing integer object. There are however several global
objects defined so that you don't have to manually create integer
objects for zero, one, two, etc. repeatedly:

  * cons_negeins
  * cons_null
  * cons_eins
  * cons_zwei
  * cons_drei

As a short example, the following program constructs an integer object
corresponding to the value `2`, and checks that it is equal to the
pre-defined `cons_zwei`. The `anfang` and `ende` functions should
always be called at the beginning/end of your program to
initialize/clean-up any global data. (The `SYM_BEGIN` and `SYM_END`
macros do this for you, but they do other stuff as well.)

```c
#include <symmetrica.h>

int main(int argc, char** argv) {
  int result = 1;
  anfang();

  OP a = callocobject();
  m_i_i(2,a);

  /* The eq function is a rare example of a function whose return
   * value is itself meaningful. */
  if (eq(a,cons_zwei)) {
    result = 0;
  }

  freeall(a);
  ende();
  return result;
}
```

Particularly within symmetrica's own code, you will often find macro
versions of the getter/setter functions such as `M_I_I`, the macro
version of `m_i_i`. These are usually intended to be faster versions
that perform less error checking, but you should consult the
documentation (or the code) to be sure.

Resolving min/max name conflicts
--------------------------------

The symmetrica library places two functions `min()` and `max()` in the
global scope. Unfortunately, that means that you cannot combine
symmetrica with code that defines its own `min` and `max`.

For example, the `windef.h` header on Windows defines its own
incompatible `min` and `max` macros, and `windef.h` is included in the
more-common `windows.h` header. Unless you need the `windef.h`
implementations of `min` and `max`, the easiest solution here is to
define the magic constant `NOMINMAX`, which will tell `windef.h` to
omit those macros. For example,

```c
#define NOMINMAX
#include <windows.h>
#include <symmetrica.h>
...
```

Another common issue is that the `stdlib.h` header from the Windows
SDK defines its own `min()` and `max()` macros when `__STDC__` is
defined falsy. If you are using Microsoft's compiler, you should
[disable their proprietary
extensions](https://docs.microsoft.com/en-us/cpp/build/reference/za-ze-disable-language-extensions?view=vs-2019)
while building symmetrica. Doing so results in `__STDC__` being
defined to `1`, and the problematic macros left out.

If you are cross-compiling for Windows, you can experience similar
problems. Clang, at least, aims for [compatibility with the
non-standard Microsoft
extensions](https://clang.llvm.org/docs/UsersManual.html#microsoft-extensions)
when targeting Windows. The symmetrica build system will try to detect
this situation and append `-fno-ms-compatibility` to your `CFLAGS` to
disable compatibility mode, thus reverting back to standards-compliance.

Development
===========
The new home for Symmetrica development is on Gitlab:

  https://gitlab.com/sagemath/symmetrica

Bugs and feature requests should be reported there from now on. To
bootstrap the autotools build system within the git repository, first
run

```
autoreconf -fi
```

after which the standard instructions apply.
