[SCM] Packaging for lrcalc branch, master, updated. upstream/1.1.6-9-g708a3b5

Tobias Hansen tobias.han at gmx.de
Thu Apr 18 20:38:15 UTC 2013


The following commit has been merged in the master branch:
commit 708a3b518088ce2e3cfd2696651e4c9f533849bd
Author: Tobias Hansen <tobias.han at gmx.de>
Date:   Thu Apr 18 22:40:25 2013 +0200

    Create patch to make the programs use the shared library.

diff --git a/debian/patches/programs-use-shared-libraries.patch b/debian/patches/programs-use-shared-libraries.patch
new file mode 100644
index 0000000..f08fb30
--- /dev/null
+++ b/debian/patches/programs-use-shared-libraries.patch
@@ -0,0 +1,2117 @@
+--- a/lrcoef/Makefile.am
++++ b/lrcoef/Makefile.am
+@@ -1,11 +1,8 @@
+-AM_CFLAGS = -I .. -I ../mathlib
+-
+-noinst_LTLIBRARIES = libsymfcn.la
+-libsymfcn_la_SOURCES = symfcn.c maple.c
++AM_CFLAGS = -I .. -I ../mathlib -I ../symfcn
+ 
+ bin_PROGRAMS = coprod lrcoef lrskew mult skew
+-coprod_LDADD = ../mathlib/libmath.la libsymfcn.la
+-lrskew_LDADD = ../mathlib/libmath.la libsymfcn.la
+-lrcoef_LDADD = ../mathlib/libmath.la libsymfcn.la
+-mult_LDADD = ../mathlib/libmath.la libsymfcn.la
+-skew_LDADD   = ../mathlib/libmath.la libsymfcn.la
++coprod_LDFLAGS = -shared $(top_builddir)/liblrcalc.la
++lrcoef_LDFLAGS = -shared $(top_builddir)/liblrcalc.la
++lrskew_LDFLAGS = -shared $(top_builddir)/liblrcalc.la
++mult_LDFLAGS = -shared $(top_builddir)/liblrcalc.la
++skew_LDFLAGS = -shared $(top_builddir)/liblrcalc.la
+--- a/lrcoef/maple.c
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*  Littlewood-Richardson Calculator
+- *  Copyright (C) 1999- Anders S. Buch (asbuch at math rutgers edu)
+- *  See the file LICENSE for license information.
+- */
+-
+-#include <stdio.h>
+-#include <vector.h>
+-#include <hashtab.h>
+-#include "maple.h"
+-
+-#define OUTPUT_WIDTH 60
+-
+-int _intlen(int x)
+-{
+-  int res = 1;
+-  if (x < 0) { x = -x; res++; }
+-  if (x >= 10) res++;
+-  if (x >= 100) res++;
+-  if (x >= 1000) res++;
+-  if (x >= 10000) res++;
+-  if (x >= 100000) res++;
+-  return res;
+-}
+-
+-int maple_print_term(int c, vector *v, char *letter)
+-{
+-  int x, i;
+-#ifdef MULTLINE
+-  int cols;
+-#endif
+-  
+-  putchar((c < 0) ? '-' : '+');
+-  c = abs(c);
+-  printf("%d*%s[", c, letter);
+-#ifdef MULTLINE
+-  cols = _intlen(c) + strlen(letter) + 3 + v_length(v);
+-#endif
+-  
+-  for (i = 0; i < v_length(v); i++)
+-    {
+-      if (i > 0)
+-	putchar(',');
+-      x = v_elem(v, i);
+-      printf("%d", x);
+-#ifdef MULTLINE
+-      cols += _intlen(x);
+-#endif
+-    }
+-  putchar(']');
+-#ifdef MULTLINE
+-  return cols;
+-#else
+-  return 0;
+-#endif
+-}
+-
+-void maple_print_lincomb(hashtab *ht, char *letter, int nl)
+-{
+-  hash_itr itr;
+-  int column;
+-  
+-#ifdef MULTILINE
+-  putchar('(');
+-#endif
+-  column = 1;
+-  for (hash_first(ht, itr); hash_good(itr); hash_next(itr))
+-    {
+-      if (hash_intvalue(itr) == 0)
+-	continue;
+-      
+-      column += maple_print_term(hash_intvalue(itr), hash_key(itr),letter);
+-#ifdef MULTILINE
+-      if (column >= OUTPUT_WIDTH)
+-	{
+-	  putchar('\n');
+-	  column = 0;
+-	}
+-#endif
+-    }
+-#ifdef MULTILINE
+-  printf(");\n");
+-#else
+-  if (nl)
+-    putchar('\n');
+-#endif
+-}
+--- a/lrcoef/maple.h
++++ /dev/null
+@@ -1,6 +0,0 @@
+-#ifndef _MAPLE_H
+-#define _MAPLE_H
+-
+-void maple_print_lincomb(hashtab *ht, char *letter, int nl);
+-
+-#endif
+--- a/lrcoef/symfcn.c
++++ /dev/null
+@@ -1,873 +0,0 @@
+-/*  Littlewood-Richardson Calculator
+- *  Copyright (C) 1999- Anders S. Buch (asbuch at math rutgers edu)
+- *  See the file LICENSE for license information.
+- */
+-
+-#include <stdio.h>
+-
+-#include <alloc.h>
+-#include <vector.h>
+-#include <hashtab.h>
+-
+-#include "symfcn.h"
+-
+-
+-int part_itr_sz(vector *part)
+-{
+-  int i, e, tot;
+-
+-  i = v_length(part) - 1;
+-  while (i >= 0 && v_elem(part, i) == 1)
+-    i--;
+-  
+-  if (i < 0)
+-    return 0;
+-  
+-  e = v_elem(part, i);
+-  tot = e + v_length(part) - i - 1;
+-  
+-  while (tot >= e-1)
+-    {
+-      v_elem(part, i++) = e-1;
+-      tot -= e-1;
+-    }
+-  if (tot > 0)
+-    v_elem(part, i++) = tot;
+-  v_length(part) = i;
+-  
+-  return 1;
+-}
+-
+-int part_itr_sub(vector *part, vector *outer)
+-{
+-  int i, e;
+-
+-  i = v_length(part) - 1;
+-  while (i >= 0 && v_elem(part, i) == 0)
+-    i--;
+-  if (i < 0)
+-    return 0;
+-  
+-  e = v_elem(part, i) - 1;
+-  if (e == 0)
+-    {
+-      v_length(part) = i;
+-      return 1;
+-    }
+-  
+-  while (i < v_length(outer))
+-    {
+-      int x = v_elem(outer, i);
+-      v_elem(part, i) = (e < x) ? e : x;
+-      i++;
+-    }
+-  v_length(part) = v_length(outer);
+-  
+-  return 1;
+-}
+-
+-int part_itr_between(vector *part, vector *inner, vector *outer)
+-{
+-  int i, e;
+-  
+-  i = v_length(part) - 1;
+-  while (i >= 0 && v_elem(part, i) == v_elem(inner, i))
+-    i--;
+-  if (i < 0)
+-    return 0;
+-  
+-  e = v_elem(part, i) - 1;
+-  if (e == 0)
+-    {
+-      v_length(part) = i;
+-      return 1;
+-    }
+-  
+-  while (i < v_length(outer))
+-    {
+-      int x = v_elem(outer, i);
+-      v_elem(part, i) = (e < x) ? e : x;
+-      i++;
+-    }
+-  v_length(part) = v_length(outer);
+-  
+-  return 1;
+-}
+-
+-int part_length(vector *p)
+-{
+-  int n = v_length(p);
+-  while (n > 0 && v_elem(p, n-1) == 0)
+-    n--;
+-  return n;
+-}
+-
+-vector *part_conjugate(vector *p)
+-{
+-  int np, nc, j;
+-  vector *conj;
+-  
+-  np = v_length(p);
+-  if (np == 0)
+-    return v_new(0);
+-  
+-  nc = v_elem(p, 0);
+-  if (nc == 0)
+-    return v_new(0);
+-  
+-  conj = v_new(nc);
+-  j = 0;
+-  while (np > 0)
+-    {
+-      int jlim = v_elem(p, np - 1);
+-      while (j < jlim)
+-	v_elem(conj, j++) = np;
+-      np--;
+-    }
+-  
+-  return conj;
+-}
+-
+-int part_subset(vector *p1, vector *p2)
+-{
+-  int n;
+-  
+-  n = part_length(p1);
+-  if (n > v_length(p2))
+-    return 0;
+-  
+-  for (n--; n >= 0; n--)
+-    if (v_elem(p1, n) > v_elem(p2, n))
+-      return 0;
+-  
+-  return 1;
+-}
+-
+-
+-void _chop_cols(vector *in1, vector *out)
+-{
+-  int n, m, mm, i;
+-  
+-  n = v_length(in1);
+-  m = v_elem(in1, n - 1);
+-  mm = v_elem(out, n - 1);
+-  if (m > mm)
+-    m = mm;
+-  
+-  for (i = 0; i < n; i++)
+-    {
+-      v_elem(in1, i) -= m;
+-      v_elem(out, i) -= m;
+-    }
+-  
+-  v_length(in1) = part_length(in1);
+-  v_length(out) = part_length(out);
+-}
+-
+-void _chop_rows(vector *in1, vector *out)
+-{
+-  int m, i;
+-  
+-  m = 1;
+-  while (m < v_length(in1) && v_elem(in1, m) == v_elem(out, m))
+-    m++;
+-  
+-  for (i = 0; i < v_length(in1) - m; i++)
+-    v_elem(in1, i) = v_elem(in1, i + m);
+-  v_length(in1) -= m;
+-  
+-  for (i = 0; i < v_length(out) - m; i++)
+-    v_elem(out, i) = v_elem(out, i + m);
+-  v_length(out) -= m;
+-}
+-
+-
+-long long lrcoef(vector *outer, vector *inner1, vector *inner2)
+-{
+-  vector *out, *in1, *in2, *out_conj, *cont, *vtmp;
+-  int w_out, w_in1, w_in2, do_swap;
+-  int rows, cols, i, j, stack_sz, sp, x;
+-  int *skewtab, *itab, *jtab, *max_tab;
+-  long long res;
+-  
+-  out = v_new_copy(outer);
+-  in1 = v_new_copy(inner1);
+-  in2 = v_new_copy(inner2);
+-  
+-  v_length(out) = part_length(out);
+-  v_length(in1) = part_length(in1);
+-  v_length(in2) = part_length(in2);
+-  
+-  while (v_length(out) > 0 &&
+-	 v_length(out) >= v_length(in1) &&
+-	 v_length(out) >= v_length(in2))
+-    {
+-      if (v_length(in1) == v_length(out))
+-	{
+-	  _chop_cols(in1, out);
+-	}
+-      else if (v_length(in2) == v_length(out))
+-	{
+-	  _chop_cols(in2, out);
+-	}
+-      else if (v_length(in1) > 0 && 
+-	       v_elem(in1, 0) == v_elem(out, 0))
+-	{
+-	  _chop_rows(in1, out);
+-	}
+-      else if (v_length(in2) > 0 && 
+-	       v_elem(in2, 0) == v_elem(out, 0))
+-	{
+-	  _chop_rows(in2, out);
+-	}
+-      else
+-	break;
+-    }
+-  
+-  w_in1 = v_sum(in1);
+-  w_in2 = v_sum(in2);
+-  w_out = v_sum(out);
+-  
+-  if ((! part_subset(in1, out)) || 
+-      (! part_subset(in2, out)) ||
+-      (w_out != w_in1 + w_in2))
+-    {
+-      v_free(in1);
+-      v_free(in2);
+-      v_free(out);
+-      return 0;
+-    }
+-  
+-  if (w_in1 <= 1 || w_in2 <= 1)
+-    {
+-      v_free(in1);
+-      v_free(in2);
+-      v_free(out);
+-      return 1;
+-    }
+-  
+-  out_conj = part_conjugate(out);
+-  
+-  do_swap = (w_in1 < w_in2);
+-  
+-  if (w_in1 == w_in2)
+-    {
+-      int c1 = v_elem(in1, 0);
+-      int r1 = v_length(in1);
+-      int n1 = (c1 < r1) ? c1 : r1;
+-      
+-      int c2 = v_elem(in2, 0);
+-      int r2 = v_length(in2);
+-      int n2 = (c2 < r2) ? c2 : r2;
+-      
+-      do_swap = (n1 < n2);
+-    }
+-  
+-  if (do_swap)
+-    {
+-      int tmp;
+-      
+-      tmp = w_in1;
+-      w_in1 = w_in2;
+-      w_in2 = tmp;
+-      
+-      vtmp = in1;
+-      in1 = in2;
+-      in2 = vtmp;
+-    }
+-  
+-  if (v_length(in2) > v_elem(in2, 0))
+-    {
+-      vtmp = out;
+-      out = out_conj;
+-      out_conj = vtmp;
+-      
+-      vtmp = part_conjugate(in1);
+-      v_free(in1);
+-      in1 = vtmp;
+-      
+-      vtmp = part_conjugate(in2);
+-      v_free(in2);
+-      in2 = vtmp;
+-    }
+-  
+-  rows = v_length(out);
+-  cols = v_elem(out, 0);
+-  
+-  vtmp = v_new(rows);
+-  for (i = 0; i < v_length(in1); i++)
+-    v_elem(vtmp, i) = v_elem(in1, i);
+-  for ( ; i < rows; i++)
+-    v_elem(vtmp, i) = 0;
+-  v_free(in1);
+-  in1 = vtmp;
+-  
+-  cont = v_new_zero(v_length(in2));
+-  
+-  stack_sz = w_out - w_in1;
+-  skewtab = amalloc(stack_sz * sizeof(int));
+-  max_tab = amalloc(stack_sz * sizeof(int));
+-  
+-  itab = amalloc(stack_sz * sizeof(int));
+-  jtab = amalloc(stack_sz * sizeof(int));
+-  sp = 0;
+-  for (i = 0; i < v_length(out); i++)
+-    {
+-      int left = (i < v_length(in1)) ? v_elem(in1, i) : 0;
+-      for (j = v_elem(out, i) - 1; j >= left; j--)
+-        {
+-	  itab[sp] = i;
+-	  jtab[sp] = j;
+-	  sp++;
+-	}
+-    }
+-  
+-  res = 0;
+-  
+-  skewtab[0] = 0;
+-  v_elem(cont, 0) = 1;
+-  
+-  sp = 1;
+-  i = itab[1];
+-  j = jtab[1];
+-  max_tab[1] = (i == itab[0]) ? 0 : 
+-    v_length(in2) + i - v_elem(out_conj, j);;
+-  x = (j == jtab[0]) ? 1 : 0;
+-  
+-  while (sp > 0)
+-    {
+-      /* in each loop, do one of the following:
+-       *
+-       *   a) incr x
+-       *
+-       *   b) put x; incr sp; get x;
+-       *
+-       *   c) decr sp; get x; incr x;
+-       *
+-       * where:  put/get involves updating cont and skewtab and
+-       *
+-       *         incr sp includes setting max_tab[sp].
+-       */
+-      
+-      if (x > max_tab[sp])
+-	{
+-	  sp--;
+-	  
+-	  x = skewtab[sp];
+-	  v_elem(cont, x)--;
+-	  
+-	  x++;
+-	  continue;
+-	}
+-      
+-      if (v_elem(cont, x) == v_elem(in2, x) ||
+-	  (x > 0 && v_elem(cont, x) >= v_elem(cont, x-1)))
+-	{
+-	  x++;
+-	  continue;
+-	}
+-      
+-      if (sp + 1 == stack_sz)
+-	{
+-	  /* special case: incr res; then same as c) */
+-	  res++;
+-	  
+-	  sp--;
+-	  
+-	  x = skewtab[sp];
+-	  v_elem(cont, x)--;
+-	  
+-	  x++;
+-	  continue;
+-	}
+-      
+-      skewtab[sp] = x;
+-      v_elem(cont, x)++;
+-      
+-      sp++;
+-      i = itab[sp];
+-      j = jtab[sp];
+-      
+-      if (j < v_elem(out, i) - 1)
+-	max_tab[sp] = skewtab[sp - 1];
+-      else
+-	max_tab[sp] = v_length(in2) + i - v_elem(out_conj, j);
+-      
+-      x = 0;
+-      if (i > 0 && j >= v_elem(in1, i-1))
+-	x = skewtab[sp + v_elem(in1, i-1) - v_elem(out, i)] + 1;
+-    }
+-  
+-  afree(skewtab);
+-  afree(max_tab);
+-  afree(itab);
+-  afree(jtab);
+-
+-  v_free(in1);
+-  v_free(in2);
+-  v_free(out);
+-  v_free(out_conj);
+-  v_free(cont);
+-  
+-  return res;
+-}
+-
+-
+-void st_setmin(skewtab *st, int y, int x)
+-{
+-  while (y < st->rows)
+-    {
+-      while (x >= v_elem(st->inner, y))
+-	{
+-	  int e;
+-	  if (y == 0 || x < v_elem(st->inner, y-1))
+-	    e = 0;
+-	  else
+-	    e = st->matrix[x + (y-1) * st->cols] + 1;
+-
+-	  st->matrix[x + y * st->cols] = e;
+-
+-	  v_elem(st->conts, e)++;
+-
+-	  x--;
+-	}
+-      y++;
+-
+-      if (y < st->rows)
+-	x = v_elem(st->outer, y) - 1;
+-    }
+-}
+-
+-
+-skewtab *st_new(vector *outer, vector *inner, vector *conts, int maxrows)
+-{
+-  int rows, cols, clen;
+-  skewtab *st;
+-
+-  rows = v_length(outer);
+-  cols = (rows == 0) ? 0 : v_elem(outer, 0);
+-
+-  st = amalloc(sizeof(skewtab) + sizeof(int) * (rows * cols - 1));
+-  st->outer = outer;
+-  st->inner = inner;
+-  
+-  clen = (conts != NULL) ? v_length(conts) : 0;
+-  clen += rows;
+-  st->conts = v_new_zero(clen);
+-  if (conts != NULL)
+-    {
+-      int i;
+-      for (i = 0; i < v_length(conts); i++)
+-	v_elem(st->conts, i) = v_elem(conts, i);
+-    }
+-  
+-  st->rows = rows;
+-  st->cols = cols;
+-  
+-  st_setmin(st, 0, v_elem(outer, 0) - 1);
+-  
+-  st->conjugate = NULL;
+-  if (maxrows >= clen)
+-    maxrows = 0;
+-  st->maxrows = maxrows;
+-  
+-  if (maxrows == 0)
+-    return st;
+-  
+-  if (v_elem(st->conts, maxrows) != 0)
+-    {
+-      st_free(st);
+-      return NULL;
+-    }
+-  
+-  st->conjugate = part_conjugate(outer);
+-  
+-  return st;
+-}
+-
+-int st_next(skewtab *st)
+-{
+-  int x, y, e;
+-
+-  for (y = st->rows - 1; y >= 0; y--)
+-    {
+-      int xlim = v_elem(st->outer, y);
+-
+-      for (x = v_elem(st->inner, y); x < xlim; x++)
+-	{
+-	  int elim = (st->maxrows == 0)
+-	    ? v_length(st->conts) - 1
+-	    : st->maxrows + y - v_elem(st->conjugate, x);
+-	  
+-	  if (x != xlim - 1)
+-	    {
+-	      int next_cell = st->matrix[x+1 + y * st->cols];
+-	      if (next_cell < elim)
+-		elim = next_cell;
+-	    }
+-	  
+-	  e = st->matrix[x + y * st->cols];
+-	  v_elem(st->conts, e)--;
+-
+-	  e++;
+-	  while (e <= elim &&
+-		 v_elem(st->conts, e) == v_elem(st->conts, e-1))
+-	    e++;
+-
+-	  if (e <= elim)
+-	    {
+-	      st->matrix[x + y * st->cols] = e;
+-	      v_elem(st->conts, e)++;
+-	      st_setmin(st, y, x-1);
+-	      return 1;
+-	    }
+-	}
+-    }
+-
+-  return 0;
+-}
+-
+-void st_print(skewtab *st)
+-{
+-  int x, y;
+-  
+-  vector *inner = st->inner;
+-  vector *outer = st->outer;
+-  
+-  for (y = 0; y < v_length(outer); y++)
+-    {
+-      for (x = 0; x < v_elem(outer, y); x++)
+-	{
+-	  if (x < v_elem(inner, y))
+-	    putchar(' ');
+-	  else
+-	    printf("%d", st->matrix[x + y * st->cols]);
+-	}
+-      putchar('\n');
+-    }
+-}
+-
+-void st_free(skewtab *st)
+-{
+-  v_free(st->inner);
+-  v_free(st->outer);
+-  v_free(st->conts);
+-  if (st->conjugate != NULL)
+-    v_free(st->conjugate);
+-  afree(st);
+-}
+-
+-
+-hashtab *skew(vector *outer, vector *inner, int maxrows)
+-{
+-  vector *out0, *in0;
+-  hashtab *res;
+-  vector *part;
+-  skewtab *st;
+-  int n, i;
+-  
+-  res = hash_new((cmp_t) v_cmp, (hash_t) v_hash);
+-  
+-  n = v_length(outer);
+-  if (v_length(inner) > n)
+-    return res;
+-  
+-  out0 = v_new_copy(outer);
+-  
+-  in0 = v_new_zero(n);
+-  for (i = 0; i < v_length(inner); i++)
+-    v_elem(in0, i) = v_elem(inner, i);
+-  
+-  if (! v_lesseq(in0, out0))
+-    {
+-      v_free(in0);
+-      v_free(out0);
+-      return res;
+-    }
+-  
+-  st = st_new(out0, in0, NULL, maxrows);
+-  
+-  part = v_new(n);
+-  
+-  do {
+-    int i, *valuep;
+-    
+-    for (i = 0; i < v_length(st->conts) && v_elem(st->conts, i) != 0; i++)
+-      v_elem(part, i) = v_elem(st->conts, i);
+-    v_length(part) = i;
+-    
+-    valuep = hash_mkfindint(res, part);
+-    if (hash_key_used)
+-      part = v_new(n);
+-    (*valuep)++;
+-  } while (st_next(st));
+-  
+-  st_free(st);
+-  v_free(part);
+-  
+-  return res;
+-}
+-
+-
+-hashtab *mult(vector *sh1, vector *sh2, int maxrows)
+-{
+-  skewtab *st;
+-  vector *part, *out0, *in0;
+-  hashtab *res;
+-  int n;
+-  
+-  res = hash_new((cmp_t) v_cmp, (hash_t) v_hash);
+-  
+-  if (v_sum(sh1) > v_sum(sh2))
+-    {
+-      vector *tmp = sh1;
+-      sh1 = sh2;
+-      sh2 = tmp;
+-    }
+-  
+-  out0 = v_new_copy(sh1);
+-  in0 = v_new_zero(v_length(sh1));
+-  st = st_new(out0, in0, sh2, maxrows);
+-  if (st == NULL)
+-    return res;
+-  
+-  n = v_length(sh1) + v_length(sh2);
+-  part = v_new(n);
+-  
+-  do {
+-    int i, *valuep;
+-    
+-    for (i = 0; i < v_length(st->conts) && v_elem(st->conts, i) != 0; i++)
+-      v_elem(part, i) = v_elem(st->conts, i);
+-    v_length(part) = i;
+-    
+-    valuep = hash_mkfindint(res, part);
+-    if (hash_key_used)
+-      part = v_new(n);
+-    (*valuep)++;
+-    
+-  } while (st_next(st));
+-  
+-  st_free(st);
+-  v_free(part);
+-  
+-  return res;
+-}
+-
+-
+-hashtab *schur_lc_mult(hashtab *lc1, hashtab *lc2, int maxrows)
+-{
+-  hash_itr itr1, itr2, itr;
+-  hashtab *pairs = hash_new((cmp_t) vp_cmp, (hash_t) vp_hash);
+-  hashtab *res;
+-  
+-  for (hash_first(lc1, itr1); hash_good(itr1); hash_next(itr1))
+-    {
+-      vector *v1 = hash_key(itr1);
+-      int c1 = hash_intvalue(itr1);
+-      
+-      for (hash_first(lc2, itr2); hash_good(itr2); hash_next(itr2))
+-	{
+-	  vector *v2 = hash_key(itr2);
+-	  int c2 = hash_intvalue(itr2);
+-	  
+-	  vecpair *vp = vp_new_unordered(v_new_copy(v1), v_new_copy(v2));
+-	  int *valp = hash_mkfind(pairs, vp);
+-	  *((int *) valp) += c1 * c2;
+-	  if (! hash_key_used)
+-	    vp_free(vp);
+-	}
+-    }
+-  
+-  res = hash_new((cmp_t) v_cmp, (hash_t) v_hash);
+-  
+-  for (hash_first(pairs, itr); hash_good(itr); hash_next(itr))
+-    {
+-      vecpair *vp = hash_key(itr);
+-      int c = hash_intvalue(itr);
+-      hashtab *prd;
+-      
+-      prd = mult(vp_first(vp), vp_second(vp), maxrows);
+-      lincomb_add_multiple(res, c, prd, (freekey_t) v_free1, NULL);
+-      hash_free(prd);  /* lincomb_add_multiple has frees the vectors */
+-    }
+-  
+-  free_vp_lincomb(pairs);
+-  
+-  return res;
+-}
+-
+-
+-hashtab *coprod(vector *part, int all)
+-{
+-  hashtab *res = hash_new((cmp_t) vp_cmp, (hash_t) vp_hash);
+-  int df, in_wt, wt = v_sum(part);
+-  vecpair *vp;
+-  vector *in = v_new_copy(part);
+-  
+-  do {
+-    in_wt = v_sum(in);
+-    
+-    if (2 * in_wt >= wt)
+-      {
+-	hashtab *sk = skew(part, in, 0);
+-	hash_itr itr;
+-	
+-	for (hash_first(sk, itr); hash_good(itr); hash_next(itr))
+-	  {
+-	    vector *in2 = hash_key(itr);
+-	    int coef = hash_intvalue(itr);
+-	    
+-	    df = 1;
+-	    if (2 * in_wt == wt && (df = v_cmp(in, in2)) < 0)
+-	      {
+-		v_free(in2);
+-		continue;
+-	      }
+-	    
+-	    vp = vp_new(v_new_copy(in), in2);
+-	    hash_insertint(res, vp, coef);
+-	    
+-	    if (all && df != 0)
+-	      {
+-		vp = vp_new(v_new_copy(in2), v_new_copy(in));
+-		hash_insertint(res, vp, coef);
+-	      }
+-	  }
+-	
+-	hash_free(sk);
+-      }
+-  } while (part_itr_sub(in, part));
+-  v_free(in);
+-  
+-  return res;
+-}
+-
+-
+-int rim_hook(vector *lambda, int rows, int cols, int *qp)
+-{
+-  int i, j, len, sign, q, n;
+-  
+-  len = v_length(lambda);
+-  n = rows + cols;
+-
+-  q = 0;
+-  for (i = 0; i < len; i++)
+-    {
+-      int a = v_elem(lambda, i) + rows - i - 1;
+-      q += a / n;
+-      a %= n;
+-      v_elem(lambda, i) = a - rows + 1;
+-    }
+-
+-  /* bubble sort :-( */
+-  sign = (rows & 1) ? 0 : q;
+-  for (i = 1; i < len; i++)
+-    {
+-      int a = v_elem(lambda, i);
+-      for (j = i; j > 0 && a > v_elem(lambda, j-1); j--)
+-	{
+-	  v_elem(lambda, j) = v_elem(lambda, j-1);
+-	}
+-      if (j > 0 && a == v_elem(lambda, j-1))
+-	return 0;
+-      v_elem(lambda, j) = a;
+-      sign += i - j;
+-    }
+-  
+-  for (i = 0; i < len; i++)
+-    {
+-      v_elem(lambda, i) += i;
+-      if (v_elem(lambda, i) < 0)
+-	return 0;
+-    }
+-  
+-  while (len > 0 && v_elem(lambda, len - 1) == 0)
+-    len--;
+-  v_length(lambda) = len;
+-  *qp = q;
+-  return (sign & 1) ? -1 : 1;
+-}
+-
+-list *_quantum_reduce(hashtab* s, int rows, int cols)
+-{
+-  int sign, q, *valuep;
+-  list *qlist;
+-  hash_itr itr;
+-  
+-  qlist = l_newsz(10);
+-  
+-  for (hash_first(s, itr); hash_good(itr); hash_next(itr))
+-    {
+-      vector *lambda = hash_key(itr);
+-      int coef = hash_intvalue(itr);
+-      hashtab *tab;
+-      
+-      sign = rim_hook(lambda, rows, cols, &q);
+-      
+-      if (sign == 0)
+-	{
+-	  v_free(lambda);
+-	  continue;
+-	}
+-      
+-      while (q >= l_length(qlist))
+-	l_append(qlist, hash_new((cmp_t) v_cmp, (hash_t) v_hash));
+-      
+-      tab = l_elem(qlist, q);
+-      valuep = hash_mkfindint(tab, lambda);
+-      *valuep += sign * coef;
+-      if (! hash_key_used)
+-	v_free(lambda);
+-    }
+-  
+-  return qlist;
+-}
+-
+-list *quantum_reduce(hashtab* s, int rows, int cols)
+-{
+-  list *qlist = _quantum_reduce(s, rows, cols);
+-  hash_free(s);
+-  return qlist;
+-}
+-
+-void fusion_reduce(hashtab *lc, int rows, int cols, int opt_zero)
+-{
+-  int i, j, k, n, lamj;
+-  list *qlist = _quantum_reduce(lc, rows, cols);
+-  if (l_length(qlist) == 0)
+-    {
+-      hash_reset(lc);
+-      return;
+-    }
+-  hash_copy(lc, l_elem(qlist, 0));
+-  hash_free(l_elem(qlist, 0));
+-  n = rows + cols;
+-  for (i = 1; i < l_length(qlist); i++)
+-    {
+-      hashtab *tab = l_elem(qlist, i);
+-      hash_itr itr;
+-      
+-      for (hash_first(tab, itr); hash_good(itr); hash_next(itr))
+-	{
+-	  vector *lambda = hash_key(itr);
+-	  vector *mu;
+-	  
+-	  if (hash_intvalue(itr) == 0 && opt_zero == 0)
+-	    continue;
+-	  
+-	  mu = v_new(rows);
+-	  for (j = 0; j < rows; j++)
+-	    {
+-	      lamj = (j < v_length(lambda)) ? v_elem(lambda,j) : 0;
+-	      k = (j + i) % rows;
+-              v_elem(mu,k) = lamj + ((i+j) / rows) * cols + i;
+-	    }
+-	  hash_insertint(lc, mu, hash_intvalue(itr));
+-	}
+-      
+-      free_vec_lincomb(tab);
+-    }
+-  l_free(qlist);
+-}
+-
+--- a/lrcoef/symfcn.h
++++ /dev/null
+@@ -1,43 +0,0 @@
+-#ifndef _SYMFCN_H
+-#define _SYMFCN_H
+-
+-#include <hashtab.h>
+-#include <vector.h>
+-
+-int part_itr_sz(vector *part);
+-int part_itr_sub(vector *part, vector *outer);
+-int part_itr_between(vector *part, vector *inner, vector *outer);
+-
+-int part_length(vector *p);
+-vector *part_conjugate(vector *p);
+-int part_subset(vector *p1, vector *p2);
+-
+-long long lrcoef(vector *outer, vector *inner1, vector *inner2);
+-
+-hashtab *skew(vector *outer, vector *inner, int maxrows);
+-hashtab *mult(vector *sh1, vector *sh2, int maxrows);
+-hashtab *coprod(vector *part, int all);
+-
+-hashtab *schur_lc_mult(hashtab *lc1, hashtab *lc2, int maxrows);
+-
+-list *quantum_reduce(hashtab* s, int rows, int cols);
+-void fusion_reduce(hashtab *lc, int rows, int cols, int opt_zero);
+-
+-
+-typedef struct {
+-  vector *outer;
+-  vector *inner;
+-  vector *conts;
+-  int maxrows;
+-  vector *conjugate;
+-  int rows;
+-  int cols;
+-  int matrix[1];
+-} skewtab;
+-
+-skewtab *st_new(vector *outer, vector *inner, vector *conts, int maxrows);
+-int st_next(skewtab *st);
+-void st_print(skewtab *st);
+-void st_free(skewtab *st);
+-
+-#endif
+--- /dev/null
++++ b/symfcn/maple.c
+@@ -0,0 +1,86 @@
++/*  Littlewood-Richardson Calculator
++ *  Copyright (C) 1999- Anders S. Buch (asbuch at math rutgers edu)
++ *  See the file LICENSE for license information.
++ */
++
++#include <stdio.h>
++#include <vector.h>
++#include <hashtab.h>
++#include "maple.h"
++
++#define OUTPUT_WIDTH 60
++
++int _intlen(int x)
++{
++  int res = 1;
++  if (x < 0) { x = -x; res++; }
++  if (x >= 10) res++;
++  if (x >= 100) res++;
++  if (x >= 1000) res++;
++  if (x >= 10000) res++;
++  if (x >= 100000) res++;
++  return res;
++}
++
++int maple_print_term(int c, vector *v, char *letter)
++{
++  int x, i;
++#ifdef MULTLINE
++  int cols;
++#endif
++  
++  putchar((c < 0) ? '-' : '+');
++  c = abs(c);
++  printf("%d*%s[", c, letter);
++#ifdef MULTLINE
++  cols = _intlen(c) + strlen(letter) + 3 + v_length(v);
++#endif
++  
++  for (i = 0; i < v_length(v); i++)
++    {
++      if (i > 0)
++	putchar(',');
++      x = v_elem(v, i);
++      printf("%d", x);
++#ifdef MULTLINE
++      cols += _intlen(x);
++#endif
++    }
++  putchar(']');
++#ifdef MULTLINE
++  return cols;
++#else
++  return 0;
++#endif
++}
++
++void maple_print_lincomb(hashtab *ht, char *letter, int nl)
++{
++  hash_itr itr;
++  int column;
++  
++#ifdef MULTILINE
++  putchar('(');
++#endif
++  column = 1;
++  for (hash_first(ht, itr); hash_good(itr); hash_next(itr))
++    {
++      if (hash_intvalue(itr) == 0)
++	continue;
++      
++      column += maple_print_term(hash_intvalue(itr), hash_key(itr),letter);
++#ifdef MULTILINE
++      if (column >= OUTPUT_WIDTH)
++	{
++	  putchar('\n');
++	  column = 0;
++	}
++#endif
++    }
++#ifdef MULTILINE
++  printf(");\n");
++#else
++  if (nl)
++    putchar('\n');
++#endif
++}
+--- /dev/null
++++ b/symfcn/maple.h
+@@ -0,0 +1,6 @@
++#ifndef _MAPLE_H
++#define _MAPLE_H
++
++void maple_print_lincomb(hashtab *ht, char *letter, int nl);
++
++#endif
+--- /dev/null
++++ b/symfcn/symfcn.c
+@@ -0,0 +1,873 @@
++/*  Littlewood-Richardson Calculator
++ *  Copyright (C) 1999- Anders S. Buch (asbuch at math rutgers edu)
++ *  See the file LICENSE for license information.
++ */
++
++#include <stdio.h>
++
++#include <alloc.h>
++#include <vector.h>
++#include <hashtab.h>
++
++#include "symfcn.h"
++
++
++int part_itr_sz(vector *part)
++{
++  int i, e, tot;
++
++  i = v_length(part) - 1;
++  while (i >= 0 && v_elem(part, i) == 1)
++    i--;
++  
++  if (i < 0)
++    return 0;
++  
++  e = v_elem(part, i);
++  tot = e + v_length(part) - i - 1;
++  
++  while (tot >= e-1)
++    {
++      v_elem(part, i++) = e-1;
++      tot -= e-1;
++    }
++  if (tot > 0)
++    v_elem(part, i++) = tot;
++  v_length(part) = i;
++  
++  return 1;
++}
++
++int part_itr_sub(vector *part, vector *outer)
++{
++  int i, e;
++
++  i = v_length(part) - 1;
++  while (i >= 0 && v_elem(part, i) == 0)
++    i--;
++  if (i < 0)
++    return 0;
++  
++  e = v_elem(part, i) - 1;
++  if (e == 0)
++    {
++      v_length(part) = i;
++      return 1;
++    }
++  
++  while (i < v_length(outer))
++    {
++      int x = v_elem(outer, i);
++      v_elem(part, i) = (e < x) ? e : x;
++      i++;
++    }
++  v_length(part) = v_length(outer);
++  
++  return 1;
++}
++
++int part_itr_between(vector *part, vector *inner, vector *outer)
++{
++  int i, e;
++  
++  i = v_length(part) - 1;
++  while (i >= 0 && v_elem(part, i) == v_elem(inner, i))
++    i--;
++  if (i < 0)
++    return 0;
++  
++  e = v_elem(part, i) - 1;
++  if (e == 0)
++    {
++      v_length(part) = i;
++      return 1;
++    }
++  
++  while (i < v_length(outer))
++    {
++      int x = v_elem(outer, i);
++      v_elem(part, i) = (e < x) ? e : x;
++      i++;
++    }
++  v_length(part) = v_length(outer);
++  
++  return 1;
++}
++
++int part_length(vector *p)
++{
++  int n = v_length(p);
++  while (n > 0 && v_elem(p, n-1) == 0)
++    n--;
++  return n;
++}
++
++vector *part_conjugate(vector *p)
++{
++  int np, nc, j;
++  vector *conj;
++  
++  np = v_length(p);
++  if (np == 0)
++    return v_new(0);
++  
++  nc = v_elem(p, 0);
++  if (nc == 0)
++    return v_new(0);
++  
++  conj = v_new(nc);
++  j = 0;
++  while (np > 0)
++    {
++      int jlim = v_elem(p, np - 1);
++      while (j < jlim)
++	v_elem(conj, j++) = np;
++      np--;
++    }
++  
++  return conj;
++}
++
++int part_subset(vector *p1, vector *p2)
++{
++  int n;
++  
++  n = part_length(p1);
++  if (n > v_length(p2))
++    return 0;
++  
++  for (n--; n >= 0; n--)
++    if (v_elem(p1, n) > v_elem(p2, n))
++      return 0;
++  
++  return 1;
++}
++
++
++void _chop_cols(vector *in1, vector *out)
++{
++  int n, m, mm, i;
++  
++  n = v_length(in1);
++  m = v_elem(in1, n - 1);
++  mm = v_elem(out, n - 1);
++  if (m > mm)
++    m = mm;
++  
++  for (i = 0; i < n; i++)
++    {
++      v_elem(in1, i) -= m;
++      v_elem(out, i) -= m;
++    }
++  
++  v_length(in1) = part_length(in1);
++  v_length(out) = part_length(out);
++}
++
++void _chop_rows(vector *in1, vector *out)
++{
++  int m, i;
++  
++  m = 1;
++  while (m < v_length(in1) && v_elem(in1, m) == v_elem(out, m))
++    m++;
++  
++  for (i = 0; i < v_length(in1) - m; i++)
++    v_elem(in1, i) = v_elem(in1, i + m);
++  v_length(in1) -= m;
++  
++  for (i = 0; i < v_length(out) - m; i++)
++    v_elem(out, i) = v_elem(out, i + m);
++  v_length(out) -= m;
++}
++
++
++long long lrcoef(vector *outer, vector *inner1, vector *inner2)
++{
++  vector *out, *in1, *in2, *out_conj, *cont, *vtmp;
++  int w_out, w_in1, w_in2, do_swap;
++  int rows, cols, i, j, stack_sz, sp, x;
++  int *skewtab, *itab, *jtab, *max_tab;
++  long long res;
++  
++  out = v_new_copy(outer);
++  in1 = v_new_copy(inner1);
++  in2 = v_new_copy(inner2);
++  
++  v_length(out) = part_length(out);
++  v_length(in1) = part_length(in1);
++  v_length(in2) = part_length(in2);
++  
++  while (v_length(out) > 0 &&
++	 v_length(out) >= v_length(in1) &&
++	 v_length(out) >= v_length(in2))
++    {
++      if (v_length(in1) == v_length(out))
++	{
++	  _chop_cols(in1, out);
++	}
++      else if (v_length(in2) == v_length(out))
++	{
++	  _chop_cols(in2, out);
++	}
++      else if (v_length(in1) > 0 && 
++	       v_elem(in1, 0) == v_elem(out, 0))
++	{
++	  _chop_rows(in1, out);
++	}
++      else if (v_length(in2) > 0 && 
++	       v_elem(in2, 0) == v_elem(out, 0))
++	{
++	  _chop_rows(in2, out);
++	}
++      else
++	break;
++    }
++  
++  w_in1 = v_sum(in1);
++  w_in2 = v_sum(in2);
++  w_out = v_sum(out);
++  
++  if ((! part_subset(in1, out)) || 
++      (! part_subset(in2, out)) ||
++      (w_out != w_in1 + w_in2))
++    {
++      v_free(in1);
++      v_free(in2);
++      v_free(out);
++      return 0;
++    }
++  
++  if (w_in1 <= 1 || w_in2 <= 1)
++    {
++      v_free(in1);
++      v_free(in2);
++      v_free(out);
++      return 1;
++    }
++  
++  out_conj = part_conjugate(out);
++  
++  do_swap = (w_in1 < w_in2);
++  
++  if (w_in1 == w_in2)
++    {
++      int c1 = v_elem(in1, 0);
++      int r1 = v_length(in1);
++      int n1 = (c1 < r1) ? c1 : r1;
++      
++      int c2 = v_elem(in2, 0);
++      int r2 = v_length(in2);
++      int n2 = (c2 < r2) ? c2 : r2;
++      
++      do_swap = (n1 < n2);
++    }
++  
++  if (do_swap)
++    {
++      int tmp;
++      
++      tmp = w_in1;
++      w_in1 = w_in2;
++      w_in2 = tmp;
++      
++      vtmp = in1;
++      in1 = in2;
++      in2 = vtmp;
++    }
++  
++  if (v_length(in2) > v_elem(in2, 0))
++    {
++      vtmp = out;
++      out = out_conj;
++      out_conj = vtmp;
++      
++      vtmp = part_conjugate(in1);
++      v_free(in1);
++      in1 = vtmp;
++      
++      vtmp = part_conjugate(in2);
++      v_free(in2);
++      in2 = vtmp;
++    }
++  
++  rows = v_length(out);
++  cols = v_elem(out, 0);
++  
++  vtmp = v_new(rows);
++  for (i = 0; i < v_length(in1); i++)
++    v_elem(vtmp, i) = v_elem(in1, i);
++  for ( ; i < rows; i++)
++    v_elem(vtmp, i) = 0;
++  v_free(in1);
++  in1 = vtmp;
++  
++  cont = v_new_zero(v_length(in2));
++  
++  stack_sz = w_out - w_in1;
++  skewtab = amalloc(stack_sz * sizeof(int));
++  max_tab = amalloc(stack_sz * sizeof(int));
++  
++  itab = amalloc(stack_sz * sizeof(int));
++  jtab = amalloc(stack_sz * sizeof(int));
++  sp = 0;
++  for (i = 0; i < v_length(out); i++)
++    {
++      int left = (i < v_length(in1)) ? v_elem(in1, i) : 0;
++      for (j = v_elem(out, i) - 1; j >= left; j--)
++        {
++	  itab[sp] = i;
++	  jtab[sp] = j;
++	  sp++;
++	}
++    }
++  
++  res = 0;
++  
++  skewtab[0] = 0;
++  v_elem(cont, 0) = 1;
++  
++  sp = 1;
++  i = itab[1];
++  j = jtab[1];
++  max_tab[1] = (i == itab[0]) ? 0 : 
++    v_length(in2) + i - v_elem(out_conj, j);;
++  x = (j == jtab[0]) ? 1 : 0;
++  
++  while (sp > 0)
++    {
++      /* in each loop, do one of the following:
++       *
++       *   a) incr x
++       *
++       *   b) put x; incr sp; get x;
++       *
++       *   c) decr sp; get x; incr x;
++       *
++       * where:  put/get involves updating cont and skewtab and
++       *
++       *         incr sp includes setting max_tab[sp].
++       */
++      
++      if (x > max_tab[sp])
++	{
++	  sp--;
++	  
++	  x = skewtab[sp];
++	  v_elem(cont, x)--;
++	  
++	  x++;
++	  continue;
++	}
++      
++      if (v_elem(cont, x) == v_elem(in2, x) ||
++	  (x > 0 && v_elem(cont, x) >= v_elem(cont, x-1)))
++	{
++	  x++;
++	  continue;
++	}
++      
++      if (sp + 1 == stack_sz)
++	{
++	  /* special case: incr res; then same as c) */
++	  res++;
++	  
++	  sp--;
++	  
++	  x = skewtab[sp];
++	  v_elem(cont, x)--;
++	  
++	  x++;
++	  continue;
++	}
++      
++      skewtab[sp] = x;
++      v_elem(cont, x)++;
++      
++      sp++;
++      i = itab[sp];
++      j = jtab[sp];
++      
++      if (j < v_elem(out, i) - 1)
++	max_tab[sp] = skewtab[sp - 1];
++      else
++	max_tab[sp] = v_length(in2) + i - v_elem(out_conj, j);
++      
++      x = 0;
++      if (i > 0 && j >= v_elem(in1, i-1))
++	x = skewtab[sp + v_elem(in1, i-1) - v_elem(out, i)] + 1;
++    }
++  
++  afree(skewtab);
++  afree(max_tab);
++  afree(itab);
++  afree(jtab);
++
++  v_free(in1);
++  v_free(in2);
++  v_free(out);
++  v_free(out_conj);
++  v_free(cont);
++  
++  return res;
++}
++
++
++void st_setmin(skewtab *st, int y, int x)
++{
++  while (y < st->rows)
++    {
++      while (x >= v_elem(st->inner, y))
++	{
++	  int e;
++	  if (y == 0 || x < v_elem(st->inner, y-1))
++	    e = 0;
++	  else
++	    e = st->matrix[x + (y-1) * st->cols] + 1;
++
++	  st->matrix[x + y * st->cols] = e;
++
++	  v_elem(st->conts, e)++;
++
++	  x--;
++	}
++      y++;
++
++      if (y < st->rows)
++	x = v_elem(st->outer, y) - 1;
++    }
++}
++
++
++skewtab *st_new(vector *outer, vector *inner, vector *conts, int maxrows)
++{
++  int rows, cols, clen;
++  skewtab *st;
++
++  rows = v_length(outer);
++  cols = (rows == 0) ? 0 : v_elem(outer, 0);
++
++  st = amalloc(sizeof(skewtab) + sizeof(int) * (rows * cols - 1));
++  st->outer = outer;
++  st->inner = inner;
++  
++  clen = (conts != NULL) ? v_length(conts) : 0;
++  clen += rows;
++  st->conts = v_new_zero(clen);
++  if (conts != NULL)
++    {
++      int i;
++      for (i = 0; i < v_length(conts); i++)
++	v_elem(st->conts, i) = v_elem(conts, i);
++    }
++  
++  st->rows = rows;
++  st->cols = cols;
++  
++  st_setmin(st, 0, v_elem(outer, 0) - 1);
++  
++  st->conjugate = NULL;
++  if (maxrows >= clen)
++    maxrows = 0;
++  st->maxrows = maxrows;
++  
++  if (maxrows == 0)
++    return st;
++  
++  if (v_elem(st->conts, maxrows) != 0)
++    {
++      st_free(st);
++      return NULL;
++    }
++  
++  st->conjugate = part_conjugate(outer);
++  
++  return st;
++}
++
++int st_next(skewtab *st)
++{
++  int x, y, e;
++
++  for (y = st->rows - 1; y >= 0; y--)
++    {
++      int xlim = v_elem(st->outer, y);
++
++      for (x = v_elem(st->inner, y); x < xlim; x++)
++	{
++	  int elim = (st->maxrows == 0)
++	    ? v_length(st->conts) - 1
++	    : st->maxrows + y - v_elem(st->conjugate, x);
++	  
++	  if (x != xlim - 1)
++	    {
++	      int next_cell = st->matrix[x+1 + y * st->cols];
++	      if (next_cell < elim)
++		elim = next_cell;
++	    }
++	  
++	  e = st->matrix[x + y * st->cols];
++	  v_elem(st->conts, e)--;
++
++	  e++;
++	  while (e <= elim &&
++		 v_elem(st->conts, e) == v_elem(st->conts, e-1))
++	    e++;
++
++	  if (e <= elim)
++	    {
++	      st->matrix[x + y * st->cols] = e;
++	      v_elem(st->conts, e)++;
++	      st_setmin(st, y, x-1);
++	      return 1;
++	    }
++	}
++    }
++
++  return 0;
++}
++
++void st_print(skewtab *st)
++{
++  int x, y;
++  
++  vector *inner = st->inner;
++  vector *outer = st->outer;
++  
++  for (y = 0; y < v_length(outer); y++)
++    {
++      for (x = 0; x < v_elem(outer, y); x++)
++	{
++	  if (x < v_elem(inner, y))
++	    putchar(' ');
++	  else
++	    printf("%d", st->matrix[x + y * st->cols]);
++	}
++      putchar('\n');
++    }
++}
++
++void st_free(skewtab *st)
++{
++  v_free(st->inner);
++  v_free(st->outer);
++  v_free(st->conts);
++  if (st->conjugate != NULL)
++    v_free(st->conjugate);
++  afree(st);
++}
++
++
++hashtab *skew(vector *outer, vector *inner, int maxrows)
++{
++  vector *out0, *in0;
++  hashtab *res;
++  vector *part;
++  skewtab *st;
++  int n, i;
++  
++  res = hash_new((cmp_t) v_cmp, (hash_t) v_hash);
++  
++  n = v_length(outer);
++  if (v_length(inner) > n)
++    return res;
++  
++  out0 = v_new_copy(outer);
++  
++  in0 = v_new_zero(n);
++  for (i = 0; i < v_length(inner); i++)
++    v_elem(in0, i) = v_elem(inner, i);
++  
++  if (! v_lesseq(in0, out0))
++    {
++      v_free(in0);
++      v_free(out0);
++      return res;
++    }
++  
++  st = st_new(out0, in0, NULL, maxrows);
++  
++  part = v_new(n);
++  
++  do {
++    int i, *valuep;
++    
++    for (i = 0; i < v_length(st->conts) && v_elem(st->conts, i) != 0; i++)
++      v_elem(part, i) = v_elem(st->conts, i);
++    v_length(part) = i;
++    
++    valuep = hash_mkfindint(res, part);
++    if (hash_key_used)
++      part = v_new(n);
++    (*valuep)++;
++  } while (st_next(st));
++  
++  st_free(st);
++  v_free(part);
++  
++  return res;
++}
++
++
++hashtab *mult(vector *sh1, vector *sh2, int maxrows)
++{
++  skewtab *st;
++  vector *part, *out0, *in0;
++  hashtab *res;
++  int n;
++  
++  res = hash_new((cmp_t) v_cmp, (hash_t) v_hash);
++  
++  if (v_sum(sh1) > v_sum(sh2))
++    {
++      vector *tmp = sh1;
++      sh1 = sh2;
++      sh2 = tmp;
++    }
++  
++  out0 = v_new_copy(sh1);
++  in0 = v_new_zero(v_length(sh1));
++  st = st_new(out0, in0, sh2, maxrows);
++  if (st == NULL)
++    return res;
++  
++  n = v_length(sh1) + v_length(sh2);
++  part = v_new(n);
++  
++  do {
++    int i, *valuep;
++    
++    for (i = 0; i < v_length(st->conts) && v_elem(st->conts, i) != 0; i++)
++      v_elem(part, i) = v_elem(st->conts, i);
++    v_length(part) = i;
++    
++    valuep = hash_mkfindint(res, part);
++    if (hash_key_used)
++      part = v_new(n);
++    (*valuep)++;
++    
++  } while (st_next(st));
++  
++  st_free(st);
++  v_free(part);
++  
++  return res;
++}
++
++
++hashtab *schur_lc_mult(hashtab *lc1, hashtab *lc2, int maxrows)
++{
++  hash_itr itr1, itr2, itr;
++  hashtab *pairs = hash_new((cmp_t) vp_cmp, (hash_t) vp_hash);
++  hashtab *res;
++  
++  for (hash_first(lc1, itr1); hash_good(itr1); hash_next(itr1))
++    {
++      vector *v1 = hash_key(itr1);
++      int c1 = hash_intvalue(itr1);
++      
++      for (hash_first(lc2, itr2); hash_good(itr2); hash_next(itr2))
++	{
++	  vector *v2 = hash_key(itr2);
++	  int c2 = hash_intvalue(itr2);
++	  
++	  vecpair *vp = vp_new_unordered(v_new_copy(v1), v_new_copy(v2));
++	  int *valp = hash_mkfind(pairs, vp);
++	  *((int *) valp) += c1 * c2;
++	  if (! hash_key_used)
++	    vp_free(vp);
++	}
++    }
++  
++  res = hash_new((cmp_t) v_cmp, (hash_t) v_hash);
++  
++  for (hash_first(pairs, itr); hash_good(itr); hash_next(itr))
++    {
++      vecpair *vp = hash_key(itr);
++      int c = hash_intvalue(itr);
++      hashtab *prd;
++      
++      prd = mult(vp_first(vp), vp_second(vp), maxrows);
++      lincomb_add_multiple(res, c, prd, (freekey_t) v_free1, NULL);
++      hash_free(prd);  /* lincomb_add_multiple has frees the vectors */
++    }
++  
++  free_vp_lincomb(pairs);
++  
++  return res;
++}
++
++
++hashtab *coprod(vector *part, int all)
++{
++  hashtab *res = hash_new((cmp_t) vp_cmp, (hash_t) vp_hash);
++  int df, in_wt, wt = v_sum(part);
++  vecpair *vp;
++  vector *in = v_new_copy(part);
++  
++  do {
++    in_wt = v_sum(in);
++    
++    if (2 * in_wt >= wt)
++      {
++	hashtab *sk = skew(part, in, 0);
++	hash_itr itr;
++	
++	for (hash_first(sk, itr); hash_good(itr); hash_next(itr))
++	  {
++	    vector *in2 = hash_key(itr);
++	    int coef = hash_intvalue(itr);
++	    
++	    df = 1;
++	    if (2 * in_wt == wt && (df = v_cmp(in, in2)) < 0)
++	      {
++		v_free(in2);
++		continue;
++	      }
++	    
++	    vp = vp_new(v_new_copy(in), in2);
++	    hash_insertint(res, vp, coef);
++	    
++	    if (all && df != 0)
++	      {
++		vp = vp_new(v_new_copy(in2), v_new_copy(in));
++		hash_insertint(res, vp, coef);
++	      }
++	  }
++	
++	hash_free(sk);
++      }
++  } while (part_itr_sub(in, part));
++  v_free(in);
++  
++  return res;
++}
++
++
++int rim_hook(vector *lambda, int rows, int cols, int *qp)
++{
++  int i, j, len, sign, q, n;
++  
++  len = v_length(lambda);
++  n = rows + cols;
++
++  q = 0;
++  for (i = 0; i < len; i++)
++    {
++      int a = v_elem(lambda, i) + rows - i - 1;
++      q += a / n;
++      a %= n;
++      v_elem(lambda, i) = a - rows + 1;
++    }
++
++  /* bubble sort :-( */
++  sign = (rows & 1) ? 0 : q;
++  for (i = 1; i < len; i++)
++    {
++      int a = v_elem(lambda, i);
++      for (j = i; j > 0 && a > v_elem(lambda, j-1); j--)
++	{
++	  v_elem(lambda, j) = v_elem(lambda, j-1);
++	}
++      if (j > 0 && a == v_elem(lambda, j-1))
++	return 0;
++      v_elem(lambda, j) = a;
++      sign += i - j;
++    }
++  
++  for (i = 0; i < len; i++)
++    {
++      v_elem(lambda, i) += i;
++      if (v_elem(lambda, i) < 0)
++	return 0;
++    }
++  
++  while (len > 0 && v_elem(lambda, len - 1) == 0)
++    len--;
++  v_length(lambda) = len;
++  *qp = q;
++  return (sign & 1) ? -1 : 1;
++}
++
++list *_quantum_reduce(hashtab* s, int rows, int cols)
++{
++  int sign, q, *valuep;
++  list *qlist;
++  hash_itr itr;
++  
++  qlist = l_newsz(10);
++  
++  for (hash_first(s, itr); hash_good(itr); hash_next(itr))
++    {
++      vector *lambda = hash_key(itr);
++      int coef = hash_intvalue(itr);
++      hashtab *tab;
++      
++      sign = rim_hook(lambda, rows, cols, &q);
++      
++      if (sign == 0)
++	{
++	  v_free(lambda);
++	  continue;
++	}
++      
++      while (q >= l_length(qlist))
++	l_append(qlist, hash_new((cmp_t) v_cmp, (hash_t) v_hash));
++      
++      tab = l_elem(qlist, q);
++      valuep = hash_mkfindint(tab, lambda);
++      *valuep += sign * coef;
++      if (! hash_key_used)
++	v_free(lambda);
++    }
++  
++  return qlist;
++}
++
++list *quantum_reduce(hashtab* s, int rows, int cols)
++{
++  list *qlist = _quantum_reduce(s, rows, cols);
++  hash_free(s);
++  return qlist;
++}
++
++void fusion_reduce(hashtab *lc, int rows, int cols, int opt_zero)
++{
++  int i, j, k, n, lamj;
++  list *qlist = _quantum_reduce(lc, rows, cols);
++  if (l_length(qlist) == 0)
++    {
++      hash_reset(lc);
++      return;
++    }
++  hash_copy(lc, l_elem(qlist, 0));
++  hash_free(l_elem(qlist, 0));
++  n = rows + cols;
++  for (i = 1; i < l_length(qlist); i++)
++    {
++      hashtab *tab = l_elem(qlist, i);
++      hash_itr itr;
++      
++      for (hash_first(tab, itr); hash_good(itr); hash_next(itr))
++	{
++	  vector *lambda = hash_key(itr);
++	  vector *mu;
++	  
++	  if (hash_intvalue(itr) == 0 && opt_zero == 0)
++	    continue;
++	  
++	  mu = v_new(rows);
++	  for (j = 0; j < rows; j++)
++	    {
++	      lamj = (j < v_length(lambda)) ? v_elem(lambda,j) : 0;
++	      k = (j + i) % rows;
++              v_elem(mu,k) = lamj + ((i+j) / rows) * cols + i;
++	    }
++	  hash_insertint(lc, mu, hash_intvalue(itr));
++	}
++      
++      free_vec_lincomb(tab);
++    }
++  l_free(qlist);
++}
++
+--- /dev/null
++++ b/symfcn/symfcn.h
+@@ -0,0 +1,43 @@
++#ifndef _SYMFCN_H
++#define _SYMFCN_H
++
++#include <hashtab.h>
++#include <vector.h>
++
++int part_itr_sz(vector *part);
++int part_itr_sub(vector *part, vector *outer);
++int part_itr_between(vector *part, vector *inner, vector *outer);
++
++int part_length(vector *p);
++vector *part_conjugate(vector *p);
++int part_subset(vector *p1, vector *p2);
++
++long long lrcoef(vector *outer, vector *inner1, vector *inner2);
++
++hashtab *skew(vector *outer, vector *inner, int maxrows);
++hashtab *mult(vector *sh1, vector *sh2, int maxrows);
++hashtab *coprod(vector *part, int all);
++
++hashtab *schur_lc_mult(hashtab *lc1, hashtab *lc2, int maxrows);
++
++list *quantum_reduce(hashtab* s, int rows, int cols);
++void fusion_reduce(hashtab *lc, int rows, int cols, int opt_zero);
++
++
++typedef struct {
++  vector *outer;
++  vector *inner;
++  vector *conts;
++  int maxrows;
++  vector *conjugate;
++  int rows;
++  int cols;
++  int matrix[1];
++} skewtab;
++
++skewtab *st_new(vector *outer, vector *inner, vector *conts, int maxrows);
++int st_next(skewtab *st);
++void st_print(skewtab *st);
++void st_free(skewtab *st);
++
++#endif
+--- /dev/null
++++ b/symfcn/Makefile.am
+@@ -0,0 +1,4 @@
++AM_CFLAGS = -I .. -I ../mathlib
++
++noinst_LTLIBRARIES = libsymfcn.la
++libsymfcn_la_SOURCES = symfcn.c maple.c
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,12 +1,12 @@
+ ACLOCAL_AMFLAGS=-I m4
+-SUBDIRS=mathlib lrcoef schubert
++SUBDIRS=mathlib symfcn schubert . lrcoef
+ 
+ lib_LTLIBRARIES = liblrcalc.la
+ liblrcalc_la_SOURCES =
+ liblrcalc_la_LDFLAGS = $(LIBLRCALC_LDFLAGS) -version-info 0:0:0
+-liblrcalc_la_LIBADD = mathlib/libmath.la lrcoef/libsymfcn.la schubert/libschub.la
++liblrcalc_la_LIBADD = mathlib/libmath.la symfcn/libsymfcn.la schubert/libschub.la
+ 
+ lrcalcincludedir = $(includedir)/lrcalc
+-lrcalcinclude_HEADERS=mathlib/*.h lrcoef/*.h schubert/*.h
++lrcalcinclude_HEADERS=mathlib/*.h schubert/*.h symfcn/*.h
+ 
+ TESTS=testsuite
+--- a/configure.ac
++++ b/configure.ac
+@@ -2,7 +2,7 @@
+ 
+ AC_PREREQ([2.67])
+ AC_INIT([lrcalc],[1.1.6],[asbuch at math rutgers edu])
+-AC_CONFIG_SRCDIR(lrcoef/symfcn.h)
++AC_CONFIG_SRCDIR(symfcn/symfcn.h)
+ AC_CONFIG_HEADERS([config.h])
+ 
+ AC_CONFIG_MACRO_DIR([m4])
+@@ -51,5 +51,6 @@
+ AC_CONFIG_FILES([Makefile
+                  lrcoef/Makefile
+                  mathlib/Makefile
+-                 schubert/Makefile])
++                 schubert/Makefile
++                 symfcn/Makefile])
+ AC_OUTPUT
+--- a/schubert/Makefile.am
++++ b/schubert/Makefile.am
+@@ -1,8 +1,8 @@
+-AM_CFLAGS = -I .. -I ../mathlib -I ../lrcoef
++AM_CFLAGS = -I .. -I ../mathlib -I ../symfcn
+ 
+ bin_PROGRAMS = schubmult
+ 
+ noinst_LTLIBRARIES = libschub.la
+ libschub_la_SOURCES = schublib.c lincomb.c
+ 
+-schubmult_LDADD = ../mathlib/libmath.la ../lrcoef/libsymfcn.la libschub.la
++schubmult_LDADD = ../mathlib/libmath.la ../symfcn/libsymfcn.la libschub.la
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..2ab0d43
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+programs-use-shared-libraries.patch

-- 
Packaging for lrcalc



More information about the debian-science-commits mailing list