fide.red 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995
  1. load!-package 'fide1; % We need this loaded.
  2. %***********************************************************************
  3. %***** *****
  4. %***** D A T A FOR DISCRETIZATION (CHANGE IF YOU NEED) *****
  5. %***** *****
  6. %***********************************************************************
  7. difmatch all,1,
  8. 0,1$
  9. difmatch all,u,
  10. u=one,0,
  11. u(i),
  12. u=half,0,
  13. (u(i-1/2)+u(i+1/2))/2$
  14. difmatch all,diff(u,x),
  15. u=one,2,
  16. (u(i+1)-u(i-1))/(dip1+dim1),
  17. u=half,0,
  18. (u(i+1/2)-u(i-1/2))/di$
  19. difmatch all,diff(u,x,2),
  20. u=one,0,
  21. ((u(i+1)-u(i))/dip1-(u(i)-u(i-1))/dim1)/di,
  22. u=half,2,
  23. ((u(i+3/2)-u(i+1/2))/dip2-(u(i-1/2)-u(i-3/2))/dim2)/(dip1+dim1)$
  24. difmatch all,u*v,
  25. u=one,v=one,0,
  26. u(i)*v(i),
  27. u=one,v=half,0,
  28. u(i)*(v(i-1/2)+v(i+1/2))/2,
  29. u=half,v=one,0,
  30. (u(i-1/2)+u(i+1/2))/2*v(i),
  31. u=half,v=half,0,
  32. (u(i-1/2)*v(i-1/2)+u(i+1/2)*v(i+1/2))/2$
  33. difmatch all,u**n,
  34. u=one,0,
  35. u(i)**n,
  36. u=half,0,
  37. (u(i-1/2)**n+u(i+1/2)**n)/2$
  38. difmatch all,u*v**n,
  39. u=one,v=one,0,
  40. u(i)*v(i)**n,
  41. u=one,v=half,0,
  42. u(i)*(v(i-1/2)**n+v(i+1/2)**n)/2,
  43. u=half,v=one,0,
  44. (u(i-1/2)+u(i+1/2))/2*v(i)**n,
  45. u=half,v=half,0,
  46. (u(i-1/2)*v(i-1/2)**n+u(i+1/2)*v(i+1/2)**n)/2$
  47. difmatch all,u*v*w,
  48. u=one,v=one,w=one,0,
  49. u(i)*v(i)*w(i),
  50. u=one,v=one,w=half,0,
  51. u(i)*v(i)*(w(i+1/2)+w(i-1/2))/2,
  52. u=one,v=half,w=one,0,
  53. u(i)*(v(i-1/2)+v(i+1/2))/2*w(i),
  54. u=one,v=half,w=half,0,
  55. u(i)*(v(i-1/2)*w(i-1/2)+v(i+1/2)*w(i+1/2))/2,
  56. u=half,v=one,w=one,0,
  57. (u(i-1/2)+u(i+1/2))/2*v(i)*w(i),
  58. u=half,v=one,w=half,0,
  59. (u(i-1/2)*w(i-1/2)+u(i+1/2)*w(i+1/2))/2*v(i),
  60. u=half,v=half,w=one,0,
  61. (u(i-1/2)*v(i-1/2)+u(i+1/2)*v(i+1/2))/2*w(i),
  62. u=half,v=half,w=half,0,
  63. (u(i-1/2)*v(i-1/2)*w(i-1/2)+u(i+1/2)*v(i+1/2)*w(i+1/2))/2$
  64. difmatch all,v*diff(u,x),
  65. u=one,v=one,2,
  66. v(i)*(u(i+1)-u(i-1))/(dip1+dim1),
  67. u=one,v=half,2,
  68. (v(i+1/2)+v(i-1/2))/2*(u(i+1)-u(i-1))/(dip1+dim1),
  69. u=half,v=one,0,
  70. v(i)*(u(i+1/2)-u(i-1/2))/di,
  71. u=half,v=half,0,
  72. (v(i+1/2)+v(i-1/2))/2*(u(i+1/2)-u(i-1/2))/di$
  73. difmatch all,v*w*diff(u,x),
  74. u=one,v=one,w=one,2,
  75. v(i)*w(i)*(u(i+1)-u(i-1))/(dip1+dim1),
  76. u=one,v=one,w=half,2,
  77. v(i)*(w(i-1/2)+w(i+1/2))/2*(u(i+1)-u(i-1))/(dip1+dim1),
  78. u=one,v=half,w=one,2,
  79. (v(i+1/2)+v(i-1/2))/2*w(i)*(u(i+1)-u(i-1))/(dip1+dim1),
  80. u=one,v=half,w=half,2,
  81. (v(i+1/2)*w(i+1/2)+v(i-1/2)*w(i-1/2))/2*(u(i+1)-u(i-1))/(dip1+dim1),
  82. u=half,v=one,w=one,0,
  83. v(i)*w(i)*(u(i+1/2)-u(i-1/2))/di,
  84. u=half,v=one,w=half,0,
  85. v(i)*(w(i-1/2)+w(i+1/2))/2*(u(i+1/2)-u(i-1/2))/di,
  86. u=half,v=half,w=one,0,
  87. (v(i+1/2)+v(i-1/2))/2*w(i)*(u(i+1/2)-u(i-1/2))/di,
  88. u=half,v=half,w=half,0,
  89. (v(i+1/2)*w(i+1/2)+v(i-1/2)*w(i-1/2))/2*(u(i+1/2)-u(i-1/2))/di$
  90. difmatch all,x*u,
  91. u=one,0,
  92. x(i)*u(i),
  93. u=half,1,
  94. (x(i-1/2)*u(i-1/2)+x(i+1/2)*u(i+1/2))/2$
  95. difmatch all,u/x**n,
  96. u=one,0,
  97. u(i)/x(i)**n,
  98. u=half,0,
  99. (u(i-1/2)/x(i-1/2)**n+u(i+1/2)/x(i+1/2)**n)/2$
  100. difmatch all,u*v/x**n,
  101. u=one,v=one,0,
  102. u(i)*v(i)/x(i)**n,
  103. u=one,v=half,0,
  104. u(i)*(v(i-1/2)+v(i+1/2))/2/x(i)**n,
  105. u=half,v=one,0,
  106. (u(i-1/2)+u(i+1/2))/2*v(i)/x(i)**n,
  107. u=half,v=half,0,
  108. (u(i-1/2)*v(i-1/2)/x(i-1/2)**n+u(i+1/2)*v(i+1/2)/x(i+1/2)**n)/2$
  109. difmatch all,diff(x**n*u,x)/x**n,
  110. u=one,2,
  111. (x(i+1)**n*u(i+1)-x(i-1)**n*u(i-1))/x(i)**n/(dim1+dip1),
  112. u=half,0,
  113. (x(i+1/2)**n*u(i+1/2)-x(i-1/2)**n*u(i-1/2))/di/x(i)**n$
  114. difmatch all,diff(u*v,x),
  115. u=one,v=one,4,
  116. (u(i+1)*v(i+1)-u(i-1)*v(i-1))/(dim1+dip1),
  117. u=one,v=half,2,
  118. ((u(i+1)+u(i))/2*v(i+1/2)-(u(i-1)+u(i))/2*v(i-1/2))/di,
  119. u=half,v=one,2,
  120. ((v(i+1)+v(i))/2*u(i+1/2)-(v(i-1)+v(i))/2*u(i-1/2))/di,
  121. u=half,v=half,0,
  122. (u(i+1/2)*v(i+1/2)-u(i-1/2)*v(i-1/2))/di$
  123. difmatch all,diff(u*v,x)/x**n,
  124. u=one,v=one,4,
  125. (u(i+1)*v(i+1)-u(i-1)*v(i-1))/x(i)**n/(dim1+dip1),
  126. u=one,v=half,2,
  127. ((u(i+1)+u(i))/2*v(i+1/2)-(u(i-1)+u(i))/2*v(i-1/2))/x(i)**n/di,
  128. u=half,v=one,2,
  129. ((v(i+1)+v(i))/2*u(i+1/2)-(v(i-1)+v(i))/2*u(i-1/2))/x(i)**n/di,
  130. u=half,v=half,0,
  131. (u(i+1/2)*v(i+1/2)-u(i-1/2)*v(i-1/2))/x(i)**n/di$
  132. difmatch all,diff(u*diff(v,x),x)/x**n,
  133. u=half,v=one,0,
  134. (u(i+1/2)*(v(i+1)-v(i))/dip1-u(i-1/2)*(v(i)-v(i-1))/dim1)/di/x(i)**n,
  135. u=half,v=half,2,
  136. (u(i+1/2)*(v(i+3/2)-v(i-1/2))/(di+dip2)-u(i-1/2)*(v(i+1/2)-
  137. v(i-3/2))/(di+dim2))/di/x(i)**n,
  138. u=one,v=one,2,
  139. ((u(i+1)+u(i))/2*(v(i+1)-v(i))/dip1-(u(i)+u(i-1))/2*(v(i)-v(i-1))
  140. /dim1)/di/x(i)**n,
  141. u=one,v=half,4,
  142. ((u(i+1)+u(i))/2*(v(i+3/2)-v(i-1/2))/(di+dip2)-
  143. (u(i)+u(i-1))/2*(v(i+1/2)-v(i-3/2))/(di+dim2))/di/x(i)**n$
  144. %***********************************************************************
  145. %***** E N D OF D A T A FOR DISCRETIZATION *****
  146. %***********************************************************************
  147. %***********************************************************************
  148. %***** *****
  149. %***** M O D U L E A P P R O X *****
  150. %***** *****
  151. %***********************************************************************
  152. module approx$
  153. % Author: R. Liska$
  154. % Program APPROX, Version REDUCE 3.4 05/1991$
  155. symbolic$
  156. symbolic fluid '(!*prapprox)$
  157. switch prapprox$
  158. !*prapprox:=nil$
  159. global '(cursym!* coords!* icoords!* functions!* hipow!* lowpow!*)$
  160. % Implicitely given indices
  161. icoords!*:='(i j k l m n i1 j1 k1 l1 m1 n1)$
  162. if null getd 'coordfn then
  163. procedure coordfn$
  164. begin
  165. scalar cor,icor$
  166. flag('(into),'delim)$
  167. cor:=remcomma xread nil$
  168. remflag('(into),'delim)$
  169. if cursym!* eq 'into then
  170. icor:=remcomma xread nil
  171. else if cursym!* eq '!*semicol!* then
  172. icor:=icoords!*
  173. else return symerr('coordfn,t)$
  174. return list('putcor,
  175. mkquote cor,
  176. mkquote icor)
  177. end$
  178. put('coordinates,'stat,'coordfn)$
  179. flag('(putcor),'nochange)$
  180. if null getd'putcor then
  181. procedure putcor(u,v)$
  182. begin
  183. scalar j$
  184. j:=1$
  185. coords!*:=u$
  186. while u do
  187. <<if not idp car u then msgpri
  188. (" Coordinate ",car u," must be identifier",nil,'hold)$
  189. if not idp car v then msgpri
  190. (" Index ",car v," must be identifier",nil,'hold)$
  191. put(car u,'index,list car v)$
  192. put(car v,'coord,list car u)$
  193. put(car u,'ngrid,j)$
  194. j:=j+1$
  195. put(car u,'simpfn,'simpiden)$
  196. u:=cdr u$
  197. v:=cdr v >>
  198. end$
  199. if null getd'tcar then
  200. procedure tcar u$
  201. if pairp u then car u
  202. else u$
  203. algebraic$
  204. procedure fact(n)$
  205. if n=0 then 1
  206. else n*fact(n-1)$
  207. procedure taylor(fce,var,step,ord)$
  208. if step=0 or ord=0 then fce
  209. else fce+for j:=1:ord sum step**j/fact(j)*df(fce,var,j)$
  210. symbolic$
  211. procedure maxorder u$
  212. begin
  213. scalar movar,var$
  214. a:movar:=car u$
  215. if not eqexpr movar then return errpri2(movar,'hold)$
  216. movar:=cdr movar$
  217. var:=car movar$
  218. movar:=reval cadr movar$
  219. if not atom var or not var memq coords!* then return msgpri(
  220. " Parameter ",var," must be coordinate",nil,'hold)
  221. else if not fixp movar then return msgpri(
  222. " Parameter ", movar," must be integer",nil,'hold)
  223. else put(var,'maxorder,movar)$
  224. u:=cdr u$
  225. if u then go to a$
  226. return nil
  227. end$
  228. put('maxorder,'stat,'rlis)$
  229. procedure center u$
  230. begin
  231. scalar movar,var$
  232. a:movar:=car u$
  233. if not eqexpr movar then return errpri2(movar,'hold)$
  234. movar:=cdr movar$
  235. var:=car movar$
  236. movar:=reval cadr movar$
  237. if not atom var or not var memq coords!* then return msgpri(
  238. " Parameter ",var," must be coordinate",nil,'hold)
  239. else if not(fixp movar or (eqcar(movar,'quotient) and
  240. (fixp cadr movar or
  241. (eqcar(cadr movar,'minus) and fixp cadadr movar))
  242. and fixp caddr movar)) then return msgpri(
  243. " Parameter ", movar," must be integer or rational number",nil,
  244. 'hold)
  245. else put(var,'center,movar)$
  246. u:=cdr u$
  247. if u then go to a$
  248. return nil
  249. end$
  250. put('center,'stat,'rlis)$
  251. procedure functions u$
  252. <<functions!* := u$
  253. for each a in u do put(a,'simpfn,'simpiden) >>$
  254. put('functions,'stat,'rlis)$
  255. procedure simptaylor u$
  256. begin
  257. scalar ind,var,movar,step,fce,ifce$
  258. fce:=car u$
  259. if null cdr u then return simp fce$
  260. ifce:=cadr u$
  261. if cddr u then fce:= fce . cddr u$
  262. ind:=mvar numr simp ifce$
  263. var:=tcar get(ind,'coord)$
  264. step:=reval list('difference,
  265. ifce,
  266. list('plus,
  267. if (movar:=get(var,'center)) then movar
  268. else 0,
  269. ind))$
  270. step:=list('times,
  271. step,
  272. get(var,'gridstep))$
  273. movar:=if (movar:=get(var,'maxorder)) then movar
  274. else 3$
  275. return simp list('taylor,
  276. fce,
  277. var,
  278. step,
  279. movar)
  280. end$
  281. algebraic$
  282. procedure approx difsch$
  283. begin
  284. scalar ldifsch,rdifsch,nrcoor,coors,rest,ldifeq,rdifeq$
  285. symbolic
  286. <<for each a in functions!* do
  287. <<put(a,'simpfn,'simptaylor)$
  288. eval list('depend,mkquote (a . coords!*)) >>$
  289. flag(functions!*,'full)$
  290. for each a in coords!* do put(a,'gridstep, intern compress append
  291. (explode 'h,explode a))$
  292. nrcoor:=length coords!* - 1$
  293. eval list('array,
  294. mkquote list('steps . add1lis list(nrcoor)))$
  295. coors:=coords!*$
  296. for j:=0:nrcoor do
  297. <<setel(list('steps,j),aeval get(car coors,'gridstep))$
  298. coors:=cdr coors >> >>$
  299. ldifsch:=lhs difsch$
  300. rdifsch:=rhs difsch$
  301. ldifeq:=ldifsch$
  302. rdifeq:=rdifsch$
  303. ldifeq:=substeps(ldifeq)$
  304. rdifeq:=substeps(rdifeq)$
  305. rest:=ldifsch-ldifeq-rdifsch+rdifeq$
  306. for j:=0:nrcoor do
  307. steps(j):=steps(j)**minorder(rest,steps(j))$
  308. write " Difference scheme approximates differential equation ",
  309. ldifeq=rdifeq$
  310. write " with orders of approximation:"$
  311. on div$
  312. for j:=0:nrcoor do write steps(j)$
  313. off div$
  314. symbolic if !*prapprox
  315. then algebraic write " Rest of approximation : ",rest$
  316. symbolic
  317. <<for each a in functions!* do
  318. <<put(a,'simpfn,'simpiden)$
  319. eval list('nodepend,mkquote (a . coords!*)) >>$
  320. remflag(functions!*,'full)>>$
  321. clear steps
  322. end$
  323. procedure substeps u$
  324. begin
  325. scalar step,nu,du$
  326. nu:=num u$
  327. du:=den u$
  328. symbolic for each a in coords!* do
  329. <<step:=get(a,'gridstep)$
  330. flag(list step,'used!*)$
  331. put(step,'avalue,'(scalar 0)) >>$
  332. symbolic rmsubs()$
  333. nu:=nu$
  334. du:=du$
  335. symbolic for each a in coords!* do
  336. <<step:=get(a,'gridstep)$
  337. remflag(list step,'used!*)$
  338. remprop(step,'avalue) >>$
  339. if du=0 then <<write
  340. " Reformulate difference scheme, grid steps remain in denominators"$
  341. u:=0 >>
  342. else u:=nu/du$
  343. return u
  344. end$
  345. procedure minorder(pol,var)$
  346. begin
  347. scalar lcofs,mord$
  348. coeff(den pol,var)$
  349. mord:=-hipow!*$
  350. lcofs := rest coeff(num pol,var)$
  351. if not mord=0 then return (mord+lowpow!*)$
  352. mord:=1$
  353. a:if lcofs={} then return 0
  354. else if first lcofs=0 then lcofs:=rest lcofs
  355. else return mord$
  356. mord:=mord+1$
  357. go to a
  358. end$
  359. algebraic$
  360. endmodule$
  361. %***********************************************************************
  362. %***** *****
  363. %***** M O D U L E C H A R P O L *****
  364. %***** *****
  365. %***********************************************************************
  366. module charpol$
  367. % Author: R. Liska
  368. % Program CHARPOL Version REDUCE 3.4 05/1991
  369. symbolic$
  370. fluid '(!*exp !*gcd !*prfourmat)$
  371. switch prfourmat$
  372. !*prfourmat:=t$
  373. procedure coefc1 uu$
  374. begin
  375. scalar lco,l,u,v,a$
  376. u:=car uu$
  377. v:=cadr uu$
  378. a:=caddr uu$
  379. lco:=aeval list('coeff,u,v)$
  380. lco:=cdr lco$
  381. l:=length lco - 1$
  382. for i:=0:l do
  383. <<setel(list(a,i),car lco)$
  384. lco:=cdr lco >>$
  385. return (l . 1)
  386. end$
  387. deflist('((coefc1 coefc1)),'simpfn)$
  388. global '(cursym!* coords!* icoords!* unvars!*)$
  389. icoords!*:='(i j k l m n i1 j1 k1 l1 m1 n1)$
  390. if null getd'coordfn then
  391. procedure coordfn$
  392. begin
  393. scalar cor,icor$
  394. flag('(into),'delim)$
  395. cor:=remcomma xread nil$
  396. remflag('(into),'delim)$
  397. if cursym!* eq 'into then
  398. icor:=remcomma xread nil
  399. else if cursym!* eq '!*semicol!* then
  400. icor:=icoords!*
  401. else return symerr('coordfn,t)$
  402. return list('putcor,
  403. mkquote cor,
  404. mkquote icor)
  405. end$
  406. put('coordinates,'stat,'coordfn)$
  407. flag('(putcor),'nochange)$
  408. if null getd'putcor then
  409. procedure putcor(u,v)$
  410. begin
  411. scalar j$
  412. j:=1$
  413. coords!*:=u$
  414. while u do
  415. <<if not idp car u then msgpri
  416. (" Coordinate ",car u," must be identifier",nil,'hold)$
  417. if not idp car v then msgpri
  418. (" Index ",car v," must be identifier",nil,'hold)$
  419. put(car u,'index,list car v)$
  420. put(car v,'coord,list car u)$
  421. put(car u,'ngrid,j)$
  422. j:=j+1$
  423. put(car u,'simpfn,'simpiden)$
  424. u:=cdr u$
  425. v:=cdr v >>
  426. end$
  427. if null getd'tcar then
  428. procedure tcar u$
  429. if pairp u then car u
  430. else u$
  431. if null getd 'grid then
  432. procedure grid u$
  433. eval list(get(car u,'grid),
  434. mkquote cdr u)$
  435. put('grid,'stat,'rlis)$
  436. put('uniform,'grid,'gridunif)$
  437. if null getd'gridunif then
  438. procedure gridunif u$
  439. flag(u,'uniform)$
  440. flag('(tcon unit charmat ampmat denotemat),'matflg)$
  441. put('unit,'rtypefn,'getrtypecar)$
  442. put('charmat,'rtypefn,'getrtypecar)$
  443. put('ampmat,'rtypefn,'getrtypecar)$
  444. put('denotemat,'rtypefn,'getrtypecar)$
  445. procedure unit u$
  446. generateident length matsm u$
  447. procedure charmat u$
  448. matsm list('difference,list('times,'lam,list('unit,u)),u)$
  449. procedure charpol u$
  450. simp list('det,list('charmat,carx(u,'charpol)))$
  451. put('charpol,'simpfn,'charpol)$
  452. algebraic$
  453. korder lam$
  454. procedure re(x)$
  455. sub(i=0,x)$
  456. procedure im(x)$
  457. (x-re(x))/i$
  458. procedure con(x)$
  459. sub(i=-i,x)$
  460. procedure complexpol x$
  461. begin
  462. scalar y$
  463. y:=troot1 x$
  464. return if im y=0 then y
  465. else y*con y
  466. end$
  467. procedure troot1 x$
  468. begin
  469. scalar y$
  470. y:=x$
  471. while not(sub(lam=0,y)=y) and sub(lam=1,y)=0 do y:=y/(lam-1)$
  472. x:=sub(lam=1,y)$
  473. if not(numberp y or (numberp num y and numberp den y)) then
  474. write " If ",re x," = 0 and ",im x,
  475. " = 0 , a root of the polynomial is equal to 1."$
  476. return y
  477. end$
  478. procedure hurw(x)$
  479. % X is a polynomial in LAM, all its roots are |LAMI|<1 <=> for all roots
  480. % of the polynomial HURW(X) holds RE(LAMI)<0.
  481. (lam-1)**deglam(num x)*sub(lam=(lam+1)/(lam-1),x)$
  482. symbolic$
  483. procedure deglam x$
  484. begin
  485. scalar y,z,exp$
  486. exp:=!*exp$
  487. !*exp:=t$
  488. y:=simp car x$
  489. if not numberp cdr y then go to e$
  490. y:=car y$
  491. if mvar y='lam then z:=ldeg y
  492. else go to e$
  493. !*exp:=exp$
  494. return (z . 1)$
  495. e:typerr(x, "polynomial in LAM")
  496. end$
  497. put('deglam,'simpfn,'deglam)$
  498. procedure unfunc u$
  499. <<unvars!*:=u$
  500. for each a in u do put(a,'simpfn,'simpiden) >>$
  501. put('unfunc,'stat,'rlis)$
  502. global '(denotation!* denotid!*)$
  503. denotation!*:=nil$
  504. denotid!*:='a$
  505. procedure denotid u$
  506. <<denotid!*:=car u$nil>>$
  507. put('denotid,'stat,'rlis)$
  508. procedure cleardenot$
  509. denotation!*:=nil$
  510. put('cleardenot,'stat,'endstat)$
  511. flag('(cleardenot),'eval)$
  512. algebraic$
  513. array cofpol!*(20)$
  514. procedure denotepol u$
  515. begin
  516. scalar nco,dco$
  517. dco:=den u$
  518. u:=num u$
  519. nco:=coefc1 (u,lam,cofpol!*)$
  520. for j:=0:nco do cofpol!*(j):=cofpol!*(j)/dco$
  521. denotear nco$
  522. u:=for j:=0:nco sum lam**j*cofpol!*(j)$
  523. return u
  524. end$
  525. symbolic$
  526. put('denotear,'simpfn,'denotear)$
  527. procedure denotear u$
  528. begin
  529. scalar nco,x$
  530. nco:=car u$
  531. for i:=0:nco do
  532. <<x:=list('cofpol!*,i)$
  533. setel(x,mk!*sq denote(getel x,0,i)) >>$
  534. return (nil .1)
  535. end$
  536. procedure denotemat u$
  537. begin
  538. scalar i,j,x$
  539. i:=0$
  540. x:=for each a in matsm u collect
  541. <<i:=i+1$
  542. j:=0$
  543. for each b in a collect
  544. <<j:=j+1$
  545. denote(mk!*sq b,i,j) >> >>$
  546. return x
  547. end$
  548. procedure denote(u,i,j)$
  549. % U is prefix form, I,J are integers
  550. begin
  551. scalar reu,imu,ireu,iimu,eij,fgcd$
  552. if atom u then return simp u$
  553. fgcd:=!*gcd$
  554. !*gcd:=t$
  555. reu:=simp!* list('re,u)$
  556. imu:=simp!* list('im,u)$
  557. !*gcd:=fgcd$
  558. eij:=append(explode i,explode j)$
  559. ireu:=intern compress append(append(explode denotid!* ,'(r)),eij)$
  560. iimu:=intern compress append(append(explode denotid!* ,'(i)),eij)$
  561. if car reu then insdenot(ireu,reu)$
  562. if car imu then insdenot(iimu,imu)$
  563. return simp list('plus,
  564. if car reu then ireu
  565. else 0,
  566. list('times,
  567. 'i,
  568. if car imu then iimu
  569. else 0))
  570. end$
  571. procedure insdenot(iden,u)$
  572. denotation!*:=(u . iden) . denotation!*$
  573. procedure prdenot$
  574. for each a in reverse denotation!* do
  575. varpri(list('!*sq,car a,t),list('setq,cdr a,nil),'only)$
  576. put('prdenot,'stat,'endstat)$
  577. flag('(prdenot),'eval)$
  578. procedure ampmat u$
  579. begin
  580. scalar x,i,h1,h0,un,rh1,rh0,ru,ph1,ph0,exp$
  581. exp:=!*exp$
  582. !*exp:=t$
  583. fouriersubs()$
  584. u:=car matsm u$
  585. x:=for each a in coords!* collect if a='t then 0
  586. else list('times,
  587. tcar get(a,'index),
  588. get(a,'wave),
  589. get(a,'step))$
  590. x:=list('expp,'plus . x)$
  591. x:=simp x$
  592. u:=for each a in u collect resimp quotsq(a,x)$
  593. gonsubs()$
  594. u:=for each a in u collect resimp a$
  595. remfourier()$
  596. a:if null u then go to d$
  597. ru:=caar u$
  598. un:=unvars!*$
  599. i:=1$
  600. b:if un then go to c$
  601. rh1:=reverse rh1$
  602. rh0:=reverse rh0$
  603. h1:=rh1 . h1$
  604. h0:=rh0 . h0$
  605. rh0:=rh1:=nil$
  606. u:=cdr u$
  607. go to a$
  608. c:rh1:=coefck(ru,list('u1!*,i)) . rh1$
  609. rh0:=negsq coefck(ru,list('u0!*,i)) . rh0$
  610. un:=cdr un$
  611. i:=i+1$
  612. go to b$
  613. d:h1:=reverse h1$
  614. h0:=reverse h0$
  615. if !*prfourmat then
  616. <<ph1:=for each a in h1 collect
  617. for each b in a collect prepsq!* b$
  618. setmatpri('h1,nil . ph1)$
  619. ph1:=nil$
  620. ph0:=for each a in h0 collect
  621. for each b in a collect prepsq!* b$
  622. setmatpri('h0,nil . ph0)$
  623. ph0:=nil >>$
  624. x:=if length h1=1 then list list quotsq(caar h0,caar h1)
  625. else lnrsolve(h1,h0)$
  626. x:=for each a in x collect for each b in a collect
  627. simp list('isimp,list('!*sq,b,nil))$
  628. !*exp:=exp$
  629. return x
  630. end$
  631. algebraic procedure isimp x$
  632. begin
  633. scalar n,d,y$
  634. n:=num x$
  635. d:=den x$
  636. y:=sub(i=-i,d)$
  637. n:=n*y$
  638. d:=d*y$
  639. on gcd$
  640. y:=n/d$
  641. off gcd$
  642. return y
  643. end$
  644. procedure coefck(x,y)$
  645. % X is standard form, Y is prefix form, returns coefficient of Y
  646. % appearing in X, i.e. X contains COEFCK(X,Y)*Y
  647. begin
  648. scalar ky,xs$
  649. ky:=!*a2k y$
  650. xs:=car subf(x,list(ky . 0))$
  651. xs:=addf(x,negf xs)$
  652. if null xs then return(nil . 1)$
  653. xs:=quotf1(xs,!*k2f ky)$
  654. return if null xs then <<msgpri
  655. ("COEFCK failed on ",list('sq!*,x . 1,nil)," with ",y,'hold)$
  656. xread nil$
  657. !*f2q xs>>
  658. else !*f2q xs
  659. end$
  660. procedure simpfour u$
  661. begin
  662. scalar nrunv,x,ex,arg,mv,cor,incr,lcor$
  663. nrunv:=get(car u,'nrunvar)$
  664. a:u:=cdr u$
  665. if null u then go to r$
  666. arg:=simp car u$
  667. mv:=mvar car arg$
  668. if not atom mv or not numberp cdr arg then return msgpri
  669. ("Bad index ",car u,nil,nil,'hold)$
  670. cor:=tcar get(mv,'coord)$
  671. if not cor member coords!* then return msgpri
  672. ("Term ",car u," contains non-coordinate ",mv,'hold)$
  673. if cor member lcor then return msgpri
  674. ("Term ",car u," means second appearance of coordinate ",cor,
  675. 'hold)$
  676. if not cor='t and cdr arg>get(cor,'maxden)
  677. then put(cor,'maxden,cdr arg)$
  678. lcor:=cor . lcor$
  679. incr:=addsq(arg,negsq !*k2q mv)$
  680. if not flagp(cor,'uniform) then return lprie
  681. ("Non-uniform grids not yet supported")$
  682. if cor='t then go to ti$
  683. ex:=list('times,car u,get(cor,'step),get(cor,'wave)) . ex$
  684. go to a$
  685. ti:if null car incr then x:=list('u0!*,nrunv)
  686. else if incr= 1 . 1 then x:=list('u1!*,nrunv)
  687. else return lprie "Scheme is not twostep in time"$
  688. go to a$
  689. r:for each a in setdiff(coords!*,lcor) do
  690. if a='t then x:=list('u0!*,nrunv)
  691. else ex:=list('times,tcar get(a,'index),get(a,'step),get(a,'wave))
  692. . ex$
  693. return simp list('times,x,list('expp,'plus . ex))
  694. end$
  695. procedure fouriersubs$
  696. begin
  697. scalar x,i$
  698. for each a in '(expp u1!* u0!*) do put(a,'simpfn,'simpiden)$
  699. x:=unvars!*$
  700. i:=1$
  701. a:if null x then go to b$
  702. put(car x,'nrunvar,i)$
  703. i:=i+1$
  704. x:=cdr x$
  705. go to a$
  706. b:flag(unvars!*,'full)$
  707. for each a in unvars!* do put(a,'simpfn,'simpfour)$
  708. for each a in coords!* do
  709. if not a='t then
  710. <<x:=intern compress append(explode 'h,explode a)$
  711. put(a,'step,x)$
  712. if not flagp(a,'uniform) then put(x,'simpfn,'simpiden)$
  713. x:=intern compress append(explode 'k,explode a)$
  714. put(a,'wave,x)$
  715. x:=intern compress append(explode 'a,explode a)$
  716. put(a,'angle,x)$
  717. put(a,'maxden,1) >>$
  718. algebraic for all z,y,v let
  719. expp((z+y)/v)=expp(z/v)*expp(y/v),
  720. expp(z+y)=expp z*expp y
  721. end$
  722. procedure gonsubs$
  723. begin
  724. scalar xx$
  725. algebraic for all z,y,v clear expp((z+y)/v),expp(z+y)$
  726. for each a in coords!* do
  727. if not a='t then
  728. <<xx:=list('quotient,
  729. list('times,
  730. get(a,'maxden),
  731. get(a,'angle)),
  732. get(a,'step))$
  733. setk(get(a,'wave),aeval xx)$
  734. xx:=list('times,
  735. get(a,'wave),
  736. get(a,'step))$
  737. mathprint list('setq,
  738. get(a,'angle),
  739. if get(a,'maxden)=1 then xx
  740. else list('quotient,
  741. xx,
  742. get(a,'maxden))) >>$
  743. algebraic for all x let expp x=cos x+i*sin x$
  744. algebraic for all x,n such that numberp n and n>1 let
  745. sin(n*x)=sin x*cos((n-1)*x)+cos x*sin((n-1)*x),
  746. cos(n*x)=cos x*cos((n-1)*x)-sin x*sin((n-1)*x)$
  747. for each a in unvars!* do
  748. <<put(a,'simpfn,'simpiden)$
  749. remprop(a,'nrunvar) >>
  750. end$
  751. procedure remfourier$
  752. <<algebraic for all x clear expp x$
  753. algebraic for all x,n such that numberp n and n>1 clear
  754. sin(n*x),cos(n*x)$
  755. for each a in coords!* do
  756. if not a='t then
  757. <<remprop(a,'step)$
  758. remprop(remprop(a,'wave),'avalue)$
  759. remprop(a,'maxden) >> >>$
  760. operator numberp$
  761. algebraic$
  762. endmodule$
  763. %***********************************************************************
  764. %***** *****
  765. %***** M O D U L E H U R W P *****
  766. %***** *****
  767. %***********************************************************************
  768. module hurwp$
  769. % Author: R. Liska
  770. % Program HURWP Version REDUCE 3.4 05/1991
  771. symbolic$
  772. global '(ofl!* mlist!*)$
  773. fluid '(!*exp !*gcd)$
  774. symbolic if not getd 're then algebraic procedure re(x)$
  775. sub(i=0,x)$
  776. symbolic if not getd 'im then algebraic procedure im(x)$
  777. (x-re(x))/i$
  778. symbolic if not getd'con then algebraic procedure con(x)$
  779. sub(i=-i,x)$
  780. flag('(tcon),'matflg)$
  781. put('tcon,'msimpfn,'tcon)$
  782. put('tcon,'rtypefn,'getrtypecar)$
  783. procedure tcon u$
  784. % Calculates complex conjugate and transpose matrix
  785. begin
  786. scalar v,b$
  787. v:=matsm list('tp,u)$
  788. for each a in v do
  789. <<b:=a$
  790. while b do
  791. <<rplaca(b,quotsq(subf(numr car b, '((i minus i))),
  792. !*f2q denr car b))$
  793. b:=cdr b >> >>$
  794. return v
  795. end$
  796. algebraic$
  797. korder lam$
  798. symbolic if not getd 'hurw then algebraic procedure hurw(x)$
  799. (lam-1)**deglam(x)*sub(lam=(lam+1)/(lam-1),x)$
  800. symbolic$
  801. if not getd 'deglam then procedure deglam x$
  802. begin
  803. scalar y,z,exp$
  804. exp:=!*exp$
  805. !*exp:=t$
  806. y:=simp car x$
  807. if not numberp cdr y then go to e$
  808. y:=car y$
  809. if mvar y='lam then z:=ldeg y
  810. else go to e$
  811. !*exp:=exp$
  812. return (z . 1)$
  813. e:typerr(x,"Polynomial in LAM")
  814. end$
  815. put('deglam,'simpfn,'deglam)$
  816. global '(positive!* userpos!* userneg!* !*pfactor)$
  817. !*pfactor:=nil$
  818. procedure positivep u$
  819. % U is prefix form. Procedure tests if U>0, eventually writes this
  820. % condition and puts U into POSITIVE!*. If U<=0 then returns NIL,
  821. % if U>0 then T, in other cases 'COND.
  822. % If it does not know if U>0 and program is running in interactive
  823. % mode it asks user if U>0 and return value is based on user reply.
  824. if numberp u then
  825. if u>0 then t
  826. else nil
  827. else if eqcar(u,'!*sq) and fixp caadr u and fixp cdadr u then
  828. if caadr u*cdadr u>0 then t
  829. else nil
  830. else
  831. begin
  832. scalar x,exp$
  833. exp:=!*exp$
  834. if !*pfactor and
  835. member('factor,mlist!*) then
  836. <<!*exp:=nil$
  837. u:=aeval list('ppfactor,u) >>$
  838. u:=prepsq!* simp u$
  839. !*exp:=exp$
  840. x:=if terminalp() and null ofl!* then
  841. begin
  842. scalar y,z$
  843. prin2!* "Is it true, that "$
  844. maprin u$
  845. prin2!* " > 0 ?"$
  846. a:prin2!* " Reply (Y/N/?)"$
  847. terpri!* t$
  848. y:=read()$
  849. if y eq 'y then <<z:=t$ userpos!*:=u . userpos!* >>
  850. else if y eq 'n
  851. then <<z:=nil$ userneg!*:=u . userneg!*>>
  852. else if y eq '? then z:='cond
  853. else go to a$
  854. return z
  855. end
  856. else 'cond$
  857. if x eq 'cond then
  858. if null positive!* then positive!*:= list (1 . u)
  859. else positive!* := ((caar positive!* + 1) . u) . positive!*$
  860. return x
  861. end$
  862. global'(hconds!*)$
  863. algebraic$
  864. array cof(20),fcof(20)$
  865. share hconds!*$
  866. procedure ppfactor x$
  867. begin
  868. scalar d,n,de$
  869. d:=factorize(num x)$
  870. n:=for each a in d product a$
  871. if den x=1 then return n$
  872. d:=factorize(den x)$
  873. de:=for each a in d product a$
  874. return (n/de)
  875. end$
  876. procedure hurwitzp u$
  877. % U is a polynomial in LAM. Procedure tests if it is Hurwitz polynomial
  878. % i.e. for all its rools LAMI holds RE(LAMI)<0.
  879. % Returned values: YES - definitely yes
  880. % NO - definitely no
  881. % COND - if conditions holds (all members of POSITIVE!*
  882. % are >0)
  883. if im u=0 then rehurwp u
  884. else cohurwp u$
  885. symbolic$
  886. procedure coef1(u,v,a)$
  887. begin
  888. scalar lco,l$
  889. lco:=aeval list('coeff,u,v)$
  890. lco:=cdr lco$
  891. l:=length lco - 1$
  892. for i:=0:l do
  893. <<setel(list(a,i),car lco)$
  894. lco:=cdr lco >>$
  895. return l
  896. end$
  897. procedure rehurwp u$
  898. begin
  899. scalar deg,hurp,gcd$
  900. gcd:=!*gcd$
  901. !*gcd:=t$
  902. deg:=coef1(car u,'lam,'cof)$
  903. if deg=0 then return typerr(u,"Polynomial in LAM")$
  904. positive!* := userpos!* := userneg!* := nil$
  905. if deg <= 2 then
  906. <<for i:=0:deg do setel(list('cof,i),
  907. aeval list('quotient,
  908. getel list('cof,i),
  909. getel list('cof,deg)))$
  910. if deg=1 then hurp:=positivep getel list('cof,0)
  911. else if deg=2 then hurp:=
  912. if positivep getel list('cof,0) and
  913. positivep getel list('cof,1) then
  914. if positive!* then 'cond
  915. else t
  916. else nil$
  917. printcond(nil) >>
  918. else hurp:=rehurwp1 deg$
  919. !*gcd:=gcd$
  920. return rethurp hurp
  921. end$
  922. procedure rethurp hurp$
  923. <<hconds!*:= 'list . if positive!* then mapcar(positive!*,function cdr)
  924. else nil$
  925. !*k2q(if null hurp then 'no
  926. else if null positive!* then 'yes
  927. else 'cond) >>$
  928. put('rehurwp,'simpfn,'rehurwp)$
  929. procedure cohurwp u$
  930. begin
  931. scalar deg$
  932. u:=reval list('sub,'(equal lam (times i lam)),car u)$
  933. deg:=coef1(u,'lam,'cof)$
  934. if deg=0 then return typerr(u,"Polynomial in LAM")$
  935. positive!* := userpos!* := userneg!* :=nil$
  936. if aeval list('im,getel list('cof,deg))=0 then
  937. for j:= 0:deg do setel(list('cof,j),
  938. aeval list('times,'i,getel list('cof,j)))$
  939. return rethurp cohurwp1 (deg)
  940. end$
  941. put('cohurwp,'simpfn,'cohurwp)$
  942. procedure rehurwp1 deg$
  943. begin
  944. scalar i,bai,bdi,x,lich,sud,bsud,matr,hmat,csud,clich,dsud,dlich$
  945. a:i:=deg$
  946. csud:=clich:=nil$
  947. bsud:=t$
  948. b:x:=positivep getel list('cof,i)$
  949. if null x then go to c
  950. else if x eq t then bai:=t
  951. else if x eq 'cond then
  952. if i=deg or i=0 then <<csud:=caar positive!* . csud$
  953. clich:=caar positive!* . clich >>
  954. else if bsud then csud:=caar positive!* . csud
  955. else clich:=caar positive!* . clich$
  956. i:=i-1$
  957. bsud:=not bsud$
  958. if i>=0 then go to b$
  959. go to d$
  960. % Change of sign AI = - AI
  961. c:if bai or bdi then go to n
  962. else bai:=t$
  963. for i:=0:deg do setel(list('cof,i),
  964. aeval list('minus,getel list('cof,i)))$
  965. go to a$
  966. % Checking DI > 0 - Hurwitz determinants
  967. % Splitting to odd and even coeffs. AI, A0 is coeff. by LAM**DEG
  968. d:bsud:=t$
  969. for i:=deg step -1 until 0 do
  970. <<x:=simp getel list('cof,i)$
  971. if bsud then sud:=x . sud
  972. else lich:=x . lich$
  973. bsud:=not bsud >>$
  974. sud:=reverse sud$
  975. lich:=reverse lich$
  976. % Filling of SUD and LICH on the length DEG by zeroes from right
  977. sud:=filzero(sud,deg)$
  978. lich:=filzero(lich,deg)$
  979. dsud:=dlich:=nil$
  980. matr:=nil$
  981. i:=1$
  982. bsud:=nil$
  983. d1:matr:=nconc(matr,list lich)$
  984. lich:=(nil . 1) . lich$
  985. d2:hmat:=cutmat(matr,i)$
  986. x:=mk!*sq detq hmat$
  987. x:=positivep x$ % Necessary to add storing of odd and even DIs
  988. if null x then
  989. if bsud then go to n
  990. else go to c
  991. else if x eq t and not bsud then bdi:=t
  992. else if x eq 'cond then
  993. if bsud then dsud:=caar positive!* . dsud
  994. else dlich:=caar positive!* . dlich$
  995. i:=i+1$
  996. bsud:=not bsud$
  997. if i>deg then go to k$
  998. if not bsud then go to d1$
  999. matr:=nconc(matr,list sud)$
  1000. sud:=(nil . 1) . sud$
  1001. go to d2$
  1002. n:return nil$
  1003. k:if null positive!* or ((null csud or null clich) and
  1004. (null dsud or null dlich))
  1005. then return <<printuser()$ t>>$
  1006. prin2t "If we denote:"$
  1007. printcond(t)$
  1008. printdef('c1,clich:=reverse clich)$
  1009. printdef('c2,csud:=reverse csud)$
  1010. printdef('d1,dlich:=reverse dlich)$
  1011. printdef('d2,dsud:=reverse dsud)$
  1012. prin2t "Necessary and sufficient conditions are:"$
  1013. prin2t if null csud or null clich then " (D1) OR (D2)"
  1014. else if null dsud or null dlich then " (C1) OR (C2)"
  1015. else " ( (C1) OR (C2) ) AND ( (D1) OR (D2) )"$
  1016. printuser()$
  1017. return 'cond
  1018. end$
  1019. procedure printcond(x)$
  1020. <<if not x then
  1021. prin2t "Necessary and sufficient conditions are:"$
  1022. positive!*:=reverse positive!*$
  1023. for each a in positive!* do
  1024. <<if x then <<prin2!* " ("$
  1025. prin2!* car a$
  1026. prin2!* ") " >>$
  1027. maprin cdr a$
  1028. prin2!* " > 0"$
  1029. terpri!* t >>$
  1030. if not x then printuser() >>$
  1031. procedure printuser()$
  1032. if userpos!* or userneg!* then
  1033. <<prin2t"You have explicitly stated:"$
  1034. for each a in userpos!* do <<maprin a$
  1035. prin2!* " > 0"$
  1036. terpri!* t >>$
  1037. for each a in userneg!* do <<maprin a$
  1038. prin2!* " <= 0"$
  1039. terpri!* t >> >>$
  1040. procedure printdef(x,y)$
  1041. if y then
  1042. <<prin2!* " ("$
  1043. prin2!* x$
  1044. prin2!* ") ("$
  1045. prin2!* car y$
  1046. prin2!* ")"$
  1047. if cdr y then for each a in cdr y do
  1048. <<prin2!* " AND ("$
  1049. prin2!* a$
  1050. prin2!* ")" >>$
  1051. terpri!* t >>$
  1052. procedure filzero(x,n)$
  1053. % Adds zeros (in S.Q. form) to the list X from right on the length N
  1054. begin
  1055. scalar y,i$
  1056. y:=x$
  1057. i:=1$
  1058. if null x then return typerr(x,"Empty list")$
  1059. while cdr y do
  1060. <<y:=cdr y$
  1061. i:=i+1>>$
  1062. while i<n do
  1063. <<rplacd(y,list(nil . 1))$
  1064. y:=cdr y$
  1065. i:=i+1 >>$
  1066. return x
  1067. end$
  1068. procedure cutmat(x,n)$
  1069. % From each member of list X, i.e. row of a matrix, remains
  1070. % the first N elements
  1071. for each a in x collect cutrow(a,n)$
  1072. procedure cutrow(y,n)$
  1073. begin
  1074. scalar i,z,zz$
  1075. i:=1$
  1076. z:=list car y$
  1077. zz:=z$
  1078. y:=cdr y$
  1079. while i<n do
  1080. <<rplacd(zz,list car y)$
  1081. y:=cdr y$
  1082. zz:=cdr zz$
  1083. i:=i+1 >>$
  1084. return z
  1085. end$
  1086. procedure cohurwp1 (deg)$
  1087. begin
  1088. scalar k,x,y,ak,bk,akk,bkk,matr,hmat$
  1089. % Splitting on RE and IM part
  1090. for j:=0:deg do
  1091. <<x:=getel list('cof,j)$
  1092. y:=simp list('re,x)$
  1093. x:=resimp simp list('quotient,list('difference,x,mk!*sq y),'i)$
  1094. ak:=x . ak$
  1095. bk:=y . bk >>$
  1096. % Construction of coeffs. AI, BI
  1097. positive!*:=userpos!*:=userneg!*:=nil$
  1098. akk:=filzero(ak,2*deg)$
  1099. bkk:=filzero(bk,2*deg)$
  1100. k:=2$
  1101. d1:matr:=nconc(matr,list akk)$
  1102. matr:=nconc(matr,list bkk)$
  1103. akk:=(nil . 1) . akk$
  1104. bkk:=(nil . 1) . bkk$
  1105. hmat:=cutmat(matr,k)$
  1106. x:=mk!*sq detq hmat$
  1107. x:=positivep x$
  1108. if null x then go to n$
  1109. if k=2*deg then go to ko$
  1110. k:=k+2$
  1111. go to d1$
  1112. n:return nil$
  1113. ko:printcond(nil)$
  1114. return t
  1115. end$
  1116. algebraic$
  1117. endmodule$
  1118. %***********************************************************************
  1119. %***** ******
  1120. %***** M O D U L E L I N B A N D ******
  1121. %***** ******
  1122. %***********************************************************************
  1123. module linband$
  1124. % Author: R. Liska
  1125. % Program LINBAND Version REDUCE 3.4 05/1991
  1126. % GENTRAN package has to be loaded prior to this module
  1127. symbolic$
  1128. global'(fortcurrind!* genstmtnum!* genstmtincr!*)$
  1129. fluid'(!*period)$ % declaration for 3.4
  1130. %global'(!*period)$ % declaration for 3.3
  1131. fluid'(!*imsl !*nag !*essl)$
  1132. switch imsl,nag,essl$
  1133. !*imsl:=nil$
  1134. !*nag:=nil$
  1135. !*essl:=nil$
  1136. procedure ison x$
  1137. if eval x then 1
  1138. else 0$
  1139. operator ison$
  1140. if null getd 'gentempst then
  1141. procedure gentempst$
  1142. list('gentemp,xread t)$
  1143. global'(temp!*)$
  1144. temp!*:=nil$
  1145. procedure gentemp u$
  1146. <<temp!* := ((!*period . fortcurrind!*) . u) . temp!*$ nil>>$
  1147. put('gentemp,'stat,'gentempst)$
  1148. put('gentemp,'formfn,'formgentran)$
  1149. load!-package 'gentran;
  1150. procedure outtemp$
  1151. begin
  1152. scalar period,fortind$
  1153. period:=!*period$
  1154. fortind:=fortcurrind!*$
  1155. for each a in reverse temp!* do
  1156. <<!*period:=caar a$
  1157. fortcurrind!*:=cdar a$
  1158. eval list('gentran,mkquote cdr a,nil)>>$
  1159. temp!* := nil$
  1160. !*period:=period$
  1161. fortcurrind!*:=fortind$
  1162. return nil
  1163. end$
  1164. put('outtemp,'stat,'endstat)$
  1165. flag('(outtemp),'eval)$
  1166. algebraic$
  1167. procedure genlinbandsol(nlc,nuc,system)$
  1168. % Generates FORTRAN program for solving of linear algebraic system
  1169. % of equations with band matrix with NLC lower codiagonals and NUC
  1170. % upper codiagonals.
  1171. begin
  1172. scalar pvars,svars,vareq,fveq$
  1173. % PVARS - list of variables before actual variable
  1174. % SVARS - list of variables after actual variable
  1175. % VAREQ - actual v-equation (list {variable equation})
  1176. symbolic
  1177. <<put('list,'evfno,get('list,'evfn))$
  1178. put('list,'evfn,'listnoeval)$
  1179. put('equal,'psopfno,get('equal,'psopfn))$
  1180. put('equal,'psopfn,'equalaeval)>>$
  1181. system:=expanddo(nlc,nuc,system)$
  1182. vareq:=first system$
  1183. pvars:={}$
  1184. svars:=findsvars(nuc,vareq,system)$
  1185. off period$
  1186. gentran n:=1$
  1187. gentemp n:=1$
  1188. on period$
  1189. ncol!*:=nlc+nuc+1$
  1190. for i:=1:nlc do
  1191. <<genvareq(pvars,svars,vareq,nlc,nlc-i+1,pfix!*)$
  1192. pvars:=append(pvars,first vareq . {})$
  1193. system:=nextvareqsys(vareq,system)$
  1194. vareq:=first system$
  1195. system:=rest system$
  1196. gennp1()$
  1197. svars:=findsvars(nuc,vareq,system) >>$
  1198. while length svars=nuc do
  1199. <<genvareq(pvars,svars,vareq,nlc,0,0)$
  1200. pvars:=append(rest pvars,first vareq . {})$
  1201. fveq:=first system$
  1202. system:=nextvareqsys(vareq,system)$
  1203. vareq:=first system$
  1204. system:=rest system$
  1205. % Get in and get out of loop
  1206. if (ffst system=do) and (first vareq=first frrfst system and
  1207. rest vareq=rest frrfst system) then
  1208. pvars:=findpvars(nlc,first system)
  1209. else if first fveq=do and not(ffst system=do) then
  1210. pvars:=lastvars(nlc,fveq)$
  1211. gennp1()$
  1212. svars:=findsvars(nuc,vareq,system) >>$
  1213. for i:=1:nuc do
  1214. <<genvareq(pvars,svars,vareq,nlc,i,sfix!*)$
  1215. pvars:=append(rest pvars,first vareq . {})$
  1216. system:=nextvareqsys(vareq,system)$
  1217. vareq:=first system$
  1218. system:=rest system$
  1219. if not(svars={}) then
  1220. <<svars:=rest svars$
  1221. gennp1() >> >>$
  1222. off period$
  1223. if ison !*imsl = 1 then pvars:=gencall!-imsl(nlc,nuc)
  1224. else if ison !*nag = 1 then pvars:=gencall!-nag(nlc,nuc)
  1225. else if ison !*essl= 1 then pvars:=gencall!-essl(nlc,nuc)
  1226. else pvars:=gencall!-linpack(nlc,nuc)$
  1227. on period$
  1228. outtemp$
  1229. symbolic <<put('list,'evfn,remprop('list,'evfno))$
  1230. put('equal,'psopfn,remprop('equal,'psopfno))>>
  1231. end$
  1232. procedure gencall!-imsl (nlc,nuc)$
  1233. gentran
  1234. <<literal tab!*,"CALL LEQT1B(ACOF,N,",eval nlc,",",eval nuc,
  1235. ",IACOF,ARHS,1,IARHS,0,XL,IER)",cr!*$
  1236. literal "C IACOF IS ACTUAL 1-ST DIMENSION OF THE ACOF ARRAY",cr!*$
  1237. literal "C IARHS IS ACTUAL 1-ST DIMENSION OF THE ARHS ARRAY",cr!*$
  1238. literal "C XL IS WORKING ARRAY WITH SIZE N*(NLC+1)",cr!*$
  1239. literal
  1240. "C WHERE N IS NUMBER OF EQUATIONS NLC NUMBER OF LOWER",cr!*$
  1241. literal "C CODIAGONALS",cr!*$
  1242. literal
  1243. "C IF IER=129( .NE.0) MATRIX ACOF IS ALGORITHMICALLY SINGULAR",
  1244. cr!*$
  1245. literal tab!*,"IF(IER.NE.0) CALL ERROUT",cr!*>>$
  1246. procedure gencall!-linpack(nlc,nuc)$
  1247. if ncol!*=3 and nlc=1 then gencall!-linpack!-trid(nlc,nuc)
  1248. else gentran
  1249. <<literal tab!*,"CALL DGBFA(ACOF,IACOF,N,",eval nlc,",",eval nuc,
  1250. ",IPVT,IER)",cr!*$
  1251. literal "C N IS NUMBER OF EQUATIONS",cr!*$
  1252. literal "C ACOF IS ARRAY OF DIMENSION (IACOF,P), P >= N",cr!*$
  1253. literal "C IACOF >= ",eval(nlc+ncol!*),cr!*$
  1254. literal "C IPVT IS ARRAY OF DIMENSION AT LEAST (N)",cr!*$
  1255. literal "C IF (IER.NE.0) MATRIX ACOF IS ALGORITHMICALLY SINGULAR",
  1256. cr!*$
  1257. literal tab!*,"IF(IER.NE.0) CALL ERROUT",cr!*$
  1258. literal tab!*,"CALL DGBSL(ACOF,IACOF,N,",eval nlc,",",eval nuc,
  1259. ",IPVT,ARHS,0)",cr!*>>$
  1260. procedure gencall!-linpack!-trid(nlc,nuc)$
  1261. gentran
  1262. <<literal tab!*,"CALL DGTSL(N,ALCD,AD,AUCD,ARHS,IER)",cr!*$
  1263. literal "C N IS NUMBER OF EQUATIONS",cr!*$
  1264. literal
  1265. "C ALCD,AD,AUCD,ARHS ARE ARRAYS OF DIMENSION AT LEAST (N)",cr!*$
  1266. literal "C IF (IER.NE.0) MATRIX ACOF IS ALGORITHMICALLY SINGULAR",
  1267. cr!*$
  1268. literal tab!*,"IF(IER.NE.0) CALL ERROUT",cr!* >>$
  1269. procedure gencall!-essl(nlc,nuc)$
  1270. if ncol!*=3 and nlc=1 then gencall!-essl!-trid(nlc,nuc)
  1271. else gentran
  1272. <<literal tab!*,"CALL DGBF(ACOF,IACOF,N,",eval nlc,",",eval nuc,
  1273. ",IPVT)",cr!*$
  1274. literal "C N IS NUMBER OF EQUATIONS",cr!*$
  1275. literal "C ACOF AND ARHS ARE DOUBLE PRECISION TYPE",cr!*$
  1276. literal "C FOR SINGLE PRECISION CHANGE DGBF TO SGBF AND ",
  1277. "DGBS TO SGBS",cr!*$
  1278. literal "C ACOF IS ARRAY OF DIMENSION (IACOF,P), P >= N",cr!*$
  1279. literal "C IACOF >= ",eval(nlc+ncol!*+15),cr!*$
  1280. literal "C ARHS IS ARRAY OF DIMENSION AT LEAST (N)",cr!*$
  1281. literal "C IPVT IS INTEGER ARRAY OF DIMENSION AT LEAST (N)",cr!*$
  1282. literal tab!*,"CALL DGBS(ACOF,IACOF,N,",eval nlc,",",eval nuc,
  1283. ",IPVT,ARHS)",cr!*>>$
  1284. procedure gencall!-essl!-trid(nlc,nuc)$
  1285. gentran
  1286. <<literal tab!*,"CALL DGTF(N,ALCD,AD,AUCD,AF,IPVT)",cr!*$
  1287. literal "C N IS NUMBER OF EQUATIONS",cr!*$
  1288. literal
  1289. "C ALCD,AD,AUCD,AF,ARHS ARE ARRAYS OF DIMENSION AT LEAST (N)",cr!*$
  1290. literal "C THESE ARRAYS ARE DOUBLE PRECISION TYPE",cr!*$
  1291. literal "C FOR SINGLE PRECISION CHANGE DGTF TO SGTF AND ",
  1292. "DGTS TO SGTS",cr!*$
  1293. literal
  1294. "C IPVT IS INTEGER ARRAY OF DIMENSION AT LEAST (N+3)/8",cr!*$
  1295. literal tab!*,"CALL DGTS(N,ALCD,AD,AUCD,AF,IPVT,ARHS)",cr!* >>$
  1296. procedure gencall!-nag(nlc,nuc)$
  1297. if ncol!*=3 and nlc=1 then gencall!-nag!-trid(nlc,nuc)
  1298. else gentran
  1299. <<ier:=0$
  1300. literal tab!*,"CALL F01LBF(N,",eval nlc,",",eval nuc,
  1301. ",ACOF,IACOF,AL,IAL,IN,IV,IER)",cr!*$
  1302. literal "C N IS NUMBER OF EQUATIONS",cr!*$
  1303. literal "C ACOF IS ARRAY OF DIMENSION (IACOF,P), P >= N",cr!*$
  1304. literal "C IACOF >= MIN(N,",eval ncol!*,")",cr!*$
  1305. literal "C AL IS ARRAY OF DIMENSION (IAL,P), P >= N",cr!*$
  1306. literal "C IAL >= MAX(1,",eval nlc,")",cr!*$
  1307. literal "C IN IS INTEGER ARRAY OF DIMENSION AT LEAST (N)",cr!*$
  1308. literal tab!*,"IF(IER.NE.0) CALL ERROUT",cr!*$
  1309. literal tab!*,"CALL F04LDF(N,",eval nlc,",",eval nuc,
  1310. ",1,ACOF,IACOF,AL,IAL,IN,ARHS,IARHS,IER)",cr!*$
  1311. literal "C ARHS IS ARRAY OF DIMENSION (IARHS), IARHS >= N",cr!*$
  1312. literal tab!*,"IF(IER.NE.0) CALL ERROUT",cr!* >>$
  1313. procedure gencall!-nag!-trid(nlc,nuc)$
  1314. gentran
  1315. <<ier:=0$
  1316. literal tab!*,
  1317. "CALL F01LEF(N,AD,0.,AUCD,ALCD,1.E-10,AU2CD,IN,IER)",cr!*$
  1318. literal "C N IS NUMBER OF EQUATIONS",cr!*$
  1319. literal
  1320. "C ALCD,AD,AUCD,AU2CD,ARHS ARE ARRAYS OF DIMENSION AT LEAST (N)",cr!*$
  1321. literal "C IN IS INTEGER ARRAY OF DIMENSION AT LEAST (N)",cr!*$
  1322. literal tab!*,"IF(IER.NE.0 .OR. IN(N).NE.0) CALL ERROUT",cr!*$
  1323. literal tab!*,
  1324. "CALL F04LEF(1,N,AD,AUCD,ALCD,AU2CD,IN,ARHS,0.,IER)",cr!*$
  1325. literal tab!*,"IF(IER.NE.0) CALL ERROUT",cr!* >>$
  1326. procedure gennp1$
  1327. <<off period$
  1328. gentran n:=n+1$
  1329. gentemp n:=n+1$
  1330. on period >>$
  1331. % Definition of operator SUBE
  1332. symbolic$
  1333. symbolic procedure simpsube u$
  1334. begin
  1335. scalar x$
  1336. a:if null cdr u then go to d
  1337. else if null eqexpr car u then errpri2(car u,t)$
  1338. x:=list('equal,reval cadar u,caddar u) . x$
  1339. u:=cdr u$
  1340. go to a$
  1341. d:x:=reverse(car u . x)$
  1342. x:=subeval x$
  1343. return x
  1344. end$
  1345. symbolic put('sube,'psopfn,'simpsube)$
  1346. algebraic$
  1347. % Procedures FFRRST etc.
  1348. procedure ffst u$
  1349. first first u$
  1350. procedure frst u$
  1351. first rest u$
  1352. procedure rfst u$
  1353. rest first u$
  1354. procedure rrst u$
  1355. rest rest u$
  1356. procedure fffst u$
  1357. first ffst u$
  1358. procedure ffrst u$
  1359. first frst u$
  1360. procedure frfst u$
  1361. first rfst u$
  1362. procedure frrst u$
  1363. first rrst u$
  1364. procedure rffst u$
  1365. rest ffst u$
  1366. procedure rfrst u$
  1367. rest frst u$
  1368. procedure rrfst u$
  1369. rest rfst u$
  1370. procedure rrrst u$
  1371. rest rrst u$
  1372. procedure ffffst u$
  1373. ffst ffst u$
  1374. procedure fffrst u$
  1375. ffst frst u$
  1376. procedure ffrfst u$
  1377. ffst rfst u$
  1378. procedure ffrrst u$
  1379. ffst rrst u$
  1380. procedure frffst u$
  1381. frst ffst u$
  1382. procedure frfrst u$
  1383. frst frst u$
  1384. procedure frrfst u$
  1385. frst rfst u$
  1386. procedure frrrst u$
  1387. frst rrst u$
  1388. procedure rfffst u$
  1389. rfst ffst u$
  1390. procedure rffrst u$
  1391. rfst frst u$
  1392. procedure rfrfst u$
  1393. rfst rfst u$
  1394. procedure rfrrst u$
  1395. rfst rrst u$
  1396. procedure rrffst u$
  1397. rrst ffst u$
  1398. procedure rrfrst u$
  1399. rrst frst u$
  1400. procedure rrrfst u$
  1401. rrst rfst u$
  1402. procedure rrrrst u$
  1403. rrst rrst u$
  1404. procedure findsvars(nuc,vareq,system)$
  1405. % Looks for NUC next variables in SYSTEM
  1406. % VAREQ is actual v-equation
  1407. if ffst system=do then findsvarsdo(nuc,vareq,first system)
  1408. else findsvars1(nuc,rest system)$
  1409. procedure findsvars1(nuc,system)$
  1410. % Substitutes values for loop variable
  1411. if nuc=0 or system={} then {}
  1412. else if ffst system=do then fsvars1do(nuc,first system)
  1413. else ffst system . findsvars1(nuc-1,rest system)$
  1414. procedure fsvars1do(nuc,cykl)$
  1415. % Substitutes into the loop CYKL
  1416. begin
  1417. scalar id,from,step,syst,x,y$
  1418. cykl:=rest cykl$
  1419. syst:=first cykl$
  1420. id:=first syst$
  1421. from:=frst syst$
  1422. step:=frrrst syst$
  1423. syst:=rest cykl$
  1424. x:={}$
  1425. a:y:=sube(id=from,ffst syst)$
  1426. x:=y . x$
  1427. nuc:=nuc-1$
  1428. if nuc=0 then go to r$
  1429. syst:=rest syst$
  1430. if not(syst={}) then go to a$
  1431. syst:=rest cykl$
  1432. from:=from+step$
  1433. go to a$
  1434. r:x:=reverse x$
  1435. return x
  1436. end$
  1437. procedure findsvarsdo(nuc,vareq,cykl)$
  1438. % Does not substitute for loop variable, only increases it
  1439. % by STEP if it is necessary
  1440. begin
  1441. scalar id,add1,step,syst,x,y$
  1442. cykl:=rest cykl$
  1443. syst:=first cykl$
  1444. id:=first syst$
  1445. step:=frrrst syst$
  1446. syst:=rest cykl$
  1447. while not(first vareq=ffst syst and rest vareq=rfst syst)
  1448. do syst:=rest syst$
  1449. syst:=rest syst$
  1450. add1:=0$
  1451. x:={}$
  1452. a:if syst={} then go to b$
  1453. y:=sube(id=id+add1,ffst syst)$
  1454. x:=y . x$
  1455. nuc:=nuc-1$
  1456. if nuc=0 then go to r$
  1457. syst:=rest syst$
  1458. go to a$
  1459. b:syst:=rest cykl$
  1460. add1:=add1+step$
  1461. go to a$
  1462. r:x:=reverse x$
  1463. return x
  1464. end$
  1465. procedure expanddo(nlc,nuc,system)$
  1466. % Every loop in SYSTEM is expanded so that more than or equal to
  1467. % NLC first elements and more than or equal NUC last elements are
  1468. % excluded from the loop, and changes the parameters of loop so
  1469. % that its meaning remains the same
  1470. begin
  1471. scalar x$
  1472. x:={}$
  1473. a:if system={} then go to r$
  1474. if ffst system=do then x:=append(expddo(nlc,nuc,first system),x)
  1475. else x:=first system . x$
  1476. system:=rest system$
  1477. go to a$
  1478. r:x:=reverse x$
  1479. return x
  1480. end$
  1481. procedure expddo(nlc,nuc,cykl)$
  1482. % Performs the expansion of the loop CYKL - returns reverse list
  1483. begin
  1484. scalar id,from,to1,step,syst,lsyst,ns,x,y,bn$
  1485. cykl:=rest cykl$
  1486. syst:=first cykl$
  1487. id:=first syst$
  1488. from:=frst syst$
  1489. to1:=frrst syst$
  1490. step:=frrrst syst$
  1491. syst:=rest cykl$
  1492. lsyst:=length syst$
  1493. ns:=quotient1(nlc,lsyst)$
  1494. if nlc>ns*lsyst then ns:=ns+1$
  1495. bn:=0$
  1496. x:={}$
  1497. a:y:=sube(id=from,ffst syst) . sube(id=from,frfst syst) . {}$
  1498. x:=y . x$
  1499. syst:=rest syst$
  1500. if not(syst={}) then go to a$
  1501. ns:=ns-1$
  1502. from:=from+step$
  1503. if ns=0 then go to b$
  1504. syst:=rest cykl$
  1505. go to a$
  1506. b:if bn=1 then go to r$
  1507. syst:=rest cykl$
  1508. ns:=quotient1(nuc,lsyst)$
  1509. if nuc>ns*lsyst then ns:=ns+1$
  1510. to1:=to1-ns*step$
  1511. y:=do . (id . from . to1 . step . {}) . syst$
  1512. x:=y . x$
  1513. from:=to1+step$
  1514. bn:=1$
  1515. go to a$
  1516. r:return x
  1517. end$
  1518. symbolic procedure quotient1(u,v)$
  1519. quotient(u,v)$
  1520. symbolic operator quotient1$
  1521. operator acof,arhs$
  1522. procedure genvareq(pvars,svars,vareq,nlc,nzero,mode)$
  1523. if ison !*imsl = 1 then
  1524. genvareq!-imsl(pvars,svars,vareq,nlc,nzero,mode)
  1525. else if ison !*nag = 1 then
  1526. genvareq!-nag(pvars,svars,vareq,nlc,nzero,mode)
  1527. else genvareq!-linpack(pvars,svars,vareq,nlc,nzero,mode)$
  1528. procedure genvareq!-imsl(pvars,svars,vareq,nlc,nzero,mode)$
  1529. % Generates N-th row of coeff. matrix ACOF and right hand side ARHS
  1530. % according to the v-equation VAREQ.
  1531. % NZERO is number of zeroes before or after (according to MODE).
  1532. % Matrix ACOF is transformed to IMSL band matrix storage.
  1533. begin
  1534. integer j$
  1535. scalar var,rhside,lhside,x,y$
  1536. if not(length pvars + length svars+1+nzero=ncol!*) then return
  1537. write" Unconsistent PVARS:",pvars," SVARS:",svars," NZERO:",nzero$
  1538. var:=first vareq$
  1539. vareq:=frst vareq$
  1540. rhside:=rhs vareq$
  1541. lhside:=lhs vareq$
  1542. j:=1$
  1543. x:=0$
  1544. if mode=pfix!* then while j<=nzero do
  1545. <<gentran acof(n,eval j):=0$
  1546. j:=j+1 >>$
  1547. for each a in pvars do
  1548. <<y:=lincof(lhside,a)$
  1549. x:=x+a*y$
  1550. gentran acof(n,eval j):=:y$
  1551. j:=j+1>>$
  1552. y:=lincof(lhside,var)$
  1553. x:=x+var*y$
  1554. gentran acof(n,eval j):=:y$
  1555. j:=j+1$
  1556. for each a in svars do
  1557. <<y:=lincof(lhside,a)$
  1558. x:=x+a*y$
  1559. gentran acof(n,eval j):=:y$
  1560. j:=j+1>>$
  1561. if mode=sfix!* then while j<=ncol!* do
  1562. <<gentran acof(n,eval j):=0$
  1563. j:=j+1 >>$
  1564. gentran arhs(n):=:rhside$
  1565. gentemp eval(var):=arhs(n)$
  1566. if not(x-lhside=0) then write " For equation ",vareq," given only ",
  1567. "variables ",pvars,svars,var$
  1568. return
  1569. end$
  1570. procedure genvareq!-linpack(pvars,svars,vareq,nlc,nzero,mode)$
  1571. % Generates N-th row of coeff. matrix ACOF and right hand side ARHS
  1572. % according to the v-equation VAREQ.
  1573. % NZERO is number of zeroes before or after (according to MODE).
  1574. % Matrix ACOF is transformed to LINPACK band matrix storage.
  1575. % NCOL!* is the band width.
  1576. begin
  1577. integer j,jj,nn$
  1578. scalar var,rhside,lhside,x,y$
  1579. if not(length pvars + length svars+1+nzero=ncol!*) then return
  1580. write" Unconsistent PVARS:",pvars," SVARS:",svars," NZERO:",nzero$
  1581. if nlc=1 and ncol!*=3 then return
  1582. genvareq!-linpack!-trid(pvars,svars,vareq,nlc,nzero,mode)$
  1583. var:=first vareq$
  1584. vareq:=frst vareq$
  1585. rhside:=rhs vareq$
  1586. lhside:=lhs vareq$
  1587. j:=n-nlc$
  1588. jj:=1$
  1589. nn:=ncol!*+nlc$
  1590. x:=0$
  1591. if mode=pfix!* then while jj<=nzero do
  1592. <<nn:=nn-1$
  1593. jj:=jj+1$
  1594. j:=j+1 >>$
  1595. for each a in pvars do
  1596. <<y:=lincof(lhside,a)$
  1597. x:=x+a*y$
  1598. gentran acof(nn,j)::=:y$
  1599. nn:=nn-1$
  1600. j:=j+1>>$
  1601. y:=lincof(lhside,var)$
  1602. x:=x+var*y$
  1603. gentran acof(nn,j)::=:y$
  1604. nn:=nn-1$
  1605. j:=j+1$
  1606. for each a in svars do
  1607. <<y:=lincof(lhside,a)$
  1608. x:=x+a*y$
  1609. gentran acof(nn,j)::=:y$
  1610. nn:=nn-1$
  1611. j:=j+1>>$
  1612. gentran arhs(n):=:rhside$
  1613. gentemp eval(var):=arhs(n)$
  1614. if not(x-lhside=0) then write " For equation ",vareq," given only ",
  1615. "variables ",pvars,svars,var$
  1616. return
  1617. end$
  1618. procedure genvareq!-linpack!-trid(pvars,svars,vareq,nlc,nzero,mode)$
  1619. begin
  1620. scalar var,rhside,lhside,x,y$
  1621. var:=first vareq$
  1622. vareq:=frst vareq$
  1623. rhside:=rhs vareq$
  1624. lhside:=lhs vareq$
  1625. x:=0$
  1626. for each a in pvars do
  1627. <<y:=lincof(lhside,a)$
  1628. x:=x+a*y$
  1629. gentran alcd(n):=:y >>$
  1630. y:=lincof(lhside,var)$
  1631. x:=x+var*y$
  1632. gentran ad(n):=:y$
  1633. for each a in svars do
  1634. <<y:=lincof(lhside,a)$
  1635. x:=x+a*y$
  1636. gentran aucd(n):=:y >>$
  1637. gentran arhs(n):=:rhside$
  1638. gentemp eval(var):=arhs(n)$
  1639. if not(x-lhside=0) then write " For equation ",vareq," given only ",
  1640. "variables ",pvars,svars,var$
  1641. return
  1642. end$
  1643. procedure genvareq!-nag(pvars,svars,vareq,nlc,nzero,mode)$
  1644. % Generates N-th row of coeff. matrix ACOF and right hand side ARHS
  1645. % according to the v-equation VAREQ.
  1646. % NZERO is number of zeroes before or after (according to MODE).
  1647. % Matrix ACOF is transformed to NAG band matrix storage.
  1648. % NCOL!* is the band width.
  1649. begin
  1650. integer j$
  1651. scalar var,rhside,lhside,x,y$
  1652. if not(length pvars + length svars+1+nzero=ncol!*) then return
  1653. write" Unconsistent PVARS:",pvars," SVARS:",svars," NZERO:",nzero$
  1654. if nlc=1 and ncol!*=3 then return
  1655. genvareq!-nag!-trid(pvars,svars,vareq,nlc,nzero,mode)$
  1656. var:=first vareq$
  1657. vareq:=frst vareq$
  1658. rhside:=rhs vareq$
  1659. lhside:=lhs vareq$
  1660. j:=1$
  1661. x:=0$
  1662. for each a in pvars do
  1663. <<y:=lincof(lhside,a)$
  1664. x:=x+a*y$
  1665. gentran acof(eval j,n):=:y$
  1666. j:=j+1>>$
  1667. y:=lincof(lhside,var)$
  1668. x:=x+var*y$
  1669. gentran acof(eval j,n):=:y$
  1670. j:=j+1$
  1671. for each a in svars do
  1672. <<y:=lincof(lhside,a)$
  1673. x:=x+a*y$
  1674. gentran acof(eval j,n):=:y$
  1675. j:=j+1>>$
  1676. gentran arhs(n):=:rhside$
  1677. gentemp eval(var):=arhs(n)$
  1678. if not(x-lhside=0) then write " For equation ",vareq," given only ",
  1679. "variables ",pvars,svars,var$
  1680. return
  1681. end$
  1682. procedure genvareq!-nag!-trid(pvars,svars,vareq,nlc,nzero,mode)$
  1683. begin
  1684. scalar var,rhside,lhside,x,y$
  1685. var:=first vareq$
  1686. vareq:=frst vareq$
  1687. rhside:=rhs vareq$
  1688. lhside:=lhs vareq$
  1689. x:=0$
  1690. for each a in pvars do
  1691. <<y:=lincof(lhside,a)$
  1692. x:=x+a*y$
  1693. gentran alcd(n):=:y >>$
  1694. y:=lincof(lhside,var)$
  1695. x:=x+var*y$
  1696. gentran ad(n):=:y$
  1697. for each a in svars do
  1698. <<y:=lincof(lhside,a)$
  1699. x:=x+a*y$
  1700. gentran aucd(n+1):=:y >>$
  1701. gentran arhs(n):=:rhside$
  1702. gentemp eval(var):=arhs(n)$
  1703. if not(x-lhside=0) then write " For equation ",vareq," given only ",
  1704. "variables ",pvars,svars,var$
  1705. return
  1706. end$
  1707. procedure lincof(expre,ker)$
  1708. % Expression EXPRE is linear in kernel KER.
  1709. % Returns coeff. of KER in EXPRE.
  1710. (expre-sube(ker=0,expre))/ker$
  1711. stackdolabel!*:={}$
  1712. procedure nextvareqsys(vareq,system)$
  1713. % Looks for the next v-equation. Returns the new v-equation . SYSTEM.
  1714. % During get into the loop generates the beginning of the loop,
  1715. % during get out of the loop generates end of the loop.
  1716. if rest system={} then {} . {}
  1717. else if ffst system=do then nextvesdo(vareq,system)
  1718. else if ffrst system=do then nextvesdofst(rest system)
  1719. else frst system . rest system$
  1720. procedure nextvesdofst(system)$
  1721. % Get into the loop
  1722. begin
  1723. scalar id,from,to1,step$
  1724. id:=frfst system$
  1725. from:=frst id$
  1726. to1:=frrst id$
  1727. step:=frrrst id$
  1728. id:=first id$
  1729. genstmtnum!*:=genstmtnum!*+genstmtincr!*$
  1730. gentran literal tab!*,"DO ",eval(genstmtnum!*)," ",eval(id),"=",
  1731. eval(from),",",eval(to1),",",eval(step),cr!*$
  1732. stackdolabel!*:=genstmtnum!* . stackdolabel!*$
  1733. genstmtnum!*:=genstmtnum!*+genstmtincr!*$
  1734. gentemp <<literal tab!*,"DO ",eval(genstmtnum!*)," ",
  1735. eval(id),"=",eval(from),
  1736. ",",eval(to1),",",eval(step),cr!*>>$
  1737. fortcurrind!*:=fortcurrind!* + 4$
  1738. stackdolabel!*:=genstmtnum!* . stackdolabel!*$
  1739. id:=frrfst system . system$
  1740. return id
  1741. end$
  1742. procedure nextvesdo(vareq,system)$
  1743. % SYSTEM begins with a loop - test on the end of loop.
  1744. % Suppose that after the loop cannot be another loop, which
  1745. % follows from EXPANDDO.
  1746. begin
  1747. scalar vareqs$
  1748. vareqs:=rrfst system$
  1749. while not(first vareq=ffst vareqs and rest vareq=rfst vareqs) and
  1750. not(rest vareqs={}) do vareqs:=rest vareqs$
  1751. vareqs:=rest vareqs$
  1752. if vareqs={} then
  1753. % End of loop
  1754. <<fortcurrind!* := fortcurrind!* - 4$
  1755. gentemp<<literal eval first stackdolabel!*,tab!*,"CONTINUE",
  1756. cr!*>>$
  1757. stackdolabel!*:=rest stackdolabel!*$
  1758. gentran literal eval first stackdolabel!*,tab!*,"CONTINUE",cr!*$
  1759. stackdolabel!*:=rest stackdolabel!*$
  1760. vareqs:=frst system . rest system >>
  1761. else vareqs:=first vareqs . system$
  1762. return vareqs
  1763. end$
  1764. procedure findpvars(nlc,cykl)$
  1765. % Looks for NLC previous variables during geting into the loop
  1766. begin
  1767. scalar id,step$
  1768. id:=frst cykl$
  1769. step:=frrrst id$
  1770. id:=first id$
  1771. cykl:=reverse rrst cykl$
  1772. id:=reverse fsvars1do(nlc,
  1773. do . (id . (id-step) . 0 . (-step) . {}) . cykl)$
  1774. return id
  1775. end$
  1776. procedure lastvars(nlc,cykl)$
  1777. % Looks for the NLC last variables of the loop CYKL
  1778. begin
  1779. scalar id,step,to1$
  1780. id:=frst cykl$
  1781. to1:=frrst id$
  1782. step:=frrrst id$
  1783. id:=first id$
  1784. cykl:=reverse rrst cykl$
  1785. id:=reverse fsvars1do(nlc,do . (id . to1 . 0 . (-step) . {}) . cykl)$
  1786. return id
  1787. end$
  1788. symbolic$
  1789. flag('(ffst frst rfst rrst fffst ffrst frfst frrst rffst rfrst rrfst
  1790. rrrst ffffst fffrst ffrfst ffrrst frffst frfrst frrfst frrrst
  1791. rfffst rffrst rfrfst rfrrst rrffst rrfrst rrrfst rrrrst
  1792. findsvars findsvars1 fsvars1do findsvarsdo expanddo expddo
  1793. genvareq nextvareqsys nextvesdofst nextvesdo findpvars lastvars),
  1794. 'noval)$
  1795. procedure equalaeval u$
  1796. 'equal . aevlis u$
  1797. procedure aevlis u$
  1798. for each a in u collect aeval a$
  1799. procedure listnoeval(u,v)$
  1800. if atom u then listnoeval(cadr get(u,'avalue),v)
  1801. else u$
  1802. endmodule$
  1803. algebraic$
  1804. end$