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

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

1.1       maekawa     1: with Chebychev_Polynomials;              use Chebychev_Polynomials;
                      2: with Standard_Natural_Vectors;
                      3: with Standard_Floating_Vectors;          use Standard_Floating_Vectors;
                      4: with Standard_Random_Numbers;            use Standard_Random_Numbers;
                      5: with Standard_Floating_Linear_Solvers;   use Standard_Floating_Linear_Solvers;
                      6: with Standard_Floating_QR_Decomposition; use Standard_Floating_QR_Decomposition;
                      7:
                      8: package body Osculating_Planes is
                      9:
                     10:   function Standard_Basis
                     11:                 ( n,d : natural; s : double_float ) return Matrix is
                     12:
                     13:     res : Matrix(1..n,1..d);
                     14:     acc : double_float;
                     15:     fac,lim : integer;
                     16:
                     17:   begin
                     18:     for i in 1..d loop                     -- set the zeros and ones
                     19:       res(i,i) := 1.0;
                     20:       for j in (i+1)..d loop
                     21:         res(i,j) := 0.0;
                     22:       end loop;
                     23:     end loop;
                     24:     for j in 1..d loop                     -- set the powers of the s-values
                     25:       acc := s;
                     26:       for i in (j+1)..n loop
                     27:         res(i,j) := acc;
                     28:         acc := acc*s;
                     29:       end loop;
                     30:     end loop;
                     31:     for i in 3..n loop                  -- compute the factors from derivation
                     32:       fac := 1;
                     33:       if i-1 > d
                     34:        then lim := d;
                     35:        else lim := i-1;
                     36:       end if;
                     37:       for j in 2..lim loop
                     38:         fac := fac*(i+1-j);
                     39:         res(i,j) := double_float(fac)*res(i,j);
                     40:       end loop;
                     41:       if i <= d
                     42:        then res(i,i) := double_float(fac);
                     43:       end if;
                     44:     end loop;
                     45:     for j in 3..d loop                     -- scale the columns
                     46:       for i in (j+1)..n loop
                     47:         res(i,j) := res(i,j)/res(j,j);
                     48:       end loop;
                     49:       res(j,j) := 1.0;
                     50:     end loop;
                     51:     return res;
                     52:   end Standard_Basis;
                     53:
                     54:   function Chebychev_Basis
                     55:                 ( n,d : natural; s : double_float ) return Matrix is
                     56:
                     57:     res : Matrix(1..n,1..d);
                     58:     lim : integer;
                     59:
                     60:   begin
                     61:     for i in 1..d loop                     -- set the zeros and ones
                     62:       res(i,i) := 1.0;
                     63:       for j in (i+1)..d loop
                     64:         res(i,j) := 0.0;
                     65:       end loop;
                     66:     end loop;
                     67:     for i in 2..n loop                     -- evaluate and differentiate
                     68:       declare
                     69:         p : constant Vector := Chebychev_Polynomials.Create(i-1);
                     70:       begin
                     71:         res(i,1) := Eval(p,s);
                     72:         if i > d
                     73:          then lim := d;
                     74:          else lim := i;
                     75:         end if;
                     76:         for j in 2..lim loop
                     77:           declare
                     78:             dp : constant Vector := Chebychev_Polynomials.Diff(p,j-1);
                     79:           begin
                     80:             res(i,j) := Eval(dp,s);
                     81:           end;
                     82:         end loop;
                     83:       end;
                     84:     end loop;
                     85:     for j in 3..d loop                     -- scale the columns
                     86:       for i in (j+1)..n loop
                     87:         res(i,j) := res(i,j)/res(j,j);
                     88:       end loop;
                     89:       res(j,j) := 1.0;
                     90:     end loop;
                     91:     return res;
                     92:   end Chebychev_Basis;
                     93:
                     94:   function Orthogonal_Basis
                     95:               ( n,d : natural; s : double_float ) return Matrix is
                     96:
                     97:     res : Matrix(1..n,1..d) := Chebychev_Basis(n,d,s);
                     98:     wrk : Matrix(1..n,1..d);
                     99:     bas : Matrix(1..n,1..n);
                    100:     qra : Standard_Floating_Vectors.Vector(1..n) := (1..n => 0.0);
                    101:     pvt : Standard_Natural_Vectors.Vector(1..n) := (1..n => 0);
                    102:
                    103:   begin
                    104:     wrk := res;
                    105:     QRD(wrk,qra,pvt,false);
                    106:     for i in wrk'range(1) loop
                    107:       for j in wrk'range(2) loop
                    108:         bas(i,j) := wrk(i,j);
                    109:       end loop;
                    110:       for j in d+1..n loop
                    111:         bas(i,j) := 0.0;
                    112:          end loop;
                    113:     end loop;
                    114:     Basis(bas,res);
                    115:     for i in res'range(1) loop
                    116:       for j in res'range(2) loop
                    117:         res(i,j) := bas(i,j);
                    118:       end loop;
                    119:     end loop;
                    120:     return res;
                    121:   end Orthogonal_Basis;
                    122:
                    123:   function Determinant
                    124:               ( mat : Matrix; rows : Standard_Natural_Vectors.Vector )
                    125:                 return double_float is
                    126:
                    127:
                    128:   -- DESCRIPTION :
                    129:   --   Computes the determinant of the matrix obtained by selecting rows.
                    130:
                    131:     res : double_float := 1.0;
                    132:     sqm : Matrix(rows'range,rows'range);
                    133:     piv : Standard_Natural_Vectors.Vector(rows'range);
                    134:     inf : natural;
                    135:
                    136:   begin
                    137:     for i in rows'range loop
                    138:       piv(i) := i;
                    139:       for j in rows'range loop
                    140:         sqm(i,j) := mat(rows(i),j);
                    141:       end loop;
                    142:     end loop;
                    143:     lufac(sqm,rows'last,piv,inf);
                    144:     for i in rows'range loop
                    145:       res := res*sqm(i,i);
                    146:     end loop;
                    147:     for i in piv'range loop
                    148:       if piv(i) > i
                    149:        then res := -res;
                    150:       end if;
                    151:     end loop;
                    152:     return res;
                    153:   end Determinant;
                    154:
                    155:   procedure Maximal_Minors ( n,d : in natural; mat : in Matrix;
                    156:                              min,max : out double_float ) is
                    157:
                    158:   -- DESCRIPTION :
                    159:   --   Computes all maximal minors of a (nxd)-matrix mat, d < n.
                    160:
                    161:     rows : Standard_Natural_Vectors.Vector(1..d);
                    162:     first : boolean := true;
                    163:     mindet,maxdet : double_float;
                    164:
                    165:     procedure Select_Rows ( k,start : in natural ) is
                    166:
                    167:       det : double_float;
                    168:
                    169:     begin
                    170:       if k > d
                    171:        then det := Determinant(mat,rows);
                    172:             det := abs(det);
                    173:             if first
                    174:              then mindet := det; maxdet := det; first := false;
                    175:              else if det > maxdet
                    176:                    then maxdet := det;
                    177:                    elsif det < mindet
                    178:                        then mindet := det;
                    179:                   end if;
                    180:             end if;
                    181:        else for j in start..n loop
                    182:               rows(k) := j;
                    183:               Select_Rows(k+1,j+1);
                    184:             end loop;
                    185:       end if;
                    186:     end Select_Rows;
                    187:
                    188:   begin
                    189:     Select_Rows(1,1);
                    190:     min := mindet; max := maxdet;
                    191:   end Maximal_Minors;
                    192:
                    193:   procedure Sampled_Chebychev_Basis
                    194:                   ( n,d,m : in natural; mat : out Matrix;
                    195:                     s,ratio : out double_float ) is
                    196:
                    197:     rs,min,max,rat,bestrat,bests : double_float;
                    198:     first : boolean;
                    199:     themat : Matrix(1..n,1..d);
                    200:
                    201:   begin
                    202:     first := true;
                    203:     for i in 1..m loop
                    204:       rs := Random;
                    205:       themat := Chebychev_Basis(n,d,rs);
                    206:       Maximal_Minors(n,d,themat,min,max);
                    207:       rat := max/min;
                    208:       if first
                    209:        then bestrat := rat; bests := rs; first := false;
                    210:        else if rat < bestrat
                    211:              then bestrat := rat; bests := rs;
                    212:                   mat := themat;
                    213:             end if;
                    214:       end if;
                    215:     end loop;
                    216:     ratio := bestrat;
                    217:     s := bests;
                    218:   end Sampled_Chebychev_Basis;
                    219:
                    220: end Osculating_Planes;

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