Annotation of OpenXM_contrib/PHC/Ada/Schubert/osculating_planes.adb, Revision 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>