[BACK]Return to determinantal_systems.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Schubert

Annotation of OpenXM_contrib/PHC/Ada/Schubert/determinantal_systems.adb, Revision 1.1.1.1

1.1       maekawa     1: with Standard_Floating_Numbers;          use Standard_Floating_Numbers;
                      2: with Standard_Complex_Numbers;           use Standard_Complex_Numbers;
                      3: with Standard_Natural_Vectors;
                      4: with Standard_Complex_Polynomials;       use Standard_Complex_Polynomials;
                      5: with Bracket_Monomials;                  use Bracket_Monomials;
                      6: with Bracket_Systems;                    use Bracket_Systems;
                      7: with Evaluated_Minors;                   use Evaluated_Minors;
                      8: with Symbolic_Minor_Equations;           use Symbolic_Minor_Equations;
                      9: with Numeric_Minor_Equations;            use Numeric_Minor_Equations;
                     10:
                     11: package body Determinantal_Systems is
                     12:
                     13: -- AUXILIARY TO EVALUATION OF MAXIMAL MINORS :
                     14:
                     15:   function Number_of_Maximal_Minors ( nrows,ncols : natural ) return natural is
                     16:
                     17:   -- DESCRIPTION :
                     18:   --   Returns the number of maximal minors of a matrix with nrows and ncols.
                     19:
                     20:   -- REQUIRED : nrows > ncols.
                     21:
                     22:   begin
                     23:     if ncols = 1
                     24:      then return nrows;
                     25:      else return Number_of_Maximal_Minors(nrows-1,ncols-1)*nrows/ncols;
                     26:     end if;
                     27:   end Number_of_Maximal_Minors;
                     28:
                     29: -- LOCALIZATION MAPS :
                     30:
                     31:   function Localize ( locmap : Standard_Natural_Matrices.Matrix;
                     32:                       t : Term ) return Term is
                     33:
                     34:   -- DESCRIPTION :
                     35:   --   Applies the localization map to the term, eliminating those xij's
                     36:   --   xij for which the corresponding entry in locmap is either 0 or 1.
                     37:
                     38:   -- NOTE :
                     39:   --   This localization assumes that t.dg(k) = 0 with k for which the
                     40:   --   corresponding (i,j) with locmap(i,j) = 0.
                     41:
                     42:     res : Term;
                     43:     ndg : Standard_Natural_Vectors.Vector(t.dg'range);
                     44:     cnt : natural := t.dg'first-1;
                     45:     ind : natural := cnt;
                     46:
                     47:   begin
                     48:     for i in locmap'range(1) loop       -- lexicographic order of variables
                     49:       for j in locmap'range(2) loop
                     50:         ind := ind+1;
                     51:         if locmap(i,j) = 2
                     52:          then cnt := cnt + 1;
                     53:               ndg(cnt) := t.dg(ind);
                     54:         end if;
                     55:       end loop;
                     56:     end loop;
                     57:     for i in ind+1..t.dg'last loop      -- leave the lifting !
                     58:       cnt := cnt+1;
                     59:       ndg(cnt) := t.dg(i);
                     60:     end loop;
                     61:     res.cf := t.cf;
                     62:     res.dg := new Standard_Natural_Vectors.Vector'(ndg(1..cnt));
                     63:     return res;
                     64:   end Localize;
                     65:
                     66:   function Localize ( locmap : Standard_Natural_Matrices.Matrix;
                     67:                       p : Poly ) return Poly is
                     68:
                     69:   -- DESCRIPTION :
                     70:   --   Applies the localization map to the polynomial, eliminating
                     71:   --   those xij's for which locmap(i,j) is either 0 or 1.
                     72:
                     73:     res : Poly := Null_Poly;
                     74:
                     75:     procedure Localize_Term ( t : in Term; continue : out boolean ) is
                     76:
                     77:       lt : Term := Localize(locmap,t);
                     78:
                     79:     begin
                     80:       Add(res,lt);
                     81:       Clear(lt.dg);
                     82:       continue := true;
                     83:     end Localize_Term;
                     84:     procedure Localize_Terms is new Visiting_Iterator(Localize_Term);
                     85:
                     86:   begin
                     87:     Localize_Terms(p);
                     88:     return res;
                     89:   end Localize;
                     90:
                     91: -- TARGET ROUTINES :
                     92:
                     93:   function Standard_Coordinate_Frame
                     94:              ( x : Standard_Complex_Poly_Matrices.Matrix;
                     95:                plane : Standard_Complex_Matrices.Matrix )
                     96:              return Standard_Natural_Matrices.Matrix is
                     97:
                     98:     res : Standard_Natural_Matrices.Matrix(x'range(1),x'range(2));
                     99:     tol : constant double_float := 10.0**(-10);
                    100:     first : boolean;
                    101:
                    102:   begin
                    103:     for j in res'range(2) loop
                    104:       first := true;
                    105:       for i in res'range(1) loop
                    106:         if x(i,j) = Null_Poly
                    107:          then res(i,j) := 0;
                    108:          elsif (first and (AbsVal(plane(i,j)) > tol))
                    109:              then res(i,j) := 1; first := false;
                    110:              else res(i,j) := 2;
                    111:         end if;
                    112:       end loop;
                    113:     end loop;
                    114:     return res;
                    115:   end Standard_Coordinate_Frame;
                    116:
                    117:   function Maximal_Coordinate_Frame
                    118:              ( x : Standard_Complex_Poly_Matrices.Matrix;
                    119:                plane : Standard_Complex_Matrices.Matrix )
                    120:              return Standard_Natural_Matrices.Matrix is
                    121:
                    122:     res : Standard_Natural_Matrices.Matrix(x'range(1),x'range(2));
                    123:     max,tmp : double_float;
                    124:     ind : natural;
                    125:
                    126:   begin
                    127:     for j in res'range(2) loop
                    128:       for i in res'range(1) loop
                    129:         if x(i,j) = Null_Poly
                    130:          then res(i,j) := 0;
                    131:          else res(i,j) := 2;
                    132:         end if;
                    133:       end loop;
                    134:       max := 0.0; ind := 0;
                    135:       for i in res'range(1) loop
                    136:         tmp := AbsVal(plane(i,j));
                    137:         if tmp > max
                    138:          then max := tmp; ind := i;
                    139:         end if;
                    140:       end loop;
                    141:       res(ind,j) := 1;
                    142:     end loop;
                    143:     return res;
                    144:   end Maximal_Coordinate_Frame;
                    145:
                    146:   function Localize ( locmap : Standard_Natural_Matrices.Matrix;
                    147:                       p : Poly_Sys ) return Poly_Sys is
                    148:
                    149:     res : Poly_Sys(p'range);
                    150:
                    151:   begin
                    152:     for i in p'range loop
                    153:       res(i) := Localize(locmap,p(i));
                    154:     end loop;
                    155:     return res;
                    156:   end Localize;
                    157:
                    158: -- CONSTRUCT THE POLYNOMIAL EQUATIONS :
                    159:
                    160:   function Polynomial_Equations
                    161:               ( l : Standard_Complex_Matrices.Matrix;
                    162:                 x : Standard_Complex_Poly_Matrices.Matrix ) return Poly_Sys is
                    163:
                    164:     n : constant natural := x'length(1);
                    165:     p : constant natural := x'length(2);
                    166:     kd : constant natural := p + l'length(2);
                    167:     bm : Bracket_Monomial := Maximal_Minors(n,kd);
                    168:     bs : Bracket_System(0..Number_of_Brackets(bm))
                    169:        := Minor_Equations(kd,kd-p,bm);
                    170:     res : Poly_Sys(bs'first+1..bs'last) := Expanded_Minors(l,x,bs);
                    171:
                    172:   begin
                    173:     Clear(bm); Clear(bs);
                    174:     return res;
                    175:   end Polynomial_Equations;
                    176:
                    177:   procedure Concat ( l : in out Link_to_Poly_Sys; p : Poly_Sys ) is
                    178:   begin
                    179:     if l = null
                    180:      then declare
                    181:             newsys : Poly_Sys(p'range);
                    182:             cnt : natural := p'first-1;
                    183:           begin
                    184:             for i in p'range loop
                    185:               if p(i) /= Null_Poly
                    186:                then cnt := cnt+1;
                    187:                     newsys(cnt) := p(i);
                    188:               end if;
                    189:             end loop;
                    190:             l := new Poly_Sys'(newsys(p'first..cnt));
                    191:           end;
                    192:      else declare
                    193:             newsys : Poly_Sys(l'first..l'last+p'length);
                    194:             ind : natural := l'last;
                    195:           begin
                    196:             newsys(l'range) := l(l'range);
                    197:             for i in p'range loop
                    198:               if p(i) /= Null_Poly
                    199:                then ind := ind+1;
                    200:                     newsys(ind) := p(i);
                    201:               end if;
                    202:             end loop;
                    203:             l := new Poly_Sys'(newsys(l'first..ind));
                    204:           end;
                    205:     end if;
                    206:   end Concat;
                    207:
                    208:   function Polynomial_Equations
                    209:               ( l : Standard_Complex_VecMats.VecMat;
                    210:                 x : Standard_Complex_Poly_Matrices.Matrix ) return Poly_Sys is
                    211:
                    212:     n : constant natural := x'length(1);
                    213:     p : constant natural := x'length(2);
                    214:     kd : constant natural := p + l(l'first)'length(2);
                    215:     bm : Bracket_Monomial := Maximal_Minors(n,kd);
                    216:     bs : Bracket_System(0..Number_of_Brackets(bm))
                    217:        := Minor_Equations(kd,kd-p,bm);
                    218:     nb : constant natural := l'length;
                    219:     res : Poly_Sys(bs'first+1..nb*bs'last);
                    220:     cnt : natural := bs'first;
                    221:
                    222:   begin
                    223:     for i in 1..nb loop
                    224:       declare
                    225:         sys : constant Poly_Sys := Expanded_Minors(l(i).all,x,bs);
                    226:       begin
                    227:         for j in sys'range loop
                    228:           cnt := cnt + 1;
                    229:           res(cnt) := sys(j);
                    230:         end loop;
                    231:       end;
                    232:     end loop;
                    233:     Clear(bm); Clear(bs);
                    234:     return res;
                    235:   end Polynomial_Equations;
                    236:
                    237: -- EVALUATORS AND DIFFERENTIATORS :
                    238:
                    239:   function Eval ( l,x : Standard_Complex_Matrices.Matrix )
                    240:                 return Complex_Number is
                    241:
                    242:     wrk : Standard_Complex_Matrices.Matrix(x'range(1),x'range(1));
                    243:
                    244:   begin
                    245:     for j in l'range(2) loop
                    246:       for i in l'range(1) loop
                    247:         wrk(i,j) := l(i,j);
                    248:       end loop;
                    249:     end loop;
                    250:     for j in x'range(2) loop
                    251:       for i in x'range(1) loop
                    252:         wrk(i,l'last(2)+j) := x(i,j);
                    253:       end loop;
                    254:     end loop;
                    255:     return Determinant(wrk);
                    256:   end Eval;
                    257:
                    258:   function Eval ( l,x : Standard_Complex_Matrices.Matrix ) return Vector is
                    259:
                    260:     n : constant natural := l'length(2) + x'length(2);
                    261:     dim : constant natural := Number_of_Maximal_Minors(l'length(1),n);
                    262:     res : Standard_Complex_Vectors.Vector(1..dim);
                    263:       -- := (1..dim => Create(0.0));
                    264:     cnt : natural := 0;
                    265:     rws : Standard_Natural_Vectors.Vector(1..n);
                    266:     wrk : Standard_Complex_Matrices.Matrix(1..n,1..n);
                    267:
                    268:     procedure Choose_next_Row ( k,start : in natural ) is
                    269:
                    270:     -- DESCRIPTION :
                    271:     --   Chooses next k-th row within the range start..l'last(1), if k <= n.
                    272:     --   If k > n, then the minor defined by the current row selection
                    273:    --    is computed and added to the result.
                    274:
                    275:     begin
                    276:       if k > n
                    277:        then for j in l'range(2) loop              -- select rows
                    278:               for i in 1..n loop
                    279:                 wrk(i,j) := l(rws(i),j);
                    280:               end loop;
                    281:             end loop;
                    282:             for j in x'range(2) loop
                    283:               for i in 1..n loop
                    284:                 wrk(i,l'last(2)+j) := x(rws(i),j);
                    285:               end loop;
                    286:             end loop;
                    287:             cnt := cnt + 1;
                    288:             res(cnt) := Determinant(wrk);
                    289:        else for i in start..l'last(1) loop
                    290:               rws(k) := i;
                    291:               Choose_next_Row(k+1,i+1);
                    292:             end loop;
                    293:       end if;
                    294:     end Choose_next_Row;
                    295:
                    296:   begin
                    297:     Choose_next_Row(1,1);
                    298:     return res;
                    299:   end Eval;
                    300:
                    301:   function Minor ( l,x : Standard_Complex_Matrices.Matrix; row,col : natural )
                    302:                  return Complex_Number is
                    303:
                    304:   -- DESCRIPTION :
                    305:   --   Returns the minor [l|x] with row and column removed and with
                    306:   --   the appropriate sign.
                    307:
                    308:     wrk : Standard_Complex_Matrices.Matrix
                    309:             (x'first(1)..x'last(1)-1,x'first(1)..x'last(1)-1);
                    310:     ind : natural;
                    311:
                    312:   begin
                    313:     for j in l'range(2) loop
                    314:       for i in l'range(1) loop
                    315:         if i < row
                    316:          then wrk(i,j) := l(i,j);
                    317:          elsif i > row
                    318:              then wrk(i-1,j) := l(i,j);
                    319:         end if;
                    320:       end loop;
                    321:     end loop;
                    322:     for j in x'range(2) loop
                    323:       if j < col
                    324:        then ind := l'last(2) + j;
                    325:        elsif j > col
                    326:            then ind := l'last(2) + j - 1;
                    327:       end if;
                    328:       if j /= col
                    329:        then for i in x'range(1) loop
                    330:               if i < row
                    331:                then wrk(i,ind) := x(i,j);
                    332:                elsif i > row
                    333:                    then wrk(i-1,ind) := x(i,j);
                    334:               end if;
                    335:             end loop;
                    336:       end if;
                    337:     end loop;
                    338:     if (row + l'last(2) + col) mod 2 = 0
                    339:         then return Determinant(wrk);
                    340:         else return -Determinant(wrk);
                    341:     end if;
                    342:   end Minor;
                    343:
                    344:   function Diff ( l,x : Standard_Complex_Matrices.Matrix; i : natural )
                    345:                 return Complex_Number is
                    346:
                    347:     p : constant natural := x'length(2);
                    348:     row,col : natural;
                    349:
                    350:   begin
                    351:     row := i/p + 1;
                    352:     col := i mod p;
                    353:     if col = 0
                    354:      then col := p;
                    355:           row := row - 1;
                    356:     end if;
                    357:     return Minor(l,x,row,col);
                    358:   end Diff;
                    359:
                    360:   function Diff ( l,x : Standard_Complex_Matrices.Matrix;
                    361:                   locmap : Standard_Natural_Matrices.Matrix; i : natural )
                    362:                 return Complex_Number is
                    363:
                    364:     row,col : natural;
                    365:     cnt : natural := 0;
                    366:
                    367:   begin
                    368:     for k1 in locmap'range(1) loop
                    369:       for k2 in locmap'range(2) loop
                    370:         if locmap(k1,k2) = 2
                    371:          then cnt := cnt+1;
                    372:               if cnt = i
                    373:                then row := k1;
                    374:                     col := k2;
                    375:               end if;
                    376:         end if;
                    377:         exit when (cnt = i);
                    378:       end loop;
                    379:       exit when (cnt = i);
                    380:     end loop;
                    381:     return Minor(l,x,row,col);
                    382:   end Diff;
                    383:
                    384:   function Eval ( l : Standard_Complex_VecMats.VecMat;
                    385:                   x : Standard_Complex_Matrices.Matrix )
                    386:                 return Standard_Complex_Vectors.Vector is
                    387:
                    388:     res : Standard_Complex_Vectors.Vector(l'range);
                    389:
                    390:   begin
                    391:     for i in l'range loop
                    392:       res(i) := Eval(l(i).all,x);
                    393:     end loop;
                    394:     return res;
                    395:   end Eval;
                    396:
                    397:   function Diff ( l : Standard_Complex_VecMats.VecMat;
                    398:                   x : Standard_Complex_Matrices.Matrix )
                    399:                 return Standard_Complex_Matrices.Matrix is
                    400:
                    401:     res : Standard_Complex_Matrices.Matrix(l'range,1..x'last(1)*x'last(2));
                    402:
                    403:   begin
                    404:     for i in res'range(1) loop
                    405:       for j in res'range(2) loop
                    406:         res(i,j) := Diff(l(i).all,x,j);
                    407:       end loop;
                    408:     end loop;
                    409:     return res;
                    410:   end Diff;
                    411:
                    412:   function Old_Diff ( l : Standard_Complex_VecMats.VecMat;
                    413:                       x : Standard_Complex_Matrices.Matrix; nvars : natural;
                    414:                       locmap : Standard_Natural_Matrices.Matrix )
                    415:                     return Standard_Complex_Matrices.Matrix is
                    416:
                    417:     res : Standard_Complex_Matrices.Matrix(l'range,1..nvars);
                    418:
                    419:   begin
                    420:     for i in res'range(1) loop
                    421:       for j in res'range(2) loop
                    422:         res(i,j) := Diff(l(i).all,x,locmap,j);
                    423:       end loop;
                    424:     end loop;
                    425:     return res;
                    426:   end Old_Diff;
                    427:
                    428:   function Diff ( l : Standard_Complex_VecMats.VecMat;
                    429:                   x : Standard_Complex_Matrices.Matrix; nvars : natural;
                    430:                   locmap : Standard_Natural_Matrices.Matrix )
                    431:                 return Standard_Complex_Matrices.Matrix is
                    432:
                    433:   -- NOTE :
                    434:   --   This Diff is organized according to the localization map,
                    435:   --   to avoid multiple searches.
                    436:
                    437:     res : Standard_Complex_Matrices.Matrix(l'range,1..nvars);
                    438:     ind : natural := 0;
                    439:
                    440:   begin
                    441:     for i in locmap'range loop
                    442:       for j in locmap'range loop
                    443:         if locmap(i,j) = 2
                    444:          then ind := ind+1;
                    445:               for k in l'range loop
                    446:                 res(k,ind) := Minor(l(k).all,x,i,j);
                    447:               end loop;
                    448:         end if;
                    449:       end loop;
                    450:     end loop;
                    451:     return res;
                    452:   end Diff;
                    453:
                    454: end Determinantal_Systems;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>