sle.pas 55 KB

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