symwork.red 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. module symwork;
  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. % symwork.red
  13. % underground functions
  14. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  15. %
  16. % Boolean functions
  17. %
  18. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  19. %symbolic procedure complex!_case!_p();
  20. % returns true, if complex arithmetic is desired
  21. %begin
  22. % if !*complex then return t else return nil;
  23. %end;
  24. switch outerzeroscheck;
  25. symbolic procedure correct!_diagonal!_p(matrixx,representation,mats);
  26. % returns true, if matrix may be block diagonalized to mats
  27. begin
  28. scalar basis,diag;
  29. basis:=mk!_sym!_basis (representation);
  30. diag:= mk!+mat!*mat!*mat(
  31. mk!+hermitean!+matrix(basis),
  32. matrixx,basis);
  33. if equal!+matrices!+p(diag,mats) then return t;
  34. end;
  35. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  36. %
  37. % functions on data depending on real or complex case
  38. %
  39. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  40. symbolic procedure get!_nr!_irred!_reps(group);
  41. % returns number of irreducible representations of group
  42. begin
  43. if !*complex then
  44. return get!*nr!*complex!*irred!*reps(group) else
  45. return get!*nr!*real!*irred!*reps(group);
  46. end;
  47. symbolic procedure get!_dim!_irred!_reps(group,nr);
  48. % returns dimension of nr-th irreducible representations of group
  49. begin
  50. scalar rep;
  51. % if !*complex then
  52. % return get!_char!_dim(get!*complex!*character(group,nr)) else
  53. % return get!_char!_dim(get!*real!*character(group,nr));
  54. if !*complex then
  55. rep:= get!*complex!*irreducible!*rep(group,nr) else
  56. rep:= get!*real!*irreducible!*rep(group,nr);
  57. return get!_dimension!_in(rep);
  58. end;
  59. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  60. %
  61. % functions for user given representations
  62. %
  63. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  64. symbolic procedure get!_group!_out(representation);
  65. % returns the group identifier given in representation
  66. begin
  67. scalar group,found,eintrag,repl;
  68. found:=nil;
  69. repl:=cdr representation;
  70. while (not(found) and (length(repl)>1)) do
  71. <<
  72. eintrag:=car repl;
  73. repl:=cdr repl;
  74. if idp(eintrag) then
  75. <<
  76. group:=eintrag;
  77. found:=t;
  78. >>;
  79. >>;
  80. if found then return group else
  81. rederr("group identifier missing");
  82. end;
  83. symbolic procedure get!_repmatrix!_out(elem,representation);
  84. % returns the representation matrix of elem given in representation
  85. % output in internal structure
  86. begin
  87. scalar repl,found,matelem,eintrag;
  88. found:=nil;
  89. repl:= cdr representation;
  90. while (null(found) and (length(repl)>0)) do
  91. <<
  92. eintrag:=car repl;
  93. repl:=cdr repl;
  94. if eqcar(eintrag,'equal) then
  95. <<
  96. if not(length(eintrag) = 3) then
  97. rederr("incomplete equation");
  98. if (cadr(eintrag) = elem) then
  99. <<
  100. found:=t;
  101. matelem:=caddr eintrag;
  102. >>;
  103. >>;
  104. >>;
  105. if found then return matelem else
  106. rederr("representation matrix for one generator missing");
  107. end;
  108. symbolic procedure mk!_rep!_relation(representation,generators);
  109. % representation in user given structure
  110. % returns a list of pairs with generator and its representation matrix
  111. % in internal structure
  112. begin
  113. scalar g,matg,res;
  114. res:=for each g in generators collect
  115. <<
  116. matg:= mk!+inner!+mat(get!_repmatrix!_out(g,representation));
  117. if not(unitarian!+p(matg)) then
  118. rederr("please give an orthogonal or unitarian matrix");
  119. list(g,matg)
  120. >>;
  121. return res;
  122. end;
  123. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  124. %
  125. % functions which compute, do the real work, get correct arguments
  126. % and use get-functions from sym_handle_data.red
  127. %
  128. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  129. symbolic procedure mk!_character(representation);
  130. % returns the character of the representation (in internal structure)
  131. % result in internal structure
  132. begin
  133. scalar group,elem,char;
  134. group:=get!_group!_in(representation);
  135. char:= for each elem in get!*elements(group) collect
  136. list(elem,
  137. mk!+trace(get!_rep!_matrix!_in(
  138. elem,representation)
  139. )
  140. );
  141. char:=append(list(group),char);
  142. return char;
  143. end;
  144. symbolic procedure mk!_multiplicity(representation,nr);
  145. % returns the multiplicity of the nr-th rep. in representation
  146. % internal structure
  147. begin
  148. scalar multnr,char1,group;
  149. group:=get!_group!_in(representation);
  150. if !*complex then
  151. char1:=mk!_character(get!*complex!*irreducible!*rep(group,nr))
  152. else
  153. char1:=mk!_character(get!*real!*irreducible!*rep(group,nr));
  154. multnr:=char!_prod(char1,mk!_character(representation));
  155. % complex case factor 1/2 !!
  156. if (not(!*complex) and
  157. (get!*real!*comp!*chartype!*p(group,nr))) then
  158. multnr:=multsq(multnr,(1 ./ 2));
  159. return change!+sq!+to!+int(multnr);
  160. end;
  161. symbolic procedure char!_prod(char1,char2);
  162. % returns the inner product of the two characters as sq
  163. begin
  164. scalar group,elems,sum,g,product;
  165. group:=get!_char!_group(char1);
  166. if not(group = get!_char!_group(char2))
  167. then rederr("no product for two characters of different groups");
  168. if not (available!*p(group)) and not(storing!*p(group)) then
  169. rederr("strange group in character product");
  170. elems:=get!*elements(group);
  171. sum:=nil ./ 1;
  172. for each g in elems do
  173. <<
  174. product:=multsq(
  175. get!_char!_value(char1,g),
  176. get!_char!_value(char2,get!*inverse(group,g))
  177. );
  178. sum:=addsq(sum,product);
  179. >>;
  180. return quotsq(sum,change!+int!+to!+sq(get!*order(group)));
  181. end;
  182. symbolic procedure mk!_proj!_iso(representation,nr);
  183. % returns the projection onto the isotypic component nr
  184. begin
  185. scalar group,elems,g,charnr,dimen,mapping,fact;
  186. group:=get!_group!_in(representation);
  187. if not (available!*p(group)) then
  188. rederr("strange group in projection");
  189. if not(irr!:nr!:p(nr,group)) then
  190. rederr("incorrect number of representation");
  191. elems:=get!*elements(group);
  192. if !*complex then
  193. charnr:=
  194. mk!_character(get!*complex!*irreducible!*rep(group,nr))
  195. else
  196. charnr:=mk!_character(get!*real!*irreducible!*rep(group,nr));
  197. dimen:=get!_dimension!_in(representation);
  198. mapping:=mk!+null!+mat(dimen,dimen);
  199. for each g in elems do
  200. <<
  201. mapping:=mk!+mat!+plus!+mat(
  202. mapping,
  203. mk!+scal!+mult!+mat(
  204. get!_char!_value(charnr,get!*inverse(group,g)),
  205. get!_rep!_matrix!_in(g,representation)
  206. )
  207. );
  208. >>;
  209. fact:=quotsq(change!+int!+to!+sq(get!_char!_dim(charnr)),
  210. change!+int!+to!+sq(get!*order(group)));
  211. mapping:=mk!+scal!+mult!+mat(fact,mapping);
  212. % complex case factor 1/2 !!
  213. if (not(!*complex) and
  214. (get!*real!*comp!*chartype!*p(group,nr))) then
  215. mapping:=mk!+scal!+mult!+mat((1 ./ 2),mapping);
  216. return mapping;
  217. end;
  218. symbolic procedure mk!_proj!_first(representation,nr);
  219. % returns the projection onto the first vector space of the
  220. % isotypic component nr
  221. begin
  222. scalar group,elems,g,irrrep,dimen,mapping,fact,charnr,irrdim;
  223. group:=get!_group!_in(representation);
  224. if not (available!*p(group)) then
  225. rederr("strange group in projection");
  226. if not(irr!:nr!:p(nr,group)) then
  227. rederr("incorrect number of representation");
  228. elems:=get!*elements(group);
  229. if !*complex then
  230. irrrep:=get!*complex!*irreducible!*rep(group,nr) else
  231. irrrep:=get!*real!*irreducible!*rep(group,nr);
  232. dimen:=get!_dimension!_in(representation);
  233. mapping:=mk!+null!+mat(dimen,dimen);
  234. for each g in elems do
  235. <<
  236. mapping:=mk!+mat!+plus!+mat(
  237. mapping,
  238. mk!+scal!+mult!+mat(
  239. get!_rep!_matrix!_entry(irrrep,get!*inverse(group,g),1,1),
  240. get!_rep!_matrix!_in(g,representation)
  241. )
  242. );
  243. >>;
  244. irrdim:=get!_dimension!_in(irrrep);
  245. fact:=quotsq(change!+int!+to!+sq(irrdim),
  246. change!+int!+to!+sq(get!*order(group)));
  247. mapping:=mk!+scal!+mult!+mat(fact,mapping);
  248. % no special rule for real irreducible representations of complex type
  249. return mapping;
  250. end;
  251. symbolic procedure mk!_mapping(representation,nr,count);
  252. % returns the mapping from V(nr 1) to V(nr count)
  253. % output is internal matrix
  254. begin
  255. scalar group,elems,g,irrrep,dimen,mapping,fact,irrdim;
  256. group:=get!_group!_in(representation);
  257. if not (available!*p(group)) then
  258. rederr("strange group in projection");
  259. if not(irr!:nr!:p(nr,group)) then
  260. rederr("incorrect number of representation");
  261. elems:=get!*elements(group);
  262. if !*complex then
  263. irrrep:=get!*complex!*irreducible!*rep(group,nr) else
  264. irrrep:=get!*real!*irreducible!*rep(group,nr);
  265. dimen:=get!_dimension!_in(representation);
  266. mapping:=mk!+null!+mat(dimen,dimen);
  267. for each g in elems do
  268. <<
  269. mapping:=mk!+mat!+plus!+mat(
  270. mapping,
  271. mk!+scal!+mult!+mat(
  272. get!_rep!_matrix!_entry(irrrep,get!*inverse(group,g),1,count),
  273. get!_rep!_matrix!_in(g,representation)
  274. )
  275. );
  276. >>;
  277. irrdim:=get!_dimension!_in(irrrep);
  278. fact:=quotsq(change!+int!+to!+sq(irrdim),
  279. change!+int!+to!+sq(get!*order(group)));
  280. mapping:=mk!+scal!+mult!+mat(fact,mapping);
  281. % no special rule for real irreducible representations of complex type
  282. return mapping;
  283. end;
  284. symbolic procedure mk!_part!_sym (representation,nr);
  285. % computes the symmetry adapted basis of component nr
  286. % output matrix
  287. begin
  288. scalar unitlist, veclist2, mapping, v;
  289. unitlist:=gen!+can!+bas(get!_dimension!_in(representation));
  290. mapping:=mk!_proj!_iso(representation,nr);
  291. veclist2:= for each v in unitlist collect
  292. mk!+mat!+mult!+vec(mapping,v);
  293. return mk!+internal!+mat(Gram!+Schmid(veclist2));
  294. end;
  295. symbolic procedure mk!_part!_sym1 (representation,nr);
  296. % computes the symmetry adapted basis of component V(nr 1)
  297. % internal structure for in and out
  298. % output matrix
  299. begin
  300. scalar unitlist, veclist2, mapping, v,group;
  301. unitlist:=gen!+can!+bas(get!_dimension!_in(representation));
  302. group:=get!_group!_in (representation);
  303. if (not(!*complex) and
  304. get!*real!*comp!*chartype!*p(group,nr)) then
  305. <<
  306. mapping:=mk!_proj!_iso(representation,nr);
  307. >> else
  308. mapping:=mk!_proj!_first(representation,nr);
  309. veclist2:= for each v in unitlist collect
  310. mk!+mat!+mult!+vec(mapping,v);
  311. veclist2:=mk!+resimp!+mat(veclist2);
  312. return mk!+internal!+mat(Gram!+Schmid(veclist2));
  313. end;
  314. symbolic procedure mk!_part!_symnext (representation,nr,count,mat1);
  315. % computes the symmetry adapted basis of component V(nr count)
  316. % internal structure for in and out -- count > 2
  317. % bas1 -- internal matrix
  318. % output matrix
  319. begin
  320. scalar veclist1, veclist2, mapping, v;
  321. mapping:=mk!_mapping(representation,nr,count);
  322. veclist1:=mat!+veclist(mat1);
  323. veclist2:= for each v in veclist1 collect
  324. mk!+mat!+mult!+vec(mapping,v);
  325. return mk!+internal!+mat(veclist2);
  326. end;
  327. symbolic procedure mk!_sym!_basis (representation);
  328. % computes the complete symmetry adapted basis
  329. % internal structure for in and out
  330. begin
  331. scalar nr,anz,group,dimen,mats,matels,mat1,mat2;
  332. group:=get!_group!_in(representation);
  333. anz:=get!_nr!_irred!_reps(group);
  334. mats:=for nr := 1:anz join
  335. if not(null(mk!_multiplicity(representation,nr))) then
  336. <<
  337. if get!_dim!_irred!_reps(group,nr)=1 then
  338. mat1:=mk!_part!_sym (representation,nr)
  339. else
  340. mat1:=mk!_part!_sym1 (representation,nr);
  341. if (not(!*complex) and
  342. get!*real!*comp!*chartype!*p(group,nr)) then
  343. <<
  344. matels:=list(mat1);
  345. >> else
  346. <<
  347. if get!_dim!_irred!_reps(group,nr)=1 then
  348. <<
  349. matels:=list(mat1);
  350. >> else
  351. <<
  352. matels:=
  353. for dimen:=2:get!_dim!_irred!_reps(group,nr) collect
  354. mk!_part!_symnext(representation,nr,dimen,mat1);
  355. matels:=append(list(mat1),matels);
  356. >>;
  357. >>;
  358. matels
  359. >>;
  360. if length(mats)<1 then rederr("no mats in mk!_sym!_basis");
  361. mat2:=car mats;
  362. for each mat1 in cdr mats do
  363. mat2:=add!+two!+mats(mat2,mat1);
  364. return mat2;
  365. end;
  366. symbolic procedure mk!_part!_sym!_all (representation,nr);
  367. % computes the complete symmetry adapted basis
  368. % internal structure for in and out
  369. begin
  370. scalar group,dimen,matels,mat1,mat2;
  371. group:=get!_group!_in(representation);
  372. if get!_dim!_irred!_reps(group,nr)=1 then
  373. mat1:=mk!_part!_sym (representation,nr)
  374. else
  375. <<
  376. mat1:=mk!_part!_sym1 (representation,nr);
  377. if (not(!*complex) and
  378. get!*real!*comp!*chartype!*p(group,nr)) then
  379. <<
  380. mat1:=mat1;
  381. >> else
  382. <<
  383. if get!_dim!_irred!_reps(group,nr)>1 then
  384. << matels:=
  385. for dimen:=2:get!_dim!_irred!_reps(group,nr) collect
  386. mk!_part!_symnext(representation,nr,dimen,mat1);
  387. for each mat2 in matels do
  388. mat1:=add!+two!+mats(mat1,mat2);
  389. >>;
  390. >>;
  391. >>;
  392. return mat1;
  393. end;
  394. symbolic procedure mk!_diagonal (matrix1,representation);
  395. % computes the matrix in diagonal form
  396. % internal structure for in and out
  397. begin
  398. scalar nr,anz,mats,group,mat1,diamats,matdia,dimen;
  399. group:=get!_group!_in(representation);
  400. anz:=get!_nr!_irred!_reps(group);
  401. mats:=for nr := 1:anz join
  402. if not(null(mk!_multiplicity(representation,nr))) then
  403. <<
  404. if get!_dim!_irred!_reps(group,nr)=1 then
  405. mat1:=mk!_part!_sym (representation,nr)
  406. else
  407. mat1:=mk!_part!_sym1 (representation,nr);
  408. % if (not(!*complex) and
  409. % get!*real!*comp!*chartype!*p(group,nr)) then
  410. % mat1:=add!+two!+mats(mat1,
  411. % mk!_part!_symnext(representation,nr,2,mat1));
  412. matdia:= mk!+mat!*mat!*mat(
  413. mk!+hermitean!+matrix(mat1),matrix1,mat1
  414. );
  415. if (not(!*complex) and
  416. get!*real!*comp!*chartype!*p(group,nr)) then
  417. <<
  418. diamats:=list(matdia);
  419. >> else
  420. <<
  421. diamats:=
  422. for dimen:=1:get!_dim!_irred!_reps(group,nr) collect
  423. matdia;
  424. >>;
  425. diamats
  426. >>;
  427. mats:=mk!+block!+diagonal!+mat(mats);
  428. if !*outerzeroscheck then
  429. if not(correct!_diagonal!_p(matrix1,representation,mats)) then
  430. rederr("wrong diagonalisation");
  431. return mats;
  432. end;
  433. endmodule;
  434. end;