gramschm.red 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. module gramchmd;
  2. %**********************************************************************%
  3. % %
  4. % Computation of the Gram Schmidt Orthonormalisation process. The %
  5. % input vectors are represented by lists. %
  6. % %
  7. % Authors: Karin Gatermann (used symbolically in her symmetry package).%
  8. % Matt Rebbeck (first few lines of code that make it %
  9. % available from the user level). May 1994. %
  10. % %
  11. %**********************************************************************%
  12. put('gram_schmidt,'psopfn,'gram_schmidt1); % To allow variable input.
  13. symbolic procedure gram_schmidt1(vec_list);
  14. %
  15. % Can take a list of lists(which are representing vectors) or any
  16. % number of arguments each being a list(again which represent the
  17. % vectors).
  18. %
  19. % Karin used lists of standard quotient elements as vectors so a bit
  20. % of fiddling is required to get the input/output right.
  21. %
  22. begin
  23. scalar gs_list;
  24. % Deal with the possibility of the user entering a list of lists.
  25. if pairp vec_list and pairp car vec_list and caar vec_list = 'list
  26. and pairp cdar vec_list and pairp cadar vec_list
  27. and caadar vec_list = 'list
  28. then vec_list := cdar vec_list;
  29. vec_list := convert_to_sq(vec_list);
  30. % This bit does all the real work.
  31. gs_list := gram!+schmid(vec_list);
  32. return convert_from_sq(gs_list);
  33. end;
  34. symbolic procedure convert_to_sq(vec_list);
  35. %
  36. % Takes algebraic list and converts to sq form for input into
  37. % GramSchmidt.
  38. %
  39. begin
  40. scalar sq_list;
  41. sq_list := for each list in vec_list collect
  42. for each elt in cdr list collect simp!* elt;
  43. return sq_list;
  44. end;
  45. symbolic procedure convert_from_sq(sq_list);
  46. %
  47. % Converts sq_list to a readable (from algebraic mode) form.
  48. %
  49. begin
  50. scalar gs_list;
  51. gs_list := 'list.for each elt1 in sq_list collect
  52. 'list.for each elt in elt1 collect prepsq elt;
  53. return gs_list;
  54. end;
  55. %
  56. % All the rest is Karin's.
  57. %
  58. symbolic procedure vector!+p(vector1);
  59. %
  60. % returns the length of a vector
  61. % vector -- list of sqs
  62. %
  63. begin
  64. if length(vector1)>0 then return t;
  65. end;
  66. symbolic procedure get!+vec!+dim(vector1);
  67. %
  68. % returns the length of a vector
  69. % vector -- list of sqs
  70. %
  71. begin
  72. return length(vector1);
  73. end;
  74. symbolic procedure get!+vec!+entry(vector1,elem);
  75. %
  76. % returns the length of a vector
  77. % vector -- list of sqs
  78. %
  79. begin
  80. return nth(vector1,elem);
  81. end;
  82. symbolic procedure mk!+vec!+add!+vec(vector1,vector2);
  83. %
  84. % returns a vector= vector1+vector2 (internal structure)
  85. %
  86. begin
  87. scalar ent,res,h;
  88. res:=for ent:=1:get!+vec!+dim(vector1) collect
  89. <<
  90. h:= addsq(get!+vec!+entry(vector1,ent),
  91. get!+vec!+entry(vector2,ent));
  92. h:=subs2 h where !*sub2=t;
  93. h
  94. >>;
  95. return res;
  96. end;
  97. symbolic procedure mk!+squared!+norm(vector1);
  98. %
  99. % returns a scalar= sum vector_i^2 (internal structure)
  100. %
  101. begin
  102. return mk!+inner!+product(vector1,vector1);
  103. end;
  104. symbolic procedure my!+nullsq!+p(scal);
  105. %
  106. % returns true, if ths sq is zero
  107. %
  108. begin
  109. if null(numr( scal)) then return t;
  110. end;
  111. symbolic procedure mk!+null!+vec(dimen);
  112. %
  113. % returns a vector of zeros
  114. %
  115. begin
  116. scalar nullsq,i,res;
  117. nullsq:=(nil ./ 1);
  118. res:=for i:=1:dimen collect nullsq;
  119. return res;
  120. end;
  121. symbolic procedure null!+vec!+p(vector1);
  122. %
  123. % returns a true, if vector is the zero vector
  124. begin
  125. if my!+nullsq!+p(mk!+squared!+norm(vector1)) then return t;
  126. end;
  127. symbolic procedure mk!+normalize!+vector(vector1);
  128. %
  129. % returns a normalized vector (internal structure)
  130. %
  131. begin
  132. scalar scalo,vecres;
  133. scalo:=simp!* {'sqrt, mk!*sq(mk!+squared!+norm(vector1))};
  134. if my!+nullsq!+p(scalo) then
  135. vecres:= mk!+null!+vec(get!+vec!+dim(vector1))
  136. else
  137. <<
  138. scalo:=simp prepsq scalo;
  139. scalo:=quotsq((1 ./ 1),scalo);
  140. vecres:= mk!+scal!+mult!+vec(scalo,vector1);
  141. >>;
  142. return vecres;
  143. end;
  144. symbolic procedure mk!+Gram!+Schmid(vectorlist,vector1);
  145. %
  146. % returns a vectorlist of orthonormal vectors
  147. % assumptions: vectorlist is orthonormal basis, internal structure
  148. %
  149. begin
  150. scalar i,orthovec,scalo,vectors;
  151. orthovec:=vector1;
  152. for i:=1:(length(vectorlist)) do
  153. <<
  154. scalo:= negsq(mk!+inner!+product(orthovec,nth(vectorlist,i)));
  155. orthovec:=mk!+vec!+add!+vec(orthovec,
  156. mk!+scal!+mult!+vec(scalo,nth(vectorlist,i)));
  157. >>;
  158. orthovec:=mk!+normalize!+vector(orthovec);
  159. if null!+vec!+p(orthovec) then vectors:=vectorlist
  160. else vectors:=add!+vector!+to!+list(orthovec,vectorlist);
  161. return vectors;
  162. end;
  163. symbolic procedure Gram!+Schmid(vectorlist);
  164. %
  165. % returns a vectorlist of orthonormal vectors
  166. %
  167. begin
  168. scalar ortholist,i;
  169. if length(vectorlist)<1
  170. then rederr "Error in Gram Schmidt: no input.";
  171. if vector!+p(car vectorlist) then ortholist:=nil
  172. else rederr "Error in Gram_schmidt: empty input.";
  173. for i:=1:length(vectorlist) do
  174. ortholist:=mk!+Gram!+Schmid(ortholist,nth(vectorlist,i));
  175. return ortholist;
  176. end;
  177. symbolic procedure add!+vector!+to!+list(vector1,vectorlist);
  178. %
  179. % returns a list of vectors consisting of vectorlist
  180. % and the vector1 at the end
  181. % internal structure
  182. begin
  183. return append(vectorlist,list(vector1));
  184. end;
  185. symbolic procedure mk!+inner!+product(vector1,vector2);
  186. %
  187. % returns the inner product of vector1 and vector2
  188. % (internal structure)
  189. %
  190. begin
  191. scalar z,sum,vec2;
  192. if not(get!+vec!+dim(vector1) = get!+vec!+dim(vector2)) then rederr
  193. "Error in Gram_schmidt: each list in input must be the same length.";
  194. sum:=(nil ./ 1);
  195. if !*complex then vec2:=mk!+conjugate!+vec(vector2)
  196. else vec2:=vector2;
  197. for z:=1:get!+vec!+dim(vector1) do
  198. sum:=addsq(sum,multsq(
  199. get!+vec!+entry(vector1,z),
  200. get!+vec!+entry(vec2,z)
  201. )
  202. );
  203. sum:=subs2 sum where !*sub2=t;
  204. return sum;
  205. end;
  206. symbolic procedure mk!+scal!+mult!+vec(scal1,vector1);
  207. %
  208. % returns a vector= scalar*vector (internal structure)
  209. %
  210. begin
  211. scalar entry,res,h;
  212. res:=for each entry in vector1 collect
  213. <<
  214. h:=multsq(scal1,entry);
  215. h:=subs2 h where !*sub2=t;
  216. h
  217. >>;
  218. return res;
  219. end;
  220. endmodule; % gram_schmidt.
  221. end;