I like to demonstrate a few tricks with Maxima and EMT. Assume you want to generate the Vandermonde matrix, and check the identity
\(\det \begin{pmatrix} 1 & x_0 & \ldots & x_0^n \\ \vdots & \vdots & & \vdots \\ 1 & x_n & \ldots & x_n^n \end{pmatrix} = \prod\limits_{0 \le i<j \le n} (x_j-x_i)\)
You can generate this matrix easily in EMT for specific values.
>n=3; v=0:3; V=v'^(0:3) 1 0 0 0 1 1 1 1 1 2 4 8 1 3 9 27 >det(V) 12
It is a bit more difficult to check the right hand side of the equation. Of course, you can simply write a function
>function vprod (v:vector) ... $p=1; n=length(v); $for i=1 to n; $ for j=i+1 to n; $ p=p*(v[j]-v[i]); $ end; $end; $return p; $endfunction >vprod(v) 12
It is also possible with Matrix tricks. We generate all differences in a matrix, square the matrix, set the diagonal to 1, take the total product of all matrix elements and take the 4-th root.
>(prod(prod(setdiag((v-v')^2,0,1))'))^(1/4) 12
But that is not the general case with variables. To generate this we use purely symbolic functions in EMT. These functions evaluate in Maxima at the time when they are used, not when they are defined.
>function mrow (k,v,n) &&= create_list(v[k]^m,m,0,n) m create_list(v , m, 0, n) k >function Vand (v,n) &&= apply(matrix,create_list(mrow(k,v,n),k,0,n)) apply(matrix, create_list(mrow(k, v, n), k, 0, n)) >&Vand(v,2) [ 2 ] [ 1 v v ] [ 0 0 ] [ ] [ 2 ] [ 1 v v ] [ 1 1 ] [ ] [ 2 ] [ 1 v v ] [ 2 2 ]
This is almost self explaining, once you know that „matrix(a,b,c)“ generates a matrix in Maxima with rows „a,b,c“. The creation takes place for the specific symbolic v when „Vand(v,2)“ is called.
Maxima prints the result with indices. But it is a string of the following form.
>V &= Vand(v,2); >""+V matrix([1,v[0],v[0]^2],[1,v[1],v[1]^2],[1,v[2],v[2]^2])
Since EMT vectors start with index 1 by default, we can only evaluate this expression for zero based vectors (unless we modify the functions above a little bit).
>v=0:2; zerobase v; >V() 1 0 0 1 1 1 1 2 4
Maxima can factor the determinant of any Vandermonde determinant of specific size.
>&factor(determinant(Vand(v,3))) (v - v ) (v - v ) (v - v ) (v - v ) (v - v ) (v - v ) 1 0 2 0 2 1 3 0 3 1 3 2
This is in accordance with the theory. Let me try the following matrix.
\(\begin{pmatrix} (x_0-x_0)^n & \ldots & (x_0-x_n)^n \\ \vdots & & \vdots \\ (x_n-x_0)^n & \ldots & (x_n-x_n)^n \end{pmatrix}\)
>function mrow (k,v,n) &&= create_list((v[k]-v[m])^n,m,0,n) n create_list((v - v ) , m, 0, n) k m >function Vand (v,n) &&= apply(matrix,create_list(mrow(k,v,n),k,0,n)) apply(matrix, create_list(mrow(k, v, n), k, 0, n)) >&Vand(v,2) [ 2 2 ] [ 0 (v - v ) (v - v ) ] [ 0 1 0 2 ] [ ] [ 2 2 ] [ (v - v ) 0 (v - v ) ] [ 1 0 1 2 ] [ ] [ 2 2 ] [ (v - v ) (v - v ) 0 ] [ 2 0 2 1 ]
I am not sure if you are aware of the following formula.
>&factor(determinant(Vand(v,3))) 2 2 2 2 2 9 (v - v ) (v - v ) (v - v ) (v - v ) (v - v ) 1 0 2 0 2 1 3 0 3 1 2 (v - v ) 3 2
The factor 9 is interesting. For n=4, it is 96, and for n=5, it is 2500. Do you guesswork. The factorization of the case n=4 takes some seconds. I did not try higher degrees.
Of course, it is easy to compute this numerically, even for very large matrices.
>function d1(v) := det((v'-v)^(cols(v)-1)) >d1(0:10) 1.43679021499e+072