3

I think this little program:

(defn average [lst] (/ (reduce + lst) (count lst)))
(defn sqsum [lst] (reduce + (map #(* % %) lst)))


(defn tet [row col]
  (cond (= [row col] [0 0]) 0
        (= [row col] [1 0]) 1
        (< row (inc col)) 0
        (> row (inc col)) (average (for [i (range row)] (tet i col)))
        (= row (inc col)) (Math/sqrt (- 1 (sqsum (for [i (range col)] (tet row i)))))))

gives me the coordinates of the vertices of generalised tetrahedra / euclidean simplices in various dimensions.

Unfortunately clojure will express things like sqrt(3/4) in floating point, whereas I'd like the answers in symbolic form.

Maxima would be ideal for this sort of thing, but I don't know how to express this relation in maxima.

Alternatively, solutions involving adding symbolic square roots to clojure would also be nice.

Charles
  • 50,943
  • 13
  • 104
  • 142
John Lawrence Aspden
  • 17,124
  • 11
  • 67
  • 110

3 Answers3

2

In Maxima, a memoizing function is defined by f[x, y] := ..., that is, with square brackets instead of parentheses for the arguments.

From what I can tell, this is a translation of the Clojure function:

average (lst) := apply ("+", lst) / length (lst);
sqsum (lst) := apply ("+", map (lambda ([x], x^2), lst));

tet [row, col] :=
  if row < col + 1 then 0
  else if row > col + 1 then average (makelist (tet [i, col], i, 0, row - 1))
  else if row = col + 1 then sqrt (1 - sqsum (makelist (tet [row, i], i, 0, col - 1)));

tet [0, 0] : 0;
tet [1, 0] : 1;

E.g.:

radcan (tet[4, 3]);
 => sqrt(5)/2^(3/2)

radcan (tet[7, 6]);
 => 2/sqrt(7)

First one agrees with a[4, 3] above. Dunno about the second.

Robert Dodier
  • 16,905
  • 2
  • 31
  • 48
1

This does the business

a[0,0]:0;
a[1,0]:1;

for row:2 while row<=15 do (
    (col:(row-1)),
    for r:0 while r<=col do (a[r,col]:0),
    for c:0 while c<col do (a[row,c]:(sum(a[i,c],i,0,row-1))/row),
    a[row,col]:radcan(sqrt(1-sum(a[row,c]^2,c,0,col-1))),
    disp(a[row,col]^2));

But is there anyway to express it as the original recursion and memoize it so it runs in finite time?

John Lawrence Aspden
  • 17,124
  • 11
  • 67
  • 110
0

I've done the first few 'by hand' in maxima, like this, if anyone needs inspiration. (This is the 2d iteration which is equivalent to the above recursion (once memoized))

So I guess my question now could be 'how do I express this as a for loop in maxima'

one-simplex

a[0,0]:0;

a[1,0]:1;

two-simplex (equilateral triangle)

a[0,1]:0;

a[1,1]:0;

a[2,0]:(a[0,0]+a[1,0])/2;

a[2,1]:sqrt(1-a[2,0]^2);

three-simplex (tetrahedron)

a[0,2]:0;

a[1,2]:0;

a[2,2]:0;

a[3,0]:(a[0,0]+a[1,0]+a[2,0])/3;

a[3,1]:(a[0,1]+a[1,1]+a[2,1])/3;

a[3,2]:sqrt(1-a[3,0]^2-a[3,1]^2);

four-simplex (tetrahedron)

col:3;

a[0,col]:0;

a[1,col]:0;

a[2,col]:0;

a[3,col]:0;

col:0;

a[4,col]:(a[0,col]+a[1,col]+a[2,col]+a[3,col])/4;

col:1;

a[4,col]:(a[0,col]+a[1,col]+a[2,col]+a[3,col])/4;

col:2;

a[4,col]:(a[0,col]+a[1,col]+a[2,col]+a[3,col])/4;

a[4,3]:sqrt(1-a[4,0]^2-a[4,1]^2-a[4,2]^2);

radcan(%);
John Lawrence Aspden
  • 17,124
  • 11
  • 67
  • 110