Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Stalift/floating_pruning_methods.adb, Revision 1.1.1.1
1.1 maekawa 1: with Standard_Natural_Vectors;
2: with Standard_Floating_Matrices; use Standard_Floating_Matrices;
3: with Standard_Floating_Linear_Solvers; use Standard_Floating_Linear_Solvers;
4: with Floating_Linear_Inequalities; use Floating_Linear_Inequalities;
5: with Lists_of_Floating_Vectors; use Lists_of_Floating_Vectors;
6:
7: package body Floating_Pruning_Methods is
8:
9: -- GENERAL AUXILIARIES :
10:
11: procedure Normalize ( v : in out Standard_Floating_Vectors.Vector ) is
12:
13: -- DESCRIPTION : Divides every entry by v(v'last).
14:
15: begin
16: for i in v'range loop
17: v(i) := v(i)/v(v'last);
18: end loop;
19: end Normalize;
20:
21: function Convert ( fa : Face_Array ) return Array_of_Lists is
22:
23: -- DESCRIPTION :
24: -- Converts the array of faces into an array of lists by
25: -- converting the first element of each list of faces.
26:
27: res : Array_of_Lists(fa'range);
28:
29: begin
30: for k in fa'range loop
31: res(k) := Shallow_Create(fa(k).all);
32: end loop;
33: return res;
34: end Convert;
35:
36: -- AUXILIARIES FOR THE PRUNING ALGORITHMS :
37:
38: procedure Initialize ( n : in natural; mat : out Matrix;
39: ipvt : out Standard_Natural_Vectors.Vector ) is
40:
41: -- DESCRIPTION :
42: -- Initializes an n*(n+1) matrix with zeroes and the pivoting vector
43: -- with the entries 1..n.
44:
45: begin
46: for i in 1..n loop
47: for j in 1..n+1 loop
48: mat(i,j) := 0.0;
49: end loop;
50: end loop;
51: for i in 1..n loop
52: ipvt(i) := i;
53: end loop;
54: end Initialize;
55:
56: function Number_of_Inequalities
57: ( mix : Vector; lifted : Array_of_Lists ) return natural is
58:
59: -- DESCRIPTION :
60: -- Returns the maximal number of inequalities for pruning.
61:
62: res : natural := 0;
63:
64: begin
65: for k in lifted'range loop
66: res := res + Length_Of(lifted(k)) - mix(k) - 1;
67: end loop;
68: return res;
69: end Number_of_Inequalities;
70:
71: procedure Ordered_Inequalities ( k : in natural; mat : in out Matrix ) is
72:
73: -- DESCRIPTION :
74: -- Defines k inequalities mat(k,k) - mat(k+1,k) >= 0.
75:
76: begin
77: for i in mat'first(1)..k loop
78: for j in mat'range(2) loop
79: mat(i,j) := 0.0;
80: end loop;
81: mat(i,i) := 1.0; mat(i,i+1) := -1.0;
82: end loop;
83: end Ordered_Inequalities;
84:
85: procedure Check_and_Update
86: ( mic : in Face_Array; lifted : in Array_of_Lists;
87: m : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
88: tol : in double_float;
89: mixsub,mixsub_last : in out Mixed_Subdivision ) is
90:
91: -- DESCRIPTION :
92: -- Computes the normal to the points in pts, by solving the
93: -- linear system defined by m and ipvt.
94: -- If the computed normal is an inner normal w.r.t. the lifted points,
95: -- then the mixed subdivision will be updated with a new cell.
96:
97: use Standard_Floating_Vectors;
98: v : Standard_Floating_Vectors.Vector(m'range(2)) := Solve(m,tol,ipvt);
99: pts : Array_of_Lists(mic'range);
100:
101: begin
102: if abs(v(v'last)) > tol
103: then Normalize(v);
104: if v(v'last) < 0.0
105: then Min(v);
106: end if;
107: -- pts := Convert(mic);
108: -- Update(pts,v,mixsub,mixsub_last);
109: declare
110: cell : Mixed_Cell;
111: begin
112: cell.nor := new Standard_Floating_Vectors.Vector'(v);
113: cell.pts := new Array_of_Lists'(Convert(mic));
114: cell.sub := null;
115: Append(mixsub,mixsub_last,cell);
116: end;
117: end if;
118: end Check_and_Update;
119:
120: procedure Create_Equalities
121: ( n : in natural; f : in Face; mat,ineq : in Matrix;
122: tol : in double_float;
123: ipvt : in Standard_Natural_Vectors.Vector;
124: row,rowineq : in natural;
125: newmat,newineq : in out Matrix;
126: newipvt : in out Standard_Natural_Vectors.Vector;
127: newrow,newrowineq : in out natural; fail : out boolean ) is
128:
129: -- DESCRIPTION :
130: -- Creates new equalities and uses them to eliminate unknowns in the
131: -- matrices of equalities and inequalities. Failure is reported when
132: -- a zero row is encountered. On entry, all new* variables must be
133: -- initialized with the corresponding *-ones.
134:
135: shi : Standard_Floating_Vectors.Vector(1..n+1) := f(f'first).all;
136: fl : boolean := false;
137: pivot : natural;
138:
139: begin
140: for i in f'first+1..f'last loop
141: newrow := newrow + 1;
142: for j in f(i)'range loop
143: newmat(newrow,j) := f(i)(j) - shi(j);
144: end loop;
145: Switch(newipvt,newrow,newmat);
146: Upper_Triangulate(newrow,newmat,tol,newipvt,pivot);
147: fl := (pivot = 0);
148: exit when fl;
149: Switch(newrow,pivot,ineq'first,rowineq,newineq);
150: end loop;
151: fail := fl;
152: end Create_Equalities;
153:
154: procedure Complementary_Slackness
155: ( tableau : in out matrix;
156: tol : in double_float; feasible : out boolean ) is
157:
158: lastcol : constant integer := tableau'last(2)-1;
159: rhs,sol : Standard_Floating_Vectors.Vector(tableau'range(1));
160: columns : Vector(sol'range);
161:
162: begin
163: for i in rhs'range loop
164: rhs(i) := double_float(tableau(i,tableau'last(2)));
165: end loop;
166: Complementary_Slackness(tableau,lastcol,rhs,tol,sol,columns,feasible);
167: end Complementary_Slackness;
168:
169: function Check_Feasibility ( k,m,n : natural; ineq : Matrix;
170: tol : double_float ) return boolean is
171:
172: -- DESCRIPTION :
173: -- Returns true if -v(n+1) > 0 can be derived, false otherwise.
174:
175: -- ON ENTRY :
176: -- k current unknown that has been eliminated,
177: -- for all i <= k : ineq(l,i) = 0, for l in ineq'first..m;
178: -- m number of inequalities;
179: -- n dimension;
180: -- ineq matrix of inequalities.
181:
182: tableau : Matrix(1..n-k+1,1..m+1);
183: feasi : boolean;
184:
185: begin
186: if m = 0
187: then feasi := false;
188: else for i in k+1..n+1 loop
189: for j in 1..m loop
190: tableau(i-k,j) := ineq(j,i);
191: end loop;
192: tableau(i-k,m+1) := 0.0;
193: end loop;
194: tableau(n-k+1,m+1) := -1.0;
195: Complementary_Slackness(tableau,tol,feasi);
196: end if;
197: return feasi;
198: end Check_Feasibility;
199:
200: procedure Update_Inequalities
201: ( k,rowmat1,rowmat2,n : in natural;
202: mat : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
203: tol : in double_float;
204: rowineq : in out natural; ineq : in out Matrix;
205: lifted : in Array_of_Lists; mic : in out Face_Array ) is
206:
207: -- DESCRIPTION :
208: -- The inequalities will be updated w.r.t. the equality
209: -- constraints on the inner normal.
210:
211: tmp : List;
212: pt,shi : Standard_Floating_Vectors.Link_to_Vector;
213:
214: begin
215: for i in ineq'first..rowineq loop -- update the old inequalities
216: for j in rowmat1..rowmat2 loop
217: Upper_Triangulate(j,mat,tol,i,ineq);
218: end loop;
219: end loop;
220: shi := mic(k)(mic(k)'first);
221: tmp := lifted(k); -- make new inequalities
222: while not Is_Null(tmp) loop
223: pt := Head_Of(tmp);
224: if not Is_In(mic(k),pt.all)
225: then rowineq := rowineq + 1;
226: for j in pt'range loop
227: ineq(rowineq,j) := pt(j) - shi(j);
228: end loop;
229: Switch(ipvt,rowineq,ineq);
230: for i in 1..rowmat2 loop
231: Upper_Triangulate(i,mat,tol,rowineq,ineq);
232: end loop;
233: end if;
234: tmp := Tail_Of(tmp);
235: end loop;
236: end Update_Inequalities;
237:
238: -- CONSTRUCTION WITH PRUNING :
239:
240: procedure Gen1_Create
241: ( n : in natural; mix : in Vector; fa : in Array_of_Faces;
242: lifted : in Array_of_Lists; tol : in double_float;
243: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector;
244: mixsub : out Mixed_Subdivision ) is
245:
246: res,res_last : Mixed_Subdivision;
247: accu : Face_Array(fa'range);
248: ma : Matrix(1..n,1..n+1);
249: ipvt : Standard_Natural_Vectors.Vector(1..n);
250: ineqrows : natural;
251:
252: procedure Compute_Mixed_Cells
253: ( k,row : in natural; mat : in Matrix;
254: ipvt : in Standard_Natural_Vectors.Vector;
255: rowineq : in natural; ineq : in Matrix;
256: mic : in out Face_Array; continue : out boolean );
257:
258: -- DESCRIPTION :
259: -- Backtrack recursive procedure to enumerate face-face combinations.
260:
261: -- ON ENTRY :
262: -- k index for current point set;
263: -- row number of rows already in the matrix;
264: -- mat matrix which determines the inner normal;
265: -- ipvt contains the pivoting information;
266: -- rowineq number of inequality constraints already in ineq;
267: -- ineq matrix for the inequality constraints on the
268: -- inner normal v, of type <.,v> >= 0;
269: -- mic contains the current selected faces, up to k-1.
270:
271: -- ON RETURN :
272: -- mic updated selected faces.
273: -- continue indicates whether to continue the creation or not.
274:
275: procedure Process_Inequalities
276: ( k,rowmat1,rowmat2 : in natural;
277: mat : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
278: rowineq : in out natural; ineq : in out Matrix;
279: mic : in out Face_Array; cont : out boolean ) is
280:
281: -- DESCRIPTION :
282: -- Updates inequalities and checks feasibility before proceeding.
283:
284: fl : boolean := false;
285: tmp : List;
286: pt,shi : Link_to_Vector;
287:
288: begin
289: Update_Inequalities(k,rowmat1,rowmat2,n,mat,ipvt,tol,rowineq,ineq,
290: lifted,mic);
291: if Check_Feasibility(rowmat2,rowineq,n,ineq,tol)
292: then nbfail(k) := nbfail(k) + 1.0;
293: cont := true;
294: else nbsucc(k) := nbsucc(k) + 1.0;
295: Compute_Mixed_Cells(k+1,rowmat2,mat,ipvt,rowineq,ineq,mic,cont);
296: end if;
297: end Process_Inequalities;
298:
299: procedure Compute_Mixed_Cells
300: ( k,row : in natural; mat : in Matrix;
301: ipvt : in Standard_Natural_Vectors.Vector;
302: rowineq : in natural; ineq : in Matrix;
303: mic : in out Face_Array; continue : out boolean ) is
304:
305: old : Mixed_Subdivision := res_last;
306: cont : boolean := true;
307: tmpfa : Faces;
308:
309: begin
310: if k > mic'last
311: then Check_and_Update(mic,lifted,mat,ipvt,tol,res,res_last);
312: if old /= res_last
313: then Process(Head_Of(res_last),continue);
314: else continue := true;
315: end if;
316: else tmpfa := fa(k);
317: while not Is_Null(tmpfa) loop -- enumerate faces of kth polytope
318: mic(k) := Head_Of(tmpfa);
319: declare -- update the matrices
320: fl : boolean;
321: newipvt : Standard_Natural_Vectors.Vector(ipvt'range) := ipvt;
322: newmat : Matrix(mat'range(1),mat'range(2)) := mat;
323: newineq : Matrix(ineq'range(1),ineq'range(2)) := ineq;
324: newrow : natural := row;
325: newrowineq : natural := rowineq;
326: begin
327: Create_Equalities
328: (n,mic(k),mat,ineq,tol,ipvt,row,rowineq,newmat,newineq,
329: newipvt,newrow,newrowineq,fl);
330: if fl
331: then nbfail(k) := nbfail(k) + 1.0;
332: else Process_Inequalities(k,row+1,newrow,newmat,newipvt,
333: newrowineq,newineq,mic,cont);
334: end if;
335: end;
336: tmpfa := Tail_Of(tmpfa);
337: exit when not cont;
338: end loop;
339: continue := cont;
340: end if;
341: end Compute_Mixed_Cells;
342:
343: begin
344: Initialize(n,ma,ipvt);
345: ineqrows := Number_of_Inequalities(mix,lifted);
346: declare
347: ineq : matrix(1..ineqrows,1..n+1);
348: cont : boolean;
349: begin
350: ineq(1,1) := 0.0;
351: Compute_Mixed_Cells(accu'first,0,ma,ipvt,0,ineq,accu,cont);
352: end;
353: mixsub := res;
354: end Gen1_Create;
355:
356: procedure Create
357: ( n : in natural; mix : in Vector; fa : in Array_of_Faces;
358: lifted : in Array_of_Lists; tol : in double_float;
359: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector;
360: mixsub : out Mixed_Subdivision ) is
361:
362: res,res_last : Mixed_Subdivision;
363: accu : Face_Array(fa'range);
364: ma : Matrix(1..n,1..n+1);
365: ipvt : Standard_Natural_Vectors.Vector(1..n);
366: ineqrows : natural;
367:
368: procedure Compute_Mixed_Cells
369: ( k,row : in natural; mat : in Matrix;
370: ipvt : in Standard_Natural_Vectors.Vector;
371: rowineq : in natural; ineq : in Matrix;
372: mic : in out Face_Array );
373:
374: -- DESCRIPTION :
375: -- Backtrack recursive procedure to enumerate face-face combinations.
376:
377: -- ON ENTRY :
378: -- k index for current point set;
379: -- row number of rows already in the matrix;
380: -- mat matrix which determines the inner normal;
381: -- ipvt contains the pivoting information;
382: -- rowineq number of inequality constraints already in ineq;
383: -- ineq matrix for the inequality constraints on the
384: -- inner normal v, of type <.,v> >= 0;
385: -- mic contains the current selected faces, up to k-1.
386:
387: -- ON RETURN :
388: -- mic updated selected faces.
389:
390: procedure Process_Inequalities
391: ( k,rowmat1,rowmat2 : in natural;
392: mat : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
393: rowineq : in out natural; ineq : in out matrix;
394: mic : in out Face_Array) is
395:
396: -- DESCRIPTION :
397: -- Updates inequalities and checks feasibility before proceeding.
398:
399: tmp : List;
400: pt,shi : Link_to_Vector;
401:
402: begin
403: Update_Inequalities(k,rowmat1,rowmat2,n,mat,ipvt,tol,rowineq,ineq,
404: lifted,mic);
405: if Check_Feasibility(rowmat2,rowineq,n,ineq,tol)
406: then nbfail(k) := nbfail(k) + 1.0;
407: else nbsucc(k) := nbsucc(k) + 1.0;
408: Compute_Mixed_Cells(k+1,rowmat2,mat,ipvt,rowineq,ineq,mic);
409: end if;
410: end Process_Inequalities;
411:
412: procedure Compute_Mixed_Cells
413: ( k,row : in natural; mat : in Matrix;
414: ipvt : in Standard_Natural_Vectors.Vector;
415: rowineq : in natural; ineq : in Matrix;
416: mic : in out Face_Array ) is
417:
418: tmpfa : Faces;
419:
420: begin
421: if k > mic'last
422: then Check_and_Update(mic,lifted,mat,ipvt,tol,res,res_last);
423: else tmpfa := fa(k);
424: while not Is_Null(tmpfa) loop -- enumerate faces of kth polytope
425: mic(k) := Head_Of(tmpfa);
426: declare -- update matrices
427: fl : boolean;
428: newipvt : Standard_Natural_Vectors.Vector(ipvt'range) := ipvt;
429: newmat : Matrix(mat'range(1),mat'range(2)) := mat;
430: newineq : Matrix(ineq'range(1),ineq'range(2)) := ineq;
431: newrow : natural := row;
432: newrowineq : natural := rowineq;
433: begin
434: Create_Equalities
435: (n,mic(k),mat,ineq,tol,ipvt,row,rowineq,newmat,newineq,
436: newipvt,newrow,newrowineq,fl);
437: if fl
438: then nbfail(k) := nbfail(k) + 1.0;
439: else Process_Inequalities
440: (k,row+1,newrow,newmat,newipvt,newrowineq,newineq,mic);
441: end if;
442: end;
443: tmpfa := Tail_Of(tmpfa);
444: end loop;
445: end if;
446: end Compute_Mixed_Cells;
447:
448: begin
449: Initialize(n,ma,ipvt);
450: ineqrows := Number_of_Inequalities(mix,lifted);
451: declare
452: ineq : Matrix(1..ineqrows,1..n+1);
453: begin
454: ineq(1,1) := 0.0;
455: Compute_Mixed_Cells(accu'first,0,ma,ipvt,0,ineq,accu);
456: end;
457: mixsub := res;
458: end Create;
459:
460: end Floating_Pruning_Methods;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>