123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277 |
- {
- This file is part of the Numlib package.
- Copyright (c) 1986-2000 by
- Kees van Ginneken, Wil Kortsmit and Loek van Reij of the
- Computational centre of the Eindhoven University of Technology
- FPC port Code by Marco van de Voort ([email protected])
- documentation by Michael van Canneyt ([email protected])
- !! modifies randseed, might not exactly work as TP version!!!
- Solve set of linear equations of the type Ax=b, for generic, and a
- variety of special matrices.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {Solve set of linear equations of the type Ax=b, for generic, and a variety of
- special matrices.
- One (generic) function for overdetermined sets of this kind : slegls
- overdetermined are sets that look like this: (I don't know if I
- translated "overdetermined" right)
- 6 1 2 3 9
- 3 9 3 4 2
- 17 27 42 15 62
- 17 27 42 15 61
- The two bottom rows look much alike, which introduces a big uncertainty in the
- result, therefore these matrices need special treatment.
- All procedures have similar procedure with a "L" appended to the name. We
- didn't receive docs for those procedures. If you know what the difference is,
- please mail us }
- Unit sle;
- interface
- {$I DIRECT.INC}
- uses typ, omv;
- {solve for special tridiagonal matrices}
- Procedure sledtr(n: ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
- {solve for generic bandmatrices}
- Procedure slegba(n, l, r: ArbInt;
- Var a, b, x, ca: ArbFloat; Var term:ArbInt);
- Procedure slegbal(n, l, r: ArbInt;
- Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
- {generic solve for all matrices}
- Procedure slegen(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Procedure slegenl( n: ArbInt;
- Var a1;
- Var b1, x1, ca: ArbFloat;
- Var term: ArbInt);
- {solve for overdetermined matrices, see unit comments}
- Procedure slegls(Var a: ArbFloat; m, n, rwidtha: ArbInt; Var b, x: ArbFloat;
- Var term: ArbInt);
- Procedure sleglsl(Var a1; m, n: ArbInt; Var b1, x1: ArbFloat;
- Var term: ArbInt);
- {Symmetrical positive definitive bandmatrices}
- Procedure slegpb(n, l: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Procedure slegpbl(n, l: ArbInt;
- Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
- {Symmetrical positive definitive matrices}
- Procedure slegpd(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Procedure slegpdl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
- Var term: ArbInt);
- {Symmetrical matrices}
- Procedure slegsy(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Procedure slegsyl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
- Var term: ArbInt);
- {tridiagonal matrices}
- Procedure slegtr(n:ArbInt; Var l, d, u, b, x, ca: ArbFloat;
- Var term: ArbInt);
- implementation
- Uses DSL,MDT;
- {Here originally stood an exact copy of mdtgtr from unit mdt}
- {Here originally stood an exact copy of dslgtr from unit DSL}
- Procedure decomp(Var qr: ArbFloat; m, n, rwidthq: ArbInt; Var alpha: ArbFloat;
- Var pivot, term: ArbInt);
- Var i, j, jbar, k, ns, ii : ArbInt;
- beta, sigma, alphak, qrkk, s : ArbFloat;
- pqr, pal, y, sum : ^arfloat1;
- piv : ^arint1;
- Begin
- term := 1;
- pqr := @qr;
- pal := @alpha;
- piv := @pivot;
- ns := n*sizeof(ArbFloat);
- getmem(y, ns);
- getmem(sum, ns);
- For j:=1 To n Do
- Begin
- s := 0;
- For i:=1 To m Do
- s := s+sqr(pqr^[(i-1)*rwidthq+j]);
- sum^[j] := s;
- piv^[j] := j
- End; {j}
- For k:=1 To n Do
- Begin
- sigma := sum^[k];
- jbar := k;
- For j:=k+1 To n Do
- If sigma < sum^[j] Then
- Begin
- sigma := sum^[j];
- jbar := j
- End;
- If jbar <> k
- Then
- Begin
- i := piv^[k];
- piv^[k] := piv^[jbar];
- piv^[jbar] := i;
- sum^[jbar] := sum^[k];
- sum^[k] := sigma;
- For i:=1 To m Do
- Begin
- ii := (i-1)*rwidthq;
- sigma := pqr^[ii+k];
- pqr^[ii+k] := pqr^[ii+jbar];
- pqr^[ii+jbar] := sigma
- End; {i}
- End; {column interchange}
- sigma := 0;
- For i:=k To m Do
- sigma := sigma+sqr(pqr^[(i-1)*rwidthq+k]);
- If sigma=0 Then
- Begin
- term := 2;
- freemem(y, ns);
- freemem(sum, ns);
- exit
- End;
- qrkk := pqr^[(k-1)*rwidthq+k];
- If qrkk < 0 Then
- alphak := sqrt(sigma)
- Else
- alphak := -sqrt(sigma);
- pal^[k] := alphak;
- beta := 1/(sigma-qrkk*alphak);
- pqr^[(k-1)*rwidthq+k] := qrkk-alphak;
- For j:=k+1 To n Do
- Begin
- s := 0;
- For i:=k To m Do
- Begin
- ii := (i-1)*rwidthq;
- s := s+pqr^[ii+k]*pqr^[ii+j]
- End; {i}
- y^[j] := beta*s
- End; {j}
- For j:=k+1 To n Do
- Begin
- For i:=k To m Do
- Begin
- ii := (i-1)*rwidthq;
- pqr^[ii+j] := pqr^[ii+j]-pqr^[ii+k]*y^[j]
- End; {i}
- sum^[j] := sum^[j]-sqr(pqr^[(k-1)*rwidthq+j])
- End {j}
- End; {k}
- freemem(y, ns);
- freemem(sum, ns);
- End; {decomp}
- Procedure decomp1(Var qr1; m, n: ArbInt; Var alpha1: ArbFloat;
- Var pivot1, term: ArbInt);
- Var i, j, jbar, k, ns : ArbInt;
- beta, sigma, alphak, qrkk, s : ArbFloat;
- qr : ar2dr1 absolute qr1;
- alpha : arfloat1 absolute alpha1;
- pivot : arint1 absolute pivot1;
- y, sum : ^arfloat1;
- Begin
- term := 1;
- ns := n*sizeof(ArbFloat);
- getmem(y, ns);
- getmem(sum, ns);
- For j:=1 To n Do
- Begin
- s := 0;
- For i:=1 To m Do
- s := s+sqr(qr[i]^[j]);
- sum^[j] := s;
- pivot[j] := j
- End; {j}
- For k:=1 To n Do
- Begin
- sigma := sum^[k];
- jbar := k;
- For j:=k+1 To n Do
- If sigma < sum^[j]
- Then
- Begin
- sigma := sum^[j];
- jbar := j
- End;
- If jbar <> k
- Then
- Begin
- i := pivot[k];
- pivot[k] := pivot[jbar];
- pivot[jbar] := i;
- sum^[jbar] := sum^[k];
- sum^[k] := sigma;
- For i:=1 To m Do
- Begin
- sigma := qr[i]^[k];
- qr[i]^[k] := qr[i]^[jbar];
- qr[i]^[jbar] := sigma
- End; {i}
- End; {column interchange}
- sigma := 0;
- For i:=k To m Do
- sigma := sigma+sqr(qr[i]^[k]);
- If sigma=0
- Then
- Begin
- term := 2;
- freemem(y, ns);
- freemem(sum, ns);
- exit
- End;
- qrkk := qr[k]^[k];
- If qrkk < 0 Then alphak := sqrt(sigma)
- Else alphak := -sqrt(sigma);
- alpha[k] := alphak;
- beta := 1/(sigma-qrkk*alphak);
- qr[k]^[k] := qrkk-alphak;
- For j:=k+1 To n Do
- Begin
- s := 0;
- For i:=k To m Do
- s := s+qr[i]^[k]*qr[i]^[j];
- y^[j] := beta*s
- End; {j}
- For j:=k+1 To n Do
- Begin
- For i:=k To m Do
- qr[i]^[j] := qr[i]^[j]-qr[i]^[k]*y^[j];
- sum^[j] := sum^[j]-sqr(qr[k]^[j])
- End {j}
- End; {k}
- freemem(y, ns);
- freemem(sum, ns);
- End; {decomp1}
- Procedure solve(Var qr: ArbFloat; m, n, rwidthq: ArbInt; Var alpha: ArbFloat;
- Var pivot: ArbInt; Var r, y: ArbFloat);
- Var i, j, ii : ArbInt;
- gamma, s : ArbFloat;
- pqr, pal, pr, py, z : ^arfloat1;
- piv : ^arint1;
- Begin
- pqr := @qr;
- pal := @alpha;
- piv := @pivot;
- pr := @r;
- py := @y;
- getmem(z, n*sizeof(ArbFloat));
- For j:=1 To n Do
- Begin
- gamma := 0;
- For i:=j To m Do
- gamma := gamma+pqr^[(i-1)*rwidthq+j]*pr^[i];
- gamma := gamma/(pal^[j]*pqr^[(j-1)*rwidthq+j]);
- For i:=j To m Do
- pr^[i] := pr^[i]+gamma*pqr^[(i-1)*rwidthq+j]
- End; {j}
- z^[n] := pr^[n]/pal^[n];
- For i:=n-1 Downto 1 Do
- Begin
- s := pr^[i];
- ii := (i-1)*rwidthq;
- For j:=i+1 To n Do
- s := s-pqr^[ii+j]*z^[j];
- z^[i] := s/pal^[i]
- End; {i}
- For i:=1 To n Do
- py^[piv^[i]] := z^[i];
- freemem(z, n*sizeof(ArbFloat));
- End; {solve}
- Procedure solve1(Var qr1; m, n: ArbInt; Var alpha1: ArbFloat;
- Var pivot1: ArbInt; Var r1, y1: ArbFloat);
- Var i, j : ArbInt;
- gamma, s : ArbFloat;
- qr : ar2dr1 absolute qr1;
- alpha : arfloat1 absolute alpha1;
- r : arfloat1 absolute r1;
- y : arfloat1 absolute y1;
- pivot : arint1 absolute pivot1;
- z : ^arfloat1;
- Begin
- getmem(z, n*sizeof(ArbFloat));
- For j:=1 To n Do
- Begin
- gamma := 0;
- For i:=j To m Do
- gamma := gamma+qr[i]^[j]*r[i];
- gamma := gamma/(alpha[j]*qr[j]^[j]);
- For i:=j To m Do
- r[i] := r[i]+gamma*qr[i]^[j]
- End; {j}
- z^[n] := r[n]/alpha[n];
- For i:=n-1 Downto 1 Do
- Begin
- s := r[i];
- For j:=i+1 To n Do
- s := s-qr[i]^[j]*z^[j];
- z^[i] := s/alpha[i]
- End; {i}
- For i:=1 To n Do
- y[pivot[i]] := z^[i];
- freemem(z, n*sizeof(ArbFloat));
- End; {solve1}
- Procedure sledtr(n: ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
- Var i, j, sr : ArbInt;
- lj, di : ArbFloat;
- pd, pu, pb, px, dd : ^arfloat1;
- pl : ^arfloat2;
- Begin
- If n<1
- Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- pl := @l;
- pd := @d;
- pu := @u;
- pb := @b;
- px := @x;
- sr := sizeof(ArbFloat);
- getmem(dd, n*sr);
- move(pb^, px^, n*sr);
- j := 1;
- di := pd^[j];
- dd^[j] := di;
- If di=0
- Then
- term := 2
- Else
- term := 1;
- while (term=1) and (j <> n) Do
- Begin
- i := j;
- j := j+1;
- lj := pl^[j]/di;
- di := pd^[j]-lj*pu^[i];
- dd^[j] := di;
- If di=0
- Then
- term := 2
- Else
- px^[j] := px^[j]-lj*px^[i]
- End; {j}
- If term=1
- Then
- Begin
- px^[n] := px^[n]/dd^[n];
- For i:=n-1 Downto 1 Do
- px^[i] := (px^[i]-pu^[i]*px^[i+1])/dd^[i]
- End; {term=1}
- freemem(dd, n*sr);
- End; {sledtr}
- Procedure slegba(n, l, r: ArbInt;
- Var a, b, x, ca: ArbFloat; Var term:ArbInt);
- Var
- sr, i, j, k, ipivot, m, lbj, lbi, ubi, ls,
- ii, jj, ll, s, js, ubj, rwidth : ArbInt;
- ra, normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
- pa, pb, px, au, sumrow, t, row : ^arfloat1;
- Begin
- If (n<1) Or (l<0) Or (r<0) Or (l>n-1) Or (r>n-1)
- Then
- Begin
- term := 3;
- exit
- End; {term=3}
- sr := sizeof(ArbFloat);
- pa := @a;
- pb := @b;
- px := @x;
- ll := l+r+1;
- ls := ll*sr;
- getmem(au, ls*n);
- getmem(sumrow, n*sr);
- getmem(t, n*sr);
- getmem(row, ls);
- move(pb^, px^, n*sr);
- jj := 1;
- ii := 1;
- For i:=1 To n Do
- Begin
- If i <= l+1 Then
- Begin
- If i <= n-r Then rwidth := r+i
- Else rwidth := n
- End
- Else
- If i <= n-r Then rwidth := ll
- Else rwidth := n-i+l+1;
- move(pa^[jj], au^[ii], rwidth*sr);
- fillchar(au^[ii+rwidth], (ll-rwidth)*sr, 0);
- jj := jj+rwidth;
- ii := ii+ll;
- End; {i}
- lbi := n-r+1;
- lbj := 0;
- normr := 0;
- term := 1;
- ii := 1;
- For i:=1 To n Do
- Begin
- sumrowi := omvn1v(au^[ii], ll);
- ii := ii+ll;
- sumrow^[i] := sumrowi;
- h := 2*random-1;
- t^[i] := sumrowi*h;
- h := abs(h);
- If normr<h Then normr := h;
- If sumrowi=0 Then term := 2
- End; {i}
- ubi := l;
- k := 0;
- jj := 1;
- while (k<n) and (term=1) Do
- Begin
- maxim := 0;
- k := k+1;
- ipivot := k;
- ii := jj;
- If ubi<n
- Then ubi := ubi+1;
- For i:=k To ubi Do
- Begin
- sumrowi := sumrow^[i];
- If sumrowi <> 0
- Then
- Begin
- h := abs(au^[ii])/sumrowi;
- ii := ii+ll;
- If maxim<h
- Then
- Begin
- maxim := h;
- ipivot := i
- End {maxim<h}
- End {sumrowi <> 0}
- End; {i}
- If maxim=0
- Then
- term := 2
- Else
- Begin
- If ipivot <> k
- Then
- Begin
- ii := (ipivot-1)*ll+1;
- move(au^[ii], row^, ls);
- move(au^[jj], au^[ii], ls);
- move(row^, au^[jj], ls);
- h := t^[ipivot];
- t^[ipivot] := t^[k];
- t^[k] := h;
- h := px^[ipivot];
- px^[ipivot] := px^[k];
- px^[k] := h;
- sumrow^[ipivot] := sumrow^[k]
- End; {ipivot <> k}
- pivot := au^[jj];
- ii := jj;
- For i:=k+1 To ubi Do
- Begin
- ii := ii+ll;
- h := au^[ii]/pivot;
- For j:=0 To ll-2 Do
- au^[ii+j] := au^[ii+j+1]-h*au^[jj+j+1];
- au^[ii+ll-1] := 0;
- t^[i] := t^[i]-h*t^[k];
- px^[i] := px^[i]-h*px^[k];
- End {i}
- End; {maxim <> 0}
- jj := jj+ll
- End; {k}
- If term=1
- Then
- Begin
- normt := 0;
- ubj := -l-1;
- jj := n*ll+1;
- For i:=n Downto 1 Do
- Begin
- jj := jj-ll;
- If ubj<r
- Then
- ubj := ubj+1;
- h := t^[i];
- For j:=1 To ubj+l Do
- h := h-au^[jj+j]*t^[i+j];
- t^[i] := h/au^[jj];
- h := px^[i];
- For j:=1 To ubj+l Do
- h := h-au^[jj+j]*px^[i+j];
- px^[i] := h/au^[jj];
- h := abs(t^[i]);
- If normt<h
- Then
- normt := h
- End; {i}
- ca := normt/normr
- End; {term=1}
- freemem(au, ls*n);
- freemem(sumrow, n*sr);
- freemem(t, n*sr);
- freemem(row, ls)
- End; {slegba}
- Procedure slegbal(n, l, r: ArbInt;
- Var a1; Var b1, x1, ca: ArbFloat; Var term:ArbInt);
- Var
- sr, i, j, k, ipivot, m, lbj, lbi, ubi, ls,
- ll, s, js, ubj, rwidth : ArbInt;
- ra, normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
- a : ar2dr1 absolute a1;
- b : arfloat1 absolute b1;
- x : arfloat1 absolute x1;
- au : par2dr1;
- sumrow, t, row : ^arfloat1;
- Begin
- If (n<1) Or (l<0) Or (r<0) Or (l>n-1) Or (r>n-1)
- Then
- Begin
- term := 3;
- exit
- End; {term=3}
- sr := sizeof(ArbFloat);
- ll := l+r+1;
- ls := ll*sr;
- AllocateAr2dr(n, ll, au);
- getmem(sumrow, n*sr);
- getmem(t, n*sr);
- getmem(row, ls);
- move(b[1], x[1], n*sr);
- For i:=1 To n Do
- Begin
- If i <= l+1 Then
- Begin
- If i <= n-r Then rwidth := r+i
- Else rwidth := n
- End
- Else
- If i <= n-r Then rwidth := ll
- Else rwidth := n-i+l+1;
- move(a[i]^, au^[i]^, rwidth*sr);
- fillchar(au^[i]^[rwidth+1], (ll-rwidth)*sr, 0);
- End; {i}
- normr := 0;
- term := 1;
- For i:=1 To n Do
- Begin
- sumrowi := omvn1v(au^[i]^[1], ll);
- sumrow^[i] := sumrowi;
- h := 2*random-1;
- t^[i] := sumrowi*h;
- h := abs(h);
- If normr<h Then normr := h;
- If sumrowi=0 Then term := 2
- End; {i}
- ubi := l;
- k := 0;
- while (k<n) and (term=1) Do
- Begin
- maxim := 0;
- k := k+1;
- ipivot := k;
- If ubi<n Then ubi := ubi+1;
- For i:=k To ubi Do
- Begin
- sumrowi := sumrow^[i];
- If sumrowi <> 0 Then
- Begin
- h := abs(au^[i]^[1])/sumrowi;
- If maxim<h Then
- Begin
- maxim := h;
- ipivot := i
- End {maxim<h}
- End {sumrowi <> 0}
- End; {i}
- If maxim=0 Then term := 2
- Else
- Begin
- If ipivot <> k Then
- Begin
- move(au^[ipivot]^, row^, ls);
- move(au^[k]^, au^[ipivot]^, ls);
- move(row^, au^[k]^, ls);
- h := t^[ipivot];
- t^[ipivot] := t^[k];
- t^[k] := h;
- h := x[ipivot];
- x[ipivot] := x[k];
- x[k] := h;
- sumrow^[ipivot] := sumrow^[k]
- End; {ipivot <> k}
- pivot := au^[k]^[1];
- For i:=k+1 To ubi Do
- Begin
- h := au^[i]^[1]/pivot;
- For j:=0 To ll-2 Do
- au^[i]^[j+1] := au^[i]^[j+2]-h*au^[k]^[j+2];
- au^[i]^[ll] := 0;
- t^[i] := t^[i]-h*t^[k];
- x[i] := x[i]-h*x[k];
- End {i}
- End; {maxim <> 0}
- End; {k}
- If term=1 Then
- Begin
- normt := 0;
- ubj := -l-1;
- For i:=n Downto 1 Do
- Begin
- If ubj<r Then ubj := ubj+1;
- h := t^[i];
- For j:=1 To ubj+l Do
- h := h-au^[i]^[j+1]*t^[i+j];
- t^[i] := h/au^[i]^[1];
- h := x[i];
- For j:=1 To ubj+l Do
- h := h-au^[i]^[j+1]*x[i+j];
- x[i] := h/au^[i]^[1];
- h := abs(t^[i]);
- If normt<h Then normt := h
- End; {i}
- ca := normt/normr
- End; {term=1}
- freemem(sumrow, n*sr);
- freemem(t, n*sr);
- freemem(row, ls);
- DeAllocateAr2dr(n, ll, au);
- End; {slegbal}
- Procedure slegen(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Var
- nsr, i, j, k, ipiv, ip, ik, i1n, k1n : ArbInt;
- singular : boolean;
- normr, pivot, l, normt, maxim, h, s : ArbFloat;
- pa, px, pb, au, sumrow, t, row : ^arfloat1;
- Begin
- If (n<1) Or (rwidth<1)
- Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- getmem(au, sqr(n)*sizeof(ArbFloat));
- nsr := n*sizeof(ArbFloat);
- getmem(t, nsr);
- getmem(row, nsr);
- getmem(sumrow, nsr);
- pa := @a;
- pb := @b;
- px := @x;
- For i:= 1 To n Do
- move(pa^[1+(i-1)*rwidth], au^[1+(i-1)*n], nsr);
- move(pb^[1], px^[1], nsr);
- normr := 0;
- singular := false ;
- i := 0;
- j := 0;
- while (i<n) and (Not singular) Do
- Begin
- i := i+1;
- sumrow^[i] := omvn1v(au^[1+(i-1)*n], n);
- If sumrow^[i]=0
- Then
- singular := true
- Else
- Begin
- h := 2*random-1;
- t^[i] := sumrow^[i]*h;
- h := abs(h);
- If normr<h
- Then
- normr := h
- End
- End;
- k := 0;
- while (k<n) and not singular Do
- Begin
- k := k+1;
- maxim := 0;
- ipiv := k;
- For i:=k To n Do
- Begin
- h := abs(au^[k+(i-1)*n])/sumrow^[i];
- If maxim<h
- Then
- Begin
- maxim := h;
- ipiv := i
- End
- End;
- If maxim=0
- Then
- singular := true
- Else
- Begin
- k1n := (k-1)*n;
- If ipiv <> k
- Then
- Begin
- ip := 1+(ipiv-1)*n;
- ik := 1+k1n;
- move(au^[ip], row^[1], nsr);
- move(au^[ik], au^[ip], nsr);
- move(row^[1], au^[ik], nsr);
- h := t^[ipiv];
- t^[ipiv] := t^[k];
- t^[k] := h;
- h := px^[ipiv];
- px^[ipiv] := px^[k];
- px^[k] := h;
- sumrow^[ipiv] := sumrow^[k]
- End;
- pivot := au^[k+k1n];
- For i:=k+1 To n Do
- Begin
- i1n := (i-1)*n;
- l := au^[k+i1n]/pivot;
- If l <> 0
- Then
- Begin
- For j:=k+1 To n Do
- au^[j+i1n] := au^[j+i1n]-l*au^[j+k1n];
- t^[i] := t^[i]-l*t^[k];
- px^[i] := px^[i]-l*px^[k]
- End
- End
- End
- End;
- If Not singular
- Then
- Begin
- normt := 0;
- For i:=n Downto 1 Do
- Begin
- s := 0;
- i1n := (i-1)*n;
- For j:=i+1 To n Do
- s := s+t^[j]*au^[j+i1n];
- t^[i] := (t^[i]-s)/au^[i+i1n];
- s := 0;
- For j:=i+1 To n Do
- s := s+px^[j]*au^[j+i1n];
- px^[i] := (px^[i]-s)/au^[i+i1n];
- h := abs(t^[i]);
- If normt<h
- Then
- normt := h
- End;
- ca := normt/normr
- End;
- If singular
- Then
- term := 2
- Else
- term := 1;
- freemem(au, sqr(n)*sizeof(ArbFloat));
- freemem(t, nsr);
- freemem(row, nsr);
- freemem(sumrow, nsr);
- End; {slegen}
- Procedure slegenl( n: ArbInt;
- Var a1;
- Var b1, x1, ca: ArbFloat;
- Var term: ArbInt);
- Var
- nsr, i, j, k, ipiv : ArbInt;
- singular : boolean;
- normr, pivot, l, normt, maxim, h, s : ArbFloat;
- a : ar2dr1 absolute a1;
- x : arfloat1 absolute x1;
- b : arfloat1 absolute b1;
- au: par2dr1;
- sumrow, t, row : ^arfloat1;
- Begin
- If n<1 Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- AllocateAr2dr(n, n, au);
- nsr := n*sizeof(ArbFloat);
- getmem(t, nsr);
- getmem(row, nsr);
- getmem(sumrow, nsr);
- For i:= 1 To n Do
- move(a[i]^, au^[i]^, nsr);
- move(b[1], x[1], nsr);
- normr := 0;
- singular := false ;
- i := 0;
- j := 0;
- while (i<n) and (Not singular) Do
- Begin
- i := i+1;
- sumrow^[i] := omvn1v(au^[i]^[1], n);
- If sumrow^[i]=0
- Then
- singular := true
- Else
- Begin
- h := 2*random-1;
- t^[i] := sumrow^[i]*h;
- h := abs(h);
- If normr<h
- Then
- normr := h
- End
- End;
- k := 0;
- while (k<n) and not singular Do
- Begin
- k := k+1;
- maxim := 0;
- ipiv := k;
- For i:=k To n Do
- Begin
- h := abs(au^[i]^[k])/sumrow^[i];
- If maxim<h
- Then
- Begin
- maxim := h;
- ipiv := i
- End
- End;
- If maxim=0
- Then
- singular := true
- Else
- Begin
- If ipiv <> k
- Then
- Begin
- move(au^[ipiv]^, row^, nsr);
- move(au^[k]^, au^[ipiv]^, nsr);
- move(row^, au^[k]^, nsr);
- h := t^[ipiv];
- t^[ipiv] := t^[k];
- t^[k] := h;
- h := x[ipiv];
- x[ipiv] := x[k];
- x[k] := h;
- sumrow^[ipiv] := sumrow^[k]
- End;
- pivot := au^[k]^[k];
- For i:=k+1 To n Do
- Begin
- l := au^[i]^[k]/pivot;
- If l <> 0
- Then
- Begin
- For j:=k+1 To n Do
- au^[i]^[j] := au^[i]^[j]-l*au^[k]^[j];
- t^[i] := t^[i]-l*t^[k];
- x[i] := x[i]-l*x[k]
- End
- End
- End
- End;
- If Not singular
- Then
- Begin
- normt := 0;
- For i:=n Downto 1 Do
- Begin
- s := 0;
- For j:=i+1 To n Do
- s := s+t^[j]*au^[i]^[j];
- t^[i] := (t^[i]-s)/au^[i]^[i];
- s := 0;
- For j:=i+1 To n Do
- s := s+x[j]*au^[i]^[j];
- x[i] := (x[i]-s)/au^[i]^[i];
- h := abs(t^[i]);
- If normt<h
- Then
- normt := h
- End;
- ca := normt/normr
- End;
- If singular
- Then
- term := 2
- Else
- term := 1;
- freemem(t, nsr);
- freemem(row, nsr);
- freemem(sumrow, nsr);
- DeAllocateAr2dr(n, n, au);
- End; {slegenl}
- Procedure slegls(Var a: ArbFloat; m, n, rwidtha: ArbInt; Var b, x: ArbFloat;
- Var term: ArbInt);
- Var i, j, ns, ms, ii : ArbInt;
- normy0, norme0, norme1, s : ArbFloat;
- pa, pb, px, qr, alpha, e, y, r : ^arfloat1;
- pivot : ^arint1;
- Begin
- If (n<1) Or (m<n)
- Then
- Begin
- term := 3;
- exit
- End;
- pa := @a;
- pb := @b;
- px := @x;
- ns := n*sizeof(ArbFloat);
- ms := m*sizeof(ArbFloat);
- getmem(qr, m*ns);
- getmem(alpha, ns);
- getmem(e, ns);
- getmem(y, ns);
- getmem(r, m*sizeof(ArbFloat));
- getmem(pivot, n*sizeof(ArbInt));
- For i:=1 To m Do
- move(pa^[(i-1)*rwidtha+1], qr^[(i-1)*n+1], ns);
- decomp(qr^[1], m, n, n, alpha^[1], pivot^[1], term);
- If term=2
- Then
- Begin
- freemem(qr, m*ns);
- freemem(alpha, ns);
- freemem(e, ns);
- freemem(y, ns);
- freemem(r, m*sizeof(ArbFloat));
- freemem(pivot, n*sizeof(ArbInt));
- exit
- End;
- move(pb^[1], r^[1], ms);
- solve(qr^[1], m, n, n, alpha^[1], pivot^[1], r^[1], y^[1]);
- For i:=1 To m Do
- Begin
- s := pb^[i];
- ii := (i-1)*rwidtha;
- For j:=1 To n Do
- s := s-pa^[ii+j]*y^[j];
- r^[i] := s
- End; {i}
- solve(qr^[1], m, n, n, alpha^[1], pivot^[1], r^[1], e^[1]);
- normy0 := 0;
- norme1 := 0;
- For i:=1 To n Do
- Begin
- normy0 := normy0+sqr(y^[i]);
- norme1 := norme1+sqr(e^[i])
- End; {i}
- If norme1 > 0.0625*normy0
- Then
- Begin
- term := 2;
- freemem(qr, m*ns);
- freemem(alpha, ns);
- freemem(e, ns);
- freemem(y, ns);
- freemem(r, m*sizeof(ArbFloat));
- freemem(pivot, n*sizeof(ArbInt));
- exit
- End;
- For i:=1 To n Do
- px^[i] := y^[i];
- freemem(qr, m*ns);
- freemem(alpha, ns);
- freemem(e, ns);
- freemem(y, ns);
- freemem(r, m*sizeof(ArbFloat));
- freemem(pivot, n*sizeof(ArbInt));
- End; {slegls}
- Procedure sleglsl(Var a1; m, n: ArbInt; Var b1, x1: ArbFloat;
- Var term: ArbInt);
- Var i, j, ns, ms : ArbInt;
- normy0, norme0, norme1, s : ArbFloat;
- a : ar2dr1 absolute a1;
- b : arfloat1 absolute b1;
- x : arfloat1 absolute x1;
- alpha, e, y, r : ^arfloat1;
- qr : par2dr1;
- pivot : ^arint1;
- Begin
- If (n<1) Or (m<n)
- Then
- Begin
- term := 3;
- exit
- End;
- AllocateAr2dr(m, n, qr);
- ns := n*sizeof(ArbFloat);
- ms := m*sizeof(ArbFloat);
- getmem(alpha, ns);
- getmem(e, ns);
- getmem(y, ns);
- getmem(r, ms);
- getmem(pivot, n*sizeof(ArbInt));
- For i:=1 To m Do
- move(a[i]^, qr^[i]^, ns);
- decomp1(qr^[1], m, n, alpha^[1], pivot^[1], term);
- If term=2
- Then
- Begin
- freemem(qr, m*ns);
- freemem(alpha, ns);
- freemem(e, ns);
- freemem(y, ns);
- freemem(r, ms);
- freemem(pivot, n*sizeof(ArbInt));
- exit
- End;
- move(b[1], r^, ms);
- solve1(qr^[1], m, n, alpha^[1], pivot^[1], r^[1], y^[1]);
- For i:=1 To m Do
- Begin
- s := b[i];
- For j:=1 To n Do
- s := s-a[i]^[j]*y^[j];
- r^[i] := s
- End; {i}
- solve1(qr^[1], m, n, alpha^[1], pivot^[1], r^[1], e^[1]);
- normy0 := 0;
- norme1 := 0;
- For i:=1 To n Do
- Begin
- normy0 := normy0+sqr(y^[i]);
- norme1 := norme1+sqr(e^[i])
- End; {i}
- If norme1 > 0.0625*normy0
- Then
- Begin
- term := 2;
- freemem(qr, m*ns);
- freemem(alpha, ns);
- freemem(e, ns);
- freemem(y, ns);
- freemem(r, m*sizeof(ArbFloat));
- freemem(pivot, n*sizeof(ArbInt));
- exit
- End;
- For i:=1 To n Do
- x[i] := y^[i];
- freemem(alpha, ns);
- freemem(e, ns);
- freemem(y, ns);
- freemem(r, ms);
- freemem(pivot, n*sizeof(ArbInt));
- DeAllocateAr2dr(m, n, qr);
- End; {sleglsl}
- Procedure slegpb(n, l: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Var
- posdef : boolean;
- i, j, k, r, p, q, jmin1, ii, jj, ri, ind,
- ll, llm1, sr, rwidth : ArbInt;
- h, normr, normt, sumrowi, hh, alim, norma : ArbFloat;
- pa, pb, px, al, t, v : ^arfloat1;
- Procedure decomp(i, r: ArbInt);
- Var k: ArbInt;
- Begin
- ri := (r-1)*ll;
- h := al^[ii+j];
- q := ll-j+p;
- For k:=p To jmin1 Do
- Begin
- h := h-al^[ii+k]*al^[ri+q];
- q := q+1
- End ;
- If j<ll
- Then
- al^[ii+j] := h/al^[ri+ll];
- End; {decomp}
- Begin
- If (n<1) Or (l<0) Or (l>n-1)
- Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- sr := sizeof(ArbFloat);
- pa := @a;
- pb := @b;
- px := @x;
- ll := l+1;
- getmem(al, ll*n*sr);
- getmem(t, n*sr);
- getmem(v, ll*sr);
- move(pb^, px^, n*sr);
- jj := 1;
- ii := 1;
- For i:=1 To n Do
- Begin
- If i>l Then rwidth := ll
- Else rwidth := i;
- move(pa^[jj], al^[ii+ll-rwidth], rwidth*sr);
- jj := jj+rwidth;
- ii := ii+ll
- End; {i}
- normr := 0;
- p := ll+1;
- norma := 0;
- For i:=1 To n Do
- Begin
- If p>1
- Then
- p := p-1;
- For j:=p To ll Do
- v^[j] := al^[j+(i-1)*ll];
- sumrowi := omvn1v(v^[p], ll-p+1);
- r := i;
- j := ll;
- while (r<n) and (j>1) Do
- Begin
- r := r+1;
- j := j-1;
- sumrowi := sumrowi+abs(al^[j+(r-1)*ll])
- End; {r,j}
- If norma<sumrowi
- Then
- norma := sumrowi;
- h := 2*random-1;
- t^[i] := h;
- h := abs(h);
- If normr<h
- Then
- normr := h
- End; {i}
- llm1 := ll-1;
- p := ll+1;
- i := 0;
- posdef := true ;
- while (i<n) and posdef Do
- Begin
- i := i+1;
- If p>1 Then p := p-1;
- r := i-ll+p;
- j := p-1;
- ii := (i-1)*ll;
- while j<llm1 Do
- Begin
- jmin1 := j;
- j := j+1;
- decomp(i, r);
- r := r+1
- End ; {j}
- jmin1 := llm1;
- j := ll;
- decomp(i, i);
- If h <= 0
- Then
- posdef := false
- Else
- Begin
- alim := sqrt(h);
- al^[ii+ll] := alim;
- h := t^[i];
- q := i;
- For k:=llm1 Downto p Do
- Begin
- q := q-1;
- h := h-al^[ii+k]*t^[q]
- End ;
- t^[i] := h/alim;
- h := px^[i];
- q := i;
- For k:=llm1 Downto p Do
- Begin
- q := q-1;
- h := h-al^[ii+k]*px^[q]
- End; {k}
- px^[i] := h/alim
- End {posdef}
- End; {i}
- If posdef
- Then
- Begin
- normt := 0;
- p := ll+1;
- For i:=n Downto 1 Do
- Begin
- If p>1
- Then
- p := p-1;
- q := i;
- h := t^[i];
- hh := px^[i];
- For k:=llm1 Downto p Do
- Begin
- q := q+1;
- ind := (q-1)*ll+k;
- h := h-al^[ind]*t^[q];
- hh := hh-al^[ind]*px^[q]
- End; {k}
- ind := i*ll;
- t^[i] := h/al^[ind];
- px^[i] := hh/al^[ind];
- h := abs(t^[i]);
- If normt<h
- Then
- normt := h
- End; {i}
- ca := norma*normt/normr
- End ; {posdef}
- If posdef
- Then
- term := 1
- Else
- term := 2;
- freemem(al, ll*n*sr);
- freemem(t, n*sr);
- freemem(v, ll*sr);
- End; {slegpb}
- Procedure slegpbl(n, l: ArbInt;
- Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
- Var
- posdef : boolean;
- i, j, k, r, p, q, ll, sr, rwidth : ArbInt;
- h, normr, normt, sumrowi, hh, alim, norma : ArbFloat;
- a : ar2dr1 absolute a1;
- b : arfloat1 absolute b1;
- x : arfloat1 absolute x1;
- al : par2dr1;
- t, v : ^arfloat1;
- Procedure decomp(r: ArbInt);
- Var k: ArbInt;
- Begin
- h := al^[i]^[j];
- q := ll-j+p;
- For k:=p To j-1 Do
- Begin
- h := h-al^[i]^[k]*al^[r]^[q];
- Inc(q)
- End ;
- If j<ll Then al^[i]^[j] := h/al^[r]^[ll];
- End; {decomp}
- Begin
- If (n<1) Or (l<0) Or (l>n-1)
- Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- sr := sizeof(ArbFloat);
- ll := l+1;
- AllocateAr2dr(n, ll, al);
- getmem(t, n*sr);
- getmem(v, ll*sr);
- move(b[1], x[1], n*sr);
- For i:=1 To n Do
- Begin
- If i>l Then rwidth := ll
- Else rwidth := i;
- move(a[i]^, al^[i]^[ll-rwidth+1], rwidth*sr);
- End; {i}
- normr := 0;
- p := ll+1;
- norma := 0;
- For i:=1 To n Do
- Begin
- If p>1 Then Dec(p);
- For j:=p To ll Do
- v^[j] := al^[i]^[j];
- sumrowi := omvn1v(v^[p], ll-p+1);
- r := i;
- j := ll;
- while (r<n) and (j>1) Do
- Begin
- Inc(r);
- Dec(j);
- sumrowi := sumrowi+abs(al^[r]^[j])
- End; {r,j}
- If norma<sumrowi Then norma := sumrowi;
- h := 2*random-1;
- t^[i] := h;
- h := abs(h);
- If normr<h Then normr := h
- End; {i}
- p := ll+1;
- i := 0;
- posdef := true ;
- while (i<n) and posdef Do
- Begin
- Inc(i);
- If p>1 Then Dec(p);
- r := i-ll+p;
- j := p-1;
- while j<ll-1 Do
- Begin
- Inc(j);
- decomp(r);
- Inc(r)
- End ; {j}
- j := ll;
- decomp(i);
- If h <= 0 Then posdef := false
- Else
- Begin
- alim := sqrt(h);
- al^[i]^[ll] := alim;
- h := t^[i];
- q := i;
- For k:=ll-1 Downto p Do
- Begin
- q := q-1;
- h := h-al^[i]^[k]*t^[q]
- End ;
- t^[i] := h/alim;
- h := x[i];
- q := i;
- For k:=ll-1 Downto p Do
- Begin
- q := q-1;
- h := h-al^[i]^[k]*x[q]
- End; {k}
- x[i] := h/alim
- End {posdef}
- End; {i}
- If posdef
- Then
- Begin
- normt := 0;
- p := ll+1;
- For i:=n Downto 1 Do
- Begin
- If p>1 Then Dec(p);
- q := i;
- h := t^[i];
- hh := x[i];
- For k:=ll-1 Downto p Do
- Begin
- Inc(q);
- h := h-al^[q]^[k]*t^[q];
- hh := hh-al^[q]^[k]*x[q]
- End; {k}
- t^[i] := h/al^[i]^[ll];
- x[i] := hh/al^[i]^[ll];
- h := abs(t^[i]);
- If normt<h Then normt := h
- End; {i}
- ca := norma*normt/normr
- End ; {posdef}
- If posdef Then term := 1
- Else term := 2;
- freemem(t, n*sr);
- freemem(v, ll*sr);
- DeAllocateAr2dr(n, ll, al);
- End; {slegpbl}
- Procedure slegpd(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Var
- sr, i, j, k, kmin1, kk, k1n, i1n, ik, ii : ArbInt;
- pd : boolean;
- h, lkk, normr, normt, sumrowi, norma : ArbFloat;
- pa, pb, px, al, t : ^arfloat1;
- Begin
- If (n<1) Or (rwidth<1)
- Then
- Begin
- term := 3;
- exit
- End;
- sr := sizeof(ArbFloat);
- getmem(al, sqr(n)*sr);
- getmem(t, n*sr);
- pa := @a;
- pb := @b;
- px := @x;
- For i:=1 To n Do
- move(pa^[1+(i-1)*rwidth], al^[1+(i-1)*n], i*sr);
- move(pb^[1], px^[1], n*sr);
- normr := 0;
- pd := true ;
- norma := 0;
- For i:=1 To n Do
- Begin
- sumrowi := 0;
- For j:=1 To i Do
- sumrowi := sumrowi+abs(al^[j+(i-1)*n]);
- For j:=i+1 To n Do
- sumrowi := sumrowi+abs(al^[i+(j-1)*n]);
- If norma<sumrowi
- Then
- norma := sumrowi;
- t^[i] := 2*random-1;
- h := abs(t^[i]);
- If normr<h
- Then
- normr := h
- End; {i}
- k := 0;
- while (k<n) and pd Do
- Begin
- kmin1 := k;
- k := k+1;
- k1n := (k-1)*n;
- kk := k+k1n;
- lkk := al^[kk];
- For j:=1 To kmin1 Do
- lkk := lkk-sqr(al^[j+k1n]);
- If lkk<=0
- Then
- pd := false
- Else
- Begin
- al^[kk] := sqrt(lkk);
- lkk := al^[kk];
- For i:=k+1 To n Do
- Begin
- i1n := (i-1)*n;
- ik := k+i1n;
- h := al^[ik];
- For j:=1 To kmin1 Do
- h := h-al^[j+k1n]*al^[j+i1n];
- al^[ik] := h/lkk
- End; {i}
- h := t^[k];
- For j:=1 To kmin1 Do
- h := h-al^[j+k1n]*t^[j];
- t^[k] := h/lkk;
- h := px^[k];
- For j:=1 To kmin1 Do
- h := h-al^[j+k1n]*px^[j];
- px^[k] := h/lkk
- End {lkk > 0}
- End; {k}
- If pd
- Then
- Begin
- normt := 0;
- For i:=n Downto 1 Do
- Begin
- ii := i+(i-1)*n;
- h := t^[i];
- For j:=i+1 To n Do
- h := h-al^[i+(j-1)*n]*t^[j];
- t^[i] := h/al^[ii];
- h := px^[i];
- For j:=i+1 To n Do
- h := h-al^[i+(j-1)*n]*px^[j];
- px^[i] := h/al^[ii];
- h := abs(t^[i]);
- If normt<h
- Then
- normt := h
- End; {i}
- ca := norma*normt/normr
- End; {pd}
- If pd
- Then
- term := 1
- Else
- term := 2;
- freemem(al, sqr(n)*sr);
- freemem(t, n*sr);
- End; {slegpd}
- Procedure slegpdl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
- Var term: ArbInt);
- Var sr, i, j, k, kmin1 : ArbInt;
- pd : boolean;
- h, lkk, normr, normt, sumrowi, norma : ArbFloat;
- a : ar2dr1 absolute a1;
- b : arfloat1 absolute b1;
- x : arfloat1 absolute x1;
- al : par2dr1;
- t : ^arfloat1;
- Begin
- If n<1 Then
- Begin
- term := 3;
- exit
- End;
- sr := sizeof(ArbFloat);
- AllocateL2dr(n, al);
- getmem(t, n*sr);
- For i:=1 To n Do
- move(a[i]^, al^[i]^, i*sr);
- move(b[1], x[1], n*sr);
- normr := 0;
- pd := true ;
- norma := 0;
- For i:=1 To n Do
- Begin
- sumrowi := 0;
- For j:=1 To i Do
- sumrowi := sumrowi+abs(al^[i]^[j]);
- For j:=i+1 To n Do
- sumrowi := sumrowi+abs(al^[j]^[i]);
- If norma<sumrowi Then norma := sumrowi;
- t^[i] := 2*random-1;
- h := abs(t^[i]);
- If normr<h Then normr := h
- End; {i}
- k := 0;
- while (k<n) and pd Do
- Begin
- kmin1 := k;
- k := k+1;
- lkk := al^[k]^[k];
- For j:=1 To kmin1 Do
- lkk := lkk-sqr(al^[k]^[j]);
- If lkk<=0 Then pd := false
- Else
- Begin
- al^[k]^[k] := sqrt(lkk);
- lkk := al^[k]^[k];
- For i:=k+1 To n Do
- Begin
- h := al^[i]^[k];
- For j:=1 To kmin1 Do
- h := h-al^[k]^[j]*al^[i]^[j];
- al^[i]^[k] := h/lkk
- End; {i}
- h := t^[k];
- For j:=1 To kmin1 Do
- h := h-al^[k]^[j]*t^[j];
- t^[k] := h/lkk;
- h := x[k];
- For j:=1 To kmin1 Do
- h := h-al^[k]^[j]*x[j];
- x[k] := h/lkk
- End {lkk > 0}
- End; {k}
- If pd Then
- Begin
- normt := 0;
- For i:=n Downto 1 Do
- Begin
- h := t^[i];
- For j:=i+1 To n Do
- h := h-al^[j]^[i]*t^[j];
- t^[i] := h/al^[i]^[i];
- h := x[i];
- For j:=i+1 To n Do
- h := h-al^[j]^[i]*x[j];
- x[i] := h/al^[i]^[i];
- h := abs(t^[i]);
- If normt<h Then normt := h
- End; {i}
- ca := norma*normt/normr
- End; {pd}
- If pd Then term := 1
- Else term := 2;
- DeAllocateL2dr(n, al);
- freemem(t, n*sr);
- End; {slegpdl}
- Procedure slegsy(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
- Var term:ArbInt);
- Var
- i, j, kmin1, k, kplus1, kmin2, imin2, nsr, nsi, nsb, ii,
- imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt;
- ra, h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
- pa, pb, pb1, px, alt, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
- p : ^arint1;
- q : ^arbool1;
- Begin
- If (n<1) Or (rwidth<1)
- Then
- Begin
- term := 3;
- exit
- End; {if}
- pa := @a;
- pb := @b;
- px := @x;
- nsr := n*sizeof(ArbFloat);
- nsi := n*sizeof(ArbInt);
- nsb := n*sizeof(boolean);
- getmem(alt, n*nsr);
- getmem(l, nsr);
- getmem(d, nsr);
- getmem(t, nsr);
- getmem(u, nsr);
- getmem(v, nsr);
- getmem(p, nsi);
- getmem(q, nsb);
- getmem(l1, nsr);
- getmem(d1, nsr);
- getmem(u1, nsr);
- getmem(t1, nsr);
- getmem(pb1, nsr);
- move(pb^, pb1^, nsr);
- For i:=1 To n Do
- Begin
- indi := (i-1)*n;
- For j:=1 To i Do
- alt^[indi+j] := pa^[(i-1)*rwidth+j];
- End; {i}
- norma := 0;
- For i:=1 To n Do
- Begin
- indi := (i-1)*n;
- p^[i] := i;
- sumrowi := 0;
- For j:=1 To i Do
- sumrowi := sumrowi+abs(alt^[indi+j]);
- For j:=i+1 To n Do
- sumrowi := sumrowi+abs(alt^[(j-1)*n+i]);
- If norma<sumrowi
- Then
- norma := sumrowi
- End; {i}
- kmin1 := -1;
- k := 0;
- kplus1 := 1;
- while k<n Do
- Begin
- kmin2 := kmin1;
- kmin1 := k;
- k := kplus1;
- kplus1 := kplus1+1;
- indk := kmin1*n;
- If k>3
- Then
- Begin
- t^[2] := alt^[n+2]*alt^[indk+1]+alt^[2*n+2]*alt^[indk+2];
- For i:=3 To kmin2 Do
- Begin
- indi := (i-1)*n;
- t^[i] := alt^[indi+i-1]*alt^[indk+i-2]+alt^[indi+i]
- *alt^[indk+i-1]+alt^[indi+n+i]*alt^[indk+i]
- End; {i}
- t^[kmin1] := alt^[indk-n+kmin2]*alt^[indk+k-3]
- +alt^[indk-n+kmin1]*alt^[indk+kmin2]
- +alt^[indk+kmin1];
- h := alt^[indk+k];
- For j:=2 To kmin1 Do
- h := h-t^[j]*alt^[indk+j-1];
- t^[k] := h;
- alt^[indk+k] := h-alt^[indk+kmin1]*alt^[indk+kmin2]
- End {k>3}
- Else
- If k=3
- Then
- Begin
- t^[2] := alt^[n+2]*alt^[2*n+1]+alt^[2*n+2];
- h := alt^[2*n+3]-t^[2]*alt^[2*n+1];
- t^[3] := h;
- alt^[2*n+3] := h-alt^[2*n+2]*alt^[2*n+1]
- End {k=3}
- Else
- If k=2
- Then
- t^[2] := alt^[n+2];
- maxim := 0;
- For i:=kplus1 To n Do
- Begin
- indi := (i-1)*n;
- h := alt^[indi+k];
- For j:=2 To k Do
- h := h-t^[j]*alt^[indi+j-1];
- absh := abs(h);
- If maxim<absh
- Then
- Begin
- maxim := absh;
- indexpivot := i
- End; {if}
- alt^[indi+k] := h
- End; {i}
- If maxim <> 0
- Then
- Begin
- If indexpivot>kplus1
- Then
- Begin
- indp := (indexpivot-1)*n;
- indk := k*n;
- p^[kplus1] := indexpivot;
- For j:=1 To k Do
- Begin
- h := alt^[indk+j];
- alt^[indk+j] := alt^[indp+j];
- alt^[indp+j] := h
- End; {j}
- For j:=indexpivot Downto kplus1 Do
- Begin
- indj := (j-1)*n;
- h := alt^[indj+kplus1];
- alt^[indj+kplus1] := alt^[indp+j];
- alt^[indp+j] := h
- End; {j}
- For i:=indexpivot To n Do
- Begin
- indi := (i-1)*n;
- h := alt^[indi+kplus1];
- alt^[indi+kplus1] := alt^[indi+indexpivot];
- alt^[indi+indexpivot] := h
- End {i}
- End; {if}
- pivot := alt^[k*n+k];
- For i:=k+2 To n Do
- alt^[(i-1)*n+k] := alt^[(i-1)*n+k]/pivot
- End {maxim <> 0}
- End; {k}
- d^[1] := alt^[1];
- i := 1;
- while i<n Do
- Begin
- imin1 := i;
- i := i+1;
- u^[imin1] := alt^[(i-1)*n+imin1];
- l^[imin1] := u^[imin1];
- d^[i] := alt^[(i-1)*n+i]
- End; {i}
- mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
- q^[1], ct, term);
- If term=1
- Then
- Begin
- normr := 0;
- For i:=1 To n Do
- Begin
- t^[i] := 2*random-1;
- h := t^[i];
- h := abs(h);
- If normr<h
- Then
- normr := h
- End; {i}
- For i:=1 To n Do
- Begin
- indexpivot := p^[i];
- If indexpivot <> i
- Then
- Begin
- h := pb1^[i];
- pb1^[i] := pb1^[indexpivot];
- pb1^[indexpivot] := h
- End {if}
- End; {i}
- i := 0;
- while i<n Do
- Begin
- indi := i*n;
- imin1 := i;
- i := i+1;
- j := 1;
- h := t^[i];
- s := pb1^[i];
- while j<imin1 Do
- Begin
- jmin1 := j;
- j := j+1;
- s := s-alt^[indi+jmin1]*pb1^[j];
- h := h-alt^[indi+jmin1]*t^[j]
- End; {j}
- t^[i] := h;
- pb1^[i] := s
- End; {i}
- dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], pb1^[1], px^[1], term);
- dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
- i := n+1;
- imin1 := n;
- normt := 0;
- while i>2 Do
- Begin
- iplus1 := i;
- i := imin1;
- imin1 := imin1-1;
- h := t1^[i];
- s := px^[i];
- For j:=iplus1 To n Do
- Begin
- indj := (j-1)*n+imin1;
- h := h-alt^[indj]*t1^[j];
- s := s-alt^[indj]*px^[j]
- End; {j}
- px^[i] := s;
- t1^[i] := h;
- h := abs(h);
- If normt<h
- Then
- normt := h
- End; {i}
- For i:=n Downto 1 Do
- Begin
- indexpivot := p^[i];
- If indexpivot <> i
- Then
- Begin
- h := px^[i];
- px^[i] := px^[indexpivot];
- px^[indexpivot] := h
- End {if}
- End; {i}
- ca := norma*normt/normr
- End {term=1}
- Else
- term := 2;
- freemem(alt, n*nsr);
- freemem(l, nsr);
- freemem(d, nsr);
- freemem(t, nsr);
- freemem(u, nsr);
- freemem(v, nsr);
- freemem(p, nsi);
- freemem(q, nsb);
- freemem(l1, nsr);
- freemem(d1, nsr);
- freemem(u1, nsr);
- freemem(t1, nsr);
- freemem(pb1, nsr);
- End; {slegsy}
- Procedure slegsyl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
- Var term: ArbInt);
- Var
- i, j, kmin1, k, kplus1, kmin2, imin2, nsr, nsi, nsb, ii,
- imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt;
- ra, h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
- a : ar2dr1 absolute a1;
- b : arfloat1 absolute b1;
- x : arfloat1 absolute x1;
- b0, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
- alt : par2dr1;
- p : ^arint1;
- q : ^arbool1;
- Begin
- If n<1 Then
- Begin
- term := 3;
- exit
- End; {if}
- nsr := n*sizeof(ArbFloat);
- nsi := n*sizeof(ArbInt);
- nsb := n*sizeof(boolean);
- AllocateL2dr(n, alt);
- getmem(l, nsr);
- getmem(d, nsr);
- getmem(t, nsr);
- getmem(u, nsr);
- getmem(v, nsr);
- getmem(p, nsi);
- getmem(q, nsb);
- getmem(l1, nsr);
- getmem(d1, nsr);
- getmem(u1, nsr);
- getmem(t1, nsr);
- getmem(b0, nsr);
- move(b[1], b0^, nsr);
- For i:=1 To n Do
- move(a[i]^, alt^[i]^, i*sizeof(ArbFloat));
- norma := 0;
- For i:=1 To n Do
- Begin
- p^[i] := i;
- sumrowi := 0;
- For j:=1 To i Do
- sumrowi := sumrowi+abs(alt^[i]^[j]);
- For j:=i+1 To n Do
- sumrowi := sumrowi+abs(alt^[j]^[i]);
- If norma<sumrowi Then norma := sumrowi
- End; {i}
- k := 0;
- while k<n Do
- Begin
- Inc(k);
- If k>3 Then
- Begin
- t^[2] := alt^[2]^[2]*alt^[k]^[1]+alt^[3]^[2]*alt^[k]^[2];
- For i:=3 To k-2 Do
- t^[i] := alt^[i]^[i-1]*alt^[k]^[i-2]+alt^[i]^[i]
- *alt^[k]^[i-1]+alt^[i+1]^[i]*alt^[k]^[i];
- t^[k-1] := alt^[k-1]^[k-2]*alt^[k]^[k-3]
- +alt^[k-1]^[k-1]*alt^[k]^[k-2]+alt^[k]^[k-1];
- h := alt^[k]^[k];
- For j:=2 To k-1 Do
- h := h-t^[j]*alt^[k]^[j-1];
- t^[k] := h;
- alt^[k]^[k] := h-alt^[k]^[k-1]*alt^[k]^[k-2]
- End {k>3}
- Else
- If k=3
- Then
- Begin
- t^[2] := alt^[2]^[2]*alt^[3]^[1]+alt^[3]^[2];
- h := alt^[3]^[3]-t^[2]*alt^[3]^[1];
- t^[3] := h;
- alt^[3]^[3] := h-alt^[3]^[2]*alt^[3]^[1]
- End {k=3}
- Else
- If k=2 Then t^[2] := alt^[2]^[2];
- maxim := 0;
- For i:=k+1 To n Do
- Begin
- h := alt^[i]^[k];
- For j:=2 To k Do
- h := h-t^[j]*alt^[i]^[j-1];
- absh := abs(h);
- If maxim<absh Then
- Begin
- maxim := absh;
- indexpivot := i
- End; {if}
- alt^[i]^[k] := h
- End; {i}
- If maxim <> 0
- Then
- Begin
- If indexpivot>k+1 Then
- Begin
- p^[k+1] := indexpivot;
- For j:=1 To k Do
- Begin
- h := alt^[k+1]^[j];
- alt^[k+1]^[j] := alt^[indexpivot]^[j];
- alt^[indexpivot]^[j] := h
- End; {j}
- For j:=indexpivot Downto k+1 Do
- Begin
- h := alt^[j]^[k+1];
- alt^[j]^[k+1] := alt^[indexpivot]^[j];
- alt^[indexpivot]^[j] := h
- End; {j}
- For i:=indexpivot To n Do
- Begin
- h := alt^[i]^[k+1];
- alt^[i]^[k+1] := alt^[i]^[indexpivot];
- alt^[i]^[indexpivot] := h
- End {i}
- End; {if}
- pivot := alt^[k+1]^[k];
- For i:=k+2 To n Do
- alt^[i]^[k] := alt^[i]^[k]/pivot
- End {maxim <> 0}
- End; {k}
- d^[1] := alt^[1]^[1];
- i := 1;
- while i<n Do
- Begin
- Inc(i);
- u^[i-1] := alt^[i]^[i-1];
- l^[i-1] := u^[i-1];
- d^[i] := alt^[i]^[i]
- End; {i}
- mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
- q^[1], ct, term);
- If term=1 Then
- Begin
- normr := 0;
- For i:=1 To n Do
- Begin
- t^[i] := 2*random-1;
- h := t^[i];
- h := abs(h);
- If normr<h Then normr := h
- End; {i}
- For i:=1 To n Do
- Begin
- indexpivot := p^[i];
- If indexpivot <> i
- Then
- Begin
- h := b0^[i];
- b0^[i] := b0^[indexpivot];
- b0^[indexpivot] := h
- End {if}
- End; {i}
- i := 0;
- while i<n Do
- Begin
- Inc(i);
- j := 1;
- h := t^[i];
- s := b0^[i];
- while j<i-1 Do
- Begin
- Inc(j);
- s := s-alt^[i]^[j-1]*b0^[j];
- h := h-alt^[i]^[j-1]*t^[j]
- End; {j}
- t^[i] := h;
- b0^[i] := s
- End; {i}
- dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], b0^[1], x[1], term);
- dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
- i := n+1;
- normt := 0;
- while i>2 Do
- Begin
- Dec(i);
- h := t1^[i];
- s := x[i];
- For j:=i+1 To n Do
- Begin
- h := h-alt^[j]^[i-1]*t1^[j];
- s := s-alt^[j]^[i-1]*x[j]
- End; {j}
- x[i] := s;
- t1^[i] := h;
- h := abs(h);
- If normt<h Then normt := h
- End; {i}
- For i:=n Downto 1 Do
- Begin
- indexpivot := p^[i];
- If indexpivot <> i Then
- Begin
- h := x[i];
- x[i] := x[indexpivot];
- x[indexpivot] := h
- End {if}
- End; {i}
- ca := norma*normt/normr
- End {term=1}
- Else
- term := 2;
- freemem(l, nsr);
- freemem(d, nsr);
- freemem(t, nsr);
- freemem(u, nsr);
- freemem(v, nsr);
- freemem(p, nsi);
- freemem(q, nsb);
- freemem(l1, nsr);
- freemem(d1, nsr);
- freemem(u1, nsr);
- freemem(t1, nsr);
- freemem(b0, nsr);
- DeAllocateL2dr(n, alt);
- End; {slegsyl}
- Procedure slegtr(n:ArbInt; Var l, d, u, b, x, ca: ArbFloat;
- Var term: ArbInt);
- Var singular, ch : boolean;
- i, j, nm1, sr, n1s, ns, n2s : ArbInt;
- normr, normt, h, lj, di, ui, m : ArbFloat;
- pl, ll : ^arfloat2;
- pd, pu, pb, px, dd, uu1, u2, t, sumrow : ^arfloat1;
- Begin
- If n<1
- Then
- Begin
- term := 3;
- exit
- End; {n<1}
- sr := sizeof(ArbFloat);
- n1s := (n-1)*sr;
- ns := n1s+sr;
- n2s := n1s;
- getmem(ll, n1s);
- getmem(uu1, n1s);
- getmem(u2, n2s);
- getmem(dd, ns);
- getmem(t, ns);
- getmem(sumrow, ns);
- pl := @l;
- pd := @d;
- pu := @u;
- pb := @b;
- px := @x;
- move(pl^[2], ll^[2], n1s);
- move(pd^[1], dd^[1], ns);
- If n>1
- Then
- move(pu^[1], uu1^[1], n1s);
- move(pb^[1], px^[1], ns);
- normr := 0;
- singular := false;
- nm1 := n-1;
- i := 0;
- while (i<n) and not singular Do
- Begin
- i := i+1;
- If i=1
- Then
- Begin
- sumrow^[i] := abs(dd^[1]);
- If n>1
- Then
- sumrow^[i] := sumrow^[i]+abs(uu1^[1])
- End {i=1}
- Else
- If i=n
- Then
- sumrow^[i] := abs(ll^[n])+abs(dd^[n])
- Else
- sumrow^[i] := abs(ll^[i])+abs(dd^[i])+abs(uu1^[i]);
- If sumrow^[i]=0
- Then
- singular := true
- Else
- Begin
- h := 2*random-1;
- t^[i] := sumrow^[i]*h;
- h := abs(h);
- If normr<h
- Then
- normr := h
- End {sumrow^[i] <> 0}
- End; {i}
- j := 1;
- while (j <> n) and not singular Do
- Begin
- i := j;
- j := j+1;
- lj := ll^[j];
- If lj <> 0
- Then
- Begin
- di := dd^[i];
- ch := abs(di/sumrow^[i])<abs(lj/sumrow^[j]);
- If ch
- Then
- Begin
- ui := uu1^[i];
- dd^[i] := lj;
- uu1^[i] := dd^[j];
- m := di/lj;
- dd^[j] := ui-m*dd^[j];
- If i<nm1
- Then
- Begin
- u2^[i] := uu1^[j];
- uu1^[j] := -m*u2^[i]
- End; {i<nm1}
- sumrow^[j] := sumrow^[i];
- h := t^[i];
- t^[i] := t^[j];
- t^[j] := h-m*t^[i];
- h := px^[i];
- px^[i] := px^[j];
- px^[j] := h-m*px^[i]
- End {ch}
- Else
- Begin
- m := lj/di;
- dd^[j] := dd^[j]-m*uu1^[i];
- If i<nm1
- Then
- u2^[i] := 0;
- t^[j] := t^[j]-m*t^[i];
- px^[j] := px^[j]-m*px^[i]
- End {not ch}
- End {lj <> 0}
- Else
- Begin
- If i < nm1
- Then
- u2^[i] := 0;
- If dd^[i]=0
- Then
- singular := true
- End {lj=0}
- End; {j}
- If dd^[n]=0
- Then
- singular := true;
- If Not singular
- Then
- Begin
- normt := 0;
- t^[n] := t^[n]/dd^[n];
- px^[n] := px^[n]/dd^[n];
- h := abs(t^[n]);
- If normt<h
- Then
- normt := h;
- If n>1
- Then
- Begin
- t^[nm1] := (t^[nm1]-uu1^[nm1]*t^[n])/dd^[nm1];
- px^[nm1] := (px^[nm1]-uu1^[nm1]*px^[n])/dd^[nm1];
- h := abs(t^[nm1])
- End; {n>1}
- If normt<h
- Then
- normt := h;
- For i:=n-2 Downto 1 Do
- Begin
- t^[i] := (t^[i]-uu1^[i]*t^[i+1]-u2^[i]*t^[i+2])/dd^[i];
- px^[i] := (px^[i]-uu1^[i]*px^[i+1]-u2^[i]*px^[i+2])/dd^[i];
- h := abs(t^[i]);
- If normt<h
- Then
- normt := h
- End; {i}
- ca := normt/normr
- End; {not singular}
- If singular
- Then
- term := 2
- Else
- term := 1;
- freemem(ll, n1s);
- freemem(uu1, n1s);
- freemem(u2, n2s);
- freemem(dd, ns);
- freemem(t, ns);
- freemem(sumrow, ns);
- End; {slegtr}
- Begin
- randseed := 12345
- End.
|