Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/build/pkgs/cddlib/patches/cddcore.c
8818 views
1
/* cddcore.c: Core Procedures for cddlib
2
written by Komei Fukuda, [email protected]
3
Version 0.94f, February 7, 2008
4
*/
5
6
/* cddlib : C-library of the double description method for
7
computing all vertices and extreme rays of the polyhedron
8
P= {x : b - A x >= 0}.
9
Please read COPYING (GNU General Public Licence) and
10
the manual cddlibman.tex for detail.
11
*/
12
13
#include "setoper.h" /* set operation library header (Ver. June 1, 2000 or later) */
14
#include "cdd.h"
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <time.h>
18
#include <math.h>
19
#include <string.h>
20
#include "random.h" /* include last - overrides RAND_MAX */
21
22
void dd_CheckAdjacency(dd_ConePtr cone,
23
dd_RayPtr *RP1, dd_RayPtr *RP2, dd_boolean *adjacent)
24
{
25
dd_RayPtr TempRay;
26
dd_boolean localdebug=dd_FALSE;
27
static dd_rowset Face, Face1;
28
static dd_rowrange last_m=0;
29
30
if (last_m!=cone->m) {
31
if (last_m>0){
32
set_free(Face); set_free(Face1);
33
}
34
set_initialize(&Face, cone->m);
35
set_initialize(&Face1, cone->m);
36
last_m=cone->m;
37
}
38
39
if (dd_debug) localdebug=dd_TRUE;
40
*adjacent = dd_TRUE;
41
set_int(Face1, (*RP1)->ZeroSet, (*RP2)->ZeroSet);
42
set_int(Face, Face1, cone->AddedHalfspaces);
43
if (set_card(Face)< cone->d - 2) {
44
*adjacent = dd_FALSE;
45
if (localdebug) {
46
fprintf(stderr,"non adjacent: set_card(face) %ld < %ld = cone->d.\n",
47
set_card(Face),cone->d);
48
}
49
return;
50
}
51
else if (cone->parent->NondegAssumed) {
52
*adjacent = dd_TRUE;
53
return;
54
}
55
TempRay = cone->FirstRay;
56
while (TempRay != NULL && *adjacent) {
57
if (TempRay != *RP1 && TempRay != *RP2) {
58
set_int(Face1, TempRay->ZeroSet, cone->AddedHalfspaces);
59
if (set_subset(Face, Face1)) *adjacent = dd_FALSE;
60
}
61
TempRay = TempRay->Next;
62
}
63
}
64
65
void dd_Eliminate(dd_ConePtr cone, dd_RayPtr*Ptr)
66
{
67
/*eliminate the record pointed by Ptr^.Next*/
68
dd_RayPtr TempPtr;
69
dd_colrange j;
70
71
TempPtr = (*Ptr)->Next;
72
(*Ptr)->Next = (*Ptr)->Next->Next;
73
if (TempPtr == cone->FirstRay) /*Update the first pointer*/
74
cone->FirstRay = (*Ptr)->Next;
75
if (TempPtr == cone->LastRay) /*Update the last pointer*/
76
cone->LastRay = *Ptr;
77
78
/* Added, Marc Pfetsch 010219 */
79
for (j=0;j < cone->d;j++)
80
dd_clear(TempPtr->Ray[j]);
81
dd_clear(TempPtr->ARay);
82
83
free(TempPtr->Ray); /* free the ray vector memory */
84
set_free(TempPtr->ZeroSet); /* free the ZeroSet memory */
85
free(TempPtr); /* free the dd_Ray structure memory */
86
cone->RayCount--;
87
}
88
89
void dd_SetInequalitySets(dd_ConePtr cone)
90
{
91
dd_rowrange i;
92
93
set_emptyset(cone->GroundSet);
94
set_emptyset(cone->EqualitySet);
95
set_emptyset(cone->NonequalitySet);
96
for (i = 1; i <= (cone->parent->m); i++){
97
set_addelem(cone->GroundSet, i);
98
if (cone->parent->EqualityIndex[i]==1) set_addelem(cone->EqualitySet,i);
99
if (cone->parent->EqualityIndex[i]==-1) set_addelem(cone->NonequalitySet,i);
100
}
101
}
102
103
104
void dd_AValue(mytype *val, dd_colrange d_size, dd_Amatrix A, mytype *p, dd_rowrange i)
105
{
106
/*return the ith component of the vector A x p */
107
dd_colrange j;
108
mytype x;
109
110
dd_init(x);
111
dd_set(*val,dd_purezero);
112
/* Changed by Marc Pfetsch 010219 */
113
114
for (j = 0; j < d_size; j++){
115
dd_mul(x,A[i - 1][j], p[j]);
116
dd_add(*val, *val, x);
117
}
118
dd_clear(x);
119
}
120
121
void dd_StoreRay1(dd_ConePtr cone, mytype *p, dd_boolean *feasible)
122
{ /* Original ray storing routine when RelaxedEnumeration is dd_FALSE */
123
dd_rowrange i,k,fii=cone->m+1;
124
dd_colrange j;
125
mytype temp;
126
dd_RayPtr RR;
127
dd_boolean localdebug=dd_debug;
128
129
dd_init(temp);
130
RR=cone->LastRay;
131
*feasible = dd_TRUE;
132
set_initialize(&(RR->ZeroSet),cone->m);
133
for (j = 0; j < cone->d; j++){
134
dd_set(RR->Ray[j],p[j]);
135
}
136
for (i = 1; i <= cone->m; i++) {
137
k=cone->OrderVector[i];
138
dd_AValue(&temp, cone->d, cone->A, p, k);
139
if (localdebug) {
140
fprintf(stderr,"dd_StoreRay1: dd_AValue at row %ld =",k);
141
dd_WriteNumber(stderr, temp);
142
fprintf(stderr,"\n");
143
}
144
if (dd_EqualToZero(temp)) {
145
set_addelem(RR->ZeroSet, k);
146
if (localdebug) {
147
fprintf(stderr,"recognized zero!\n");
148
}
149
}
150
if (dd_Negative(temp)){
151
if (localdebug) {
152
fprintf(stderr,"recognized negative!\n");
153
}
154
*feasible = dd_FALSE;
155
if (fii>cone->m) fii=i; /* the first violating inequality index */
156
if (localdebug) {
157
fprintf(stderr,"this ray is not feasible, neg comp = %ld\n", fii);
158
dd_WriteNumber(stderr, temp); fprintf(stderr,"\n");
159
}
160
}
161
}
162
RR->FirstInfeasIndex=fii;
163
RR->feasible = *feasible;
164
dd_clear(temp);
165
}
166
167
void dd_StoreRay2(dd_ConePtr cone, mytype *p,
168
dd_boolean *feasible, dd_boolean *weaklyfeasible)
169
/* Ray storing routine when RelaxedEnumeration is dd_TRUE.
170
weaklyfeasible is true iff it is feasible with
171
the strict_inequality conditions deleted. */
172
{
173
dd_RayPtr RR;
174
dd_rowrange i,k,fii=cone->m+1;
175
dd_colrange j;
176
mytype temp;
177
dd_boolean localdebug=dd_debug;
178
179
dd_init(temp);
180
RR=cone->LastRay;
181
if (dd_debug) localdebug=dd_TRUE;
182
*feasible = dd_TRUE;
183
*weaklyfeasible = dd_TRUE;
184
set_initialize(&(RR->ZeroSet),cone->m);
185
for (j = 0; j < cone->d; j++){
186
dd_set(RR->Ray[j],p[j]);
187
}
188
for (i = 1; i <= cone->m; i++) {
189
k=cone->OrderVector[i];
190
dd_AValue(&temp, cone->d, cone->A, p, k);
191
if (dd_EqualToZero(temp)){
192
set_addelem(RR->ZeroSet, k);
193
if (cone->parent->EqualityIndex[k]==-1)
194
*feasible=dd_FALSE; /* strict inequality required */
195
}
196
/* if (temp < -zero){ */
197
if (dd_Negative(temp)){
198
*feasible = dd_FALSE;
199
if (fii>cone->m && cone->parent->EqualityIndex[k]>=0) {
200
fii=i; /* the first violating inequality index */
201
*weaklyfeasible=dd_FALSE;
202
}
203
}
204
}
205
RR->FirstInfeasIndex=fii;
206
RR->feasible = *feasible;
207
dd_clear(temp);
208
}
209
210
211
void dd_AddRay(dd_ConePtr cone, mytype *p)
212
{
213
dd_boolean feasible, weaklyfeasible;
214
dd_colrange j;
215
216
if (cone->FirstRay == NULL) {
217
cone->FirstRay = (dd_RayPtr) malloc(sizeof(dd_RayType));
218
cone->FirstRay->Ray = (mytype *) calloc(cone->d, sizeof(mytype));
219
for (j=0; j<cone->d; j++) dd_init(cone->FirstRay->Ray[j]);
220
dd_init(cone->FirstRay->ARay);
221
if (dd_debug)
222
fprintf(stderr,"Create the first ray pointer\n");
223
cone->LastRay = cone->FirstRay;
224
cone->ArtificialRay->Next = cone->FirstRay;
225
} else {
226
cone->LastRay->Next = (dd_RayPtr) malloc(sizeof(dd_RayType));
227
cone->LastRay->Next->Ray = (mytype *) calloc(cone->d, sizeof(mytype));
228
for (j=0; j<cone->d; j++) dd_init(cone->LastRay->Next->Ray[j]);
229
dd_init(cone->LastRay->Next->ARay);
230
if (dd_debug) fprintf(stderr,"Create a new ray pointer\n");
231
cone->LastRay = cone->LastRay->Next;
232
}
233
cone->LastRay->Next = NULL;
234
cone->RayCount++;
235
cone->TotalRayCount++;
236
if (dd_debug) {
237
if (cone->TotalRayCount % 100 == 0) {
238
fprintf(stderr,"*Rays (Total, Currently Active, Feasible) =%8ld%8ld%8ld\n",
239
cone->TotalRayCount, cone->RayCount, cone->FeasibleRayCount);
240
}
241
}
242
if (cone->parent->RelaxedEnumeration){
243
dd_StoreRay2(cone, p, &feasible, &weaklyfeasible);
244
if (weaklyfeasible) (cone->WeaklyFeasibleRayCount)++;
245
} else {
246
dd_StoreRay1(cone, p, &feasible);
247
if (feasible) (cone->WeaklyFeasibleRayCount)++;
248
/* weaklyfeasible is equiv. to feasible in this case. */
249
}
250
if (!feasible) return;
251
else {
252
(cone->FeasibleRayCount)++;
253
}
254
}
255
256
void dd_AddArtificialRay(dd_ConePtr cone)
257
{
258
dd_Arow zerovector;
259
dd_colrange j,d1;
260
dd_boolean feasible;
261
262
if (cone->d<=0) d1=1; else d1=cone->d;
263
dd_InitializeArow(d1, &zerovector);
264
if (cone->ArtificialRay != NULL) {
265
fprintf(stderr,"Warning !!! FirstRay in not nil. Illegal Call\n");
266
free(zerovector); /* 086 */
267
return;
268
}
269
cone->ArtificialRay = (dd_RayPtr) malloc(sizeof(dd_RayType));
270
cone->ArtificialRay->Ray = (mytype *) calloc(d1, sizeof(mytype));
271
for (j=0; j<d1; j++) dd_init(cone->ArtificialRay->Ray[j]);
272
dd_init(cone->ArtificialRay->ARay);
273
274
if (dd_debug) fprintf(stderr,"Create the artificial ray pointer\n");
275
276
cone->LastRay=cone->ArtificialRay;
277
dd_StoreRay1(cone, zerovector, &feasible);
278
/* This stores a vector to the record pointed by cone->LastRay */
279
cone->ArtificialRay->Next = NULL;
280
for (j = 0; j < d1; j++){
281
dd_clear(zerovector[j]);
282
}
283
free(zerovector); /* 086 */
284
}
285
286
void dd_ConditionalAddEdge(dd_ConePtr cone,
287
dd_RayPtr Ray1, dd_RayPtr Ray2, dd_RayPtr ValidFirstRay)
288
{
289
long it,it_row,fii1,fii2,fmin,fmax;
290
dd_boolean adjacent,lastchance;
291
dd_RayPtr TempRay,Rmin,Rmax;
292
dd_AdjacencyType *NewEdge;
293
dd_boolean localdebug=dd_FALSE;
294
dd_rowset ZSmin, ZSmax;
295
static dd_rowset Face, Face1;
296
static dd_rowrange last_m=0;
297
298
if (last_m!=cone->m) {
299
if (last_m>0){
300
set_free(Face); set_free(Face1);
301
}
302
set_initialize(&Face, cone->m);
303
set_initialize(&Face1, cone->m);
304
last_m=cone->m;
305
}
306
307
fii1=Ray1->FirstInfeasIndex;
308
fii2=Ray2->FirstInfeasIndex;
309
if (fii1<fii2){
310
fmin=fii1; fmax=fii2;
311
Rmin=Ray1;
312
Rmax=Ray2;
313
}
314
else{
315
fmin=fii2; fmax=fii1;
316
Rmin=Ray2;
317
Rmax=Ray1;
318
}
319
ZSmin = Rmin->ZeroSet;
320
ZSmax = Rmax->ZeroSet;
321
if (localdebug) {
322
fprintf(stderr,"dd_ConditionalAddEdge: FMIN = %ld (row%ld) FMAX=%ld\n",
323
fmin, cone->OrderVector[fmin], fmax);
324
}
325
if (fmin==fmax){
326
if (localdebug) fprintf(stderr,"dd_ConditionalAddEdge: equal FII value-> No edge added\n");
327
}
328
else if (set_member(cone->OrderVector[fmin],ZSmax)){
329
if (localdebug) fprintf(stderr,"dd_ConditionalAddEdge: No strong separation -> No edge added\n");
330
}
331
else { /* the pair will be separated at the iteration fmin */
332
lastchance=dd_TRUE;
333
/* flag to check it will be the last chance to store the edge candidate */
334
set_int(Face1, ZSmax, ZSmin);
335
(cone->count_int)++;
336
if (localdebug){
337
fprintf(stderr,"Face: ");
338
for (it=1; it<=cone->m; it++) {
339
it_row=cone->OrderVector[it];
340
if (set_member(it_row, Face1)) fprintf(stderr,"%ld ",it_row);
341
}
342
fprintf(stderr,"\n");
343
}
344
for (it=cone->Iteration+1; it < fmin && lastchance; it++){
345
it_row=cone->OrderVector[it];
346
if (cone->parent->EqualityIndex[it_row]>=0 && set_member(it_row, Face1)){
347
lastchance=dd_FALSE;
348
(cone->count_int_bad)++;
349
if (localdebug){
350
fprintf(stderr,"There will be another chance iteration %ld (row %ld) to store the pair\n", it, it_row);
351
}
352
}
353
}
354
if (lastchance){
355
adjacent = dd_TRUE;
356
(cone->count_int_good)++;
357
/* adjacent checking */
358
set_int(Face, Face1, cone->AddedHalfspaces);
359
if (localdebug){
360
fprintf(stderr,"Check adjacency\n");
361
fprintf(stderr,"AddedHalfspaces: "); set_fwrite(stderr,cone->AddedHalfspaces);
362
fprintf(stderr,"Face: ");
363
for (it=1; it<=cone->m; it++) {
364
it_row=cone->OrderVector[it];
365
if (set_member(it_row, Face)) fprintf(stderr,"%ld ",it_row);
366
}
367
fprintf(stderr,"\n");
368
}
369
if (set_card(Face)< cone->d - 2) {
370
adjacent = dd_FALSE;
371
}
372
else if (cone->parent->NondegAssumed) {
373
adjacent = dd_TRUE;
374
}
375
else{
376
TempRay = ValidFirstRay; /* the first ray for adjacency checking */
377
while (TempRay != NULL && adjacent) {
378
if (TempRay != Ray1 && TempRay != Ray2) {
379
set_int(Face1, TempRay->ZeroSet, cone->AddedHalfspaces);
380
if (set_subset(Face, Face1)) {
381
if (localdebug) set_fwrite(stderr,Face1);
382
adjacent = dd_FALSE;
383
}
384
}
385
TempRay = TempRay->Next;
386
}
387
}
388
if (adjacent){
389
if (localdebug) fprintf(stderr,"The pair is adjacent and the pair must be stored for iteration %ld (row%ld)\n",
390
fmin, cone->OrderVector[fmin]);
391
NewEdge=(dd_AdjacencyPtr) malloc(sizeof *NewEdge);
392
NewEdge->Ray1=Rmax; /* save the one remains in iteration fmin in the first */
393
NewEdge->Ray2=Rmin; /* save the one deleted in iteration fmin in the second */
394
NewEdge->Next=NULL;
395
(cone->EdgeCount)++;
396
(cone->TotalEdgeCount)++;
397
if (cone->Edges[fmin]==NULL){
398
cone->Edges[fmin]=NewEdge;
399
if (localdebug) fprintf(stderr,"Create a new edge list of %ld\n", fmin);
400
}else{
401
NewEdge->Next=cone->Edges[fmin];
402
cone->Edges[fmin]=NewEdge;
403
}
404
}
405
}
406
}
407
}
408
409
void dd_CreateInitialEdges(dd_ConePtr cone)
410
{
411
dd_RayPtr Ptr1, Ptr2;
412
dd_rowrange fii1,fii2;
413
long count=0;
414
dd_boolean adj,localdebug=dd_FALSE;
415
416
cone->Iteration=cone->d; /* CHECK */
417
if (cone->FirstRay ==NULL || cone->LastRay==NULL){
418
/* fprintf(stderr,"Warning: dd_ CreateInitialEdges called with NULL pointer(s)\n"); */
419
goto _L99;
420
}
421
Ptr1=cone->FirstRay;
422
while(Ptr1!=cone->LastRay && Ptr1!=NULL){
423
fii1=Ptr1->FirstInfeasIndex;
424
Ptr2=Ptr1->Next;
425
while(Ptr2!=NULL){
426
fii2=Ptr2->FirstInfeasIndex;
427
count++;
428
if (localdebug) fprintf(stderr,"dd_ CreateInitialEdges: edge %ld \n",count);
429
dd_CheckAdjacency(cone, &Ptr1, &Ptr2, &adj);
430
if (fii1!=fii2 && adj)
431
dd_ConditionalAddEdge(cone, Ptr1, Ptr2, cone->FirstRay);
432
Ptr2=Ptr2->Next;
433
}
434
Ptr1=Ptr1->Next;
435
}
436
_L99:;
437
}
438
439
440
void dd_UpdateEdges(dd_ConePtr cone, dd_RayPtr RRbegin, dd_RayPtr RRend)
441
/* This procedure must be called after the ray list is sorted
442
by dd_EvaluateARay2 so that FirstInfeasIndex's are monotonically
443
increasing.
444
*/
445
{
446
dd_RayPtr Ptr1, Ptr2begin, Ptr2;
447
dd_rowrange fii1;
448
dd_boolean ptr2found,quit,localdebug=dd_FALSE;
449
long count=0,pos1, pos2;
450
float workleft,prevworkleft=110.0,totalpairs;
451
452
totalpairs=(cone->ZeroRayCount-1.0)*(cone->ZeroRayCount-2.0)+1.0;
453
Ptr2begin = NULL;
454
if (RRbegin ==NULL || RRend==NULL){
455
if (1) fprintf(stderr,"Warning: dd_UpdateEdges called with NULL pointer(s)\n");
456
goto _L99;
457
}
458
Ptr1=RRbegin;
459
pos1=1;
460
do{
461
ptr2found=dd_FALSE;
462
quit=dd_FALSE;
463
fii1=Ptr1->FirstInfeasIndex;
464
pos2=2;
465
for (Ptr2=Ptr1->Next; !ptr2found && !quit; Ptr2=Ptr2->Next,pos2++){
466
if (Ptr2->FirstInfeasIndex > fii1){
467
Ptr2begin=Ptr2;
468
ptr2found=dd_TRUE;
469
}
470
else if (Ptr2==RRend) quit=dd_TRUE;
471
}
472
if (ptr2found){
473
quit=dd_FALSE;
474
for (Ptr2=Ptr2begin; !quit ; Ptr2=Ptr2->Next){
475
count++;
476
if (localdebug) fprintf(stderr,"dd_UpdateEdges: edge %ld \n",count);
477
dd_ConditionalAddEdge(cone, Ptr1,Ptr2,RRbegin);
478
if (Ptr2==RRend || Ptr2->Next==NULL) quit=dd_TRUE;
479
}
480
}
481
Ptr1=Ptr1->Next;
482
pos1++;
483
workleft = 100.0 * (cone->ZeroRayCount-pos1) * (cone->ZeroRayCount - pos1-1.0) / totalpairs;
484
if (cone->ZeroRayCount>=500 && dd_debug && pos1%10 ==0 && prevworkleft-workleft>=10 ) {
485
fprintf(stderr,"*Work of iteration %5ld(/%ld): %4ld/%4ld => %4.1f%% left\n",
486
cone->Iteration, cone->m, pos1, cone->ZeroRayCount, workleft);
487
prevworkleft=workleft;
488
}
489
}while(Ptr1!=RRend && Ptr1!=NULL);
490
_L99:;
491
}
492
493
void dd_FreeDDMemory0(dd_ConePtr cone)
494
{
495
dd_RayPtr Ptr, PrevPtr;
496
long count;
497
dd_colrange j;
498
dd_boolean localdebug=dd_FALSE;
499
500
/* THIS SHOULD BE REWRITTEN carefully */
501
PrevPtr=cone->ArtificialRay;
502
if (PrevPtr!=NULL){
503
count=0;
504
for (Ptr=cone->ArtificialRay->Next; Ptr!=NULL; Ptr=Ptr->Next){
505
/* Added Marc Pfetsch 2/19/01 */
506
for (j=0;j < cone->d;j++)
507
dd_clear(PrevPtr->Ray[j]);
508
dd_clear(PrevPtr->ARay);
509
510
free(PrevPtr->Ray);
511
free(PrevPtr->ZeroSet);
512
free(PrevPtr);
513
count++;
514
PrevPtr=Ptr;
515
};
516
cone->FirstRay=NULL;
517
/* Added Marc Pfetsch 010219 */
518
for (j=0;j < cone->d;j++)
519
dd_clear(cone->LastRay->Ray[j]);
520
dd_clear(cone->LastRay->ARay);
521
522
free(cone->LastRay->Ray);
523
cone->LastRay->Ray = NULL;
524
set_free(cone->LastRay->ZeroSet);
525
cone->LastRay->ZeroSet = NULL;
526
free(cone->LastRay);
527
cone->LastRay = NULL;
528
cone->ArtificialRay=NULL;
529
if (localdebug) fprintf(stderr,"%ld ray storage spaces freed\n",count);
530
}
531
/* must add (by Sato) */
532
free(cone->Edges);
533
534
set_free(cone->GroundSet);
535
set_free(cone->EqualitySet);
536
set_free(cone->NonequalitySet);
537
set_free(cone->AddedHalfspaces);
538
set_free(cone->WeaklyAddedHalfspaces);
539
set_free(cone->InitialHalfspaces);
540
free(cone->InitialRayIndex);
541
free(cone->OrderVector);
542
free(cone->newcol);
543
544
/* Fixed by Shawn Rusaw. Originally it was cone->d instead of cone->d_alloc */
545
dd_FreeBmatrix(cone->d_alloc,cone->B);
546
dd_FreeBmatrix(cone->d_alloc,cone->Bsave);
547
548
/* Fixed by Marc Pfetsch 010219*/
549
dd_FreeAmatrix(cone->m_alloc,cone->d_alloc,cone->A);
550
cone->A = NULL;
551
552
free(cone);
553
}
554
555
void dd_FreeDDMemory(dd_PolyhedraPtr poly)
556
{
557
dd_FreeDDMemory0(poly->child);
558
poly->child=NULL;
559
}
560
561
void dd_FreePolyhedra(dd_PolyhedraPtr poly)
562
{
563
dd_bigrange i;
564
565
if ((poly)->child != NULL) dd_FreeDDMemory(poly);
566
dd_FreeAmatrix((poly)->m_alloc,poly->d_alloc, poly->A);
567
dd_FreeArow((poly)->d_alloc,(poly)->c);
568
free((poly)->EqualityIndex);
569
if (poly->AincGenerated){
570
for (i=1; i<=poly->m1; i++){
571
set_free(poly->Ainc[i-1]);
572
}
573
free(poly->Ainc);
574
set_free(poly->Ared);
575
set_free(poly->Adom);
576
poly->Ainc=NULL;
577
}
578
579
free(poly);
580
}
581
582
void dd_Normalize(dd_colrange d_size, mytype *V)
583
{
584
long j,jmin=0;
585
mytype temp,min;
586
dd_boolean nonzerofound=dd_FALSE;
587
588
if (d_size>0){
589
dd_init(min); dd_init(temp);
590
dd_abs(min,V[0]); jmin=0; /* set the minmizer to 0 */
591
if (dd_Positive(min)) nonzerofound=dd_TRUE;
592
for (j = 1; j < d_size; j++) {
593
dd_abs(temp,V[j]);
594
if (dd_Positive(temp)){
595
if (!nonzerofound || dd_Smaller(temp,min)){
596
nonzerofound=dd_TRUE;
597
dd_set(min, temp); jmin=j;
598
}
599
}
600
}
601
if (dd_Positive(min)){
602
for (j = 0; j < d_size; j++) dd_div(V[j], V[j], min);
603
}
604
dd_clear(min); dd_clear(temp);
605
}
606
}
607
608
609
void dd_ZeroIndexSet(dd_rowrange m_size, dd_colrange d_size, dd_Amatrix A, mytype *x, dd_rowset ZS)
610
{
611
dd_rowrange i;
612
mytype temp;
613
614
/* Changed by Marc Pfetsch 010219 */
615
dd_init(temp);
616
set_emptyset(ZS);
617
for (i = 1; i <= m_size; i++) {
618
dd_AValue(&temp, d_size, A, x, i);
619
if (dd_EqualToZero(temp)) set_addelem(ZS, i);
620
}
621
622
/* Changed by Marc Pfetsch 010219 */
623
dd_clear(temp);
624
}
625
626
void dd_CopyBmatrix(dd_colrange d_size, dd_Bmatrix T, dd_Bmatrix TCOPY)
627
{
628
dd_rowrange i;
629
dd_colrange j;
630
631
for (i=0; i < d_size; i++) {
632
for (j=0; j < d_size; j++) {
633
dd_set(TCOPY[i][j],T[i][j]);
634
}
635
}
636
}
637
638
639
void dd_CopyArow(mytype *acopy, mytype *a, dd_colrange d)
640
{
641
dd_colrange j;
642
643
for (j = 0; j < d; j++) {
644
dd_set(acopy[j],a[j]);
645
}
646
}
647
648
void dd_CopyNormalizedArow(mytype *acopy, mytype *a, dd_colrange d)
649
{
650
dd_CopyArow(acopy, a, d);
651
dd_Normalize(d,acopy);
652
}
653
654
void dd_CopyAmatrix(mytype **Acopy, mytype **A, dd_rowrange m, dd_colrange d)
655
{
656
dd_rowrange i;
657
658
for (i = 0; i< m; i++) {
659
dd_CopyArow(Acopy[i],A[i],d);
660
}
661
}
662
663
void dd_CopyNormalizedAmatrix(mytype **Acopy, mytype **A, dd_rowrange m, dd_colrange d)
664
{
665
dd_rowrange i;
666
667
for (i = 0; i< m; i++) {
668
dd_CopyNormalizedArow(Acopy[i],A[i],d);
669
}
670
}
671
672
void dd_PermuteCopyAmatrix(mytype **Acopy, mytype **A, dd_rowrange m, dd_colrange d, dd_rowindex roworder)
673
{
674
dd_rowrange i;
675
676
for (i = 1; i<= m; i++) {
677
dd_CopyArow(Acopy[i-1],A[roworder[i]-1],d);
678
}
679
}
680
681
void dd_PermutePartialCopyAmatrix(mytype **Acopy, mytype **A, dd_rowrange m, dd_colrange d, dd_rowindex roworder,dd_rowrange p, dd_rowrange q)
682
{
683
/* copy the rows of A whose roworder is positive. roworder[i] is the row index of the copied row. */
684
dd_rowrange i,k;
685
686
k=0;
687
for (i = 1; i<= m; i++) {
688
if (roworder[i]>0) dd_CopyArow(Acopy[roworder[i]-1],A[i-1],d);
689
}
690
}
691
692
void dd_InitializeArow(dd_colrange d,dd_Arow *a)
693
{
694
dd_colrange j;
695
696
if (d>0) *a=(mytype*) calloc(d,sizeof(mytype));
697
for (j = 0; j < d; j++) {
698
dd_init((*a)[j]);
699
}
700
}
701
702
void dd_InitializeAmatrix(dd_rowrange m,dd_colrange d,dd_Amatrix *A)
703
{
704
dd_rowrange i;
705
706
if (m>0) (*A)=(mytype**) calloc(m,sizeof(mytype*));
707
for (i = 0; i < m; i++) {
708
dd_InitializeArow(d,&((*A)[i]));
709
}
710
}
711
712
void dd_FreeAmatrix(dd_rowrange m,dd_colrange d,dd_Amatrix A)
713
{
714
dd_rowrange i;
715
dd_colrange j;
716
717
for (i = 0; i < m; i++) {
718
for (j = 0; j < d; j++) {
719
dd_clear(A[i][j]);
720
}
721
}
722
if (A!=NULL) {
723
for (i = 0; i < m; i++) {
724
free(A[i]);
725
}
726
free(A);
727
}
728
}
729
730
void dd_FreeArow(dd_colrange d, dd_Arow a)
731
{
732
dd_colrange j;
733
734
for (j = 0; j < d; j++) {
735
dd_clear(a[j]);
736
}
737
free(a);
738
}
739
740
741
void dd_InitializeBmatrix(dd_colrange d,dd_Bmatrix *B)
742
{
743
dd_colrange i,j;
744
745
(*B)=(mytype**) calloc(d,sizeof(mytype*));
746
for (j = 0; j < d; j++) {
747
(*B)[j]=(mytype*) calloc(d,sizeof(mytype));
748
}
749
for (i = 0; i < d; i++) {
750
for (j = 0; j < d; j++) {
751
dd_init((*B)[i][j]);
752
}
753
}
754
}
755
756
void dd_FreeBmatrix(dd_colrange d,dd_Bmatrix B)
757
{
758
dd_colrange i,j;
759
760
for (i = 0; i < d; i++) {
761
for (j = 0; j < d; j++) {
762
dd_clear(B[i][j]);
763
}
764
}
765
if (B!=NULL) {
766
for (j = 0; j < d; j++) {
767
free(B[j]);
768
}
769
free(B);
770
}
771
}
772
773
dd_SetFamilyPtr dd_CreateSetFamily(dd_bigrange fsize, dd_bigrange ssize)
774
{
775
dd_SetFamilyPtr F;
776
dd_bigrange i,f0,f1,s0,s1;
777
778
if (fsize<=0) {
779
f0=0; f1=1;
780
/* if fsize<=0, the fsize is set to zero and the created size is one */
781
} else {
782
f0=fsize; f1=fsize;
783
}
784
if (ssize<=0) {
785
s0=0; s1=1;
786
/* if ssize<=0, the ssize is set to zero and the created size is one */
787
} else {
788
s0=ssize; s1=ssize;
789
}
790
791
F=(dd_SetFamilyPtr) malloc (sizeof(dd_SetFamilyType));
792
F->set=(set_type*) calloc(f1,sizeof(set_type));
793
for (i=0; i<f1; i++) {
794
set_initialize(&(F->set[i]), s1);
795
}
796
F->famsize=f0;
797
F->setsize=s0;
798
return F;
799
}
800
801
802
void dd_FreeSetFamily(dd_SetFamilyPtr F)
803
{
804
dd_bigrange i,f1;
805
806
if (F!=NULL){
807
if (F->famsize<=0) f1=1; else f1=F->famsize;
808
/* the smallest created size is one */
809
for (i=0; i<f1; i++) {
810
set_free(F->set[i]);
811
}
812
free(F->set);
813
free(F);
814
}
815
}
816
817
dd_MatrixPtr dd_CreateMatrix(dd_rowrange m_size,dd_colrange d_size)
818
{
819
dd_MatrixPtr M;
820
dd_rowrange m0,m1;
821
dd_colrange d0,d1;
822
823
if (m_size<=0){
824
m0=0; m1=1;
825
/* if m_size <=0, the number of rows is set to zero, the actual size is 1 */
826
} else {
827
m0=m_size; m1=m_size;
828
}
829
if (d_size<=0){
830
d0=0; d1=1;
831
/* if d_size <=0, the number of cols is set to zero, the actual size is 1 */
832
} else {
833
d0=d_size; d1=d_size;
834
}
835
M=(dd_MatrixPtr) malloc (sizeof(dd_MatrixType));
836
dd_InitializeAmatrix(m1,d1,&(M->matrix));
837
dd_InitializeArow(d1,&(M->rowvec));
838
M->rowsize=m0;
839
set_initialize(&(M->linset), m1);
840
M->colsize=d0;
841
M->objective=dd_LPnone;
842
M->numbtype=dd_Unknown;
843
M->representation=dd_Unspecified;
844
return M;
845
}
846
847
void dd_FreeMatrix(dd_MatrixPtr M)
848
{
849
dd_rowrange m1;
850
dd_colrange d1;
851
852
if (M!=NULL) {
853
if (M->rowsize<=0) m1=1; else m1=M->rowsize;
854
if (M->colsize<=0) d1=1; else d1=M->colsize;
855
if (M!=NULL) {
856
dd_FreeAmatrix(m1,d1,M->matrix);
857
dd_FreeArow(d1,M->rowvec);
858
set_free(M->linset);
859
free(M);
860
}
861
}
862
}
863
864
void dd_SetToIdentity(dd_colrange d_size, dd_Bmatrix T)
865
{
866
dd_colrange j1, j2;
867
868
for (j1 = 1; j1 <= d_size; j1++) {
869
for (j2 = 1; j2 <= d_size; j2++) {
870
if (j1 == j2)
871
dd_set(T[j1 - 1][j2 - 1],dd_one);
872
else
873
dd_set(T[j1 - 1][j2 - 1],dd_purezero);
874
}
875
}
876
}
877
878
void dd_ColumnReduce(dd_ConePtr cone)
879
{
880
dd_colrange j,j1=0;
881
dd_rowrange i;
882
dd_boolean localdebug=dd_FALSE;
883
884
for (j=1;j<=cone->d;j++) {
885
if (cone->InitialRayIndex[j]>0){
886
j1=j1+1;
887
if (j1<j) {
888
for (i=1; i<=cone->m; i++) dd_set(cone->A[i-1][j1-1],cone->A[i-1][j-1]);
889
cone->newcol[j]=j1;
890
if (localdebug){
891
fprintf(stderr,"shifting the column %ld to column %ld\n", j, j1);
892
}
893
/* shifting forward */
894
}
895
} else {
896
cone->newcol[j]=0;
897
if (localdebug) {
898
fprintf(stderr,"a generator (or an equation) of the linearity space: ");
899
for (i=1; i<=cone->d; i++) dd_WriteNumber(stderr, cone->B[i-1][j-1]);
900
fprintf(stderr,"\n");
901
}
902
}
903
}
904
cone->d=j1; /* update the dimension. cone->d_orig remembers the old. */
905
dd_CopyBmatrix(cone->d_orig, cone->B, cone->Bsave);
906
/* save the dual basis inverse as Bsave. This matrix contains the linearity space generators. */
907
cone->ColReduced=dd_TRUE;
908
}
909
910
long dd_MatrixRank(dd_MatrixPtr M, dd_rowset ignoredrows, dd_colset ignoredcols, dd_rowset *rowbasis, dd_colset *colbasis)
911
{
912
dd_boolean stop, chosen, localdebug=dd_debug;
913
dd_rowset NopivotRow,PriorityRow;
914
dd_colset ColSelected;
915
dd_Bmatrix B;
916
dd_rowindex roworder;
917
dd_rowrange r;
918
dd_colrange s;
919
long rank;
920
921
rank = 0;
922
stop = dd_FALSE;
923
set_initialize(&ColSelected, M->colsize);
924
set_initialize(&NopivotRow, M->rowsize);
925
set_initialize(rowbasis, M->rowsize);
926
set_initialize(colbasis, M->colsize);
927
set_initialize(&PriorityRow, M->rowsize);
928
set_copy(NopivotRow,ignoredrows);
929
set_copy(ColSelected,ignoredcols);
930
dd_InitializeBmatrix(M->colsize, &B);
931
dd_SetToIdentity(M->colsize, B);
932
roworder=(long *)calloc(M->rowsize+1,sizeof(long));
933
for (r=0; r<M->rowsize; r++){roworder[r+1]=r+1;
934
}
935
936
do { /* Find a set of rows for a basis */
937
dd_SelectPivot2(M->rowsize, M->colsize,M->matrix,B,dd_MinIndex,roworder,
938
PriorityRow,M->rowsize, NopivotRow, ColSelected, &r, &s, &chosen);
939
if (dd_debug && chosen)
940
fprintf(stderr,"Procedure dd_MatrixRank: pivot on (r,s) =(%ld, %ld).\n", r, s);
941
if (chosen) {
942
set_addelem(NopivotRow, r);
943
set_addelem(*rowbasis, r);
944
set_addelem(ColSelected, s);
945
set_addelem(*colbasis, s);
946
rank++;
947
dd_GaussianColumnPivot(M->rowsize, M->colsize, M->matrix, B, r, s);
948
if (localdebug) dd_WriteBmatrix(stderr,M->colsize,B);
949
} else {
950
stop=dd_TRUE;
951
}
952
if (rank==M->colsize) stop = dd_TRUE;
953
} while (!stop);
954
dd_FreeBmatrix(M->colsize,B);
955
free(roworder);
956
set_free(ColSelected);
957
set_free(NopivotRow);
958
set_free(PriorityRow);
959
return rank;
960
}
961
962
963
void dd_FindBasis(dd_ConePtr cone, long *rank)
964
{
965
dd_boolean stop, chosen, localdebug=dd_debug;
966
dd_rowset NopivotRow;
967
dd_colset ColSelected;
968
dd_rowrange r;
969
dd_colrange j,s;
970
971
*rank = 0;
972
stop = dd_FALSE;
973
for (j=0;j<=cone->d;j++) cone->InitialRayIndex[j]=0;
974
set_emptyset(cone->InitialHalfspaces);
975
set_initialize(&ColSelected, cone->d);
976
set_initialize(&NopivotRow, cone->m);
977
set_copy(NopivotRow,cone->NonequalitySet);
978
dd_SetToIdentity(cone->d, cone->B);
979
do { /* Find a set of rows for a basis */
980
dd_SelectPivot2(cone->m, cone->d,cone->A,cone->B,cone->HalfspaceOrder,cone->OrderVector,
981
cone->EqualitySet,cone->m, NopivotRow, ColSelected, &r, &s, &chosen);
982
if (dd_debug && chosen)
983
fprintf(stderr,"Procedure dd_FindBasis: pivot on (r,s) =(%ld, %ld).\n", r, s);
984
if (chosen) {
985
set_addelem(cone->InitialHalfspaces, r);
986
set_addelem(NopivotRow, r);
987
set_addelem(ColSelected, s);
988
cone->InitialRayIndex[s]=r; /* cone->InitialRayIndex[s] stores the corr. row index */
989
(*rank)++;
990
dd_GaussianColumnPivot(cone->m, cone->d, cone->A, cone->B, r, s);
991
if (localdebug) dd_WriteBmatrix(stderr,cone->d,cone->B);
992
} else {
993
stop=dd_TRUE;
994
}
995
if (*rank==cone->d) stop = dd_TRUE;
996
} while (!stop);
997
set_free(ColSelected);
998
set_free(NopivotRow);
999
}
1000
1001
1002
void dd_FindInitialRays(dd_ConePtr cone, dd_boolean *found)
1003
{
1004
dd_rowset CandidateRows;
1005
dd_rowrange i;
1006
long rank;
1007
dd_RowOrderType roworder_save=dd_LexMin;
1008
1009
*found = dd_FALSE;
1010
set_initialize(&CandidateRows, cone->m);
1011
if (cone->parent->InitBasisAtBottom==dd_TRUE) {
1012
roworder_save=cone->HalfspaceOrder;
1013
cone->HalfspaceOrder=dd_MaxIndex;
1014
cone->PreOrderedRun=dd_FALSE;
1015
}
1016
else cone->PreOrderedRun=dd_TRUE;
1017
if (dd_debug) dd_WriteBmatrix(stderr, cone->d, cone->B);
1018
for (i = 1; i <= cone->m; i++)
1019
if (!set_member(i,cone->NonequalitySet)) set_addelem(CandidateRows, i);
1020
/*all rows not in NonequalitySet are candidates for initial cone*/
1021
dd_FindBasis(cone, &rank);
1022
if (dd_debug) dd_WriteBmatrix(stderr, cone->d, cone->B);
1023
if (dd_debug) fprintf(stderr,"dd_FindInitialRays: rank of Amatrix = %ld\n", rank);
1024
cone->LinearityDim=cone->d - rank;
1025
if (dd_debug) fprintf(stderr,"Linearity Dimension = %ld\n", cone->LinearityDim);
1026
if (cone->LinearityDim > 0) {
1027
dd_ColumnReduce(cone);
1028
dd_FindBasis(cone, &rank);
1029
}
1030
if (!set_subset(cone->EqualitySet,cone->InitialHalfspaces)) {
1031
if (dd_debug) {
1032
fprintf(stderr,"Equality set is dependent. Equality Set and an initial basis:\n");
1033
set_fwrite(stderr,cone->EqualitySet);
1034
set_fwrite(stderr,cone->InitialHalfspaces);
1035
};
1036
}
1037
*found = dd_TRUE;
1038
set_free(CandidateRows);
1039
if (cone->parent->InitBasisAtBottom==dd_TRUE) {
1040
cone->HalfspaceOrder=roworder_save;
1041
}
1042
if (cone->HalfspaceOrder==dd_MaxCutoff||
1043
cone->HalfspaceOrder==dd_MinCutoff||
1044
cone->HalfspaceOrder==dd_MixCutoff){
1045
cone->PreOrderedRun=dd_FALSE;
1046
} else cone->PreOrderedRun=dd_TRUE;
1047
}
1048
1049
void dd_CheckEquality(dd_colrange d_size, dd_RayPtr*RP1, dd_RayPtr*RP2, dd_boolean *equal)
1050
{
1051
long j;
1052
1053
if (dd_debug)
1054
fprintf(stderr,"Check equality of two rays\n");
1055
*equal = dd_TRUE;
1056
j = 1;
1057
while (j <= d_size && *equal) {
1058
if (!dd_Equal((*RP1)->Ray[j - 1],(*RP2)->Ray[j - 1]))
1059
*equal = dd_FALSE;
1060
j++;
1061
}
1062
if (*equal)
1063
fprintf(stderr,"Equal records found !!!!\n");
1064
}
1065
1066
void dd_CreateNewRay(dd_ConePtr cone,
1067
dd_RayPtr Ptr1, dd_RayPtr Ptr2, dd_rowrange ii)
1068
{
1069
/*Create a new ray by taking a linear combination of two rays*/
1070
dd_colrange j;
1071
mytype a1, a2, v1, v2;
1072
static dd_Arow NewRay;
1073
static dd_colrange last_d=0;
1074
dd_boolean localdebug=dd_debug;
1075
1076
dd_init(a1); dd_init(a2); dd_init(v1); dd_init(v2);
1077
if (last_d!=cone->d){
1078
if (last_d>0) {
1079
for (j=0; j<last_d; j++) dd_clear(NewRay[j]);
1080
free(NewRay);
1081
}
1082
NewRay=(mytype*)calloc(cone->d,sizeof(mytype));
1083
for (j=0; j<cone->d; j++) dd_init(NewRay[j]);
1084
last_d=cone->d;
1085
}
1086
1087
dd_AValue(&a1, cone->d, cone->A, Ptr1->Ray, ii);
1088
dd_AValue(&a2, cone->d, cone->A, Ptr2->Ray, ii);
1089
if (localdebug) {
1090
fprintf(stderr,"CreatNewRay: Ray1 ="); dd_WriteArow(stderr, Ptr1->Ray, cone->d);
1091
fprintf(stderr,"CreatNewRay: Ray2 ="); dd_WriteArow(stderr, Ptr2->Ray, cone->d);
1092
}
1093
dd_abs(v1,a1);
1094
dd_abs(v2,a2);
1095
if (localdebug){
1096
fprintf(stderr,"dd_AValue1 and ABS"); dd_WriteNumber(stderr,a1); dd_WriteNumber(stderr,v1); fprintf(stderr,"\n");
1097
fprintf(stderr,"dd_AValue2 and ABS"); dd_WriteNumber(stderr,a2); dd_WriteNumber(stderr,v2); fprintf(stderr,"\n");
1098
}
1099
for (j = 0; j < cone->d; j++){
1100
dd_LinearComb(NewRay[j], Ptr1->Ray[j],v2,Ptr2->Ray[j],v1);
1101
}
1102
if (localdebug) {
1103
fprintf(stderr,"CreatNewRay: New ray ="); dd_WriteArow(stderr, NewRay, cone->d);
1104
}
1105
dd_Normalize(cone->d, NewRay);
1106
if (localdebug) {
1107
fprintf(stderr,"CreatNewRay: dd_Normalized ray ="); dd_WriteArow(stderr, NewRay, cone->d);
1108
}
1109
dd_AddRay(cone, NewRay);
1110
dd_clear(a1); dd_clear(a2); dd_clear(v1); dd_clear(v2);
1111
}
1112
1113
void dd_EvaluateARay1(dd_rowrange i, dd_ConePtr cone)
1114
/* Evaluate the ith component of the vector A x RD.Ray
1115
and rearrange the linked list so that
1116
the infeasible rays with respect to i will be
1117
placed consecutively from First
1118
*/
1119
{
1120
dd_colrange j;
1121
mytype temp,tnext;
1122
dd_RayPtr Ptr, PrevPtr, TempPtr;
1123
1124
dd_init(temp); dd_init(tnext);
1125
Ptr = cone->FirstRay;
1126
PrevPtr = cone->ArtificialRay;
1127
if (PrevPtr->Next != Ptr) {
1128
fprintf(stderr,"Error. Artificial Ray does not point to FirstRay!!!\n");
1129
}
1130
while (Ptr != NULL) {
1131
dd_set(temp,dd_purezero);
1132
for (j = 0; j < cone->d; j++){
1133
dd_mul(tnext,cone->A[i - 1][j],Ptr->Ray[j]);
1134
dd_add(temp,temp,tnext);
1135
}
1136
dd_set(Ptr->ARay,temp);
1137
/* if ( temp <= -zero && Ptr != cone->FirstRay) {*/
1138
if ( dd_Negative(temp) && Ptr != cone->FirstRay) {
1139
/* fprintf(stderr,"Moving an infeasible record w.r.t. %ld to FirstRay\n",i); */
1140
if (Ptr==cone->LastRay) cone->LastRay=PrevPtr;
1141
TempPtr=Ptr;
1142
Ptr = Ptr->Next;
1143
PrevPtr->Next = Ptr;
1144
cone->ArtificialRay->Next = TempPtr;
1145
TempPtr->Next = cone->FirstRay;
1146
cone->FirstRay = TempPtr;
1147
}
1148
else {
1149
PrevPtr = Ptr;
1150
Ptr = Ptr->Next;
1151
}
1152
}
1153
dd_clear(temp); dd_clear(tnext);
1154
}
1155
1156
void dd_EvaluateARay2(dd_rowrange i, dd_ConePtr cone)
1157
/* Evaluate the ith component of the vector A x RD.Ray
1158
and rearrange the linked list so that
1159
the infeasible rays with respect to i will be
1160
placed consecutively from First. Also for all feasible rays,
1161
"positive" rays and "zero" rays will be placed consecutively.
1162
*/
1163
{
1164
dd_colrange j;
1165
mytype temp,tnext;
1166
dd_RayPtr Ptr, NextPtr;
1167
dd_boolean zerofound=dd_FALSE,negfound=dd_FALSE,posfound=dd_FALSE;
1168
1169
if (cone==NULL || cone->TotalRayCount<=0) goto _L99;
1170
dd_init(temp); dd_init(tnext);
1171
cone->PosHead=NULL;cone->ZeroHead=NULL;cone->NegHead=NULL;
1172
cone->PosLast=NULL;cone->ZeroLast=NULL;cone->NegLast=NULL;
1173
Ptr = cone->FirstRay;
1174
while (Ptr != NULL) {
1175
NextPtr=Ptr->Next; /* remember the Next record */
1176
Ptr->Next=NULL; /* then clear the Next pointer */
1177
dd_set(temp,dd_purezero);
1178
for (j = 0; j < cone->d; j++){
1179
dd_mul(tnext,cone->A[i - 1][j],Ptr->Ray[j]);
1180
dd_add(temp,temp,tnext);
1181
}
1182
dd_set(Ptr->ARay,temp);
1183
/* if ( temp < -zero) {*/
1184
if ( dd_Negative(temp)) {
1185
if (!negfound){
1186
negfound=dd_TRUE;
1187
cone->NegHead=Ptr;
1188
cone->NegLast=Ptr;
1189
}
1190
else{
1191
Ptr->Next=cone->NegHead;
1192
cone->NegHead=Ptr;
1193
}
1194
}
1195
/* else if (temp > zero){*/
1196
else if (dd_Positive(temp)){
1197
if (!posfound){
1198
posfound=dd_TRUE;
1199
cone->PosHead=Ptr;
1200
cone->PosLast=Ptr;
1201
}
1202
else{
1203
Ptr->Next=cone->PosHead;
1204
cone->PosHead=Ptr;
1205
}
1206
}
1207
else {
1208
if (!zerofound){
1209
zerofound=dd_TRUE;
1210
cone->ZeroHead=Ptr;
1211
cone->ZeroLast=Ptr;
1212
}
1213
else{
1214
Ptr->Next=cone->ZeroHead;
1215
cone->ZeroHead=Ptr;
1216
}
1217
}
1218
Ptr=NextPtr;
1219
}
1220
/* joining three neg, pos and zero lists */
1221
if (negfound){ /* -list nonempty */
1222
cone->FirstRay=cone->NegHead;
1223
if (posfound){ /* -list & +list nonempty */
1224
cone->NegLast->Next=cone->PosHead;
1225
if (zerofound){ /* -list, +list, 0list all nonempty */
1226
cone->PosLast->Next=cone->ZeroHead;
1227
cone->LastRay=cone->ZeroLast;
1228
}
1229
else{ /* -list, +list nonempty but 0list empty */
1230
cone->LastRay=cone->PosLast;
1231
}
1232
}
1233
else{ /* -list nonempty & +list empty */
1234
if (zerofound){ /* -list,0list nonempty & +list empty */
1235
cone->NegLast->Next=cone->ZeroHead;
1236
cone->LastRay=cone->ZeroLast;
1237
}
1238
else { /* -list nonempty & +list,0list empty */
1239
cone->LastRay=cone->NegLast;
1240
}
1241
}
1242
}
1243
else if (posfound){ /* -list empty & +list nonempty */
1244
cone->FirstRay=cone->PosHead;
1245
if (zerofound){ /* -list empty & +list,0list nonempty */
1246
cone->PosLast->Next=cone->ZeroHead;
1247
cone->LastRay=cone->ZeroLast;
1248
}
1249
else{ /* -list,0list empty & +list nonempty */
1250
cone->LastRay=cone->PosLast;
1251
}
1252
}
1253
else{ /* -list,+list empty & 0list nonempty */
1254
cone->FirstRay=cone->ZeroHead;
1255
cone->LastRay=cone->ZeroLast;
1256
}
1257
cone->ArtificialRay->Next=cone->FirstRay;
1258
cone->LastRay->Next=NULL;
1259
dd_clear(temp); dd_clear(tnext);
1260
_L99:;
1261
}
1262
1263
void dd_DeleteNegativeRays(dd_ConePtr cone)
1264
/* Eliminate the infeasible rays with respect to i which
1265
are supposed to be consecutive from the head of the dd_Ray list,
1266
and sort the zero list assumed to be consecutive at the
1267
end of the list.
1268
*/
1269
{
1270
dd_rowrange fii,fiitest;
1271
mytype temp;
1272
dd_RayPtr Ptr, PrevPtr,NextPtr,ZeroPtr1,ZeroPtr0;
1273
dd_boolean found, completed, zerofound=dd_FALSE,negfound=dd_FALSE,posfound=dd_FALSE;
1274
dd_boolean localdebug=dd_FALSE;
1275
1276
dd_init(temp);
1277
cone->PosHead=NULL;cone->ZeroHead=NULL;cone->NegHead=NULL;
1278
cone->PosLast=NULL;cone->ZeroLast=NULL;cone->NegLast=NULL;
1279
1280
/* Delete the infeasible rays */
1281
PrevPtr= cone->ArtificialRay;
1282
Ptr = cone->FirstRay;
1283
if (PrevPtr->Next != Ptr)
1284
fprintf(stderr,"Error at dd_DeleteNegativeRays: ArtificialRay does not point the FirstRay.\n");
1285
completed=dd_FALSE;
1286
while (Ptr != NULL && !completed){
1287
/* if ( (Ptr->ARay) < -zero ){ */
1288
if ( dd_Negative(Ptr->ARay)){
1289
dd_Eliminate(cone, &PrevPtr);
1290
Ptr=PrevPtr->Next;
1291
}
1292
else{
1293
completed=dd_TRUE;
1294
}
1295
}
1296
1297
/* Sort the zero rays */
1298
Ptr = cone->FirstRay;
1299
cone->ZeroRayCount=0;
1300
while (Ptr != NULL) {
1301
NextPtr=Ptr->Next; /* remember the Next record */
1302
dd_set(temp,Ptr->ARay);
1303
if (localdebug) {fprintf(stderr,"Ptr->ARay :"); dd_WriteNumber(stderr, temp);}
1304
/* if ( temp < -zero) {*/
1305
if ( dd_Negative(temp)) {
1306
if (!negfound){
1307
fprintf(stderr,"Error: An infeasible ray found after their removal\n");
1308
negfound=dd_TRUE;
1309
}
1310
}
1311
/* else if (temp > zero){*/
1312
else if (dd_Positive(temp)){
1313
if (!posfound){
1314
posfound=dd_TRUE;
1315
cone->PosHead=Ptr;
1316
cone->PosLast=Ptr;
1317
}
1318
else{
1319
cone->PosLast=Ptr;
1320
}
1321
}
1322
else {
1323
(cone->ZeroRayCount)++;
1324
if (!zerofound){
1325
zerofound=dd_TRUE;
1326
cone->ZeroHead=Ptr;
1327
cone->ZeroLast=Ptr;
1328
cone->ZeroLast->Next=NULL;
1329
}
1330
else{/* Find a right position to store the record sorted w.r.t. FirstInfeasIndex */
1331
fii=Ptr->FirstInfeasIndex;
1332
found=dd_FALSE;
1333
ZeroPtr1=NULL;
1334
for (ZeroPtr0=cone->ZeroHead; !found && ZeroPtr0!=NULL ; ZeroPtr0=ZeroPtr0->Next){
1335
fiitest=ZeroPtr0->FirstInfeasIndex;
1336
if (fiitest >= fii){
1337
found=dd_TRUE;
1338
}
1339
else ZeroPtr1=ZeroPtr0;
1340
}
1341
/* fprintf(stderr,"insert position found \n %d index %ld\n",found, fiitest); */
1342
if (!found){ /* the new record must be stored at the end of list */
1343
cone->ZeroLast->Next=Ptr;
1344
cone->ZeroLast=Ptr;
1345
cone->ZeroLast->Next=NULL;
1346
}
1347
else{
1348
if (ZeroPtr1==NULL){ /* store the new one at the head, and update the head ptr */
1349
/* fprintf(stderr,"Insert at the head\n"); */
1350
Ptr->Next=cone->ZeroHead;
1351
cone->ZeroHead=Ptr;
1352
}
1353
else{ /* store the new one inbetween ZeroPtr1 and 0 */
1354
/* fprintf(stderr,"Insert inbetween\n"); */
1355
Ptr->Next=ZeroPtr1->Next;
1356
ZeroPtr1->Next=Ptr;
1357
}
1358
}
1359
/*
1360
Ptr->Next=cone->ZeroHead;
1361
cone->ZeroHead=Ptr;
1362
*/
1363
}
1364
}
1365
Ptr=NextPtr;
1366
}
1367
/* joining the pos and zero lists */
1368
if (posfound){ /* -list empty & +list nonempty */
1369
cone->FirstRay=cone->PosHead;
1370
if (zerofound){ /* +list,0list nonempty */
1371
cone->PosLast->Next=cone->ZeroHead;
1372
cone->LastRay=cone->ZeroLast;
1373
}
1374
else{ /* 0list empty & +list nonempty */
1375
cone->LastRay=cone->PosLast;
1376
}
1377
}
1378
else{ /* +list empty & 0list nonempty */
1379
cone->FirstRay=cone->ZeroHead;
1380
cone->LastRay=cone->ZeroLast;
1381
}
1382
cone->ArtificialRay->Next=cone->FirstRay;
1383
cone->LastRay->Next=NULL;
1384
dd_clear(temp);
1385
}
1386
1387
void dd_FeasibilityIndices(long *fnum, long *infnum, dd_rowrange i, dd_ConePtr cone)
1388
{
1389
/*Evaluate the number of feasible rays and infeasible rays*/
1390
/* w.r.t the hyperplane i*/
1391
dd_colrange j;
1392
mytype temp, tnext;
1393
dd_RayPtr Ptr;
1394
1395
dd_init(temp); dd_init(tnext);
1396
*fnum = 0;
1397
*infnum = 0;
1398
Ptr = cone->FirstRay;
1399
while (Ptr != NULL) {
1400
dd_set(temp,dd_purezero);
1401
for (j = 0; j < cone->d; j++){
1402
dd_mul(tnext, cone->A[i - 1][j],Ptr->Ray[j]);
1403
dd_add(temp, temp, tnext);
1404
}
1405
if (dd_Nonnegative(temp))
1406
(*fnum)++;
1407
else
1408
(*infnum)++;
1409
Ptr = Ptr->Next;
1410
}
1411
dd_clear(temp); dd_clear(tnext);
1412
}
1413
1414
dd_boolean dd_LexSmaller(mytype *v1, mytype *v2, long dmax)
1415
{ /* dmax is the size of vectors v1,v2 */
1416
dd_boolean determined, smaller;
1417
dd_colrange j;
1418
1419
smaller = dd_FALSE;
1420
determined = dd_FALSE;
1421
j = 1;
1422
do {
1423
if (!dd_Equal(v1[j - 1],v2[j - 1])) { /* 086 */
1424
if (dd_Smaller(v1[j - 1],v2[j - 1])) { /*086 */
1425
smaller = dd_TRUE;
1426
}
1427
determined = dd_TRUE;
1428
} else
1429
j++;
1430
} while (!(determined) && (j <= dmax));
1431
return smaller;
1432
}
1433
1434
1435
dd_boolean dd_LexLarger(mytype *v1, mytype *v2, long dmax)
1436
{
1437
return dd_LexSmaller(v2, v1, dmax);
1438
}
1439
1440
dd_boolean dd_LexEqual(mytype *v1, mytype *v2, long dmax)
1441
{ /* dmax is the size of vectors v1,v2 */
1442
dd_boolean determined, equal;
1443
dd_colrange j;
1444
1445
equal = dd_TRUE;
1446
determined = dd_FALSE;
1447
j = 1;
1448
do {
1449
if (!dd_Equal(v1[j - 1],v2[j - 1])) { /* 093c */
1450
equal = dd_FALSE;
1451
determined = dd_TRUE;
1452
} else {
1453
j++;
1454
}
1455
} while (!(determined) && (j <= dmax));
1456
return equal;
1457
}
1458
1459
void dd_AddNewHalfspace1(dd_ConePtr cone, dd_rowrange hnew)
1460
/* This procedure 1 must be used with PreorderedRun=dd_FALSE
1461
This procedure is the most elementary implementation of
1462
DD and can be used with any type of ordering, including
1463
dynamic ordering of rows, e.g. MaxCutoff, MinCutoff.
1464
The memory requirement is minimum because it does not
1465
store any adjacency among the rays.
1466
*/
1467
{
1468
dd_RayPtr RayPtr0,RayPtr1,RayPtr2,RayPtr2s,RayPtr3;
1469
long pos1, pos2;
1470
double prevprogress, progress;
1471
mytype value1, value2;
1472
dd_boolean adj, equal, completed;
1473
1474
dd_init(value1); dd_init(value2);
1475
dd_EvaluateARay1(hnew, cone);
1476
/*Check feasibility of rays w.r.t. hnew
1477
and put all infeasible ones consecutively */
1478
1479
RayPtr0 = cone->ArtificialRay; /*Pointer pointing RayPrt1*/
1480
RayPtr1 = cone->FirstRay; /*1st hnew-infeasible ray to scan and compare with feasible rays*/
1481
dd_set(value1,cone->FirstRay->ARay);
1482
if (dd_Nonnegative(value1)) {
1483
if (cone->RayCount==cone->WeaklyFeasibleRayCount) cone->CompStatus=dd_AllFound;
1484
goto _L99; /* Sicne there is no hnew-infeasible ray and nothing to do */
1485
}
1486
else {
1487
RayPtr2s = RayPtr1->Next;/* RayPtr2s must point the first feasible ray */
1488
pos2=1;
1489
while (RayPtr2s!=NULL && dd_Negative(RayPtr2s->ARay)) {
1490
RayPtr2s = RayPtr2s->Next;
1491
pos2++;
1492
}
1493
}
1494
if (RayPtr2s==NULL) {
1495
cone->FirstRay=NULL;
1496
cone->ArtificialRay->Next=cone->FirstRay;
1497
cone->RayCount=0;
1498
cone->CompStatus=dd_AllFound;
1499
goto _L99; /* All rays are infeasible, and the computation must stop */
1500
}
1501
RayPtr2 = RayPtr2s; /*2nd feasible ray to scan and compare with 1st*/
1502
RayPtr3 = cone->LastRay; /*Last feasible for scanning*/
1503
prevprogress=-10.0;
1504
pos1 = 1;
1505
completed=dd_FALSE;
1506
while ((RayPtr1 != RayPtr2s) && !completed) {
1507
dd_set(value1,RayPtr1->ARay);
1508
dd_set(value2,RayPtr2->ARay);
1509
dd_CheckEquality(cone->d, &RayPtr1, &RayPtr2, &equal);
1510
if ((dd_Positive(value1) && dd_Negative(value2)) || (dd_Negative(value1) && dd_Positive(value2))){
1511
dd_CheckAdjacency(cone, &RayPtr1, &RayPtr2, &adj);
1512
if (adj) dd_CreateNewRay(cone, RayPtr1, RayPtr2, hnew);
1513
}
1514
if (RayPtr2 != RayPtr3) {
1515
RayPtr2 = RayPtr2->Next;
1516
continue;
1517
}
1518
if (dd_Negative(value1) || equal) {
1519
dd_Eliminate(cone, &RayPtr0);
1520
RayPtr1 = RayPtr0->Next;
1521
RayPtr2 = RayPtr2s;
1522
} else {
1523
completed=dd_TRUE;
1524
}
1525
pos1++;
1526
progress = 100.0 * ((double)pos1 / pos2) * (2.0 * pos2 - pos1) / pos2;
1527
if (progress-prevprogress>=10 && pos1%10==0 && dd_debug) {
1528
fprintf(stderr,"*Progress of iteration %5ld(/%ld): %4ld/%4ld => %4.1f%% done\n",
1529
cone->Iteration, cone->m, pos1, pos2, progress);
1530
prevprogress=progress;
1531
}
1532
}
1533
if (cone->RayCount==cone->WeaklyFeasibleRayCount) cone->CompStatus=dd_AllFound;
1534
_L99:;
1535
dd_clear(value1); dd_clear(value2);
1536
}
1537
1538
void dd_AddNewHalfspace2(dd_ConePtr cone, dd_rowrange hnew)
1539
/* This procedure must be used under PreOrderedRun mode */
1540
{
1541
dd_RayPtr RayPtr0,RayPtr1,RayPtr2;
1542
dd_AdjacencyType *EdgePtr, *EdgePtr0;
1543
long pos1;
1544
dd_rowrange fii1, fii2;
1545
dd_boolean localdebug=dd_FALSE;
1546
1547
dd_EvaluateARay2(hnew, cone);
1548
/* Check feasibility of rays w.r.t. hnew
1549
and sort them. ( -rays, +rays, 0rays)*/
1550
1551
if (cone->PosHead==NULL && cone->ZeroHead==NULL) {
1552
cone->FirstRay=NULL;
1553
cone->ArtificialRay->Next=cone->FirstRay;
1554
cone->RayCount=0;
1555
cone->CompStatus=dd_AllFound;
1556
goto _L99; /* All rays are infeasible, and the computation must stop */
1557
}
1558
1559
if (localdebug){
1560
pos1=0;
1561
fprintf(stderr,"(pos, FirstInfeasIndex, A Ray)=\n");
1562
for (RayPtr0=cone->FirstRay; RayPtr0!=NULL; RayPtr0=RayPtr0->Next){
1563
pos1++;
1564
fprintf(stderr,"(%ld,%ld,",pos1,RayPtr0->FirstInfeasIndex);
1565
dd_WriteNumber(stderr,RayPtr0->ARay);
1566
fprintf(stderr,") ");
1567
}
1568
fprintf(stderr,"\n");
1569
}
1570
1571
if (cone->ZeroHead==NULL) cone->ZeroHead=cone->LastRay;
1572
1573
EdgePtr=cone->Edges[cone->Iteration];
1574
while (EdgePtr!=NULL){
1575
RayPtr1=EdgePtr->Ray1;
1576
RayPtr2=EdgePtr->Ray2;
1577
fii1=RayPtr1->FirstInfeasIndex;
1578
dd_CreateNewRay(cone, RayPtr1, RayPtr2, hnew);
1579
fii2=cone->LastRay->FirstInfeasIndex;
1580
if (fii1 != fii2)
1581
dd_ConditionalAddEdge(cone,RayPtr1,cone->LastRay,cone->PosHead);
1582
EdgePtr0=EdgePtr;
1583
EdgePtr=EdgePtr->Next;
1584
free(EdgePtr0);
1585
(cone->EdgeCount)--;
1586
}
1587
cone->Edges[cone->Iteration]=NULL;
1588
1589
dd_DeleteNegativeRays(cone);
1590
1591
set_addelem(cone->AddedHalfspaces, hnew);
1592
1593
if (cone->Iteration<cone->m){
1594
if (cone->ZeroHead!=NULL && cone->ZeroHead!=cone->LastRay){
1595
if (cone->ZeroRayCount>200 && dd_debug) fprintf(stderr,"*New edges being scanned...\n");
1596
dd_UpdateEdges(cone, cone->ZeroHead, cone->LastRay);
1597
}
1598
}
1599
1600
if (cone->RayCount==cone->WeaklyFeasibleRayCount) cone->CompStatus=dd_AllFound;
1601
_L99:;
1602
}
1603
1604
1605
void dd_SelectNextHalfspace0(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hnext)
1606
{
1607
/*A natural way to choose the next hyperplane. Simply the largest index*/
1608
long i;
1609
dd_boolean determined;
1610
1611
i = cone->m;
1612
determined = dd_FALSE;
1613
do {
1614
if (set_member(i, excluded))
1615
i--;
1616
else
1617
determined = dd_TRUE;
1618
} while (!determined && i>=1);
1619
if (determined)
1620
*hnext = i;
1621
else
1622
*hnext = 0;
1623
}
1624
1625
void dd_SelectNextHalfspace1(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hnext)
1626
{
1627
/*Natural way to choose the next hyperplane. Simply the least index*/
1628
long i;
1629
dd_boolean determined;
1630
1631
i = 1;
1632
determined = dd_FALSE;
1633
do {
1634
if (set_member(i, excluded))
1635
i++;
1636
else
1637
determined = dd_TRUE;
1638
} while (!determined && i<=cone->m);
1639
if (determined)
1640
*hnext = i;
1641
else
1642
*hnext=0;
1643
}
1644
1645
void dd_SelectNextHalfspace2(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hnext)
1646
{
1647
/*Choose the next hyperplane with maximum infeasibility*/
1648
long i, fea, inf, infmin, fi=0; /*feasibility and infeasibility numbers*/
1649
1650
infmin = cone->RayCount + 1;
1651
for (i = 1; i <= cone->m; i++) {
1652
if (!set_member(i, excluded)) {
1653
dd_FeasibilityIndices(&fea, &inf, i, cone);
1654
if (inf < infmin) {
1655
infmin = inf;
1656
fi = fea;
1657
*hnext = i;
1658
}
1659
}
1660
}
1661
if (dd_debug) {
1662
fprintf(stderr,"*infeasible rays (min) =%5ld, #feas rays =%5ld\n", infmin, fi);
1663
}
1664
}
1665
1666
void dd_SelectNextHalfspace3(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hnext)
1667
{
1668
/*Choose the next hyperplane with maximum infeasibility*/
1669
long i, fea, inf, infmax, fi=0; /*feasibility and infeasibility numbers*/
1670
dd_boolean localdebug=dd_debug;
1671
1672
infmax = -1;
1673
for (i = 1; i <= cone->m; i++) {
1674
if (!set_member(i, excluded)) {
1675
dd_FeasibilityIndices(&fea, &inf, i, cone);
1676
if (inf > infmax) {
1677
infmax = inf;
1678
fi = fea;
1679
*hnext = i;
1680
}
1681
}
1682
}
1683
if (localdebug) {
1684
fprintf(stderr,"*infeasible rays (max) =%5ld, #feas rays =%5ld\n", infmax, fi);
1685
}
1686
}
1687
1688
void dd_SelectNextHalfspace4(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hnext)
1689
{
1690
/*Choose the next hyperplane with the most unbalanced cut*/
1691
long i, fea, inf, max, tmax, fi=0, infi=0;
1692
/*feasibility and infeasibility numbers*/
1693
1694
max = -1;
1695
for (i = 1; i <= cone->m; i++) {
1696
if (!set_member(i, excluded)) {
1697
dd_FeasibilityIndices(&fea, &inf, i, cone);
1698
if (fea <= inf)
1699
tmax = inf;
1700
else
1701
tmax = fea;
1702
if (tmax > max) {
1703
max = tmax;
1704
fi = fea;
1705
infi = inf;
1706
*hnext = i;
1707
}
1708
}
1709
}
1710
if (!dd_debug)
1711
return;
1712
if (max == fi) {
1713
fprintf(stderr,"*infeasible rays (min) =%5ld, #feas rays =%5ld\n", infi, fi);
1714
} else {
1715
fprintf(stderr,"*infeasible rays (max) =%5ld, #feas rays =%5ld\n", infi, fi);
1716
}
1717
}
1718
1719
void dd_SelectNextHalfspace5(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hnext)
1720
{
1721
/*Choose the next hyperplane which is lexico-min*/
1722
long i, minindex;
1723
mytype *v1, *v2;
1724
1725
minindex = 0;
1726
v1 = NULL;
1727
for (i = 1; i <= cone->m; i++) {
1728
if (!set_member(i, excluded)) {
1729
v2 = cone->A[i - 1];
1730
if (minindex == 0) {
1731
minindex = i;
1732
v1=v2;
1733
} else if (dd_LexSmaller(v2,v1,cone->d)) {
1734
minindex = i;
1735
v1=v2;
1736
}
1737
}
1738
}
1739
*hnext = minindex;
1740
}
1741
1742
1743
void dd_SelectNextHalfspace6(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hnext)
1744
{
1745
/*Choose the next hyperplane which is lexico-max*/
1746
long i, maxindex;
1747
mytype *v1, *v2;
1748
1749
maxindex = 0;
1750
v1 = NULL;
1751
for (i = 1; i <= cone->m; i++) {
1752
if (!set_member(i, excluded)) {
1753
v2= cone->A[i - 1];
1754
if (maxindex == 0) {
1755
maxindex = i;
1756
v1=v2;
1757
} else if (dd_LexLarger(v2, v1, cone->d)) {
1758
maxindex = i;
1759
v1=v2;
1760
}
1761
}
1762
}
1763
*hnext = maxindex;
1764
}
1765
1766
void dd_UniqueRows(dd_rowindex OV, long p, long r, dd_Amatrix A, long dmax, dd_rowset preferred, long *uniqrows)
1767
{
1768
/* Select a subset of rows of A (with range [p, q] up to dimension dmax) by removing duplicates.
1769
When a row subset preferred is nonempty, those row indices in the set have priority. If
1770
two priority rows define the same row vector, one is chosen.
1771
For a selected unique row i, OV[i] returns a new position of the unique row i.
1772
For other nonuniqu row i, OV[i] returns a negative of the original row j dominating i.
1773
Thus the original contents of OV[p..r] will be rewritten. Other components remain the same.
1774
*uniqrows returns the number of unique rows.
1775
*/
1776
long i,iuniq,j;
1777
mytype *x;
1778
dd_boolean localdebug=dd_FALSE;
1779
1780
if (p<=0 || p > r) goto _L99;
1781
iuniq=p; j=1; /* the first unique row candidate */
1782
x=A[p-1];
1783
OV[p]=j; /* tentative row index of the candidate */
1784
for (i=p+1;i<=r; i++){
1785
if (!dd_LexEqual(x,A[i-1],dmax)) {
1786
/* a new row vector found. */
1787
iuniq=i;
1788
j=j+1;
1789
OV[i]=j; /* Tentatively register the row i. */
1790
x=A[i-1];
1791
} else {
1792
/* rows are equal */
1793
if (set_member(i, preferred) && !set_member(iuniq, preferred)){
1794
OV[iuniq]=-i; /* the row iuniq is dominated by the row i */
1795
iuniq=i; /* the row i is preferred. Change the candidate. */
1796
OV[i]=j; /* the row i is tentatively registered. */
1797
x=A[i-1];
1798
} else {
1799
OV[i]=-iuniq; /* the row iuniq is dominated by the row i */
1800
}
1801
}
1802
}
1803
*uniqrows=j;
1804
if (localdebug){
1805
printf("The number of unique rows are %ld\n with order vector",*uniqrows);
1806
for (i=p;i<=r; i++){
1807
printf(" %ld:%ld ",i,OV[i]);
1808
}
1809
printf("\n");
1810
}
1811
_L99:;
1812
}
1813
1814
long dd_Partition(dd_rowindex OV, long p, long r, dd_Amatrix A, long dmax)
1815
{
1816
mytype *x;
1817
long i,j,ovi;
1818
1819
x=A[OV[p]-1];
1820
1821
i=p-1;
1822
j=r+1;
1823
while (dd_TRUE){
1824
do{
1825
j--;
1826
} while (dd_LexLarger(A[OV[j]-1],x,dmax));
1827
do{
1828
i++;
1829
} while (dd_LexSmaller(A[OV[i]-1],x,dmax));
1830
if (i<j){
1831
ovi=OV[i];
1832
OV[i]=OV[j];
1833
OV[j]=ovi;
1834
}
1835
else{
1836
return j;
1837
}
1838
}
1839
}
1840
1841
void dd_QuickSort(dd_rowindex OV, long p, long r, dd_Amatrix A, long dmax)
1842
{
1843
long q;
1844
1845
if (p < r){
1846
q = dd_Partition(OV, p, r, A, dmax);
1847
dd_QuickSort(OV, p, q, A, dmax);
1848
dd_QuickSort(OV, q+1, r, A, dmax);
1849
}
1850
}
1851
1852
1853
void dd_RandomPermutation(dd_rowindex OV, long t, unsigned int seed)
1854
{
1855
long k,j,ovj;
1856
double u,xk,r,rand_max=(double) RAND_MAX;
1857
dd_boolean localdebug=dd_FALSE;
1858
1859
portable_srand(seed);
1860
for (j=t; j>1 ; j--) {
1861
r=portable_rand();
1862
u=r/rand_max;
1863
xk=(double)(j*u +1);
1864
k=(long)xk;
1865
if (localdebug) fprintf(stderr,"u=%g, k=%ld, r=%g, randmax= %g\n",u,k,r,rand_max);
1866
ovj=OV[j];
1867
OV[j]=OV[k];
1868
OV[k]=ovj;
1869
if (localdebug) fprintf(stderr,"row %ld is exchanged with %ld\n",j,k);
1870
}
1871
}
1872
1873
void dd_ComputeRowOrderVector(dd_ConePtr cone)
1874
{
1875
long i,itemp;
1876
1877
cone->OrderVector[0]=0;
1878
switch (cone->HalfspaceOrder){
1879
case dd_MaxIndex:
1880
for(i=1; i<=cone->m; i++) cone->OrderVector[i]=cone->m-i+1;
1881
break;
1882
1883
case dd_MinIndex:
1884
for(i=1; i<=cone->m; i++) cone->OrderVector[i]=i;
1885
break;
1886
1887
case dd_LexMin: case dd_MinCutoff: case dd_MixCutoff: case dd_MaxCutoff:
1888
for(i=1; i<=cone->m; i++) cone->OrderVector[i]=i;
1889
dd_RandomPermutation(cone->OrderVector, cone->m, cone->rseed);
1890
dd_QuickSort(cone->OrderVector, 1, cone->m, cone->A, cone->d);
1891
break;
1892
1893
case dd_LexMax:
1894
for(i=1; i<=cone->m; i++) cone->OrderVector[i]=i;
1895
dd_RandomPermutation(cone->OrderVector, cone->m, cone->rseed);
1896
dd_QuickSort(cone->OrderVector, 1, cone->m, cone->A, cone->d);
1897
for(i=1; i<=cone->m/2;i++){ /* just reverse the order */
1898
itemp=cone->OrderVector[i];
1899
cone->OrderVector[i]=cone->OrderVector[cone->m-i+1];
1900
cone->OrderVector[cone->m-i+1]=itemp;
1901
}
1902
break;
1903
1904
case dd_RandomRow:
1905
for(i=1; i<=cone->m; i++) cone->OrderVector[i]=i;
1906
dd_RandomPermutation(cone->OrderVector, cone->m, cone->rseed);
1907
break;
1908
1909
}
1910
}
1911
1912
void dd_UpdateRowOrderVector(dd_ConePtr cone, dd_rowset PriorityRows)
1913
/* Update the RowOrder vector to shift selected rows
1914
in highest order.
1915
*/
1916
{
1917
dd_rowrange i,j,k,j1=0,oj=0;
1918
long rr;
1919
dd_boolean found, localdebug=dd_FALSE;
1920
1921
if (dd_debug) localdebug=dd_TRUE;
1922
found=dd_TRUE;
1923
rr=set_card(PriorityRows);
1924
if (localdebug) set_fwrite(stderr,PriorityRows);
1925
for (i=1; i<=rr; i++){
1926
found=dd_FALSE;
1927
for (j=i; j<=cone->m && !found; j++){
1928
oj=cone->OrderVector[j];
1929
if (set_member(oj, PriorityRows)){
1930
found=dd_TRUE;
1931
if (localdebug) fprintf(stderr,"%ldth in sorted list (row %ld) is in PriorityRows\n", j, oj);
1932
j1=j;
1933
}
1934
}
1935
if (found){
1936
if (j1>i) {
1937
/* shift everything lower: ov[i]->cone->ov[i+1]..ov[j1-1]->cone->ov[j1] */
1938
for (k=j1; k>=i; k--) cone->OrderVector[k]=cone->OrderVector[k-1];
1939
cone->OrderVector[i]=oj;
1940
if (localdebug){
1941
fprintf(stderr,"OrderVector updated to:\n");
1942
for (j = 1; j <= cone->m; j++) fprintf(stderr," %2ld", cone->OrderVector[j]);
1943
fprintf(stderr,"\n");
1944
}
1945
}
1946
} else {
1947
fprintf(stderr,"UpdateRowOrder: Error.\n");
1948
goto _L99;
1949
}
1950
}
1951
_L99:;
1952
}
1953
1954
void dd_SelectPreorderedNext(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hh)
1955
{
1956
dd_rowrange i,k;
1957
1958
*hh=0;
1959
for (i=1; i<=cone->m && *hh==0; i++){
1960
k=cone->OrderVector[i];
1961
if (!set_member(k, excluded)) *hh=k ;
1962
}
1963
}
1964
1965
void dd_SelectNextHalfspace(dd_ConePtr cone, dd_rowset excluded, dd_rowrange *hh)
1966
{
1967
if (cone->PreOrderedRun){
1968
if (dd_debug) {
1969
fprintf(stderr,"debug dd_SelectNextHalfspace: Use PreorderNext\n");
1970
}
1971
dd_SelectPreorderedNext(cone, excluded, hh);
1972
}
1973
else {
1974
if (dd_debug) {
1975
fprintf(stderr,"debug dd_SelectNextHalfspace: Use DynamicOrderedNext\n");
1976
}
1977
1978
switch (cone->HalfspaceOrder) {
1979
1980
case dd_MaxIndex:
1981
dd_SelectNextHalfspace0(cone, excluded, hh);
1982
break;
1983
1984
case dd_MinIndex:
1985
dd_SelectNextHalfspace1(cone, excluded, hh);
1986
break;
1987
1988
case dd_MinCutoff:
1989
dd_SelectNextHalfspace2(cone, excluded, hh);
1990
break;
1991
1992
case dd_MaxCutoff:
1993
dd_SelectNextHalfspace3(cone, excluded, hh);
1994
break;
1995
1996
case dd_MixCutoff:
1997
dd_SelectNextHalfspace4(cone, excluded, hh);
1998
break;
1999
2000
default:
2001
dd_SelectNextHalfspace0(cone, excluded, hh);
2002
break;
2003
}
2004
}
2005
}
2006
2007
dd_boolean dd_Nonnegative(mytype val)
2008
{
2009
/* if (val>=-dd_zero) return dd_TRUE; */
2010
if (dd_cmp(val,dd_minuszero)>=0) return dd_TRUE;
2011
else return dd_FALSE;
2012
}
2013
2014
dd_boolean dd_Nonpositive(mytype val)
2015
{
2016
/* if (val<=dd_zero) return dd_TRUE; */
2017
if (dd_cmp(val,dd_zero)<=0) return dd_TRUE;
2018
else return dd_FALSE;
2019
}
2020
2021
dd_boolean dd_Positive(mytype val)
2022
{
2023
return !dd_Nonpositive(val);
2024
}
2025
2026
dd_boolean dd_Negative(mytype val)
2027
{
2028
return !dd_Nonnegative(val);
2029
}
2030
2031
dd_boolean dd_EqualToZero(mytype val)
2032
{
2033
return (dd_Nonnegative(val) && dd_Nonpositive(val));
2034
}
2035
2036
dd_boolean dd_Nonzero(mytype val)
2037
{
2038
return (dd_Positive(val) || dd_Negative(val));
2039
}
2040
2041
dd_boolean dd_Equal(mytype val1,mytype val2)
2042
{
2043
return (!dd_Larger(val1,val2) && !dd_Smaller(val1,val2));
2044
}
2045
2046
dd_boolean dd_Larger(mytype val1,mytype val2)
2047
{
2048
mytype temp;
2049
dd_boolean answer;
2050
2051
dd_init(temp);
2052
dd_sub(temp,val1, val2);
2053
answer=dd_Positive(temp);
2054
dd_clear(temp);
2055
return answer;
2056
}
2057
2058
dd_boolean dd_Smaller(mytype val1,mytype val2)
2059
{
2060
return dd_Larger(val2,val1);
2061
}
2062
2063
void dd_abs(mytype absval, mytype val)
2064
{
2065
if (dd_Negative(val)) dd_neg(absval,val);
2066
else dd_set(absval,val);
2067
}
2068
2069
void dd_LinearComb(mytype lc, mytype v1, mytype c1, mytype v2, mytype c2)
2070
/* lc := v1 * c1 + v2 * c2 */
2071
{
2072
mytype temp;
2073
2074
dd_init(temp);
2075
dd_mul(lc,v1,c1);
2076
dd_mul(temp,v2,c2);
2077
dd_add(lc,lc,temp);
2078
dd_clear(temp);
2079
}
2080
2081
void dd_InnerProduct(mytype prod, dd_colrange d, dd_Arow v1, dd_Arow v2)
2082
{
2083
mytype temp;
2084
dd_colrange j;
2085
dd_boolean localdebug=dd_FALSE;
2086
2087
dd_init(temp);
2088
dd_set_si(prod, 0);
2089
for (j = 0; j < d; j++){
2090
dd_mul(temp,v1[j],v2[j]);
2091
dd_add(prod,prod,temp);
2092
}
2093
if (localdebug) {
2094
fprintf(stderr,"InnerProduct:\n");
2095
dd_WriteArow(stderr, v1, d);
2096
dd_WriteArow(stderr, v2, d);
2097
fprintf(stderr,"prod =");
2098
dd_WriteNumber(stderr, prod);
2099
fprintf(stderr,"\n");
2100
}
2101
2102
dd_clear(temp);
2103
}
2104
2105
/* end of cddcore.c */
2106
2107
2108
2109