charpol.red 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. module charpol;
  2. % Author: R. Liska.
  3. % Version REDUCE 3.6 05/1991.
  4. fluid '(!*exp !*gcd !*prfourmat)$
  5. switch prfourmat$
  6. !*prfourmat:=t$
  7. procedure coefc1 uu$
  8. begin
  9. scalar lco,l,u,v,a$
  10. u:=car uu$
  11. v:=cadr uu$
  12. a:=caddr uu$
  13. lco:=aeval list('coeff,u,v)$
  14. lco:=cdr lco$
  15. l:=length lco - 1$
  16. for i:=0:l do
  17. <<setel(list(a,i),car lco)$
  18. lco:=cdr lco >>$
  19. return (l . 1)
  20. end$
  21. deflist('((coefc1 coefc1)),'simpfn)$
  22. global '(cursym!* coords!* icoords!* unvars!*)$
  23. icoords!*:='(i j k l m n i1 j1 k1 l1 m1 n1)$
  24. flag('(tcon unit charmat ampmat denotemat),'matflg)$
  25. put('unit,'rtypefn,'getrtypecar)$
  26. put('charmat,'rtypefn,'getrtypecar)$
  27. put('ampmat,'rtypefn,'getrtypecar)$
  28. put('denotemat,'rtypefn,'getrtypecar)$
  29. procedure unit u$
  30. generateident length matsm u$
  31. procedure charmat u$
  32. matsm list('difference,list('times,'lam,list('unit,u)),u)$
  33. procedure charpol u$
  34. begin
  35. scalar x,complexx;
  36. complexx:=!*complex;
  37. algebraic on complex;
  38. x:=simp list('det,list('charmat,carx(u,'charpol)))$
  39. if null complexx then algebraic off complex;
  40. return x
  41. end;
  42. put('charpol,'simpfn,'charpol)$
  43. algebraic$
  44. korder lam$
  45. procedure re(x)$
  46. sub(i=0,x)$
  47. procedure im(x)$
  48. (x-re(x))/i$
  49. procedure con(x)$
  50. sub(i=-i,x)$
  51. procedure complexpol x$
  52. begin
  53. scalar y$
  54. y:=troot1 x$
  55. return if im y=0 then y
  56. else y*con y
  57. end$
  58. procedure troot1 x$
  59. begin
  60. scalar y$
  61. y:=x$
  62. while not(sub(lam=0,y)=y) and sub(lam=1,y)=0 do y:=y/(lam-1)$
  63. x:=sub(lam=1,y)$
  64. if not(numberp y or (numberp num y and numberp den y)) then
  65. write " If ",re x," = 0 and ",im x,
  66. " = 0 , a root of the polynomial is equal to 1."$
  67. return y
  68. end$
  69. procedure hurw(x)$
  70. % X is a polynomial in LAM, all its roots are |LAMI|<1 <=> for all roots
  71. % of the polynomial HURW(X) holds RE(LAMI)<0.
  72. (lam-1)**deg(num x,lam)*sub(lam=(lam+1)/(lam-1),x)$
  73. symbolic$
  74. procedure unfunc u$
  75. <<unvars!*:=u$
  76. for each a in u do put(a,'simpfn,'simpiden) >>$
  77. put('unfunc,'stat,'rlis)$
  78. global '(denotation!* denotid!*)$
  79. denotation!*:=nil$
  80. denotid!*:='a$
  81. procedure denotid u$
  82. <<denotid!*:=car u$nil>>$
  83. put('denotid,'stat,'rlis)$
  84. procedure cleardenot$
  85. denotation!*:=nil$
  86. put('cleardenot,'stat,'endstat)$
  87. flag('(cleardenot),'eval)$
  88. algebraic$
  89. array cofpol!*(20)$
  90. procedure denotepol u$
  91. begin
  92. scalar nco,dco$
  93. dco:=den u$
  94. u:=num u$
  95. nco:=coefc1 (u,lam,cofpol!*)$
  96. for j:=0:nco do cofpol!*(j):=cofpol!*(j)/dco$
  97. denotear nco$
  98. u:=for j:=0:nco sum lam**j*cofpol!*(j)$
  99. return u
  100. end$
  101. symbolic$
  102. put('denotear,'simpfn,'denotear)$
  103. procedure denotear u$
  104. begin
  105. scalar nco,x$
  106. nco:=car u$
  107. for i:=0:nco do
  108. <<x:=list('cofpol!*,i)$
  109. setel(x,mk!*sq denote(getel x,0,i)) >>$
  110. return (nil .1)
  111. end$
  112. procedure denotemat u$
  113. begin
  114. scalar i,j,x$
  115. i:=0$
  116. x:=for each a in matsm u collect
  117. <<i:=i+1$
  118. j:=0$
  119. for each b in a collect
  120. <<j:=j+1$
  121. denote(mk!*sq b,i,j) >> >>$
  122. return x
  123. end$
  124. procedure denote(u,i,j)$
  125. % U is prefix form, I,J are integers
  126. begin
  127. scalar reu,imu,ireu,iimu,eij,fgcd$
  128. if atom u then return simp u$
  129. fgcd:=!*gcd$
  130. !*gcd:=t$
  131. reu:=simp!* list('re,u)$
  132. imu:=simp!* list('im,u)$
  133. !*gcd:=fgcd$
  134. eij:=append(explode i,explode j)$
  135. ireu:=intern compress append(append(explode denotid!* ,'(r)),eij)$
  136. iimu:=intern compress append(append(explode denotid!* ,'(i)),eij)$
  137. if car reu then insdenot(ireu,reu)$
  138. if car imu then insdenot(iimu,imu)$
  139. return simp list('plus,
  140. if car reu then ireu
  141. else 0,
  142. list('times,
  143. 'i,
  144. if car imu then iimu
  145. else 0))
  146. end$
  147. procedure insdenot(iden,u)$
  148. denotation!*:=(u . iden) . denotation!*$
  149. procedure prdenot$
  150. for each a in reverse denotation!* do
  151. assgnpri(list('!*sq,car a,t),list cdr a,'only)$
  152. put('prdenot,'stat,'endstat)$
  153. flag('(prdenot),'eval)$
  154. procedure ampmat u$
  155. begin
  156. scalar x,i,h1,h0,un,rh1,rh0,ru,ph1,ph0,!*exp,!*gcd,complexx$
  157. complexx:=!*complex;
  158. !*exp:=t$
  159. fouriersubs()$
  160. u:=car matsm u$
  161. x:=for each a in coords!* collect if a='t then 0
  162. else list('times,
  163. tcar get(a,'index),
  164. get(a,'wave),
  165. get(a,'step))$
  166. x:=list('expp,'plus . x)$
  167. x:=simp x$
  168. u:=for each a in u collect resimp quotsq(a,x)$
  169. gonsubs()$
  170. algebraic on complex;
  171. u:=for each a in u collect resimp a$
  172. remfourier()$
  173. a:if null u then go to d$
  174. ru:=caar u$
  175. un:=unvars!*$
  176. i:=1$
  177. b:if un then go to c$
  178. rh1:=reverse rh1$
  179. rh0:=reverse rh0$
  180. h1:=rh1 . h1$
  181. h0:=rh0 . h0$
  182. rh0:=rh1:=nil$
  183. u:=cdr u$
  184. go to a$
  185. c:rh1:=coefck(ru,list('u1!*,i)) . rh1$
  186. rh0:=negsq coefck(ru,list('u0!*,i)) . rh0$
  187. un:=cdr un$
  188. i:=i+1$
  189. go to b$
  190. d:h1:=reverse h1$
  191. h0:=reverse h0$
  192. if !*prfourmat then
  193. <<ph1:=for each a in h1 collect
  194. for each b in a collect prepsq!* b$
  195. setmatpri('h1,nil . ph1)$
  196. ph1:=nil$
  197. ph0:=for each a in h0 collect
  198. for each b in a collect prepsq!* b$
  199. setmatpri('h0,nil . ph0)$
  200. ph0:=nil >>$
  201. !*gcd:=t;
  202. x:=if length h1=1 then list list quotsq(caar h0,caar h1)
  203. else lnrsolve(h1,h0)$
  204. if null complexx then algebraic off complex;
  205. return x
  206. end$
  207. procedure coefck(x,y)$
  208. % X is standard form, Y is prefix form, returns coefficient of Y
  209. % appearing in X, i.e. X contains COEFCK(X,Y)*Y
  210. begin
  211. scalar ky,xs$
  212. ky:=!*a2k y$
  213. xs:=car subf(x,list(ky . 0))$
  214. xs:=addf(x,negf xs)$
  215. if null xs then return(nil . 1)$
  216. xs:=quotf1(xs,!*k2f ky)$
  217. return if null xs then <<msgpri
  218. ("COEFCK failed on ",list('sq!*,x . 1,nil)," with ",y,'hold)$
  219. xread nil$
  220. !*f2q xs>>
  221. else !*f2q xs
  222. end$
  223. procedure simpfour u$
  224. begin
  225. scalar nrunv,x,ex,arg,mv,cor,incr,lcor$
  226. nrunv:=get(car u,'nrunvar)$
  227. a:u:=cdr u$
  228. if null u then go to r$
  229. arg:=simp car u$
  230. mv:=mvar car arg$
  231. if not atom mv or not numberp cdr arg then return msgpri
  232. ("Bad index ",car u,nil,nil,'hold)$
  233. cor:=tcar get(mv,'coord)$
  234. if not(cor member coords!*) then return msgpri
  235. ("Term ",car u," contains non-coordinate ",mv,'hold)$
  236. if cor member lcor then return msgpri
  237. ("Term ",car u," means second appearance of coordinate ",cor,
  238. 'hold)$
  239. if not(cor='t) and cdr arg>get(cor,'maxden)
  240. then put(cor,'maxden,cdr arg)$
  241. lcor:=cor . lcor$
  242. incr:=addsq(arg,negsq !*k2q mv)$
  243. if not flagp(cor,'uniform) then return lprie
  244. ("Non-uniform grids not yet supported")$
  245. if cor='t then go to ti$
  246. ex:=list('times,car u,get(cor,'step),get(cor,'wave)) . ex$
  247. go to a$
  248. ti:if null car incr then x:=list('u0!*,nrunv)
  249. else if incr= 1 . 1 then x:=list('u1!*,nrunv)
  250. else return lprie "Scheme is not twostep in time"$
  251. go to a$
  252. r:for each a in setdiff(coords!*,lcor) do
  253. if a='t then x:=list('u0!*,nrunv)
  254. else ex:=list('times,tcar get(a,'index),get(a,'step),get(a,'wave))
  255. . ex$
  256. return simp list('times,x,list('expp,'plus . ex))
  257. end$
  258. procedure fouriersubs$
  259. begin
  260. scalar x,i$
  261. for each a in '(expp u1!* u0!*) do put(a,'simpfn,'simpiden)$
  262. x:=unvars!*$
  263. i:=1$
  264. a:if null x then go to b$
  265. put(car x,'nrunvar,i)$
  266. i:=i+1$
  267. x:=cdr x$
  268. go to a$
  269. b:flag(unvars!*,'full)$
  270. for each a in unvars!* do put(a,'simpfn,'simpfour)$
  271. for each a in coords!* do
  272. if not(a='t) then
  273. <<x:=intern compress append(explode 'h,explode a)$
  274. put(a,'step,x)$
  275. if not flagp(a,'uniform) then put(x,'simpfn,'simpiden)$
  276. x:=intern compress append(explode 'k,explode a)$
  277. put(a,'wave,x)$
  278. x:=intern compress append(explode 'a,explode a)$
  279. put(a,'angle,x)$
  280. put(a,'maxden,1) >>$
  281. algebraic for all z,y,v let
  282. expp((z+y)/v)=expp(z/v)*expp(y/v),
  283. expp(z+y)=expp z*expp y
  284. end$
  285. procedure gonsubs$
  286. begin
  287. scalar xx$
  288. algebraic for all z,y,v clear expp((z+y)/v),expp(z+y)$
  289. for each a in coords!* do
  290. if not(a='t) then
  291. <<xx:=list('quotient,
  292. list('times,
  293. get(a,'maxden),
  294. get(a,'angle)),
  295. get(a,'step))$
  296. setk(get(a,'wave),aeval xx)$
  297. xx:=list('times,
  298. get(a,'wave),
  299. get(a,'step))$
  300. mathprint list('setq,
  301. get(a,'angle),
  302. if get(a,'maxden)=1 then xx
  303. else list('quotient,
  304. xx,
  305. get(a,'maxden))) >>$
  306. algebraic for all x let expp x=cos x+i*sin x$
  307. algebraic for all x,n such that numberp n and n>1 let
  308. sin(n*x)=sin x*cos((n-1)*x)+cos x*sin((n-1)*x),
  309. cos(n*x)=cos x*cos((n-1)*x)-sin x*sin((n-1)*x)$
  310. for each a in unvars!* do
  311. <<put(a,'simpfn,'simpiden)$
  312. remprop(a,'nrunvar) >>
  313. end$
  314. procedure remfourier$
  315. <<algebraic for all x clear expp x$
  316. algebraic for all x,n such that numberp n and n>1 clear
  317. sin(n*x),cos(n*x)$
  318. for each a in coords!* do
  319. if not(a='t) then
  320. <<remprop(a,'step)$
  321. remprop(remprop(a,'wave),'avalue)$
  322. remprop(a,'maxden) >> >>$
  323. operator numberp$
  324. endmodule;
  325. end;