fide.red 50 KB

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