Hash tables, anyone?



Hi all,

Is it possible to get a reference to a hash table in maxima?

Specifically, I'm trying to write a function which will re-group an
(expanded) expression of a special form

\sum z_j e^{iwk} x^n

where x^n and e^{iwk} are not unique, to a list or a hash table, where
at the top level would be unique x^n's, and at the next level --
unique e^{iwk} terms, and at the last level -- sums of z_j's:

{
  x^{n_1} => {
    e^{iw_1k} => { z_1 + z_2 + ... + z_s },
    e^{iw_2k} => { u_1 + u_2 + ... + u_t },
    ...
  },
  x^{n_2} => { ... },
  ...
}

My plan is to use hash tables to accumulate and efficiently find x^n's
and corresponding e^{iwk} terms, by simply using expressions as
indexes into undeclared arrays (i.e., hash tables).

The rough code sketch is like this:

merge_parts_by_eiwk(k, expr, B) :=
  /* basic checks skipped */
  block(
    [eiwk, rst], /* split expr somehow into eiwk: e^{iwk}, and rst: the rest */
    /* check if unassigned */
    if subvarp(B[eiwk]) then B[eiwk]: rst
    else B[eiwk]: B[eiwk] + rst,
    B);

parts_by_eiwk(k, expr) := merge_parts_by_ewik(k, expr, B /* [1] */);

merge_parts_by_xn(x, k, expr, A) :=
  if atom(expr) then error("merge_parts_by_xp: atom")
  else if op(expr) = "+" then map(lambda([t], merge_parts_by_xn(x, k,
t, A)), to_list(expr))
  else if op(expr) = "*" then block(
    [xn, rst], /* split expr somehow into xn: x^n, and rst: the rest */
    /* check if unassigned */
    if subvarp(A[xn]) then A[xn]: parts_by_eiwk(k, rst)
    else merge_parts_by_eiwk(k, rst, A[xn]),
    A);

parts_by_xn(x, k, expr) := merge_parts_by_xn(x, k, expr, A /* [2] */);

/* [1,2] a function like makehashtable() would fit greatly here */

This kinda works, but the problem is that global namespace is polluted
by 'A' and 'B' indexes, so when parts_by_eiwk() is called for a second
time, it doesn't work with a clean 'B', but with one used in the first
invokation.

If it would be possible to create a new hash table with some function
every time, it would be really great.

Any pointers?

--
Alex