(*                         Ren-Cang Li, June 1, 1996
                           na.rcli@na-net.ornl.gov    *)

(* Definitions *)
Mm[a___, x_+y_,         b___] :=   Mm[a,x,b]+Mm[a,y,b];
Mm[a___, n_ X[i_],      b___] := n Mm[a,X[i],b];
Mm[a___, n_ y_Mm,       b___] := n Mm[a,y,b];
Mm[a___, n_?NumberQ y_, b___] := n Mm[a,y,b];

SetAttributes[Mm, Flat];
Cmt[x_,y_]:=Mm[x,y]-Mm[y,x];

(* Randomly Choose a1 --- r11 *)
a1=Random[Integer,{-1000,1000}];
a3=Random[Integer,{-1000,1000}];
a5=Random[Integer,{-1000,1000}];
b5=Random[Integer,{-1000,1000}];
a7=Random[Integer,{-1000,1000}];
b7=Random[Integer,{-1000,1000}];
c7=Random[Integer,{-1000,1000}];
d7=Random[Integer,{-1000,1000}];
a9=Random[Integer,{-1000,1000}];
b9=Random[Integer,{-1000,1000}];
c9=Random[Integer,{-1000,1000}];
d9=Random[Integer,{-1000,1000}];
e9=Random[Integer,{-1000,1000}];
f9=Random[Integer,{-1000,1000}];
g9=Random[Integer,{-1000,1000}];
h9=Random[Integer,{-1000,1000}];
a11=Random[Integer,{-1000,1000}];
b11=Random[Integer,{-1000,10000}];
c11=Random[Integer,{-1000,1000}];
d11=Random[Integer,{-1000,1000}];
e11=Random[Integer,{-1000,1000}];
f11=Random[Integer,{-1000,1000}];
g11=Random[Integer,{-1000,1000}];
h11=Random[Integer,{-1000,1000}];
i11=Random[Integer,{-1000,1000}];
j11=Random[Integer,{-1000,1000}];
k11=Random[Integer,{-1000,1000}];
l11=Random[Integer,{-1000,1000}];
m11=Random[Integer,{-1000,1000}];
n11=Random[Integer,{-1000,1000}];
o11=Random[Integer,{-1000,1000}];
p11=Random[Integer,{-1000,1000}];
q11=Random[Integer,{-1000,1000}];
r11=Random[Integer,{-1000,1000}];

d=1/Random[Integer,{-1000,1000}];

DEGREE=11;
(* Print["DEGREE is"]; Print[DEGREE]; *)

<<Coeff;

<<DefFun;

x= d t X[1] + d^3 t^3 X[3] + d^5 t^5 X[5] + d^7 t^7 X[7] + 
              d^9 t^9 X[9] + d^11 t^11 X[11];
y=( t    a1    X[1]
   +t^3  a3    X[3] 
   +t^5  a5    X[5]
   +t^5  b5  b5Cmt
   +t^7  a7    X[7]
   +t^7  b7  b7Cmt
   +t^7  c7  c7Cmt
   +t^7  d7  d7Cmt
   +t^9  a9    X[9]
   +t^9  b9  b9Cmt
   +t^9  c9  c9Cmt
   +t^9  d9  d9Cmt
   +t^9  e9  e9Cmt
   +t^9  f9  f9Cmt
   +t^9  g9  g9Cmt
   +t^9  h9  h9Cmt
   +t^11 a11   X[11]
   +t^11 b11 b11Cmt
   +t^11 c11 c11Cmt
   +t^11 d11 d11Cmt
   +t^11 e11 e11Cmt
   +t^11 f11 f11Cmt
   +t^11 g11 g11Cmt
   +t^11 h11 h11Cmt
   +t^11 i11 i11Cmt
   +t^11 j11 j11Cmt
   +t^11 k11 k11Cmt
   +t^11 l11 l11Cmt
   +t^11 m11 m11Cmt
   +t^11 n11 n11Cmt
   +t^11 o11 o11Cmt
   +t^11 p11 p11Cmt
   +t^11 q11 q11Cmt
   +t^11 r11 r11Cmt );

w=( t    newa1    X[1]
   +t^3  newa3    X[3] 
   +t^5  newa5    X[5]
   +t^5  newb5  b5Cmt
   +t^7  newa7    X[7]
   +t^7  newb7  b7Cmt
   +t^7  newc7  c7Cmt
   +t^7  newd7  d7Cmt
   +t^9  newa9    X[9]
   +t^9  newb9  b9Cmt
   +t^9  newc9  c9Cmt
   +t^9  newd9  d9Cmt
   +t^9  newe9  e9Cmt
   +t^9  newf9  f9Cmt
   +t^9  newg9  g9Cmt
   +t^9  newh9  h9Cmt
   +t^11 newa11   X[11]
   +t^11 newb11 b11Cmt
   +t^11 newc11 c11Cmt
   +t^11 newd11 d11Cmt
   +t^11 newe11 e11Cmt
   +t^11 newf11 f11Cmt
   +t^11 newg11 g11Cmt
   +t^11 newh11 h11Cmt
   +t^11 newi11 i11Cmt
   +t^11 newj11 j11Cmt
   +t^11 newk11 k11Cmt
   +t^11 newl11 l11Cmt
   +t^11 newm11 m11Cmt
   +t^11 newn11 n11Cmt
   +t^11 newo11 o11Cmt
   +t^11 newp11 p11Cmt
   +t^11 newq11 q11Cmt
   +t^11 newr11 r11Cmt );

x=Expand[Normal[Series[x,{t,0,DEGREE}]]];
y=Expand[Normal[Series[y,{t,0,DEGREE}]]];
w=Expand[Normal[Series[w,{t,0,DEGREE}]]];

MmPoly[p_,q_]:=Block[{coefp=CoefficientList[p,t],coefq=CoefficientList[q,t],
		  pq, k, i},
		 pq=Expand[coefp[[1]] q+p coefq[[1]]- coefp[[1]] coefq[[1]]];
		 Do[{pq=pq+Expand[Sum[Mm[coefp[[i]], 
                                      coefq[[k+2-i]]],{i,2,k}]] t^k},
                    {k,2,DEGREE}];
		 pq];

Print["Compute exp(X)"];
termx=x; tmpn=1; tmpx=x;
Do[{tmpx=Expand[Normal[Series[Mm[tmpx,x],{t,0,DEGREE}]]];
	tmpn=ii tmpn; termx=termx+Expand[tmpx/tmpn]}, {ii,2,DEGREE}];
termx=1+termx;

Print["Compute exp(Y)"];
termy=y; tmpn=1; tmpy=y;
Do[{tmpy=Expand[Normal[Series[Mm[tmpy,y],{t,0,DEGREE}]]];
	tmpn=ii tmpn; termy=termy+Expand[tmpy/tmpn]}, {ii,2,DEGREE}];
termy=1+termy;

Print["Compute exp(W)"];
termw=w; tmpn=1; tmpw=w;
Do[{tmpw=Expand[Normal[Series[Mm[tmpw,w],{t,0,DEGREE}]]];
	tmpn=ii tmpn; termw=termw+Expand[tmpw/tmpn]}, {ii,2,DEGREE}];
termw=1+termw;

Print["Compute exp(X)exp(Y)exp(X)"];
termxyx=MmPoly[termx,termy];
termxyx=MmPoly[termxyx,termx]; 

Print["Compute Error"];
error=Expand[termxyx-termw]
If[error==0,
   Print["Correctness is verified"],
   Print["Correctness is NOT verified"]];
