symcheck.red 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. module symcheck;
  2. %
  3. % Symmetry Package
  4. %
  5. % Author : Karin Gatermann
  6. % Konrad-Zuse-Zentrum fuer
  7. % Informationstechnik Berlin
  8. % Heilbronner Str. 10
  9. % W-1000 Berlin 31
  10. % Germany
  11. % Email: Gatermann@sc.ZIB-Berlin.de
  12. % symcheck.red
  13. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  14. %
  15. % check user input -- used by functions in sym_main.red
  16. %
  17. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  18. symbolic procedure representation!:p(rep);
  19. % returns true, if rep is a representation
  20. begin
  21. scalar group,elem,mats,mat1,dim1;
  22. if length(rep)<0 then rederr("list too short");
  23. if not(outer!+list!+p(rep)) then rederr("argument should be a list");
  24. if (length(rep)<2) then rederr("empty list is not a representation");
  25. group:=get!_group!_out(rep);
  26. if not(available!*p(group) or storing!*p(group)) then
  27. rederr("one element must be an identifier of an available group");
  28. mats:=for each elem in get!*generators(group) collect
  29. get!_repmatrix!_out(elem,rep);
  30. for each mat1 in mats do
  31. if not(alg!+matrix!+p(mat1)) then
  32. rederr("there should be a matrix for each generator");
  33. mats:=for each mat1 in mats collect mk!+inner!+mat(mat1);
  34. for each mat1 in mats do
  35. if not(squared!+matrix!+p(mat1)) then
  36. rederr("matrices should be squared");
  37. mat1:=car mats;
  38. mats:=cdr mats;
  39. dim1:=get!+row!+nr(mat1);
  40. while length(mats)>0 do
  41. <<
  42. if not(dim1=get!+row!+nr(car mats)) then
  43. rederr("representation matrices must have the same dimension");
  44. mat1:=car mats;
  45. mats:= cdr mats;
  46. >>;
  47. return t;
  48. end;
  49. symbolic procedure irr!:nr!:p(nr,group);
  50. % returns true, if group is a group and information is available
  51. % and nr is number of an irreducible representation
  52. begin
  53. if not(fixp(nr)) then rederr("nr should be an integer");
  54. if (nr>0 and nr<= get!_nr!_irred!_reps(group)) then
  55. return t;
  56. end;
  57. symbolic procedure symmetry!:p(matrix1,representation);
  58. % returns true, if the matrix has the symmetry of this representation
  59. % internal structures
  60. begin
  61. scalar group,glist,symmetryp,repmat;
  62. group:=get!_group!_in(representation);
  63. glist:=get!*generators(group);
  64. symmetryp:=t;
  65. while (symmetryp and (length(glist)>0)) do
  66. <<
  67. repmat:=get!_rep!_matrix!_in(car glist,representation);
  68. if not (equal!+matrices!+p(
  69. mk!+mat!+mult!+mat(repmat,matrix1),
  70. mk!+mat!+mult!+mat(matrix1,repmat)) ) then
  71. symmetryp:=nil;
  72. glist:= cdr glist;
  73. >>;
  74. return symmetryp;
  75. end;
  76. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  77. %
  78. % check functions used by definition of the group
  79. %
  80. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  81. symbolic procedure identifier!:list!:p(idlist);
  82. % returns true if idlist is a list of identifiers
  83. begin
  84. if length(idlist)>0 then
  85. <<
  86. if idp(car idlist) then
  87. return identifier!:list!:p(cdr idlist);
  88. >> else
  89. return t;
  90. end;
  91. symbolic procedure generator!:list!:p(group,generatorl);
  92. % returns true if generatorl is an idlist
  93. % consisting of the generators of the group
  94. begin
  95. scalar element,res;
  96. res:=t;
  97. if length(generatorl)<1 then
  98. rederr("there should be a list of generators");
  99. if length(get!*generators(group))<1 then
  100. rederr("there are no group generators stored");
  101. if not(identifier!:list!:p(generatorl)) then return nil;
  102. for each element in generatorl do
  103. if not(g!*generater!*p(group,element)) then
  104. res:=nil;
  105. return res;
  106. end;
  107. symbolic procedure relation!:list!:p(group,relations);
  108. % relations -- list of two generator lists
  109. begin
  110. if length(get!*generators(group))<1 then
  111. rederr("there are no group generators stored");
  112. return (relation!:part!:p(group,car relations) and
  113. relation!:part!:p(group,cadr relations))
  114. end;
  115. symbolic procedure relation!:part!:p(group,relationpart);
  116. % relations -- list of two generator lists
  117. begin
  118. scalar generators,res,element;
  119. res:=t;
  120. generators:=get!*generators(group);
  121. if length(generators)<1 then
  122. rederr("there are no group generators stored");
  123. if length(relationpart)<1 then
  124. rederr("wrong relation given");
  125. if not(identifier!:list!:p(relationpart)) then return nil;
  126. generators:=append(list('id),generators);
  127. for each element in relationpart do
  128. if not(memq(element,generators)) then res:=nil;
  129. return res;
  130. end;
  131. symbolic procedure group!:table!:p(group,gtable);
  132. % returns true, if gtable is a group table
  133. % gtable - matrix in internal representation
  134. begin
  135. scalar row;
  136. if not(get!+mat!+entry(gtable,1,1) = 'grouptable) then
  137. rederr("first diagonal entry in a group table must be grouptable");
  138. for each row in gtable do
  139. if not(group!:elemts!:p(group,cdr row)) then
  140. rederr("this should be a group table");
  141. for each row in mk!+transpose!+matrix(gtable) do
  142. if not(group!:elemts!:p(group,cdr row)) then
  143. rederr("this should be a group table");
  144. return t;
  145. end;
  146. symbolic procedure group!:elemts!:p(group,elems);
  147. % returns true if each element of group appears exactly once in the list
  148. begin
  149. return equal!+lists!+p(get!*elements(group),elems);
  150. end;
  151. symbolic procedure check!:complete!:rep!:p(group);
  152. % returns true if sum ni^2 = grouporder and
  153. % sum realni = sum complexni
  154. begin
  155. scalar nr,j,sum,dime,order1,sumreal,chars,complexcase;
  156. nr:=get!*nr!*complex!*irred!*reps(group);
  157. sum:=(nil ./ 1);
  158. for j:=1:nr do
  159. <<
  160. dime:=change!+int!+to!+sq( get!_dimension!_in(
  161. get!*complex!*irreducible!*rep(group,j)));
  162. sum:=addsq(sum,multsq(dime,dime));
  163. >>;
  164. order1:=change!+int!+to!+sq(get!*order(group));
  165. if not(null(numr(addsq(sum,negsq(order1))))) then
  166. rederr("one complex irreducible representation missing or
  167. is not irreducible");
  168. sum:=(nil ./ 1);
  169. for j:=1:nr do
  170. <<
  171. dime:=change!+int!+to!+sq( get!_dimension!_in(
  172. get!*complex!*irreducible!*rep(group,j)));
  173. sum:=addsq(sum,dime);
  174. >>;
  175. chars:=for j:=1:nr collect
  176. get!*complex!*character(group,j);
  177. if !*complex then
  178. <<
  179. complexcase:=t;
  180. >> else
  181. <<
  182. complexcase:=nil;
  183. on complex;
  184. >>;
  185. if not(orthogonal!:characters!:p(chars)) then
  186. rederr("characters are not orthogonal");
  187. if null(complexcase) then off complex;
  188. nr:=get!*nr!*real!*irred!*reps(group);
  189. sumreal:=(nil ./ 1);
  190. for j:=1:nr do
  191. <<
  192. dime:=change!+int!+to!+sq( get!_dimension!_in(
  193. get!*real!*irreducible!*rep(group,j)));
  194. sumreal:=addsq(sumreal,dime);
  195. >>;
  196. chars:=for j:=1:nr collect
  197. get!*real!*character(group,j);
  198. if not(orthogonal!:characters!:p(chars)) then
  199. rederr("characters are not orthogonal");
  200. if not(null(numr(addsq(sum,negsq(sumreal))))) then
  201. rederr("list real irreducible representation incomplete or wrong");
  202. return t;
  203. end;
  204. symbolic procedure orthogonal!:characters!:p(chars);
  205. % returns true if all characters in list are pairwise orthogonal
  206. begin
  207. scalar chars1,chars2,char1,char2;
  208. chars1:=chars;
  209. while (length(chars1)>0) do
  210. <<
  211. char1:=car chars1;
  212. chars1:=cdr chars1;
  213. chars2:=chars1;
  214. while (length(chars2)>0) do
  215. <<
  216. char2:=car chars2;
  217. chars2:=cdr chars2;
  218. if not(change!+sq!+to!+algnull(
  219. char!_prod(char1,char2))=0)
  220. then rederr("not orthogonal");
  221. >>;
  222. >>;
  223. return t;
  224. end;
  225. symbolic procedure write!:to!:file(group,filename);
  226. begin
  227. scalar nr,j;
  228. if not(available!*p(group)) then rederr("group is not available");
  229. out filename;
  230. rprint(list
  231. ('off, 'echo));
  232. rprint('symbolic);
  233. rprint(list
  234. ('set!*elems!*group ,mkquote group,mkquote get!*elements(group)));
  235. rprint(list
  236. ('set!*generators, mkquote group,mkquote get!*generators(group)));
  237. rprint(list
  238. ('set!*relations, mkquote group,
  239. mkquote get!*generator!*relations(group)));
  240. rprint(list
  241. ('set!*grouptable, mkquote group,mkquote get(group,'grouptable)));
  242. rprint(list
  243. ('set!*inverse, mkquote group,mkquote get(group,'inverse)));
  244. rprint(list
  245. ('set!*elemasgen, mkquote group
  246. ,mkquote get(group,'elem!_in!_generators)));
  247. rprint(list
  248. ('set!*group, mkquote group,mkquote get(group,'equiclasses)));
  249. nr:=get!*nr!*complex!*irred!*reps(group);
  250. for j:=1:nr do
  251. <<
  252. rprint(list
  253. ('set!*representation, mkquote group,
  254. mkquote cdr get!*complex!*irreducible!*rep(group,j),
  255. mkquote 'complex));
  256. >>;
  257. nr:=get!*nr!*real!*irred!*reps(group);
  258. for j:=1:nr do
  259. <<
  260. rprint(list
  261. ('set!*representation, mkquote group,
  262. mkquote get(group,mkid('realrep,j)),mkquote 'real));
  263. >>;
  264. rprint(list(
  265. 'set!*available,mkquote group));
  266. rprint('algebraic);
  267. rprint('end);
  268. shut filename;
  269. end;
  270. symbolic procedure mk!_relation!_list(relations);
  271. % input: outer structure : reval of {r*s*r^2=s,...}
  272. % output: list of pairs of lists
  273. begin
  274. scalar twolist,eqrel;
  275. if not(outer!+list!+p(relations)) then
  276. rederr("this should be a list");
  277. twolist:=for each eqrel in mk!+inner!+list(relations) collect
  278. change!_eq!_to!_lists(eqrel);
  279. return twolist;
  280. end;
  281. symbolic procedure change!_eq!_to!_lists(eqrel);
  282. begin
  283. if not(outer!+equation!+p(eqrel)) then
  284. rederr("equations should be given");
  285. return list(mk!_side!_to!_list(reval cadr eqrel),
  286. mk!_side!_to!_list(reval caddr eqrel));
  287. end;
  288. symbolic procedure mk!_side!_to!_list(identifiers);
  289. begin
  290. scalar i;
  291. if idp(identifiers) then return list(identifiers);
  292. if eqcar(identifiers,'Plus) then rederr("no addition in this group");
  293. if eqcar(identifiers,'EXPT) then
  294. return for i:=1:(caddr identifiers) collect (cadr identifiers);
  295. if eqcar(identifiers,'TIMES) then
  296. rederr("no multiplication with * in this group");
  297. if eqcar(identifiers,'!@) then
  298. return append(mk!_side!_to!_list(cadr identifiers),
  299. mk!_side!_to!_list(caddr identifiers));
  300. end;
  301. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  302. %
  303. % pass to algebraic level
  304. %
  305. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  306. symbolic procedure alg!:print!:group(group);
  307. % returns the group element list in correct algebraic mode
  308. begin
  309. return mk!+outer!+list(get!*elements(group));
  310. end;
  311. symbolic procedure alg!:generators(group);
  312. % returns the generator list of a group in correct algebraic mode
  313. begin
  314. return append(list('list),get!*generators(group));
  315. end;
  316. symbolic procedure alg!:characters(group);
  317. % returns the (real od complex) character table
  318. % in correct algebraic mode
  319. begin
  320. scalar nr,i,charlist,chari;
  321. nr:=get!_nr!_irred!_reps(group);
  322. charlist:=for i:=1:nr collect
  323. if !*complex then
  324. get!*complex!*character(group,i) else
  325. get!*real!*character(group,i);
  326. charlist:= for each chari in charlist collect
  327. alg!:print!:character(chari);
  328. return mk!+outer!+list(charlist);
  329. end;
  330. symbolic procedure alg!:irr!:reps(group);
  331. % returns the (real od complex) irr. rep. table
  332. % in correct algebraic mode
  333. begin
  334. scalar repi,reps,nr,i;
  335. nr:=get!_nr!_irred!_reps(group);
  336. reps:=for i:=1:nr collect
  337. if !*complex then
  338. get!*complex!*irreducible!*rep(group,nr) else
  339. get!*real!*irreducible!*rep(group,i);
  340. reps:= for each repi in reps collect
  341. alg!:print!:rep(repi);
  342. return mk!+outer!+list(reps);
  343. end;
  344. symbolic procedure alg!:print!:rep(representation);
  345. % returns the representation in correct algebraic mode
  346. begin
  347. scalar pair,repr,group,mat1,g;
  348. group:=get!_group!_in(representation);
  349. repr:=eli!_group!_in(representation);
  350. repr:= for each pair in repr collect
  351. <<
  352. mat1:=cadr pair;
  353. g:=car pair;
  354. mat1:=mk!+outer!+mat(mat1);
  355. mk!+equation(g,mat1)
  356. >>;
  357. repr:=append(list(group),repr);
  358. return mk!+outer!+list(repr)
  359. end;
  360. symbolic procedure alg!:can!:decomp(representation);
  361. % returns the canonical decomposition in correct algebraic mode
  362. % representation in internal structure
  363. begin
  364. scalar nr,nrirr,ints,i,sum;
  365. nrirr:=get!_nr!_irred!_reps(get!_group!_in(representation));
  366. ints:=for nr:=1:nrirr collect
  367. mk!_multiplicity(representation,nr);
  368. sum:=( nil ./ 1);
  369. ints:= for i:=1:length(ints) do
  370. sum:=addsq(sum,
  371. multsq(change!+int!+to!+sq(nth(ints,i)),
  372. simp mkid('teta,i)
  373. )
  374. );
  375. return mk!+equation('teta,prepsq sum);
  376. end;
  377. symbolic procedure alg!:print!:character(character);
  378. % changes the character from internal representation
  379. % to printable representation
  380. begin
  381. scalar group,res,equilists;
  382. group:=get!_char!_group(character);
  383. res:=get!*all!*equi!*classes(group);
  384. res:= for each equilists in res collect
  385. mk!+outer!+list(equilists);
  386. res:= for each equilists in res collect
  387. mk!+outer!+list( list(equilists,
  388. prepsq get!_char!_value(character,cadr equilists)));
  389. res:=append(list(group),res);
  390. return mk!+outer!+list(res);
  391. end;
  392. endmodule;
  393. end;