sle.pas 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291
  1. {
  2. $Id$
  3. This file is part of the Numlib package.
  4. Copyright (c) 1986-2000 by
  5. Kees van Ginneken, Wil Kortsmit and Loek van Reij of the
  6. Computational centre of the Eindhoven University of Technology
  7. FPC port Code by Marco van de Voort ([email protected])
  8. documentation by Michael van Canneyt ([email protected])
  9. !! modifies randseed, might not exactly work as TP version!!!
  10. Solve set of linear equations of the type Ax=b, for generic, and a
  11. variety of special matrices.
  12. See the file COPYING.FPC, included in this distribution,
  13. for details about the copyright.
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. **********************************************************************}
  18. {Solve set of linear equations of the type Ax=b, for generic, and a variety of
  19. special matrices.
  20. One (generic) function for overdetermined sets of this kind : slegls
  21. overdetermined are sets that look like this: (I don't know if I
  22. translated "overdetermined" right)
  23. 6 1 2 3 9
  24. 3 9 3 4 2
  25. 17 27 42 15 62
  26. 17 27 42 15 61
  27. The two bottom rows look much alike, which introduces a big uncertainty in the
  28. result, therefore these matrices need special treatment.
  29. All procedures have similar procedure with a "L" appended to the name. We
  30. didn't receive docs for those procedures. If you know what the difference is,
  31. please mail us }
  32. Unit sle;
  33. interface
  34. {$I DIRECT.INC}
  35. uses typ, omv;
  36. {solve for special tridiagonal matrices}
  37. Procedure sledtr(n: ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
  38. {solve for generic bandmatrices}
  39. Procedure slegba(n, l, r: ArbInt;
  40. Var a, b, x, ca: ArbFloat; Var term:ArbInt);
  41. Procedure slegbal(n, l, r: ArbInt;
  42. Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
  43. {generic solve for all matrices}
  44. Procedure slegen(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
  45. Var term: ArbInt);
  46. Procedure slegenl( n: ArbInt;
  47. Var a1;
  48. Var b1, x1, ca: ArbFloat;
  49. Var term: ArbInt);
  50. {solve for overdetermined matrices, see unit comments}
  51. Procedure slegls(Var a: ArbFloat; m, n, rwidtha: ArbInt; Var b, x: ArbFloat;
  52. Var term: ArbInt);
  53. Procedure sleglsl(Var a1; m, n: ArbInt; Var b1, x1: ArbFloat;
  54. Var term: ArbInt);
  55. {Symmetrical positive definitive bandmatrices}
  56. Procedure slegpb(n, l: ArbInt; Var a, b, x, ca: ArbFloat;
  57. Var term: ArbInt);
  58. Procedure slegpbl(n, l: ArbInt;
  59. Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
  60. {Symmetrical positive definitive matrices}
  61. Procedure slegpd(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
  62. Var term: ArbInt);
  63. Procedure slegpdl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
  64. Var term: ArbInt);
  65. {Symmetrical matrices}
  66. Procedure slegsy(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
  67. Var term: ArbInt);
  68. Procedure slegsyl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
  69. Var term: ArbInt);
  70. {tridiagonal matrices}
  71. Procedure slegtr(n:ArbInt; Var l, d, u, b, x, ca: ArbFloat;
  72. Var term: ArbInt);
  73. implementation
  74. Uses DSL,MDT;
  75. {Here originally stood an exact copy of mdtgtr from unit mdt}
  76. {Here originally stood an exact copy of dslgtr from unit DSL}
  77. Procedure decomp(Var qr: ArbFloat; m, n, rwidthq: ArbInt; Var alpha: ArbFloat;
  78. Var pivot, term: ArbInt);
  79. Var i, j, jbar, k, ns, ii : ArbInt;
  80. beta, sigma, alphak, qrkk, s : ArbFloat;
  81. pqr, pal, y, sum : ^arfloat1;
  82. piv : ^arint1;
  83. Begin
  84. term := 1;
  85. pqr := @qr;
  86. pal := @alpha;
  87. piv := @pivot;
  88. ns := n*sizeof(ArbFloat);
  89. getmem(y, ns);
  90. getmem(sum, ns);
  91. For j:=1 To n Do
  92. Begin
  93. s := 0;
  94. For i:=1 To m Do
  95. s := s+sqr(pqr^[(i-1)*rwidthq+j]);
  96. sum^[j] := s;
  97. piv^[j] := j
  98. End; {j}
  99. For k:=1 To n Do
  100. Begin
  101. sigma := sum^[k];
  102. jbar := k;
  103. For j:=k+1 To n Do
  104. If sigma < sum^[j] Then
  105. Begin
  106. sigma := sum^[j];
  107. jbar := j
  108. End;
  109. If jbar <> k
  110. Then
  111. Begin
  112. i := piv^[k];
  113. piv^[k] := piv^[jbar];
  114. piv^[jbar] := i;
  115. sum^[jbar] := sum^[k];
  116. sum^[k] := sigma;
  117. For i:=1 To m Do
  118. Begin
  119. ii := (i-1)*rwidthq;
  120. sigma := pqr^[ii+k];
  121. pqr^[ii+k] := pqr^[ii+jbar];
  122. pqr^[ii+jbar] := sigma
  123. End; {i}
  124. End; {column interchange}
  125. sigma := 0;
  126. For i:=k To m Do
  127. sigma := sigma+sqr(pqr^[(i-1)*rwidthq+k]);
  128. If sigma=0 Then
  129. Begin
  130. term := 2;
  131. freemem(y, ns);
  132. freemem(sum, ns);
  133. exit
  134. End;
  135. qrkk := pqr^[(k-1)*rwidthq+k];
  136. If qrkk < 0 Then
  137. alphak := sqrt(sigma)
  138. Else
  139. alphak := -sqrt(sigma);
  140. pal^[k] := alphak;
  141. beta := 1/(sigma-qrkk*alphak);
  142. pqr^[(k-1)*rwidthq+k] := qrkk-alphak;
  143. For j:=k+1 To n Do
  144. Begin
  145. s := 0;
  146. For i:=k To m Do
  147. Begin
  148. ii := (i-1)*rwidthq;
  149. s := s+pqr^[ii+k]*pqr^[ii+j]
  150. End; {i}
  151. y^[j] := beta*s
  152. End; {j}
  153. For j:=k+1 To n Do
  154. Begin
  155. For i:=k To m Do
  156. Begin
  157. ii := (i-1)*rwidthq;
  158. pqr^[ii+j] := pqr^[ii+j]-pqr^[ii+k]*y^[j]
  159. End; {i}
  160. sum^[j] := sum^[j]-sqr(pqr^[(k-1)*rwidthq+j])
  161. End {j}
  162. End; {k}
  163. freemem(y, ns);
  164. freemem(sum, ns);
  165. End; {decomp}
  166. Procedure decomp1(Var qr1; m, n: ArbInt; Var alpha1: ArbFloat;
  167. Var pivot1, term: ArbInt);
  168. Var i, j, jbar, k, ns : ArbInt;
  169. beta, sigma, alphak, qrkk, s : ArbFloat;
  170. qr : ar2dr1 absolute qr1;
  171. alpha : arfloat1 absolute alpha1;
  172. pivot : arint1 absolute pivot1;
  173. y, sum : ^arfloat1;
  174. Begin
  175. term := 1;
  176. ns := n*sizeof(ArbFloat);
  177. getmem(y, ns);
  178. getmem(sum, ns);
  179. For j:=1 To n Do
  180. Begin
  181. s := 0;
  182. For i:=1 To m Do
  183. s := s+sqr(qr[i]^[j]);
  184. sum^[j] := s;
  185. pivot[j] := j
  186. End; {j}
  187. For k:=1 To n Do
  188. Begin
  189. sigma := sum^[k];
  190. jbar := k;
  191. For j:=k+1 To n Do
  192. If sigma < sum^[j]
  193. Then
  194. Begin
  195. sigma := sum^[j];
  196. jbar := j
  197. End;
  198. If jbar <> k
  199. Then
  200. Begin
  201. i := pivot[k];
  202. pivot[k] := pivot[jbar];
  203. pivot[jbar] := i;
  204. sum^[jbar] := sum^[k];
  205. sum^[k] := sigma;
  206. For i:=1 To m Do
  207. Begin
  208. sigma := qr[i]^[k];
  209. qr[i]^[k] := qr[i]^[jbar];
  210. qr[i]^[jbar] := sigma
  211. End; {i}
  212. End; {column interchange}
  213. sigma := 0;
  214. For i:=k To m Do
  215. sigma := sigma+sqr(qr[i]^[k]);
  216. If sigma=0
  217. Then
  218. Begin
  219. term := 2;
  220. freemem(y, ns);
  221. freemem(sum, ns);
  222. exit
  223. End;
  224. qrkk := qr[k]^[k];
  225. If qrkk < 0 Then alphak := sqrt(sigma)
  226. Else alphak := -sqrt(sigma);
  227. alpha[k] := alphak;
  228. beta := 1/(sigma-qrkk*alphak);
  229. qr[k]^[k] := qrkk-alphak;
  230. For j:=k+1 To n Do
  231. Begin
  232. s := 0;
  233. For i:=k To m Do
  234. s := s+qr[i]^[k]*qr[i]^[j];
  235. y^[j] := beta*s
  236. End; {j}
  237. For j:=k+1 To n Do
  238. Begin
  239. For i:=k To m Do
  240. qr[i]^[j] := qr[i]^[j]-qr[i]^[k]*y^[j];
  241. sum^[j] := sum^[j]-sqr(qr[k]^[j])
  242. End {j}
  243. End; {k}
  244. freemem(y, ns);
  245. freemem(sum, ns);
  246. End; {decomp1}
  247. Procedure solve(Var qr: ArbFloat; m, n, rwidthq: ArbInt; Var alpha: ArbFloat;
  248. Var pivot: ArbInt; Var r, y: ArbFloat);
  249. Var i, j, ii : ArbInt;
  250. gamma, s : ArbFloat;
  251. pqr, pal, pr, py, z : ^arfloat1;
  252. piv : ^arint1;
  253. Begin
  254. pqr := @qr;
  255. pal := @alpha;
  256. piv := @pivot;
  257. pr := @r;
  258. py := @y;
  259. getmem(z, n*sizeof(ArbFloat));
  260. For j:=1 To n Do
  261. Begin
  262. gamma := 0;
  263. For i:=j To m Do
  264. gamma := gamma+pqr^[(i-1)*rwidthq+j]*pr^[i];
  265. gamma := gamma/(pal^[j]*pqr^[(j-1)*rwidthq+j]);
  266. For i:=j To m Do
  267. pr^[i] := pr^[i]+gamma*pqr^[(i-1)*rwidthq+j]
  268. End; {j}
  269. z^[n] := pr^[n]/pal^[n];
  270. For i:=n-1 Downto 1 Do
  271. Begin
  272. s := pr^[i];
  273. ii := (i-1)*rwidthq;
  274. For j:=i+1 To n Do
  275. s := s-pqr^[ii+j]*z^[j];
  276. z^[i] := s/pal^[i]
  277. End; {i}
  278. For i:=1 To n Do
  279. py^[piv^[i]] := z^[i];
  280. freemem(z, n*sizeof(ArbFloat));
  281. End; {solve}
  282. Procedure solve1(Var qr1; m, n: ArbInt; Var alpha1: ArbFloat;
  283. Var pivot1: ArbInt; Var r1, y1: ArbFloat);
  284. Var i, j : ArbInt;
  285. gamma, s : ArbFloat;
  286. qr : ar2dr1 absolute qr1;
  287. alpha : arfloat1 absolute alpha1;
  288. r : arfloat1 absolute r1;
  289. y : arfloat1 absolute y1;
  290. pivot : arint1 absolute pivot1;
  291. z : ^arfloat1;
  292. Begin
  293. getmem(z, n*sizeof(ArbFloat));
  294. For j:=1 To n Do
  295. Begin
  296. gamma := 0;
  297. For i:=j To m Do
  298. gamma := gamma+qr[i]^[j]*r[i];
  299. gamma := gamma/(alpha[j]*qr[j]^[j]);
  300. For i:=j To m Do
  301. r[i] := r[i]+gamma*qr[i]^[j]
  302. End; {j}
  303. z^[n] := r[n]/alpha[n];
  304. For i:=n-1 Downto 1 Do
  305. Begin
  306. s := r[i];
  307. For j:=i+1 To n Do
  308. s := s-qr[i]^[j]*z^[j];
  309. z^[i] := s/alpha[i]
  310. End; {i}
  311. For i:=1 To n Do
  312. y[pivot[i]] := z^[i];
  313. freemem(z, n*sizeof(ArbFloat));
  314. End; {solve1}
  315. Procedure sledtr(n: ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
  316. Var i, j, sr : ArbInt;
  317. lj, di : ArbFloat;
  318. pd, pu, pb, px, dd : ^arfloat1;
  319. pl : ^arfloat2;
  320. Begin
  321. If n<1
  322. Then
  323. Begin
  324. term := 3;
  325. exit
  326. End; {wrong input}
  327. pl := @l;
  328. pd := @d;
  329. pu := @u;
  330. pb := @b;
  331. px := @x;
  332. sr := sizeof(ArbFloat);
  333. getmem(dd, n*sr);
  334. move(pb^, px^, n*sr);
  335. j := 1;
  336. di := pd^[j];
  337. dd^[j] := di;
  338. If di=0
  339. Then
  340. term := 2
  341. Else
  342. term := 1;
  343. while (term=1) and (j <> n) Do
  344. Begin
  345. i := j;
  346. j := j+1;
  347. lj := pl^[j]/di;
  348. di := pd^[j]-lj*pu^[i];
  349. dd^[j] := di;
  350. If di=0
  351. Then
  352. term := 2
  353. Else
  354. px^[j] := px^[j]-lj*px^[i]
  355. End; {j}
  356. If term=1
  357. Then
  358. Begin
  359. px^[n] := px^[n]/dd^[n];
  360. For i:=n-1 Downto 1 Do
  361. px^[i] := (px^[i]-pu^[i]*px^[i+1])/dd^[i]
  362. End; {term=1}
  363. freemem(dd, n*sr);
  364. End; {sledtr}
  365. Procedure slegba(n, l, r: ArbInt;
  366. Var a, b, x, ca: ArbFloat; Var term:ArbInt);
  367. Var
  368. sr, i, j, k, ipivot, m, lbj, lbi, ubi, ls,
  369. ii, jj, ll, s, js, ubj, rwidth : ArbInt;
  370. ra, normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
  371. pa, pb, px, au, sumrow, t, row : ^arfloat1;
  372. Begin
  373. If (n<1) Or (l<0) Or (r<0) Or (l>n-1) Or (r>n-1)
  374. Then
  375. Begin
  376. term := 3;
  377. exit
  378. End; {term=3}
  379. sr := sizeof(ArbFloat);
  380. pa := @a;
  381. pb := @b;
  382. px := @x;
  383. ll := l+r+1;
  384. ls := ll*sr;
  385. getmem(au, ls*n);
  386. getmem(sumrow, n*sr);
  387. getmem(t, n*sr);
  388. getmem(row, ls);
  389. move(pb^, px^, n*sr);
  390. jj := 1;
  391. ii := 1;
  392. For i:=1 To n Do
  393. Begin
  394. If i <= l+1 Then
  395. Begin
  396. If i <= n-r Then rwidth := r+i
  397. Else rwidth := n
  398. End
  399. Else
  400. If i <= n-r Then rwidth := ll
  401. Else rwidth := n-i+l+1;
  402. move(pa^[jj], au^[ii], rwidth*sr);
  403. fillchar(au^[ii+rwidth], (ll-rwidth)*sr, 0);
  404. jj := jj+rwidth;
  405. ii := ii+ll;
  406. End; {i}
  407. lbi := n-r+1;
  408. lbj := 0;
  409. normr := 0;
  410. term := 1;
  411. ii := 1;
  412. For i:=1 To n Do
  413. Begin
  414. sumrowi := omvn1v(au^[ii], ll);
  415. ii := ii+ll;
  416. sumrow^[i] := sumrowi;
  417. h := 2*random-1;
  418. t^[i] := sumrowi*h;
  419. h := abs(h);
  420. If normr<h Then normr := h;
  421. If sumrowi=0 Then term := 2
  422. End; {i}
  423. ubi := l;
  424. k := 0;
  425. jj := 1;
  426. while (k<n) and (term=1) Do
  427. Begin
  428. maxim := 0;
  429. k := k+1;
  430. ipivot := k;
  431. ii := jj;
  432. If ubi<n
  433. Then ubi := ubi+1;
  434. For i:=k To ubi Do
  435. Begin
  436. sumrowi := sumrow^[i];
  437. If sumrowi <> 0
  438. Then
  439. Begin
  440. h := abs(au^[ii])/sumrowi;
  441. ii := ii+ll;
  442. If maxim<h
  443. Then
  444. Begin
  445. maxim := h;
  446. ipivot := i
  447. End {maxim<h}
  448. End {sumrowi <> 0}
  449. End; {i}
  450. If maxim=0
  451. Then
  452. term := 2
  453. Else
  454. Begin
  455. If ipivot <> k
  456. Then
  457. Begin
  458. ii := (ipivot-1)*ll+1;
  459. move(au^[ii], row^, ls);
  460. move(au^[jj], au^[ii], ls);
  461. move(row^, au^[jj], ls);
  462. h := t^[ipivot];
  463. t^[ipivot] := t^[k];
  464. t^[k] := h;
  465. h := px^[ipivot];
  466. px^[ipivot] := px^[k];
  467. px^[k] := h;
  468. sumrow^[ipivot] := sumrow^[k]
  469. End; {ipivot <> k}
  470. pivot := au^[jj];
  471. ii := jj;
  472. For i:=k+1 To ubi Do
  473. Begin
  474. ii := ii+ll;
  475. h := au^[ii]/pivot;
  476. For j:=0 To ll-2 Do
  477. au^[ii+j] := au^[ii+j+1]-h*au^[jj+j+1];
  478. au^[ii+ll-1] := 0;
  479. t^[i] := t^[i]-h*t^[k];
  480. px^[i] := px^[i]-h*px^[k];
  481. End {i}
  482. End; {maxim <> 0}
  483. jj := jj+ll
  484. End; {k}
  485. If term=1
  486. Then
  487. Begin
  488. normt := 0;
  489. ubj := -l-1;
  490. jj := n*ll+1;
  491. For i:=n Downto 1 Do
  492. Begin
  493. jj := jj-ll;
  494. If ubj<r
  495. Then
  496. ubj := ubj+1;
  497. h := t^[i];
  498. For j:=1 To ubj+l Do
  499. h := h-au^[jj+j]*t^[i+j];
  500. t^[i] := h/au^[jj];
  501. h := px^[i];
  502. For j:=1 To ubj+l Do
  503. h := h-au^[jj+j]*px^[i+j];
  504. px^[i] := h/au^[jj];
  505. h := abs(t^[i]);
  506. If normt<h
  507. Then
  508. normt := h
  509. End; {i}
  510. ca := normt/normr
  511. End; {term=1}
  512. freemem(au, ls*n);
  513. freemem(sumrow, n*sr);
  514. freemem(t, n*sr);
  515. freemem(row, ls)
  516. End; {slegba}
  517. Procedure slegbal(n, l, r: ArbInt;
  518. Var a1; Var b1, x1, ca: ArbFloat; Var term:ArbInt);
  519. Var
  520. sr, i, j, k, ipivot, m, lbj, lbi, ubi, ls,
  521. ll, s, js, ubj, rwidth : ArbInt;
  522. ra, normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
  523. a : ar2dr1 absolute a1;
  524. b : arfloat1 absolute b1;
  525. x : arfloat1 absolute x1;
  526. au : par2dr1;
  527. sumrow, t, row : ^arfloat1;
  528. Begin
  529. If (n<1) Or (l<0) Or (r<0) Or (l>n-1) Or (r>n-1)
  530. Then
  531. Begin
  532. term := 3;
  533. exit
  534. End; {term=3}
  535. sr := sizeof(ArbFloat);
  536. ll := l+r+1;
  537. ls := ll*sr;
  538. AllocateAr2dr(n, ll, au);
  539. getmem(sumrow, n*sr);
  540. getmem(t, n*sr);
  541. getmem(row, ls);
  542. move(b[1], x[1], n*sr);
  543. For i:=1 To n Do
  544. Begin
  545. If i <= l+1 Then
  546. Begin
  547. If i <= n-r Then rwidth := r+i
  548. Else rwidth := n
  549. End
  550. Else
  551. If i <= n-r Then rwidth := ll
  552. Else rwidth := n-i+l+1;
  553. move(a[i]^, au^[i]^, rwidth*sr);
  554. fillchar(au^[i]^[rwidth+1], (ll-rwidth)*sr, 0);
  555. End; {i}
  556. normr := 0;
  557. term := 1;
  558. For i:=1 To n Do
  559. Begin
  560. sumrowi := omvn1v(au^[i]^[1], ll);
  561. sumrow^[i] := sumrowi;
  562. h := 2*random-1;
  563. t^[i] := sumrowi*h;
  564. h := abs(h);
  565. If normr<h Then normr := h;
  566. If sumrowi=0 Then term := 2
  567. End; {i}
  568. ubi := l;
  569. k := 0;
  570. while (k<n) and (term=1) Do
  571. Begin
  572. maxim := 0;
  573. k := k+1;
  574. ipivot := k;
  575. If ubi<n Then ubi := ubi+1;
  576. For i:=k To ubi Do
  577. Begin
  578. sumrowi := sumrow^[i];
  579. If sumrowi <> 0 Then
  580. Begin
  581. h := abs(au^[i]^[1])/sumrowi;
  582. If maxim<h Then
  583. Begin
  584. maxim := h;
  585. ipivot := i
  586. End {maxim<h}
  587. End {sumrowi <> 0}
  588. End; {i}
  589. If maxim=0 Then term := 2
  590. Else
  591. Begin
  592. If ipivot <> k Then
  593. Begin
  594. move(au^[ipivot]^, row^, ls);
  595. move(au^[k]^, au^[ipivot]^, ls);
  596. move(row^, au^[k]^, ls);
  597. h := t^[ipivot];
  598. t^[ipivot] := t^[k];
  599. t^[k] := h;
  600. h := x[ipivot];
  601. x[ipivot] := x[k];
  602. x[k] := h;
  603. sumrow^[ipivot] := sumrow^[k]
  604. End; {ipivot <> k}
  605. pivot := au^[k]^[1];
  606. For i:=k+1 To ubi Do
  607. Begin
  608. h := au^[i]^[1]/pivot;
  609. For j:=0 To ll-2 Do
  610. au^[i]^[j+1] := au^[i]^[j+2]-h*au^[k]^[j+2];
  611. au^[i]^[ll] := 0;
  612. t^[i] := t^[i]-h*t^[k];
  613. x[i] := x[i]-h*x[k];
  614. End {i}
  615. End; {maxim <> 0}
  616. End; {k}
  617. If term=1 Then
  618. Begin
  619. normt := 0;
  620. ubj := -l-1;
  621. For i:=n Downto 1 Do
  622. Begin
  623. If ubj<r Then ubj := ubj+1;
  624. h := t^[i];
  625. For j:=1 To ubj+l Do
  626. h := h-au^[i]^[j+1]*t^[i+j];
  627. t^[i] := h/au^[i]^[1];
  628. h := x[i];
  629. For j:=1 To ubj+l Do
  630. h := h-au^[i]^[j+1]*x[i+j];
  631. x[i] := h/au^[i]^[1];
  632. h := abs(t^[i]);
  633. If normt<h Then normt := h
  634. End; {i}
  635. ca := normt/normr
  636. End; {term=1}
  637. freemem(sumrow, n*sr);
  638. freemem(t, n*sr);
  639. freemem(row, ls);
  640. DeAllocateAr2dr(n, ll, au);
  641. End; {slegbal}
  642. Procedure slegen(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
  643. Var term: ArbInt);
  644. Var
  645. nsr, i, j, k, ipiv, ip, ik, i1n, k1n : ArbInt;
  646. singular : boolean;
  647. normr, pivot, l, normt, maxim, h, s : ArbFloat;
  648. pa, px, pb, au, sumrow, t, row : ^arfloat1;
  649. Begin
  650. If (n<1) Or (rwidth<1)
  651. Then
  652. Begin
  653. term := 3;
  654. exit
  655. End; {wrong input}
  656. getmem(au, sqr(n)*sizeof(ArbFloat));
  657. nsr := n*sizeof(ArbFloat);
  658. getmem(t, nsr);
  659. getmem(row, nsr);
  660. getmem(sumrow, nsr);
  661. pa := @a;
  662. pb := @b;
  663. px := @x;
  664. For i:= 1 To n Do
  665. move(pa^[1+(i-1)*rwidth], au^[1+(i-1)*n], nsr);
  666. move(pb^[1], px^[1], nsr);
  667. normr := 0;
  668. singular := false ;
  669. i := 0;
  670. j := 0;
  671. while (i<n) and (Not singular) Do
  672. Begin
  673. i := i+1;
  674. sumrow^[i] := omvn1v(au^[1+(i-1)*n], n);
  675. If sumrow^[i]=0
  676. Then
  677. singular := true
  678. Else
  679. Begin
  680. h := 2*random-1;
  681. t^[i] := sumrow^[i]*h;
  682. h := abs(h);
  683. If normr<h
  684. Then
  685. normr := h
  686. End
  687. End;
  688. k := 0;
  689. while (k<n) and not singular Do
  690. Begin
  691. k := k+1;
  692. maxim := 0;
  693. ipiv := k;
  694. For i:=k To n Do
  695. Begin
  696. h := abs(au^[k+(i-1)*n])/sumrow^[i];
  697. If maxim<h
  698. Then
  699. Begin
  700. maxim := h;
  701. ipiv := i
  702. End
  703. End;
  704. If maxim=0
  705. Then
  706. singular := true
  707. Else
  708. Begin
  709. k1n := (k-1)*n;
  710. If ipiv <> k
  711. Then
  712. Begin
  713. ip := 1+(ipiv-1)*n;
  714. ik := 1+k1n;
  715. move(au^[ip], row^[1], nsr);
  716. move(au^[ik], au^[ip], nsr);
  717. move(row^[1], au^[ik], nsr);
  718. h := t^[ipiv];
  719. t^[ipiv] := t^[k];
  720. t^[k] := h;
  721. h := px^[ipiv];
  722. px^[ipiv] := px^[k];
  723. px^[k] := h;
  724. sumrow^[ipiv] := sumrow^[k]
  725. End;
  726. pivot := au^[k+k1n];
  727. For i:=k+1 To n Do
  728. Begin
  729. i1n := (i-1)*n;
  730. l := au^[k+i1n]/pivot;
  731. If l <> 0
  732. Then
  733. Begin
  734. For j:=k+1 To n Do
  735. au^[j+i1n] := au^[j+i1n]-l*au^[j+k1n];
  736. t^[i] := t^[i]-l*t^[k];
  737. px^[i] := px^[i]-l*px^[k]
  738. End
  739. End
  740. End
  741. End;
  742. If Not singular
  743. Then
  744. Begin
  745. normt := 0;
  746. For i:=n Downto 1 Do
  747. Begin
  748. s := 0;
  749. i1n := (i-1)*n;
  750. For j:=i+1 To n Do
  751. s := s+t^[j]*au^[j+i1n];
  752. t^[i] := (t^[i]-s)/au^[i+i1n];
  753. s := 0;
  754. For j:=i+1 To n Do
  755. s := s+px^[j]*au^[j+i1n];
  756. px^[i] := (px^[i]-s)/au^[i+i1n];
  757. h := abs(t^[i]);
  758. If normt<h
  759. Then
  760. normt := h
  761. End;
  762. ca := normt/normr
  763. End;
  764. If singular
  765. Then
  766. term := 2
  767. Else
  768. term := 1;
  769. freemem(au, sqr(n)*sizeof(ArbFloat));
  770. freemem(t, nsr);
  771. freemem(row, nsr);
  772. freemem(sumrow, nsr);
  773. End; {slegen}
  774. Procedure slegenl( n: ArbInt;
  775. Var a1;
  776. Var b1, x1, ca: ArbFloat;
  777. Var term: ArbInt);
  778. Var
  779. nsr, i, j, k, ipiv : ArbInt;
  780. singular : boolean;
  781. normr, pivot, l, normt, maxim, h, s : ArbFloat;
  782. a : ar2dr1 absolute a1;
  783. x : arfloat1 absolute x1;
  784. b : arfloat1 absolute b1;
  785. au: par2dr1;
  786. sumrow, t, row : ^arfloat1;
  787. Begin
  788. If n<1 Then
  789. Begin
  790. term := 3;
  791. exit
  792. End; {wrong input}
  793. AllocateAr2dr(n, n, au);
  794. nsr := n*sizeof(ArbFloat);
  795. getmem(t, nsr);
  796. getmem(row, nsr);
  797. getmem(sumrow, nsr);
  798. For i:= 1 To n Do
  799. move(a[i]^, au^[i]^, nsr);
  800. move(b[1], x[1], nsr);
  801. normr := 0;
  802. singular := false ;
  803. i := 0;
  804. j := 0;
  805. while (i<n) and (Not singular) Do
  806. Begin
  807. i := i+1;
  808. sumrow^[i] := omvn1v(au^[i]^[1], n);
  809. If sumrow^[i]=0
  810. Then
  811. singular := true
  812. Else
  813. Begin
  814. h := 2*random-1;
  815. t^[i] := sumrow^[i]*h;
  816. h := abs(h);
  817. If normr<h
  818. Then
  819. normr := h
  820. End
  821. End;
  822. k := 0;
  823. while (k<n) and not singular Do
  824. Begin
  825. k := k+1;
  826. maxim := 0;
  827. ipiv := k;
  828. For i:=k To n Do
  829. Begin
  830. h := abs(au^[i]^[k])/sumrow^[i];
  831. If maxim<h
  832. Then
  833. Begin
  834. maxim := h;
  835. ipiv := i
  836. End
  837. End;
  838. If maxim=0
  839. Then
  840. singular := true
  841. Else
  842. Begin
  843. If ipiv <> k
  844. Then
  845. Begin
  846. move(au^[ipiv]^, row^, nsr);
  847. move(au^[k]^, au^[ipiv]^, nsr);
  848. move(row^, au^[k]^, nsr);
  849. h := t^[ipiv];
  850. t^[ipiv] := t^[k];
  851. t^[k] := h;
  852. h := x[ipiv];
  853. x[ipiv] := x[k];
  854. x[k] := h;
  855. sumrow^[ipiv] := sumrow^[k]
  856. End;
  857. pivot := au^[k]^[k];
  858. For i:=k+1 To n Do
  859. Begin
  860. l := au^[i]^[k]/pivot;
  861. If l <> 0
  862. Then
  863. Begin
  864. For j:=k+1 To n Do
  865. au^[i]^[j] := au^[i]^[j]-l*au^[k]^[j];
  866. t^[i] := t^[i]-l*t^[k];
  867. x[i] := x[i]-l*x[k]
  868. End
  869. End
  870. End
  871. End;
  872. If Not singular
  873. Then
  874. Begin
  875. normt := 0;
  876. For i:=n Downto 1 Do
  877. Begin
  878. s := 0;
  879. For j:=i+1 To n Do
  880. s := s+t^[j]*au^[i]^[j];
  881. t^[i] := (t^[i]-s)/au^[i]^[i];
  882. s := 0;
  883. For j:=i+1 To n Do
  884. s := s+x[j]*au^[i]^[j];
  885. x[i] := (x[i]-s)/au^[i]^[i];
  886. h := abs(t^[i]);
  887. If normt<h
  888. Then
  889. normt := h
  890. End;
  891. ca := normt/normr
  892. End;
  893. If singular
  894. Then
  895. term := 2
  896. Else
  897. term := 1;
  898. freemem(t, nsr);
  899. freemem(row, nsr);
  900. freemem(sumrow, nsr);
  901. DeAllocateAr2dr(n, n, au);
  902. End; {slegenl}
  903. Procedure slegls(Var a: ArbFloat; m, n, rwidtha: ArbInt; Var b, x: ArbFloat;
  904. Var term: ArbInt);
  905. Var i, j, ns, ms, ii : ArbInt;
  906. normy0, norme0, norme1, s : ArbFloat;
  907. pa, pb, px, qr, alpha, e, y, r : ^arfloat1;
  908. pivot : ^arint1;
  909. Begin
  910. If (n<1) Or (m<n)
  911. Then
  912. Begin
  913. term := 3;
  914. exit
  915. End;
  916. pa := @a;
  917. pb := @b;
  918. px := @x;
  919. ns := n*sizeof(ArbFloat);
  920. ms := m*sizeof(ArbFloat);
  921. getmem(qr, m*ns);
  922. getmem(alpha, ns);
  923. getmem(e, ns);
  924. getmem(y, ns);
  925. getmem(r, m*sizeof(ArbFloat));
  926. getmem(pivot, n*sizeof(ArbInt));
  927. For i:=1 To m Do
  928. move(pa^[(i-1)*rwidtha+1], qr^[(i-1)*n+1], ns);
  929. decomp(qr^[1], m, n, n, alpha^[1], pivot^[1], term);
  930. If term=2
  931. Then
  932. Begin
  933. freemem(qr, m*ns);
  934. freemem(alpha, ns);
  935. freemem(e, ns);
  936. freemem(y, ns);
  937. freemem(r, m*sizeof(ArbFloat));
  938. freemem(pivot, n*sizeof(ArbInt));
  939. exit
  940. End;
  941. move(pb^[1], r^[1], ms);
  942. solve(qr^[1], m, n, n, alpha^[1], pivot^[1], r^[1], y^[1]);
  943. For i:=1 To m Do
  944. Begin
  945. s := pb^[i];
  946. ii := (i-1)*rwidtha;
  947. For j:=1 To n Do
  948. s := s-pa^[ii+j]*y^[j];
  949. r^[i] := s
  950. End; {i}
  951. solve(qr^[1], m, n, n, alpha^[1], pivot^[1], r^[1], e^[1]);
  952. normy0 := 0;
  953. norme1 := 0;
  954. For i:=1 To n Do
  955. Begin
  956. normy0 := normy0+sqr(y^[i]);
  957. norme1 := norme1+sqr(e^[i])
  958. End; {i}
  959. If norme1 > 0.0625*normy0
  960. Then
  961. Begin
  962. term := 2;
  963. freemem(qr, m*ns);
  964. freemem(alpha, ns);
  965. freemem(e, ns);
  966. freemem(y, ns);
  967. freemem(r, m*sizeof(ArbFloat));
  968. freemem(pivot, n*sizeof(ArbInt));
  969. exit
  970. End;
  971. For i:=1 To n Do
  972. px^[i] := y^[i];
  973. freemem(qr, m*ns);
  974. freemem(alpha, ns);
  975. freemem(e, ns);
  976. freemem(y, ns);
  977. freemem(r, m*sizeof(ArbFloat));
  978. freemem(pivot, n*sizeof(ArbInt));
  979. End; {slegls}
  980. Procedure sleglsl(Var a1; m, n: ArbInt; Var b1, x1: ArbFloat;
  981. Var term: ArbInt);
  982. Var i, j, ns, ms : ArbInt;
  983. normy0, norme0, norme1, s : ArbFloat;
  984. a : ar2dr1 absolute a1;
  985. b : arfloat1 absolute b1;
  986. x : arfloat1 absolute x1;
  987. alpha, e, y, r : ^arfloat1;
  988. qr : par2dr1;
  989. pivot : ^arint1;
  990. Begin
  991. If (n<1) Or (m<n)
  992. Then
  993. Begin
  994. term := 3;
  995. exit
  996. End;
  997. AllocateAr2dr(m, n, qr);
  998. ns := n*sizeof(ArbFloat);
  999. ms := m*sizeof(ArbFloat);
  1000. getmem(alpha, ns);
  1001. getmem(e, ns);
  1002. getmem(y, ns);
  1003. getmem(r, ms);
  1004. getmem(pivot, n*sizeof(ArbInt));
  1005. For i:=1 To m Do
  1006. move(a[i]^, qr^[i]^, ns);
  1007. decomp1(qr^[1], m, n, alpha^[1], pivot^[1], term);
  1008. If term=2
  1009. Then
  1010. Begin
  1011. freemem(qr, m*ns);
  1012. freemem(alpha, ns);
  1013. freemem(e, ns);
  1014. freemem(y, ns);
  1015. freemem(r, ms);
  1016. freemem(pivot, n*sizeof(ArbInt));
  1017. exit
  1018. End;
  1019. move(b[1], r^, ms);
  1020. solve1(qr^[1], m, n, alpha^[1], pivot^[1], r^[1], y^[1]);
  1021. For i:=1 To m Do
  1022. Begin
  1023. s := b[i];
  1024. For j:=1 To n Do
  1025. s := s-a[i]^[j]*y^[j];
  1026. r^[i] := s
  1027. End; {i}
  1028. solve1(qr^[1], m, n, alpha^[1], pivot^[1], r^[1], e^[1]);
  1029. normy0 := 0;
  1030. norme1 := 0;
  1031. For i:=1 To n Do
  1032. Begin
  1033. normy0 := normy0+sqr(y^[i]);
  1034. norme1 := norme1+sqr(e^[i])
  1035. End; {i}
  1036. If norme1 > 0.0625*normy0
  1037. Then
  1038. Begin
  1039. term := 2;
  1040. freemem(qr, m*ns);
  1041. freemem(alpha, ns);
  1042. freemem(e, ns);
  1043. freemem(y, ns);
  1044. freemem(r, m*sizeof(ArbFloat));
  1045. freemem(pivot, n*sizeof(ArbInt));
  1046. exit
  1047. End;
  1048. For i:=1 To n Do
  1049. x[i] := y^[i];
  1050. freemem(alpha, ns);
  1051. freemem(e, ns);
  1052. freemem(y, ns);
  1053. freemem(r, ms);
  1054. freemem(pivot, n*sizeof(ArbInt));
  1055. DeAllocateAr2dr(m, n, qr);
  1056. End; {sleglsl}
  1057. Procedure slegpb(n, l: ArbInt; Var a, b, x, ca: ArbFloat;
  1058. Var term: ArbInt);
  1059. Var
  1060. posdef : boolean;
  1061. i, j, k, r, p, q, jmin1, ii, jj, ri, ind,
  1062. ll, llm1, sr, rwidth : ArbInt;
  1063. h, normr, normt, sumrowi, hh, alim, norma : ArbFloat;
  1064. pa, pb, px, al, t, v : ^arfloat1;
  1065. Procedure decomp(i, r: ArbInt);
  1066. Var k: ArbInt;
  1067. Begin
  1068. ri := (r-1)*ll;
  1069. h := al^[ii+j];
  1070. q := ll-j+p;
  1071. For k:=p To jmin1 Do
  1072. Begin
  1073. h := h-al^[ii+k]*al^[ri+q];
  1074. q := q+1
  1075. End ;
  1076. If j<ll
  1077. Then
  1078. al^[ii+j] := h/al^[ri+ll];
  1079. End; {decomp}
  1080. Begin
  1081. If (n<1) Or (l<0) Or (l>n-1)
  1082. Then
  1083. Begin
  1084. term := 3;
  1085. exit
  1086. End; {wrong input}
  1087. sr := sizeof(ArbFloat);
  1088. pa := @a;
  1089. pb := @b;
  1090. px := @x;
  1091. ll := l+1;
  1092. getmem(al, ll*n*sr);
  1093. getmem(t, n*sr);
  1094. getmem(v, ll*sr);
  1095. move(pb^, px^, n*sr);
  1096. jj := 1;
  1097. ii := 1;
  1098. For i:=1 To n Do
  1099. Begin
  1100. If i>l Then rwidth := ll
  1101. Else rwidth := i;
  1102. move(pa^[jj], al^[ii+ll-rwidth], rwidth*sr);
  1103. jj := jj+rwidth;
  1104. ii := ii+ll
  1105. End; {i}
  1106. normr := 0;
  1107. p := ll+1;
  1108. norma := 0;
  1109. For i:=1 To n Do
  1110. Begin
  1111. If p>1
  1112. Then
  1113. p := p-1;
  1114. For j:=p To ll Do
  1115. v^[j] := al^[j+(i-1)*ll];
  1116. sumrowi := omvn1v(v^[p], ll-p+1);
  1117. r := i;
  1118. j := ll;
  1119. while (r<n) and (j>1) Do
  1120. Begin
  1121. r := r+1;
  1122. j := j-1;
  1123. sumrowi := sumrowi+abs(al^[j+(r-1)*ll])
  1124. End; {r,j}
  1125. If norma<sumrowi
  1126. Then
  1127. norma := sumrowi;
  1128. h := 2*random-1;
  1129. t^[i] := h;
  1130. h := abs(h);
  1131. If normr<h
  1132. Then
  1133. normr := h
  1134. End; {i}
  1135. llm1 := ll-1;
  1136. p := ll+1;
  1137. i := 0;
  1138. posdef := true ;
  1139. while (i<n) and posdef Do
  1140. Begin
  1141. i := i+1;
  1142. If p>1 Then p := p-1;
  1143. r := i-ll+p;
  1144. j := p-1;
  1145. ii := (i-1)*ll;
  1146. while j<llm1 Do
  1147. Begin
  1148. jmin1 := j;
  1149. j := j+1;
  1150. decomp(i, r);
  1151. r := r+1
  1152. End ; {j}
  1153. jmin1 := llm1;
  1154. j := ll;
  1155. decomp(i, i);
  1156. If h <= 0
  1157. Then
  1158. posdef := false
  1159. Else
  1160. Begin
  1161. alim := sqrt(h);
  1162. al^[ii+ll] := alim;
  1163. h := t^[i];
  1164. q := i;
  1165. For k:=llm1 Downto p Do
  1166. Begin
  1167. q := q-1;
  1168. h := h-al^[ii+k]*t^[q]
  1169. End ;
  1170. t^[i] := h/alim;
  1171. h := px^[i];
  1172. q := i;
  1173. For k:=llm1 Downto p Do
  1174. Begin
  1175. q := q-1;
  1176. h := h-al^[ii+k]*px^[q]
  1177. End; {k}
  1178. px^[i] := h/alim
  1179. End {posdef}
  1180. End; {i}
  1181. If posdef
  1182. Then
  1183. Begin
  1184. normt := 0;
  1185. p := ll+1;
  1186. For i:=n Downto 1 Do
  1187. Begin
  1188. If p>1
  1189. Then
  1190. p := p-1;
  1191. q := i;
  1192. h := t^[i];
  1193. hh := px^[i];
  1194. For k:=llm1 Downto p Do
  1195. Begin
  1196. q := q+1;
  1197. ind := (q-1)*ll+k;
  1198. h := h-al^[ind]*t^[q];
  1199. hh := hh-al^[ind]*px^[q]
  1200. End; {k}
  1201. ind := i*ll;
  1202. t^[i] := h/al^[ind];
  1203. px^[i] := hh/al^[ind];
  1204. h := abs(t^[i]);
  1205. If normt<h
  1206. Then
  1207. normt := h
  1208. End; {i}
  1209. ca := norma*normt/normr
  1210. End ; {posdef}
  1211. If posdef
  1212. Then
  1213. term := 1
  1214. Else
  1215. term := 2;
  1216. freemem(al, ll*n*sr);
  1217. freemem(t, n*sr);
  1218. freemem(v, ll*sr);
  1219. End; {slegpb}
  1220. Procedure slegpbl(n, l: ArbInt;
  1221. Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
  1222. Var
  1223. posdef : boolean;
  1224. i, j, k, r, p, q, ll, sr, rwidth : ArbInt;
  1225. h, normr, normt, sumrowi, hh, alim, norma : ArbFloat;
  1226. a : ar2dr1 absolute a1;
  1227. b : arfloat1 absolute b1;
  1228. x : arfloat1 absolute x1;
  1229. al : par2dr1;
  1230. t, v : ^arfloat1;
  1231. Procedure decomp(r: ArbInt);
  1232. Var k: ArbInt;
  1233. Begin
  1234. h := al^[i]^[j];
  1235. q := ll-j+p;
  1236. For k:=p To j-1 Do
  1237. Begin
  1238. h := h-al^[i]^[k]*al^[r]^[q];
  1239. Inc(q)
  1240. End ;
  1241. If j<ll Then al^[i]^[j] := h/al^[r]^[ll];
  1242. End; {decomp}
  1243. Begin
  1244. If (n<1) Or (l<0) Or (l>n-1)
  1245. Then
  1246. Begin
  1247. term := 3;
  1248. exit
  1249. End; {wrong input}
  1250. sr := sizeof(ArbFloat);
  1251. ll := l+1;
  1252. AllocateAr2dr(n, ll, al);
  1253. getmem(t, n*sr);
  1254. getmem(v, ll*sr);
  1255. move(b[1], x[1], n*sr);
  1256. For i:=1 To n Do
  1257. Begin
  1258. If i>l Then rwidth := ll
  1259. Else rwidth := i;
  1260. move(a[i]^, al^[i]^[ll-rwidth+1], rwidth*sr);
  1261. End; {i}
  1262. normr := 0;
  1263. p := ll+1;
  1264. norma := 0;
  1265. For i:=1 To n Do
  1266. Begin
  1267. If p>1 Then Dec(p);
  1268. For j:=p To ll Do
  1269. v^[j] := al^[i]^[j];
  1270. sumrowi := omvn1v(v^[p], ll-p+1);
  1271. r := i;
  1272. j := ll;
  1273. while (r<n) and (j>1) Do
  1274. Begin
  1275. Inc(r);
  1276. Dec(j);
  1277. sumrowi := sumrowi+abs(al^[r]^[j])
  1278. End; {r,j}
  1279. If norma<sumrowi Then norma := sumrowi;
  1280. h := 2*random-1;
  1281. t^[i] := h;
  1282. h := abs(h);
  1283. If normr<h Then normr := h
  1284. End; {i}
  1285. p := ll+1;
  1286. i := 0;
  1287. posdef := true ;
  1288. while (i<n) and posdef Do
  1289. Begin
  1290. Inc(i);
  1291. If p>1 Then Dec(p);
  1292. r := i-ll+p;
  1293. j := p-1;
  1294. while j<ll-1 Do
  1295. Begin
  1296. Inc(j);
  1297. decomp(r);
  1298. Inc(r)
  1299. End ; {j}
  1300. j := ll;
  1301. decomp(i);
  1302. If h <= 0 Then posdef := false
  1303. Else
  1304. Begin
  1305. alim := sqrt(h);
  1306. al^[i]^[ll] := alim;
  1307. h := t^[i];
  1308. q := i;
  1309. For k:=ll-1 Downto p Do
  1310. Begin
  1311. q := q-1;
  1312. h := h-al^[i]^[k]*t^[q]
  1313. End ;
  1314. t^[i] := h/alim;
  1315. h := x[i];
  1316. q := i;
  1317. For k:=ll-1 Downto p Do
  1318. Begin
  1319. q := q-1;
  1320. h := h-al^[i]^[k]*x[q]
  1321. End; {k}
  1322. x[i] := h/alim
  1323. End {posdef}
  1324. End; {i}
  1325. If posdef
  1326. Then
  1327. Begin
  1328. normt := 0;
  1329. p := ll+1;
  1330. For i:=n Downto 1 Do
  1331. Begin
  1332. If p>1 Then Dec(p);
  1333. q := i;
  1334. h := t^[i];
  1335. hh := x[i];
  1336. For k:=ll-1 Downto p Do
  1337. Begin
  1338. Inc(q);
  1339. h := h-al^[q]^[k]*t^[q];
  1340. hh := hh-al^[q]^[k]*x[q]
  1341. End; {k}
  1342. t^[i] := h/al^[i]^[ll];
  1343. x[i] := hh/al^[i]^[ll];
  1344. h := abs(t^[i]);
  1345. If normt<h Then normt := h
  1346. End; {i}
  1347. ca := norma*normt/normr
  1348. End ; {posdef}
  1349. If posdef Then term := 1
  1350. Else term := 2;
  1351. freemem(t, n*sr);
  1352. freemem(v, ll*sr);
  1353. DeAllocateAr2dr(n, ll, al);
  1354. End; {slegpbl}
  1355. Procedure slegpd(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
  1356. Var term: ArbInt);
  1357. Var
  1358. sr, i, j, k, kmin1, kk, k1n, i1n, ik, ii : ArbInt;
  1359. pd : boolean;
  1360. h, lkk, normr, normt, sumrowi, norma : ArbFloat;
  1361. pa, pb, px, al, t : ^arfloat1;
  1362. Begin
  1363. If (n<1) Or (rwidth<1)
  1364. Then
  1365. Begin
  1366. term := 3;
  1367. exit
  1368. End;
  1369. sr := sizeof(ArbFloat);
  1370. getmem(al, sqr(n)*sr);
  1371. getmem(t, n*sr);
  1372. pa := @a;
  1373. pb := @b;
  1374. px := @x;
  1375. For i:=1 To n Do
  1376. move(pa^[1+(i-1)*rwidth], al^[1+(i-1)*n], i*sr);
  1377. move(pb^[1], px^[1], n*sr);
  1378. normr := 0;
  1379. pd := true ;
  1380. norma := 0;
  1381. For i:=1 To n Do
  1382. Begin
  1383. sumrowi := 0;
  1384. For j:=1 To i Do
  1385. sumrowi := sumrowi+abs(al^[j+(i-1)*n]);
  1386. For j:=i+1 To n Do
  1387. sumrowi := sumrowi+abs(al^[i+(j-1)*n]);
  1388. If norma<sumrowi
  1389. Then
  1390. norma := sumrowi;
  1391. t^[i] := 2*random-1;
  1392. h := abs(t^[i]);
  1393. If normr<h
  1394. Then
  1395. normr := h
  1396. End; {i}
  1397. k := 0;
  1398. while (k<n) and pd Do
  1399. Begin
  1400. kmin1 := k;
  1401. k := k+1;
  1402. k1n := (k-1)*n;
  1403. kk := k+k1n;
  1404. lkk := al^[kk];
  1405. For j:=1 To kmin1 Do
  1406. lkk := lkk-sqr(al^[j+k1n]);
  1407. If lkk<=0
  1408. Then
  1409. pd := false
  1410. Else
  1411. Begin
  1412. al^[kk] := sqrt(lkk);
  1413. lkk := al^[kk];
  1414. For i:=k+1 To n Do
  1415. Begin
  1416. i1n := (i-1)*n;
  1417. ik := k+i1n;
  1418. h := al^[ik];
  1419. For j:=1 To kmin1 Do
  1420. h := h-al^[j+k1n]*al^[j+i1n];
  1421. al^[ik] := h/lkk
  1422. End; {i}
  1423. h := t^[k];
  1424. For j:=1 To kmin1 Do
  1425. h := h-al^[j+k1n]*t^[j];
  1426. t^[k] := h/lkk;
  1427. h := px^[k];
  1428. For j:=1 To kmin1 Do
  1429. h := h-al^[j+k1n]*px^[j];
  1430. px^[k] := h/lkk
  1431. End {lkk > 0}
  1432. End; {k}
  1433. If pd
  1434. Then
  1435. Begin
  1436. normt := 0;
  1437. For i:=n Downto 1 Do
  1438. Begin
  1439. ii := i+(i-1)*n;
  1440. h := t^[i];
  1441. For j:=i+1 To n Do
  1442. h := h-al^[i+(j-1)*n]*t^[j];
  1443. t^[i] := h/al^[ii];
  1444. h := px^[i];
  1445. For j:=i+1 To n Do
  1446. h := h-al^[i+(j-1)*n]*px^[j];
  1447. px^[i] := h/al^[ii];
  1448. h := abs(t^[i]);
  1449. If normt<h
  1450. Then
  1451. normt := h
  1452. End; {i}
  1453. ca := norma*normt/normr
  1454. End; {pd}
  1455. If pd
  1456. Then
  1457. term := 1
  1458. Else
  1459. term := 2;
  1460. freemem(al, sqr(n)*sr);
  1461. freemem(t, n*sr);
  1462. End; {slegpd}
  1463. Procedure slegpdl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
  1464. Var term: ArbInt);
  1465. Var sr, i, j, k, kmin1 : ArbInt;
  1466. pd : boolean;
  1467. h, lkk, normr, normt, sumrowi, norma : ArbFloat;
  1468. a : ar2dr1 absolute a1;
  1469. b : arfloat1 absolute b1;
  1470. x : arfloat1 absolute x1;
  1471. al : par2dr1;
  1472. t : ^arfloat1;
  1473. Begin
  1474. If n<1 Then
  1475. Begin
  1476. term := 3;
  1477. exit
  1478. End;
  1479. sr := sizeof(ArbFloat);
  1480. AllocateL2dr(n, al);
  1481. getmem(t, n*sr);
  1482. For i:=1 To n Do
  1483. move(a[i]^, al^[i]^, i*sr);
  1484. move(b[1], x[1], n*sr);
  1485. normr := 0;
  1486. pd := true ;
  1487. norma := 0;
  1488. For i:=1 To n Do
  1489. Begin
  1490. sumrowi := 0;
  1491. For j:=1 To i Do
  1492. sumrowi := sumrowi+abs(al^[i]^[j]);
  1493. For j:=i+1 To n Do
  1494. sumrowi := sumrowi+abs(al^[j]^[i]);
  1495. If norma<sumrowi Then norma := sumrowi;
  1496. t^[i] := 2*random-1;
  1497. h := abs(t^[i]);
  1498. If normr<h Then normr := h
  1499. End; {i}
  1500. k := 0;
  1501. while (k<n) and pd Do
  1502. Begin
  1503. kmin1 := k;
  1504. k := k+1;
  1505. lkk := al^[k]^[k];
  1506. For j:=1 To kmin1 Do
  1507. lkk := lkk-sqr(al^[k]^[j]);
  1508. If lkk<=0 Then pd := false
  1509. Else
  1510. Begin
  1511. al^[k]^[k] := sqrt(lkk);
  1512. lkk := al^[k]^[k];
  1513. For i:=k+1 To n Do
  1514. Begin
  1515. h := al^[i]^[k];
  1516. For j:=1 To kmin1 Do
  1517. h := h-al^[k]^[j]*al^[i]^[j];
  1518. al^[i]^[k] := h/lkk
  1519. End; {i}
  1520. h := t^[k];
  1521. For j:=1 To kmin1 Do
  1522. h := h-al^[k]^[j]*t^[j];
  1523. t^[k] := h/lkk;
  1524. h := x[k];
  1525. For j:=1 To kmin1 Do
  1526. h := h-al^[k]^[j]*x[j];
  1527. x[k] := h/lkk
  1528. End {lkk > 0}
  1529. End; {k}
  1530. If pd Then
  1531. Begin
  1532. normt := 0;
  1533. For i:=n Downto 1 Do
  1534. Begin
  1535. h := t^[i];
  1536. For j:=i+1 To n Do
  1537. h := h-al^[j]^[i]*t^[j];
  1538. t^[i] := h/al^[i]^[i];
  1539. h := x[i];
  1540. For j:=i+1 To n Do
  1541. h := h-al^[j]^[i]*x[j];
  1542. x[i] := h/al^[i]^[i];
  1543. h := abs(t^[i]);
  1544. If normt<h Then normt := h
  1545. End; {i}
  1546. ca := norma*normt/normr
  1547. End; {pd}
  1548. If pd Then term := 1
  1549. Else term := 2;
  1550. DeAllocateL2dr(n, al);
  1551. freemem(t, n*sr);
  1552. End; {slegpdl}
  1553. Procedure slegsy(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
  1554. Var term:ArbInt);
  1555. Var
  1556. i, j, kmin1, k, kplus1, kmin2, imin2, nsr, nsi, nsb, ii,
  1557. imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt;
  1558. ra, h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
  1559. pa, pb, pb1, px, alt, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
  1560. p : ^arint1;
  1561. q : ^arbool1;
  1562. Begin
  1563. If (n<1) Or (rwidth<1)
  1564. Then
  1565. Begin
  1566. term := 3;
  1567. exit
  1568. End; {if}
  1569. pa := @a;
  1570. pb := @b;
  1571. px := @x;
  1572. nsr := n*sizeof(ArbFloat);
  1573. nsi := n*sizeof(ArbInt);
  1574. nsb := n*sizeof(boolean);
  1575. getmem(alt, n*nsr);
  1576. getmem(l, nsr);
  1577. getmem(d, nsr);
  1578. getmem(t, nsr);
  1579. getmem(u, nsr);
  1580. getmem(v, nsr);
  1581. getmem(p, nsi);
  1582. getmem(q, nsb);
  1583. getmem(l1, nsr);
  1584. getmem(d1, nsr);
  1585. getmem(u1, nsr);
  1586. getmem(t1, nsr);
  1587. getmem(pb1, nsr);
  1588. move(pb^, pb1^, nsr);
  1589. For i:=1 To n Do
  1590. Begin
  1591. indi := (i-1)*n;
  1592. For j:=1 To i Do
  1593. alt^[indi+j] := pa^[(i-1)*rwidth+j];
  1594. End; {i}
  1595. norma := 0;
  1596. For i:=1 To n Do
  1597. Begin
  1598. indi := (i-1)*n;
  1599. p^[i] := i;
  1600. sumrowi := 0;
  1601. For j:=1 To i Do
  1602. sumrowi := sumrowi+abs(alt^[indi+j]);
  1603. For j:=i+1 To n Do
  1604. sumrowi := sumrowi+abs(alt^[(j-1)*n+i]);
  1605. If norma<sumrowi
  1606. Then
  1607. norma := sumrowi
  1608. End; {i}
  1609. kmin1 := -1;
  1610. k := 0;
  1611. kplus1 := 1;
  1612. while k<n Do
  1613. Begin
  1614. kmin2 := kmin1;
  1615. kmin1 := k;
  1616. k := kplus1;
  1617. kplus1 := kplus1+1;
  1618. indk := kmin1*n;
  1619. If k>3
  1620. Then
  1621. Begin
  1622. t^[2] := alt^[n+2]*alt^[indk+1]+alt^[2*n+2]*alt^[indk+2];
  1623. For i:=3 To kmin2 Do
  1624. Begin
  1625. indi := (i-1)*n;
  1626. t^[i] := alt^[indi+i-1]*alt^[indk+i-2]+alt^[indi+i]
  1627. *alt^[indk+i-1]+alt^[indi+n+i]*alt^[indk+i]
  1628. End; {i}
  1629. t^[kmin1] := alt^[indk-n+kmin2]*alt^[indk+k-3]
  1630. +alt^[indk-n+kmin1]*alt^[indk+kmin2]
  1631. +alt^[indk+kmin1];
  1632. h := alt^[indk+k];
  1633. For j:=2 To kmin1 Do
  1634. h := h-t^[j]*alt^[indk+j-1];
  1635. t^[k] := h;
  1636. alt^[indk+k] := h-alt^[indk+kmin1]*alt^[indk+kmin2]
  1637. End {k>3}
  1638. Else
  1639. If k=3
  1640. Then
  1641. Begin
  1642. t^[2] := alt^[n+2]*alt^[2*n+1]+alt^[2*n+2];
  1643. h := alt^[2*n+3]-t^[2]*alt^[2*n+1];
  1644. t^[3] := h;
  1645. alt^[2*n+3] := h-alt^[2*n+2]*alt^[2*n+1]
  1646. End {k=3}
  1647. Else
  1648. If k=2
  1649. Then
  1650. t^[2] := alt^[n+2];
  1651. maxim := 0;
  1652. For i:=kplus1 To n Do
  1653. Begin
  1654. indi := (i-1)*n;
  1655. h := alt^[indi+k];
  1656. For j:=2 To k Do
  1657. h := h-t^[j]*alt^[indi+j-1];
  1658. absh := abs(h);
  1659. If maxim<absh
  1660. Then
  1661. Begin
  1662. maxim := absh;
  1663. indexpivot := i
  1664. End; {if}
  1665. alt^[indi+k] := h
  1666. End; {i}
  1667. If maxim <> 0
  1668. Then
  1669. Begin
  1670. If indexpivot>kplus1
  1671. Then
  1672. Begin
  1673. indp := (indexpivot-1)*n;
  1674. indk := k*n;
  1675. p^[kplus1] := indexpivot;
  1676. For j:=1 To k Do
  1677. Begin
  1678. h := alt^[indk+j];
  1679. alt^[indk+j] := alt^[indp+j];
  1680. alt^[indp+j] := h
  1681. End; {j}
  1682. For j:=indexpivot Downto kplus1 Do
  1683. Begin
  1684. indj := (j-1)*n;
  1685. h := alt^[indj+kplus1];
  1686. alt^[indj+kplus1] := alt^[indp+j];
  1687. alt^[indp+j] := h
  1688. End; {j}
  1689. For i:=indexpivot To n Do
  1690. Begin
  1691. indi := (i-1)*n;
  1692. h := alt^[indi+kplus1];
  1693. alt^[indi+kplus1] := alt^[indi+indexpivot];
  1694. alt^[indi+indexpivot] := h
  1695. End {i}
  1696. End; {if}
  1697. pivot := alt^[k*n+k];
  1698. For i:=k+2 To n Do
  1699. alt^[(i-1)*n+k] := alt^[(i-1)*n+k]/pivot
  1700. End {maxim <> 0}
  1701. End; {k}
  1702. d^[1] := alt^[1];
  1703. i := 1;
  1704. while i<n Do
  1705. Begin
  1706. imin1 := i;
  1707. i := i+1;
  1708. u^[imin1] := alt^[(i-1)*n+imin1];
  1709. l^[imin1] := u^[imin1];
  1710. d^[i] := alt^[(i-1)*n+i]
  1711. End; {i}
  1712. mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
  1713. q^[1], ct, term);
  1714. If term=1
  1715. Then
  1716. Begin
  1717. normr := 0;
  1718. For i:=1 To n Do
  1719. Begin
  1720. t^[i] := 2*random-1;
  1721. h := t^[i];
  1722. h := abs(h);
  1723. If normr<h
  1724. Then
  1725. normr := h
  1726. End; {i}
  1727. For i:=1 To n Do
  1728. Begin
  1729. indexpivot := p^[i];
  1730. If indexpivot <> i
  1731. Then
  1732. Begin
  1733. h := pb1^[i];
  1734. pb1^[i] := pb1^[indexpivot];
  1735. pb1^[indexpivot] := h
  1736. End {if}
  1737. End; {i}
  1738. i := 0;
  1739. while i<n Do
  1740. Begin
  1741. indi := i*n;
  1742. imin1 := i;
  1743. i := i+1;
  1744. j := 1;
  1745. h := t^[i];
  1746. s := pb1^[i];
  1747. while j<imin1 Do
  1748. Begin
  1749. jmin1 := j;
  1750. j := j+1;
  1751. s := s-alt^[indi+jmin1]*pb1^[j];
  1752. h := h-alt^[indi+jmin1]*t^[j]
  1753. End; {j}
  1754. t^[i] := h;
  1755. pb1^[i] := s
  1756. End; {i}
  1757. dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], pb1^[1], px^[1], term);
  1758. dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
  1759. i := n+1;
  1760. imin1 := n;
  1761. normt := 0;
  1762. while i>2 Do
  1763. Begin
  1764. iplus1 := i;
  1765. i := imin1;
  1766. imin1 := imin1-1;
  1767. h := t1^[i];
  1768. s := px^[i];
  1769. For j:=iplus1 To n Do
  1770. Begin
  1771. indj := (j-1)*n+imin1;
  1772. h := h-alt^[indj]*t1^[j];
  1773. s := s-alt^[indj]*px^[j]
  1774. End; {j}
  1775. px^[i] := s;
  1776. t1^[i] := h;
  1777. h := abs(h);
  1778. If normt<h
  1779. Then
  1780. normt := h
  1781. End; {i}
  1782. For i:=n Downto 1 Do
  1783. Begin
  1784. indexpivot := p^[i];
  1785. If indexpivot <> i
  1786. Then
  1787. Begin
  1788. h := px^[i];
  1789. px^[i] := px^[indexpivot];
  1790. px^[indexpivot] := h
  1791. End {if}
  1792. End; {i}
  1793. ca := norma*normt/normr
  1794. End {term=1}
  1795. Else
  1796. term := 2;
  1797. freemem(alt, n*nsr);
  1798. freemem(l, nsr);
  1799. freemem(d, nsr);
  1800. freemem(t, nsr);
  1801. freemem(u, nsr);
  1802. freemem(v, nsr);
  1803. freemem(p, nsi);
  1804. freemem(q, nsb);
  1805. freemem(l1, nsr);
  1806. freemem(d1, nsr);
  1807. freemem(u1, nsr);
  1808. freemem(t1, nsr);
  1809. freemem(pb1, nsr);
  1810. End; {slegsy}
  1811. Procedure slegsyl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
  1812. Var term: ArbInt);
  1813. Var
  1814. i, j, kmin1, k, kplus1, kmin2, imin2, nsr, nsi, nsb, ii,
  1815. imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt;
  1816. ra, h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
  1817. a : ar2dr1 absolute a1;
  1818. b : arfloat1 absolute b1;
  1819. x : arfloat1 absolute x1;
  1820. b0, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
  1821. alt : par2dr1;
  1822. p : ^arint1;
  1823. q : ^arbool1;
  1824. Begin
  1825. If n<1 Then
  1826. Begin
  1827. term := 3;
  1828. exit
  1829. End; {if}
  1830. nsr := n*sizeof(ArbFloat);
  1831. nsi := n*sizeof(ArbInt);
  1832. nsb := n*sizeof(boolean);
  1833. AllocateL2dr(n, alt);
  1834. getmem(l, nsr);
  1835. getmem(d, nsr);
  1836. getmem(t, nsr);
  1837. getmem(u, nsr);
  1838. getmem(v, nsr);
  1839. getmem(p, nsi);
  1840. getmem(q, nsb);
  1841. getmem(l1, nsr);
  1842. getmem(d1, nsr);
  1843. getmem(u1, nsr);
  1844. getmem(t1, nsr);
  1845. getmem(b0, nsr);
  1846. move(b[1], b0^, nsr);
  1847. For i:=1 To n Do
  1848. move(a[i]^, alt^[i]^, i*sizeof(ArbFloat));
  1849. norma := 0;
  1850. For i:=1 To n Do
  1851. Begin
  1852. p^[i] := i;
  1853. sumrowi := 0;
  1854. For j:=1 To i Do
  1855. sumrowi := sumrowi+abs(alt^[i]^[j]);
  1856. For j:=i+1 To n Do
  1857. sumrowi := sumrowi+abs(alt^[j]^[i]);
  1858. If norma<sumrowi Then norma := sumrowi
  1859. End; {i}
  1860. k := 0;
  1861. while k<n Do
  1862. Begin
  1863. Inc(k);
  1864. If k>3 Then
  1865. Begin
  1866. t^[2] := alt^[2]^[2]*alt^[k]^[1]+alt^[3]^[2]*alt^[k]^[2];
  1867. For i:=3 To k-2 Do
  1868. t^[i] := alt^[i]^[i-1]*alt^[k]^[i-2]+alt^[i]^[i]
  1869. *alt^[k]^[i-1]+alt^[i+1]^[i]*alt^[k]^[i];
  1870. t^[k-1] := alt^[k-1]^[k-2]*alt^[k]^[k-3]
  1871. +alt^[k-1]^[k-1]*alt^[k]^[k-2]+alt^[k]^[k-1];
  1872. h := alt^[k]^[k];
  1873. For j:=2 To k-1 Do
  1874. h := h-t^[j]*alt^[k]^[j-1];
  1875. t^[k] := h;
  1876. alt^[k]^[k] := h-alt^[k]^[k-1]*alt^[k]^[k-2]
  1877. End {k>3}
  1878. Else
  1879. If k=3
  1880. Then
  1881. Begin
  1882. t^[2] := alt^[2]^[2]*alt^[3]^[1]+alt^[3]^[2];
  1883. h := alt^[3]^[3]-t^[2]*alt^[3]^[1];
  1884. t^[3] := h;
  1885. alt^[3]^[3] := h-alt^[3]^[2]*alt^[3]^[1]
  1886. End {k=3}
  1887. Else
  1888. If k=2 Then t^[2] := alt^[2]^[2];
  1889. maxim := 0;
  1890. For i:=k+1 To n Do
  1891. Begin
  1892. h := alt^[i]^[k];
  1893. For j:=2 To k Do
  1894. h := h-t^[j]*alt^[i]^[j-1];
  1895. absh := abs(h);
  1896. If maxim<absh Then
  1897. Begin
  1898. maxim := absh;
  1899. indexpivot := i
  1900. End; {if}
  1901. alt^[i]^[k] := h
  1902. End; {i}
  1903. If maxim <> 0
  1904. Then
  1905. Begin
  1906. If indexpivot>k+1 Then
  1907. Begin
  1908. p^[k+1] := indexpivot;
  1909. For j:=1 To k Do
  1910. Begin
  1911. h := alt^[k+1]^[j];
  1912. alt^[k+1]^[j] := alt^[indexpivot]^[j];
  1913. alt^[indexpivot]^[j] := h
  1914. End; {j}
  1915. For j:=indexpivot Downto k+1 Do
  1916. Begin
  1917. h := alt^[j]^[k+1];
  1918. alt^[j]^[k+1] := alt^[indexpivot]^[j];
  1919. alt^[indexpivot]^[j] := h
  1920. End; {j}
  1921. For i:=indexpivot To n Do
  1922. Begin
  1923. h := alt^[i]^[k+1];
  1924. alt^[i]^[k+1] := alt^[i]^[indexpivot];
  1925. alt^[i]^[indexpivot] := h
  1926. End {i}
  1927. End; {if}
  1928. pivot := alt^[k+1]^[k];
  1929. For i:=k+2 To n Do
  1930. alt^[i]^[k] := alt^[i]^[k]/pivot
  1931. End {maxim <> 0}
  1932. End; {k}
  1933. d^[1] := alt^[1]^[1];
  1934. i := 1;
  1935. while i<n Do
  1936. Begin
  1937. Inc(i);
  1938. u^[i-1] := alt^[i]^[i-1];
  1939. l^[i-1] := u^[i-1];
  1940. d^[i] := alt^[i]^[i]
  1941. End; {i}
  1942. mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
  1943. q^[1], ct, term);
  1944. If term=1 Then
  1945. Begin
  1946. normr := 0;
  1947. For i:=1 To n Do
  1948. Begin
  1949. t^[i] := 2*random-1;
  1950. h := t^[i];
  1951. h := abs(h);
  1952. If normr<h Then normr := h
  1953. End; {i}
  1954. For i:=1 To n Do
  1955. Begin
  1956. indexpivot := p^[i];
  1957. If indexpivot <> i
  1958. Then
  1959. Begin
  1960. h := b0^[i];
  1961. b0^[i] := b0^[indexpivot];
  1962. b0^[indexpivot] := h
  1963. End {if}
  1964. End; {i}
  1965. i := 0;
  1966. while i<n Do
  1967. Begin
  1968. Inc(i);
  1969. j := 1;
  1970. h := t^[i];
  1971. s := b0^[i];
  1972. while j<i-1 Do
  1973. Begin
  1974. Inc(j);
  1975. s := s-alt^[i]^[j-1]*b0^[j];
  1976. h := h-alt^[i]^[j-1]*t^[j]
  1977. End; {j}
  1978. t^[i] := h;
  1979. b0^[i] := s
  1980. End; {i}
  1981. dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], b0^[1], x[1], term);
  1982. dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
  1983. i := n+1;
  1984. normt := 0;
  1985. while i>2 Do
  1986. Begin
  1987. Dec(i);
  1988. h := t1^[i];
  1989. s := x[i];
  1990. For j:=i+1 To n Do
  1991. Begin
  1992. h := h-alt^[j]^[i-1]*t1^[j];
  1993. s := s-alt^[j]^[i-1]*x[j]
  1994. End; {j}
  1995. x[i] := s;
  1996. t1^[i] := h;
  1997. h := abs(h);
  1998. If normt<h Then normt := h
  1999. End; {i}
  2000. For i:=n Downto 1 Do
  2001. Begin
  2002. indexpivot := p^[i];
  2003. If indexpivot <> i Then
  2004. Begin
  2005. h := x[i];
  2006. x[i] := x[indexpivot];
  2007. x[indexpivot] := h
  2008. End {if}
  2009. End; {i}
  2010. ca := norma*normt/normr
  2011. End {term=1}
  2012. Else
  2013. term := 2;
  2014. freemem(l, nsr);
  2015. freemem(d, nsr);
  2016. freemem(t, nsr);
  2017. freemem(u, nsr);
  2018. freemem(v, nsr);
  2019. freemem(p, nsi);
  2020. freemem(q, nsb);
  2021. freemem(l1, nsr);
  2022. freemem(d1, nsr);
  2023. freemem(u1, nsr);
  2024. freemem(t1, nsr);
  2025. freemem(b0, nsr);
  2026. DeAllocateL2dr(n, alt);
  2027. End; {slegsyl}
  2028. Procedure slegtr(n:ArbInt; Var l, d, u, b, x, ca: ArbFloat;
  2029. Var term: ArbInt);
  2030. Var singular, ch : boolean;
  2031. i, j, nm1, sr, n1s, ns, n2s : ArbInt;
  2032. normr, normt, h, lj, di, ui, m : ArbFloat;
  2033. pl, ll : ^arfloat2;
  2034. pd, pu, pb, px, dd, uu1, u2, t, sumrow : ^arfloat1;
  2035. Begin
  2036. If n<1
  2037. Then
  2038. Begin
  2039. term := 3;
  2040. exit
  2041. End; {n<1}
  2042. sr := sizeof(ArbFloat);
  2043. n1s := (n-1)*sr;
  2044. ns := n1s+sr;
  2045. n2s := n1s;
  2046. getmem(ll, n1s);
  2047. getmem(uu1, n1s);
  2048. getmem(u2, n2s);
  2049. getmem(dd, ns);
  2050. getmem(t, ns);
  2051. getmem(sumrow, ns);
  2052. pl := @l;
  2053. pd := @d;
  2054. pu := @u;
  2055. pb := @b;
  2056. px := @x;
  2057. move(pl^[2], ll^[2], n1s);
  2058. move(pd^[1], dd^[1], ns);
  2059. If n>1
  2060. Then
  2061. move(pu^[1], uu1^[1], n1s);
  2062. move(pb^[1], px^[1], ns);
  2063. normr := 0;
  2064. singular := false;
  2065. nm1 := n-1;
  2066. i := 0;
  2067. while (i<n) and not singular Do
  2068. Begin
  2069. i := i+1;
  2070. If i=1
  2071. Then
  2072. Begin
  2073. sumrow^[i] := abs(dd^[1]);
  2074. If n>1
  2075. Then
  2076. sumrow^[i] := sumrow^[i]+abs(uu1^[1])
  2077. End {i=1}
  2078. Else
  2079. If i=n
  2080. Then
  2081. sumrow^[i] := abs(ll^[n])+abs(dd^[n])
  2082. Else
  2083. sumrow^[i] := abs(ll^[i])+abs(dd^[i])+abs(uu1^[i]);
  2084. If sumrow^[i]=0
  2085. Then
  2086. singular := true
  2087. Else
  2088. Begin
  2089. h := 2*random-1;
  2090. t^[i] := sumrow^[i]*h;
  2091. h := abs(h);
  2092. If normr<h
  2093. Then
  2094. normr := h
  2095. End {sumrow^[i] <> 0}
  2096. End; {i}
  2097. j := 1;
  2098. while (j <> n) and not singular Do
  2099. Begin
  2100. i := j;
  2101. j := j+1;
  2102. lj := ll^[j];
  2103. If lj <> 0
  2104. Then
  2105. Begin
  2106. di := dd^[i];
  2107. ch := abs(di/sumrow^[i])<abs(lj/sumrow^[j]);
  2108. If ch
  2109. Then
  2110. Begin
  2111. ui := uu1^[i];
  2112. dd^[i] := lj;
  2113. uu1^[i] := dd^[j];
  2114. m := di/lj;
  2115. dd^[j] := ui-m*dd^[j];
  2116. If i<nm1
  2117. Then
  2118. Begin
  2119. u2^[i] := uu1^[j];
  2120. uu1^[j] := -m*u2^[i]
  2121. End; {i<nm1}
  2122. sumrow^[j] := sumrow^[i];
  2123. h := t^[i];
  2124. t^[i] := t^[j];
  2125. t^[j] := h-m*t^[i];
  2126. h := px^[i];
  2127. px^[i] := px^[j];
  2128. px^[j] := h-m*px^[i]
  2129. End {ch}
  2130. Else
  2131. Begin
  2132. m := lj/di;
  2133. dd^[j] := dd^[j]-m*uu1^[i];
  2134. If i<nm1
  2135. Then
  2136. u2^[i] := 0;
  2137. t^[j] := t^[j]-m*t^[i];
  2138. px^[j] := px^[j]-m*px^[i]
  2139. End {not ch}
  2140. End {lj <> 0}
  2141. Else
  2142. Begin
  2143. If i < nm1
  2144. Then
  2145. u2^[i] := 0;
  2146. If dd^[i]=0
  2147. Then
  2148. singular := true
  2149. End {lj=0}
  2150. End; {j}
  2151. If dd^[n]=0
  2152. Then
  2153. singular := true;
  2154. If Not singular
  2155. Then
  2156. Begin
  2157. normt := 0;
  2158. t^[n] := t^[n]/dd^[n];
  2159. px^[n] := px^[n]/dd^[n];
  2160. h := abs(t^[n]);
  2161. If normt<h
  2162. Then
  2163. normt := h;
  2164. If n>1
  2165. Then
  2166. Begin
  2167. t^[nm1] := (t^[nm1]-uu1^[nm1]*t^[n])/dd^[nm1];
  2168. px^[nm1] := (px^[nm1]-uu1^[nm1]*px^[n])/dd^[nm1];
  2169. h := abs(t^[nm1])
  2170. End; {n>1}
  2171. If normt<h
  2172. Then
  2173. normt := h;
  2174. For i:=n-2 Downto 1 Do
  2175. Begin
  2176. t^[i] := (t^[i]-uu1^[i]*t^[i+1]-u2^[i]*t^[i+2])/dd^[i];
  2177. px^[i] := (px^[i]-uu1^[i]*px^[i+1]-u2^[i]*px^[i+2])/dd^[i];
  2178. h := abs(t^[i]);
  2179. If normt<h
  2180. Then
  2181. normt := h
  2182. End; {i}
  2183. ca := normt/normr
  2184. End; {not singular}
  2185. If singular
  2186. Then
  2187. term := 2
  2188. Else
  2189. term := 1;
  2190. freemem(ll, n1s);
  2191. freemem(uu1, n1s);
  2192. freemem(u2, n2s);
  2193. freemem(dd, ns);
  2194. freemem(t, ns);
  2195. freemem(sumrow, ns);
  2196. End; {slegtr}
  2197. Begin
  2198. randseed := 12345
  2199. End.
  2200. {
  2201. $Log$
  2202. Revision 1.1 2000-07-13 06:34:15 michael
  2203. + Initial import
  2204. Revision 1.2 2000/01/25 20:21:42 marco
  2205. * small updates, crlf fix, and RTE 207 problem
  2206. Revision 1.1 2000/01/24 22:08:58 marco
  2207. * initial version
  2208. }