pvector.red 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. %===============================================================
  2. % File: pvector.red
  3. % Purpose: Vector arithmetic.
  4. % Version: 3.01 Nov. 14, 1993
  5. %---------------------------------------------------------------
  6. % Revision 26/11/90 PermGT
  7. % 05/03/91 UpDate
  8. % Nov. 01, 1993 General revisions.
  9. % Nov. 14, 1993 Domain introduction
  10. %===============================================================
  11. lisp <<
  12. if null getd 'mkunitp then in "perm.red"$
  13. >>$
  14. module pvector$
  15. % p-vector is a list of b-vectors.
  16. % b-vector is a <coeff> . <permutation>.
  17. % coeff - integer.
  18. %---------------------- Main procedures -------------------
  19. symbolic procedure pv_simp v$
  20. (('!:pv . list(1 . car v)) ./ 1)$
  21. put('pv,'simpfn,'pv_simp)$
  22. global '(domainlist!*)$
  23. switch pvector$
  24. domainlist!*:=union('(!:pv),domainlist!*)$
  25. put('pvector,'tag,'!:pv)$
  26. put('!:pv,'dname,'pvector)$
  27. %flag('(!:pv),'field)$ % !:pv is not a field!
  28. put('!:pv,'minus,'pv_minus)$
  29. put('!:pv,'minusp,'pv_minusp)$
  30. put('!:pv,'plus,'pv_plus)$
  31. put('!:pv,'times,'pv_times)$ % v*c
  32. put('!:pv,'difference,'pv_difference)$
  33. put('!:pv,'zerop,'pv_zerop)$
  34. put('!:pv,'onep,'pv_onep)$
  35. put('!:pv,'prepfn,'pv_prep)$
  36. put('!:pv,'prifn,'pv_pri)$
  37. put('!:pv,'intequivfn,'pv_intequiv)$
  38. put('!:pv,'i2d,'i2pvector)$
  39. put('!:pv,'expt,'pv_expt)$
  40. put('!:pv,'quotient,'pv_quotient)$
  41. put('!:pv,'divide,'pv_divide)$
  42. put('!:pv,'gcd,'pv_gcd)$
  43. flag('(!:pv),'pvmode)$
  44. symbolic procedure pv_minus u$
  45. car u . pv_neg cdr u$
  46. symbolic procedure pv_minusp u$ nil$
  47. symbolic procedure pv_plus(u,v)$
  48. % if abs(cdadr u - cdadr v)>100 % incorrect test!
  49. % then rederr list('pv_plus,"*** Differ order of permutations:",u,v)
  50. % else
  51. if atom cdr u and atom cdr v then car u . (cdr u + cdr v)
  52. else if atom cdr u
  53. then rederr list('pv_plus,"*** pvector can't be added to:",cdr u)
  54. else if atom cdr v then pv_plus(v,u)
  55. else car u . pv_add(cdr u,cdr v)$
  56. symbolic procedure pv_times(u,v)$
  57. % u,v - (!:pv . pvlist)
  58. if pv_intequiv u then pv_times(v,u)
  59. else if atom cdr v then car u . pv_multc(cdr u,cdr v)
  60. else car u . pv_times1(cdr u,cdr v,nil)$
  61. % else rederr {'pv_times,"*** pvector can't be multiplied by: ",cdr v}$
  62. symbolic procedure pv_times1(u,v,w)$
  63. % u,v,w - pvlist::=((c1 . p1) ...)
  64. if null u then w
  65. else pv_times1(cdr u,v,pv_times2(car u,v,w))$
  66. symbolic procedure pv_times2(x,v,w)$
  67. % x - (c . p)
  68. % v,w - pvlist::=((c1 . p1) ...)
  69. if null v then w
  70. else pv_times2(x,cdr v
  71. ,pv_add(list pv_times3(x,car v),w)
  72. )$
  73. symbolic procedure pv_times3(x,y)$
  74. % x,y - (c . p)
  75. (car x * car y) . pappend(cdr x,cdr y)$
  76. symbolic procedure pv_difference(u,v)$
  77. pv_plus(u,pv_minus v)$
  78. symbolic procedure pv_zerop(u)$
  79. null cdr u$
  80. symbolic procedure pv_onep u$ nil$
  81. symbolic procedure pv_prep u$ u$
  82. symbolic procedure pv_pri(u)$
  83. begin scalar notfirst$
  84. for each x in cdr u do <<
  85. if notfirst and car x > 0 then prin2!* " + "
  86. else notfirst:=t$
  87. if null(car x = 1) then << prin2!* car x$ prin2!* "*" >>$
  88. prin2!* 'pv$ prin2!* '!($ prin2!* cdr x$ prin2!* '!)$
  89. >>$
  90. end$
  91. symbolic procedure pv_intequiv u$
  92. if atom cdr u then cdr u else nil$
  93. symbolic procedure i2pvector n$
  94. '!:pv . n$
  95. symbolic procedure pv_expt(u,n)$
  96. if n=1 then u
  97. else rederr list('pv_expt,"*** Can't powered pvector")$
  98. symbolic procedure pv_quotient(u,c)$
  99. if pv_intequiv c and cdr c = 1 then u
  100. else rederr list('pv_quotient,"*** pvector can't be divided by: ",c)$
  101. symbolic procedure pv_divide(u,v)$
  102. rederr list('pv_divide,"*** Can't divide pvector by pvector")$
  103. symbolic procedure pv_gcd(u,v)$ car u . 1$
  104. %-------------------------------------------------------
  105. initdmode 'pvector$
  106. symbolic procedure pv_add(v1,v2)$
  107. % v1,v2 - pvectors.
  108. % Return v1+v2.
  109. if null v1 then v2
  110. else if null v2 then v1
  111. else begin scalar r,h$
  112. while v1 or v2 do
  113. if v1 and v2 and cdar v1 = cdar v2 then <<
  114. h:=caar v1 + caar v2$
  115. if null(h = 0) then r:=(h . cdar v1) . r$
  116. v1:=cdr v1$
  117. v2:=cdr v2$
  118. >>
  119. else if (v1 and null v2) or (v1 and v2 and cdar v1 > cdar v2)
  120. then << r:=(car v1 . r)$ v1:=cdr v1 >>
  121. else << r:=(car v2 . r)$ v2:=cdr v2 >>$
  122. return reversip r$
  123. end$
  124. symbolic procedure pv_neg v1$
  125. % v1 - pvector$
  126. % Return - v1.
  127. begin scalar r$
  128. while v1 do <<
  129. r:= ((-caar v1) . cdar v1) . r$
  130. v1:=cdr v1$
  131. >>$
  132. return reversip r$
  133. end$
  134. symbolic procedure pv_multc(v,c)$
  135. if c=0 or null v then nil
  136. else if c=1 then v
  137. else begin scalar r$
  138. while v do <<
  139. if null(caar v = 0) then r:=((c*caar v) . cdar v) . r$
  140. v:=cdr v$
  141. >>$
  142. return reversip r$
  143. end$
  144. %-------------------- Sorting ... -----------------------
  145. symbolic procedure pv_sort v$
  146. if null v then nil
  147. else pv_sort1(cdr v,list car v)$
  148. symbolic procedure pv_sort1(v,v1)$
  149. if null v then reversip v1
  150. else if cdar v < cdar v1 then pv_sort1(cdr v,car v . v1)
  151. else pv_sort1(cdr v,pv_sort2(car v,v1))$
  152. symbolic procedure pv_sort2(x,v1)$
  153. << pv_sort2a(x,v1); v1 >>$
  154. symbolic procedure pv_sort2a(x,v1)$
  155. if null cdr v1
  156. then if cdr x > cdar v1 then rplacd(v1,list x)
  157. else (lambda w; rplacd(rplaca(v1,x),w)) (car v1 . cdr v1)
  158. else if cdr x > cdar v1 then pv_sort2a(x,cdr v1)
  159. else (lambda w; rplacd(rplaca(v1,x),w)) (car v1 . cdr v1)$
  160. %------------------- pv_renorm -------------------------------
  161. symbolic procedure pv_compress v$
  162. begin scalar u$
  163. while v do <<
  164. if null(caar v = 0) then u:=car v . u$
  165. v:=cdr v$
  166. >>$
  167. return reversip u$
  168. end$
  169. symbolic procedure pv_renorm v$ % not v modified.
  170. if null v then nil
  171. else begin scalar r,k$
  172. while v and caar v = 0 do v:=cdr v$
  173. if null v then return nil$
  174. if caar v < 0 then v:=pv_neg v$
  175. k:=caar v$
  176. r:=cdr v$
  177. while r and k neq 1 do <<
  178. k:=gcdf!*(k,caar r)$
  179. r:=cdr r$
  180. >>$
  181. r:=nil$
  182. for each x in v do
  183. if null(car x = 0)
  184. then r:=(if k=1 then x else ((car x/k) . cdr x)) . r$
  185. return reversip r$
  186. end$
  187. %---------------------------------------------------------------
  188. symbolic procedure pappl_pv(p,v)$
  189. pv_sort for each x in v collect (car x . pappl0(p,cdr x))$
  190. symbolic procedure pv_applp(v,p)$
  191. pv_sort for each x in v collect (car x . pappl0(cdr x,p))$
  192. symbolic procedure pv_upright(v,d)$
  193. for each x in v collect (car x . pupright(cdr x,d))$
  194. symbolic procedure vupleft(v,d)$
  195. for each x in v collect (car x . pupleft(cdr x,d))$
  196. endmodule;
  197. end;