9
//--------------------------------------------------
10
// LpSolverCdd (double precision)
11
//--------------------------------------------------
13
static ddf_MatrixPtr vectorList2Matrix(int n, const IntegerVectorList &g, ddf_ErrorType *Error)
16
ddf_rowrange m_input,i;
17
ddf_colrange d_input,j;
18
ddf_RepresentationType rep=ddf_Inequality;
19
ddf_boolean found=ddf_FALSE, newformat=ddf_FALSE, successful=ddf_FALSE;
20
char command[ddf_linelenmax], comsave[ddf_linelenmax];
25
rep=ddf_Inequality; newformat=ddf_TRUE;
28
d_input=n+1;//g.begin()->size()+1;
32
M=ddf_CreateMatrix(m_input, d_input);
33
M->representation=rep;
36
IntegerVectorList::const_iterator I=g.begin();
37
for (i = 0; i < m_input; i++) {
38
ddf_set_si(M->matrix[i][0],0);
39
for (j = 1; j < d_input; j++) {
40
ddf_set_si(M->matrix[i][j],(*I)[j-1]);
52
static bool initialized;
55
ddf_set_global_constants(); /* First, this must be called. */
60
bool LpSolverCdd::isFacet(const IntegerVectorList &g, IntegerVectorList::const_iterator i)
64
ddf_MatrixPtr M=NULL,M2=NULL,M3=NULL;
66
ddf_ErrorType err=ddf_NoError;
67
ddf_rowset redrows,linrows,ignoredrows, basisrows;
68
ddf_colset ignoredcols, basiscols;
71
ddf_DataFileType inputfile;
79
M=vectorList2Matrix(i->size(), g, &err);
81
if (err!=ddf_NoError) goto _L99;
85
// redrows=ddf_RedundantRows(M, &err);
86
// set_fwrite(Stderr, redrows);
90
for(IntegerVectorList::const_iterator J=g.begin();J!=g.end()&&J!=i;J++){index++;}
91
if(index==g.size())assert(0);
96
ddf_InitializeArow(i->size()+1,&temp);
98
ret= !ddf_Redundant(M,index+1,temp,&err);
101
ddf_FreeArow(i->size()+1,temp);
102
// ddf_FreeArow(i->size(),temp);
104
if (err!=ddf_NoError) goto _L99;
112
static LpSolverCdd theLpSolverCdd;
115
//--------------------------------------------------
116
// LpSolverCddGmp (exact arithmetics)
117
//--------------------------------------------------
120
static void cddinitGmp()
122
static bool initialized;
125
dd_set_global_constants(); /* First, this must be called. */
131
static dd_MatrixPtr vectorList2MatrixGmp(int n, const IntegerVectorList &g, dd_ErrorType *Error)
134
dd_rowrange m_input,i;
135
dd_colrange d_input,j;
136
dd_RepresentationType rep=dd_Inequality;
137
dd_boolean found=dd_FALSE, newformat=dd_FALSE, successful=dd_FALSE;
138
char command[dd_linelenmax], comsave[dd_linelenmax];
143
rep=dd_Inequality; newformat=dd_TRUE;
151
// d_input=g.begin()->size()+1;
155
if(g.begin()->size()!=n)
157
AsciiPrinter(Stderr).printVectorList(g);
161
assert(g.begin()->size()==n);
166
M=dd_CreateMatrix(m_input, d_input);
167
M->representation=rep;
170
IntegerVectorList::const_iterator I=g.begin();
171
for (i = 0; i < m_input; i++) {
172
dd_set_si(M->matrix[i][0],0);
173
for (j = 1; j < d_input; j++) {
174
dd_set_si(M->matrix[i][j],(*I)[j-1]);
185
static dd_MatrixPtr vectorList2MatrixIncludingFirstColumnGmp(int n, const IntegerVectorList &inequalities, const IntegerVectorList &equations, dd_ErrorType *Error)
188
dd_rowrange m_input,i;
189
dd_colrange d_input,j;
190
dd_RepresentationType rep=dd_Inequality;
191
dd_boolean found=dd_FALSE, newformat=dd_FALSE, successful=dd_FALSE;
192
// char command[dd_linelenmax], comsave[dd_linelenmax];
197
int numberOfEquations=equations.size();
198
int numberOfInequalities=inequalities.size();
199
m_input=numberOfEquations+numberOfInequalities;
202
rep=dd_Inequality; newformat=dd_TRUE;
209
M=dd_CreateMatrix(m_input, d_input);
210
M->representation=rep;
213
IntegerVectorList::const_iterator I=inequalities.begin();
214
for (i = 0; i < numberOfInequalities; i++) {
215
for (j = 0; j < d_input; j++)dd_set_si(M->matrix[i][j],(*I)[j]);
219
for (; i < m_input; i++) {
220
set_addelem(M->linset, i+1);
221
for (j = 0; j < d_input; j++)dd_set_si(M->matrix[i][j],(*I)[j]);
230
bool LpSolverCddGmp::hasHomogeneousSolution(int n, const IntegerVectorList &inequalities, const IntegerVectorList &equations)
232
if(n==0)return false;
233
int nrows=inequalities.size()+equations.size();
234
if(nrows==0)return true;
236
dd_LPSolverType solver=dd_DualSimplex;
238
dd_LPSolutionPtr lps1;
239
dd_ErrorType err=dd_NoError;
245
A=vectorList2MatrixIncludingFirstColumnGmp(n, inequalities, equations, &err);
247
if (err!=dd_NoError) goto _L99;
249
A->objective=dd_LPmax;
250
lp=dd_Matrix2LP(A, &err);
251
if (err!=dd_NoError) goto _L99;
254
// dd_WriteMatrix(Stderr,A);
256
/* Find an interior point with cdd LP library. */
258
lp1=dd_MakeLPforInteriorFinding(lp);
259
dd_LPSolve(lp1,solver,&err);
260
if (err!=dd_NoError) goto _L99;
262
// dd_WriteMatrix(Stderr,A);
263
// dd_WriteLP(Stderr,lp);
264
// dd_WriteLP(Stderr,lp1);
266
/* Write an interior point. */
267
lps1=dd_CopyLPSolution(lp1);
268
// dd_WriteLPSolution(Stderr,lps1);
271
for (int j=1; j <(lps1->d); j++) {
272
if(j!=1)fprintf(Stderr,", ");
273
dd_WriteNumber(Stderr,lps1->sol[j]);
275
fprintf(Stderr,")\n");
278
// dd_WriteNumber(Stderr,lps1->optvalue);
280
if(dd_Positive(lps1->optvalue))ret=1;
281
if(dd_Negative(lps1->optvalue))ret=-1;
283
// fprintf(Stderr,"ret=%i",ret);
286
dd_FreeLPSolution(lps1);
297
bool LpSolverCddGmp::isFacet(const IntegerVectorList &g, IntegerVectorList::const_iterator i)
301
dd_MatrixPtr M=NULL,M2=NULL,M3=NULL;
303
dd_ErrorType err=dd_NoError;
304
dd_rowset redrows,linrows,ignoredrows, basisrows;
305
dd_colset ignoredcols, basiscols;
308
dd_DataFileType inputfile;
317
M=vectorList2MatrixGmp(i->size(),g, &err);
319
if (err!=dd_NoError) goto _L99;
323
// redrows=dd_RedundantRows(M, &err);
324
// set_fwrite(Stderr, redrows);
328
for(IntegerVectorList::const_iterator J=g.begin();J!=g.end()&&J!=i;J++){index++;}
329
if(index==g.size())assert(0);
334
dd_InitializeArow(i->size()+1,&temp);
336
ret= !dd_Redundant(M,index+1,temp,&err);
340
dd_FreeArow(i->size()+1,temp);
342
if (err!=dd_NoError) goto _L99;
350
int staticInteriorPoint(int n, mpq_t *point, const IntegerVectorList &g, bool strictlyPositive, IntegerVector const *equalitySet=0)
351
{// copy-paste from testshoot.c in cdd
352
// AsciiPrinter(Stderr).printVectorList(g);
353
// fprintf(Stderr,"strictlyPositive:%i\n",strictlyPositive);
355
//if(equalitySet) AsciiPrinter(Stderr).printVector(*equalitySet);
356
dd_LPSolverType solver=dd_DualSimplex;
358
dd_LPSolutionPtr lps1;
359
dd_ErrorType err=dd_NoError;
365
assert(g.begin()!=g.end());
368
int n=g.begin()->size();
369
IntegerVectorList G=g;
371
G.push_back(IntegerVector::standardVector(n,i));
372
A=vectorList2MatrixGmp(n,G, &err);
375
A=vectorList2MatrixGmp(n, g, &err);
376
if (err!=dd_NoError) goto _L99;
380
for(int i=0;i<g.size();i++)
381
if(!(*equalitySet)[i])
382
dd_set_si(A->matrix[i][0],-1);
384
assert(g.size()>=equalitySet->size());
386
for(int i=0;i<equalitySet->size();i++)
387
if((*equalitySet)[i])set_addelem(A->linset, i+1);
390
A->objective=dd_LPmax;
391
lp=dd_Matrix2LP(A, &err);
392
if (err!=dd_NoError) goto _L99;
395
// dd_WriteMatrix(Stderr,A);
397
/* Find an interior point with cdd LP library. */
399
lp1=dd_MakeLPforInteriorFinding(lp);
400
dd_LPSolve(lp1,solver,&err);
401
if (err!=dd_NoError) goto _L99;
403
// dd_WriteMatrix(Stderr,A);
404
// dd_WriteLP(Stderr,lp1);
406
/* Write an interior point. */
407
lps1=dd_CopyLPSolution(lp1);
409
if(dd_Positive(lps1->optvalue))ret=1;
410
if(dd_Negative(lps1->optvalue))ret=-1;
412
// fprintf(Stderr,"ret=%i",ret);
416
for (int j=1; j <(lps1->d)-1; j++)
417
mpq_set(point[j-1],lps1->sol[j]);
420
dd_FreeLPSolution(lps1);
429
int staticRelativeInteriorPoint(int n, mpq_t *point, const IntegerVectorList &g, bool strictlyPositive, IntegerVector const *equalitySet=0)
430
{// copy-paste from testshoot.c in cdd
431
// AsciiPrinter(Stderr).printVectorList(g);
432
// fprintf(Stderr,"strictlyPositive:%i\n",strictlyPositive);
434
//if(equalitySet) AsciiPrinter(Stderr).printVector(*equalitySet);
435
dd_LPSolverType solver=dd_DualSimplex;
437
dd_LPSolutionPtr lps1;
438
dd_ErrorType err=dd_NoError;
444
// assert(g.begin()!=g.end());
447
// int n=g.begin()->size();
448
IntegerVectorList G=g;
450
G.push_back(IntegerVector::standardVector(n,i));
451
A=vectorList2MatrixGmp(n, G, &err);
454
A=vectorList2MatrixGmp(n, g, &err);
455
if (err!=dd_NoError) goto _L99;
459
for(int i=0;i<g.size();i++)
460
if(!(*equalitySet)[i])
461
dd_set_si(A->matrix[i][0],-1);
463
assert(g.size()>=equalitySet->size());
465
for(int i=0;i<equalitySet->size();i++)
466
if((*equalitySet)[i])set_addelem(A->linset, i+1);
469
A->objective=dd_LPmax;
470
lp=dd_Matrix2LP(A, &err);
471
if (err!=dd_NoError) goto _L99;
474
// dd_WriteMatrix(Stderr,A);
476
/* Find an interior point with cdd LP library. */
478
lp1=dd_MakeLPforInteriorFinding(lp);
479
dd_LPSolve(lp1,solver,&err);
480
if (err!=dd_NoError) goto _L99;
482
// dd_WriteMatrix(Stderr,A);
483
// dd_WriteLP(Stderr,lp1);
485
/* Write an interior point. */
486
lps1=dd_CopyLPSolution(lp1);
488
if(dd_Positive(lps1->optvalue))ret=1;
489
if(dd_Negative(lps1->optvalue))ret=-1;
491
// fprintf(Stderr,"ret=%i",ret);
495
for (int j=1; j <(lps1->d)-1; j++)
496
mpq_set(point[j-1],lps1->sol[j]);
499
dd_FreeLPSolution(lps1);
508
bool LpSolverCddGmp::hasInteriorPoint(const IntegerVectorList &g, bool strictlyPositive, IntegerVector const *equalitySet)
511
int n=g.begin()->size();
512
mpq_t *point = new mpq_t [n];
513
for(int i=0;i<n;i++)mpq_init(point[i]);
515
int ret=staticInteriorPoint(n, point,g,strictlyPositive,equalitySet);
517
// fprintf(Stderr,"%i\n",ret);
519
for(int i=0;i<n;i++)mpq_clear(point[i]);
522
if(equalitySet)return ret>=0; //THIS NEEDS TO BE FIXED
527
IntegerVector arrayToIntegerVector(mpq_t *point, int n)
529
IntegerVector ret(n);
531
for (int j=0; j <n; j++)
536
if((!mpz_fits_sint_p(mpq_denref(point[j])))||(!mpz_fits_sint_p(mpq_numref(point[j]))))
538
fprintf(stderr,"INTEGER OVERFLOW IN POLYHEDRAL COMPUTATION\n");
541
den=mpz_get_si(mpq_denref(point[j]));
542
num=mpz_get_si(mpq_numref(point[j]));
551
void scaleToIntegerVector(mpq_t *point, int n)
555
mpz_init_set_ui(lcm, 1);
556
mpz_init_set_ui(gcd, 0);
560
mpz_lcm(lcm,lcm,mpq_denref(point[j]));
561
mpz_gcd(gcd,gcd,mpq_numref(point[j]));
565
if(mpz_cmp(gcd,lcm)!=0)
567
assert(mpz_sgn(gcd)>0);
570
mpq_set_den(scale,gcd);
571
mpq_set_num(scale,lcm);
572
mpq_canonicalize(scale); //according to the gmp manual this call is needed, although it slows things down a bit
575
mpq_mul(point[j],point[j],scale);
584
IntegerVector LpSolverCddGmp::relativeInteriorPoint(int n, const IntegerVectorList &g, IntegerVector const *equalitySet)
586
// assert(!g.empty());
587
// int n=g.begin()->size();
588
mpq_t *point = new mpq_t [n];
589
for(int i=0;i<n;i++)mpq_init(point[i]);
591
int ret=staticRelativeInteriorPoint(n, point,g,false,equalitySet);
593
assert(ret>=0);//-- any cone has a relative interior point
597
// fprintf(stderr,"TEST1\n");
598
scaleToIntegerVector(point,n);
599
// fprintf(stderr,"TEST2\n");
603
IntegerVector result=arrayToIntegerVector(point,n);
606
for(int i=0;i<n;i++)mpq_clear(point[i]);
613
bool LpSolverCddGmp::interiorPoint(const IntegerVectorList &g, IntegerVector &result, bool strictlyPositive, IntegerVector const *equalitySet)
615
int n=g.begin()->size();
616
mpq_t *point = new mpq_t [n];
617
for(int i=0;i<n;i++)mpq_init(point[i]);
619
int ret=staticInteriorPoint(n, point,g,strictlyPositive,equalitySet);
624
scaleToIntegerVector(point,n);
628
result=arrayToIntegerVector(point,n);
632
for (int j=0; j <n; j++) {
633
if(j!=0)fprintf(f,", ");
634
dd_WriteNumber(f,point[j]);
639
fprintf(f,"The feasible region is empty.\n");
641
fprintf(f,"The feasible region is nonempty but has no interior point.\n");
645
for(int i=0;i<n;i++)mpq_clear(point[i]);
651
// the following two routines are static to avoid including gmp.h in the header file. Maybe that should be changed...
653
static bool lexicographicShootCompare(IntegerVector const &a, IntegerVector const &b, mpq_t const &aDot, mpq_t const &bDot, mpq_t &aTemp, mpq_t &bTemp)
659
mpq_set_si(aTemp,a[i],1);
660
mpq_set_si(bTemp,b[i],1);
661
mpq_mul(aTemp,aTemp,bDot);
662
mpq_mul(bTemp,bTemp,aDot);
663
int cmp=mpq_cmp(aTemp,bTemp);
664
if(cmp>0)return true;
665
if(cmp<0)return false;
671
static void computeDotProduct(mpq_t &ret, IntegerVector const &iv, mpq_t const *qv, mpq_t &temp)
677
mpq_set_si(temp,iv[i],1);
678
mpq_mul(temp,temp,qv[i]);
679
mpq_add(ret,ret,temp);
683
IntegerVectorList::const_iterator LpSolverCddGmp::shoot(const IntegerVectorList &g)
685
// fprintf(Stderr,"shoot begin\n");
687
// AsciiPrinter(Stderr).printVectorList(g);
689
int n=g.begin()->size();
690
mpq_t *point = new mpq_t [n];
691
for(int i=0;i<n;i++)mpq_init(point[i]);
693
// fprintf(Stderr,"\nVektor list with no interior point:\n");
694
// AsciiPrinter(Stderr).printVectorList(g);
697
int ret=staticInteriorPoint(n, point,g,true);
699
//fprintf(Stderr,"Interior point\n");
700
// AsciiPrinter(Stderr).printIntegerVector(point);
704
IntegerVectorList::const_iterator bestIterator=g.end();
709
mpq_t bestDotProduct;
710
mpq_init(bestDotProduct);
711
mpq_t currentDotProduct;
712
mpq_init(currentDotProduct);
714
IntegerVectorList::const_iterator i=g.begin();
716
if(LexicographicTermOrder()(*i,*i-*i))
718
computeDotProduct(bestDotProduct,*i,point,tempA);
722
// fprintf(Stderr,"A\n");
723
//if(bestIterator!=g.end())
724
// AsciiPrinter(Stderr).printVector(*bestIterator);
726
for(i++;i!=g.end();i++)
728
computeDotProduct(currentDotProduct,*i,point,tempA);
729
if(lexicographicShootCompare(*bestIterator,*i,bestDotProduct,currentDotProduct,tempA,tempB))
732
mpq_set(bestDotProduct,currentDotProduct);
735
mpq_clear(currentDotProduct);
736
mpq_clear(bestDotProduct);
740
for(int i=0;i<n;i++)mpq_clear(point[i]);
743
// fprintf(Stderr,"shoot end\n");
744
//if(bestIterator!=g.end())
745
// AsciiPrinter(Stderr).printVector(*bestIterator);
750
//-----------------------------------------
751
// Positive vector in kernel
752
//-----------------------------------------
754
bool LpSolverCddGmp::positiveVectorInKernel(const IntegerVectorList &g_, IntegerVector *result)
755
{// copy-paste from testshoot.c in cdd
756
// AsciiPrinter(Stderr).printVectorList(g);
757
// fprintf(Stderr,"strictlyPositive:%i\n",strictlyPositive);
760
IntegerVectorList g=g_;
763
// AsciiPrinter(Stderr).printVectorList(g);
768
int dimension=g.begin()->size();
770
for(int i=0;i<dimension;i++)
771
g.push_back(IntegerVector::standardVector(dimension,i));
773
dd_LPSolverType solver=dd_DualSimplex;
775
dd_LPSolutionPtr lps1;
776
dd_ErrorType err=dd_NoError;
782
A=vectorList2MatrixGmp(dimension, g, &err);
784
for(int i=0;i<dim2;i++)set_addelem(A->linset, i+1);//???
785
// set objective function
786
for (int i = 0; i < dimension; i++)
787
dd_set_si(A->rowvec[i+1],-1);
790
// set right hand side
791
for (int i = 0; i < dimension; i++)
792
dd_set_si(A->matrix[i+dim2][0],-1);
795
if (err!=dd_NoError) goto _L99;
796
A->objective=dd_LPmax;
799
/* for(int i=0;i<dimension;i++)
801
for(int j=0;j<dimension;j++)
802
dd_WriteNumber(f,point[j]);
804
fprintf(Stderr,"\n");
808
// dd_WriteMatrix(Stderr,A);
811
lp=dd_Matrix2LP(A, &err);
812
if (err!=dd_NoError) goto _L99;
814
// dd_WriteLP(Stderr,lp);
815
/* Find an interior point with cdd LP library. */
817
dd_LPSolve(lp,solver,&err);
820
if (err!=dd_NoError) goto _L99;
822
// IF INFEASIBLE RETURN FALSE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
823
if(lp->LPS==dd_Inconsistent)
830
// dd_WriteLPResult(stdout,lp,err);
832
/* Write an interior point. */
833
lps1=dd_CopyLPSolution(lp);
835
if (dd_Positive(lps1->optvalue))
837
// fprintf(Stderr,"Returning false\n");
846
for (int j=1; j <(lps1->d); j++) {
847
if(j!=1)fprintf(Stderr,", ");
848
dd_WriteNumber(Stderr,lps1->sol[j]);
850
fprintf(Stderr,")\n");
854
//transform into integer vectors
857
dd_Arow point=lps1->sol+1;
861
mpz_init_set_ui(lcm, 1);
862
mpz_init_set_ui(gcd, 0);
866
mpz_lcm(lcm,lcm,mpq_denref(point[j]));
867
mpz_gcd(gcd,gcd,mpq_numref(point[j]));
872
mpq_set_den(scale,gcd);
873
mpq_set_num(scale,lcm);
876
mpq_mul(point[j],point[j],scale);
887
for (int j=1; j <(lps1->d); j++) {
888
if(j!=1)fprintf(Stderr,", ");
889
dd_WriteNumber(Stderr,lps1->sol[j]);
891
fprintf(Stderr,")\n");
894
for (int j=1; j <(lps1->d); j++)
899
den=mpz_get_si(mpq_denref(lps1->sol[j]));
900
num=mpz_get_si(mpq_numref(lps1->sol[j]));
905
assert(j-1<result->size());
910
// dd_WriteLPSolution(lps1);
913
dd_FreeLPSolution(lps1);
921
//-----------------------------------------
923
//-----------------------------------------
925
#include "subspace.h"
926
int LpSolverCddGmp::rankOfMatrix(const IntegerVectorList &g_)
928
if(g_.size()==0)return 0;
929
FieldMatrix temp=integerMatrixToFieldMatrix(rowsToIntegerMatrix(g_),Q);
930
return temp.reduceAndComputeRank();
931
return Subspace(g_).dimension();
934
IntegerVectorList g=g_;
939
int dimension=g.begin()->size();
941
/* for(int i=0;i<dimension;i++)
942
g.push_back(IntegerVector::standardVector(dimension,i));
944
dd_LPSolverType solver=dd_DualSimplex;
946
dd_ErrorType err=dd_NoError;
951
A=vectorList2MatrixGmp(dimension, g, &err);
953
// dd_WriteMatrix(Stderr,A);
955
for(int i=0;i<g.size();i++)
956
set_addelem(A->linset,i+1);
957
// for(int i=0;i<dim2;i++)set_addelem(A->linset, i+1);//???
958
// set objective function
959
for (int i = 0; i < dimension; i++)
960
dd_set_si(A->rowvec[i+1],-1);
963
// set right hand side
964
/*for (int i = 0; i < dimension; i++)
965
dd_set_si(A->matrix[i+dim2][0],-1);
968
if (err!=dd_NoError) goto _L99;
969
A->objective=dd_LPmax;
971
//fprintf(Stderr,"rank of matrix matrix:\n");
973
// dd_WriteMatrix(Stderr,A);
975
r=dd_RedundantRows(A,&err);
976
if (err!=dd_NoError) goto _L99;
978
result=dim2-set_card(r);
980
// fprintf(Stderr,"dim2==%i set_card(r)==%i\n",dim2,set_card(r));
991
//-----------------------------------------
992
// Extreme Rays' Inequality Indices
993
//-----------------------------------------
995
// this procedure is take from cddio.c.
996
static void dd_ComputeAinc(dd_PolyhedraPtr poly)
998
/* This generates the input incidence array poly->Ainc, and
999
two sets: poly->Ared, poly->Adom.
1004
dd_boolean redundant;
1005
dd_MatrixPtr M=NULL;
1008
dd_init(sum); dd_init(temp);
1009
if (poly->AincGenerated==dd_TRUE) goto _L99;
1011
M=dd_CopyOutput(poly);
1016
/* fprintf(Stderr,"m1:%i\n",m1);
1017
fprintf(Stderr,"n:%i\n",poly->n);
1018
fprintf(Stderr,"m:%i\n",poly->m);
1020
/* this number is same as poly->m, except when
1021
poly is given by nonhomogeneous inequalty:
1022
!(poly->homogeneous) && poly->representation==Inequality,
1023
it is poly->m+1. See dd_ConeDataLoad.
1025
poly->Ainc=(set_type*)calloc(m1, sizeof(set_type));
1026
for(i=1; i<=m1; i++) set_initialize(&(poly->Ainc[i-1]),poly->n);
1027
set_initialize(&(poly->Ared), m1);
1028
set_initialize(&(poly->Adom), m1);
1030
for (k=1; k<=poly->n; k++){
1031
for (i=1; i<=poly->m; i++){
1032
dd_set(sum,dd_purezero);
1033
for (j=1; j<=poly->d; j++){
1034
dd_mul(temp,poly->A[i-1][j-1],M->matrix[k-1][j-1]);
1035
dd_add(sum,sum,temp);
1037
if (dd_EqualToZero(sum)) {
1038
set_addelem(poly->Ainc[i-1], k);
1041
if (!(poly->homogeneous) && poly->representation==dd_Inequality){
1042
if (dd_EqualToZero(M->matrix[k-1][0])) {
1043
set_addelem(poly->Ainc[m1-1], k); /* added infinity inequality (1,0,0,...,0) */
1048
for (i=1; i<=m1; i++){
1049
if (set_card(poly->Ainc[i-1])==M->rowsize){
1050
set_addelem(poly->Adom, i);
1053
for (i=m1; i>=1; i--){
1054
if (set_card(poly->Ainc[i-1])==0){
1056
set_addelem(poly->Ared, i);
1059
for (k=1; k<=m1; k++) {
1060
if (k!=i && !set_member(k, poly->Ared) && !set_member(k, poly->Adom) &&
1061
set_subset(poly->Ainc[i-1], poly->Ainc[k-1])){
1065
set_addelem(poly->Ared, i);
1071
poly->AincGenerated=dd_TRUE;
1073
dd_clear(sum); dd_clear(temp);
1077
IntegerVectorList LpSolverCddGmp::extremeRaysInequalityIndices(const IntegerVectorList &inequalityList)
1080
IntegerVectorList g=inequalityList;
1084
// assert(g.size()!=0);
1085
if(g.size()==0)return IntegerVectorList();
1087
int dimension=g.begin()->size();
1089
dd_MatrixPtr A=NULL;
1090
dd_ErrorType err=dd_NoError;
1094
A=vectorList2MatrixGmp(dimension, g, &err);
1096
// dd_WriteMatrix(Stderr,A);
1098
dd_PolyhedraPtr poly;
1099
poly=dd_DDMatrix2Poly2(A, dd_LexMin, &err);
1102
// dd_WritePolyFile(Stderr,poly);
1104
// dd_WriteIncidence(Stderr,poly);
1105
if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) assert(0);
1106
if (poly->AincGenerated==dd_FALSE) dd_ComputeAinc(poly);
1109
// dd_WriteIncidence(Stderr,poly);
1111
IntegerVectorList ret;
1113
// fprintf(Stderr,"%i %i\n",poly->n,poly->m1);
1116
How do we interpret the cddlib output? For a long ting gfan has
1117
been using poly->n as the number of rays of the cone and thus
1118
returned sets of indices that actually gave the lineality
1119
space. The mistake was then caught later in PolyhedralCone. On Feb
1120
17 2009 gfan was changed to check the length of each set to make
1121
sure that it does not specify the lineality space and only return
1122
those sets giving rise to rays. This does not seem to be the best
1123
strategy and might even be wrong.
1127
for (int k=1; k<=poly->n; k++)
1128
//for (int k=1; k<=poly->m1; k++)
1131
for (int i=1; i<=poly->m1; i++)
1132
if(set_member(k,poly->Ainc[i-1]))length++;
1135
IntegerVector v(length);
1137
for (int i=1; i<=poly->m1; i++)
1138
if(set_member(k,poly->Ainc[i-1]))v[j++]=i-1;
1143
// AsciiPrinter(Stderr).printVectorList(ret);
1144
// dd_WriteIncidence(Stderr,poly);
1147
dd_FreePolyhedra(poly);
1152
return IntegerVectorList();
1158
//-----------------------------------------
1159
// Remove Redundant Rows
1160
//-----------------------------------------
1162
void LpSolverCddGmp::removeRedundantRows(IntegerVectorList *inequalities, IntegerVectorList *equalities, bool removeInequalityRedundancies)
1164
int numberOfEqualities=equalities->size();
1165
int numberOfInequalities=inequalities->size();
1166
int numberOfRows=numberOfEqualities+numberOfInequalities;
1169
// AsciiPrinter(Stderr).printVectorList(*inequalities);
1170
// AsciiPrinter(Stderr).printVectorList(*equalities);
1173
IntegerVectorList g=*inequalities;
1174
for(IntegerVectorList::const_iterator i=equalities->begin();i!=equalities->end();i++)
1177
if(numberOfRows==0)return;//the full space, so description is alredy irredundant
1178
assert(numberOfRows>0);
1180
dd_LPSolverType solver=dd_DualSimplex;
1181
dd_MatrixPtr A=NULL;
1182
dd_ErrorType err=dd_NoError;
1186
A=vectorList2MatrixGmp(g.begin()->size(),g, &err);
1188
for(int i=numberOfInequalities;i<numberOfRows;i++)
1189
set_addelem(A->linset,i+1);
1191
// dd_WriteMatrix(Stderr,A);
1193
// for(int i=0;i<dim2;i++)set_addelem(A->linset, i+1);//???
1194
// set objective function
1195
// for (int i = 0; i < dimension; i++)
1196
// dd_set_si(A->rowvec[i+1],-1);
1199
// set right hand side
1200
/*for (int i = 0; i < dimension; i++)
1201
dd_set_si(A->matrix[i+dim2][0],-1);
1205
IntegerVectorList newLin;
1206
IntegerVectorList newIn;
1208
if (err!=dd_NoError) goto _L99;
1209
A->objective=dd_LPmax;
1211
// dd_WriteMatrix(Stderr,A);
1213
// r=dd_RedundantRows(A,&err);
1215
dd_rowset impl_linset;
1219
if(removeInequalityRedundancies)
1220
dd_MatrixCanonicalize(&A, &impl_linset, &redset, &newpos, &err);
1222
dd_MatrixCanonicalizeLinearity(&A, &impl_linset, &newpos, &err);
1224
if (err!=dd_NoError) goto _L99;
1226
// set_fwrite(stderr,redset);
1227
// set_fwrite(stderr,impl_linset);
1229
// Maybe the following should be changed... what if cononicalize generates new rows?
1233
// dd_WriteMatrix(Stderr,A);
1234
int rowsize=A->rowsize;
1236
// fprintf(Stderr,"rowsize: %i ColSize:%i\n",rowsize,n);
1237
for(int i=0;i<rowsize;i++)
1239
mpq_t *point = new mpq_t [n];
1240
for(int j=0;j<n;j++)mpq_init(point[j]);
1242
for(int j=0;j<n;j++)mpq_set(point[j],A->matrix[i][j+1]);
1244
IntegerVector v=arrayToIntegerVector(point, n);
1245
// AsciiPrinter(Stderr).printVector(v);
1247
for(int j=0;j<n;j++)mpq_clear(point[j]);
1249
if(set_member(i+1,A->linset))
1250
newLin.push_back(v);
1257
for(IntegerVectorList::iterator i=inequalities->begin();i!=inequalities->end();index++)
1259
int i2=newpos[index+1];
1262
if(set_member(i2,A->linset))
1263
newLin.push_back(*i);
1265
newIn.push_back(*i);
1270
for(IntegerVectorList::iterator i=equalities->begin();i!=equalities->end();index++)
1272
int i2=newpos[index+1];
1275
if(set_member(i2,A->linset))
1276
newLin.push_back(*i);
1278
newIn.push_back(*i);
1282
assert(index==numberOfRows);
1285
assert(set_card(A->linset)==newLin.size());
1287
if(A->rowsize!=newLin.size()+newIn.size())
1289
fprintf(stderr,"A->rowsize: %i\n",(int)A->rowsize);
1290
fprintf(stderr,"newLin.size(): %i\n",newLin.size());
1291
fprintf(stderr,"newIn.size(): %i\n",newIn.size());
1293
dd_WriteMatrix(Stderr,A);
1295
AsciiPrinter(Stderr).printVectorList(newLin);
1296
AsciiPrinter(Stderr).printVectorList(newIn);
1299
assert(A->rowsize==newLin.size()+newIn.size());
1302
set_free(impl_linset);
1303
if(removeInequalityRedundancies)
1306
// set_free();//HOW DO WE FREE newpos?
1309
*inequalities=newIn;
1317
static dd_MatrixPtr vectorLists2MatrixGmp(int n, IntegerVectorList const &inequalities, IntegerVectorList const &equations, dd_ErrorType *err)
1319
IntegerVectorList g=inequalities;
1320
int numberOfInequalities=inequalities.size();
1321
for(IntegerVectorList::const_iterator i=equations.begin();i!=equations.end();i++)
1324
// assert(g.size()); // If this restriction turns out to be a problem it should be fixed in vectorList2MatrixGmp()
1325
int numberOfRows=g.size();
1327
dd_MatrixPtr A=NULL;
1331
A=vectorList2MatrixGmp(n, g, err);
1333
for(int i=numberOfInequalities;i<numberOfRows;i++)
1334
set_addelem(A->linset,i+1);
1339
static IntegerVectorList getConstraints(dd_MatrixPtr A, bool returnEquations)
1341
IntegerVectorList ret;
1343
int rowsize=A->rowsize;
1345
// fprintf(Stderr,"rowsize: %i ColSize:%i\n",rowsize,n);
1347
mpq_t *point = new mpq_t [n];
1348
for(int j=0;j<n;j++)mpq_init(point[j]);
1350
for(int i=0;i<rowsize;i++)
1352
bool isEquation=set_member(i+1,A->linset);
1353
if(isEquation==returnEquations)
1355
for(int j=0;j<n;j++)mpq_set(point[j],A->matrix[i][j+1]);
1357
scaleToIntegerVector(point,n);
1358
IntegerVector v=arrayToIntegerVector(point, n);
1359
// AsciiPrinter(Stderr).printVector(v);
1365
for(int j=0;j<n;j++)mpq_clear(point[j]);
1372
void LpSolverCddGmp::dual(int n, const IntegerVectorList &inequalities, const IntegerVectorList &equations, IntegerVectorList *dualInequalities, IntegerVectorList *dualEquations)
1374
IntegerVectorList dummy1;
1375
IntegerVectorList dummy2;
1376
if(!dualInequalities)dualInequalities=&dummy1;
1377
if(!dualEquations)dualEquations=&dummy2;
1381
dd_MatrixPtr A=NULL;
1382
dd_ErrorType err=dd_NoError;
1386
A=vectorLists2MatrixGmp(n, inequalities, equations, &err);
1387
// A=vectorList2MatrixGmp(g, &err);
1389
// dd_WriteMatrix(Stderr,A);
1391
dd_PolyhedraPtr poly;
1392
poly=dd_DDMatrix2Poly2(A, dd_LexMin, &err);
1394
// dd_WriteIncidence(Stderr,poly);
1395
if (poly->child==NULL || poly->child->CompStatus!=dd_AllFound) assert(0);
1397
// dd_WriteIncidence(Stderr,poly);
1398
// dd_WritePolyFile(Stderr,poly);
1399
// dd_WriteMatrix(Stderr,poly->child->A);
1400
dd_MatrixPtr A2=dd_CopyGenerators(poly);
1401
// dd_WriteMatrix(Stderr,A2);
1403
*dualInequalities=getConstraints(A2,false);
1404
*dualEquations=getConstraints(A2,true);
1408
// AsciiPrinter(Stderr).printVectorList(*dualInequalities);
1409
// AsciiPrinter(Stderr).printVectorList(*dualEquations);
1414
// AsciiPrinter(Stderr).printVectorList(ret);
1415
// dd_WriteIncidence(Stderr,poly);
1418
dd_FreePolyhedra(poly);
1425
static LpSolverCddGmp theLpSolverCddGmp;