sle.pas 55 KB

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