|
|
58ec093 |
/* cdd_both_reps.c: compute reduced H and V representation of polytope
|
|
|
58ec093 |
by Volker Braun <vbraun@stp.dias.ie>
|
|
|
58ec093 |
|
|
|
58ec093 |
The input is taken from stdin and can be either a
|
|
|
58ec093 |
H or V representation, not necessarily reduced.
|
|
|
58ec093 |
|
|
|
58ec093 |
based on testcdd1.c, redcheck.c, and of course the cdd library
|
|
|
58ec093 |
written by Komei Fukuda, fukuda@ifor.math.ethz.ch
|
|
|
58ec093 |
Standard ftp site: ftp.ifor.math.ethz.ch, Directory: pub/fukuda/cdd
|
|
|
58ec093 |
*/
|
|
|
58ec093 |
|
|
|
58ec093 |
/* This program is free software; you can redistribute it and/or modify
|
|
|
58ec093 |
it under the terms of the GNU General Public License as published by
|
|
|
58ec093 |
the Free Software Foundation; either version 2 of the License, or
|
|
|
58ec093 |
(at your option) any later version.
|
|
|
58ec093 |
|
|
|
58ec093 |
This program is distributed in the hope that it will be useful,
|
|
|
58ec093 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
58ec093 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
58ec093 |
GNU General Public License for more details.
|
|
|
58ec093 |
|
|
|
58ec093 |
You should have received a copy of the GNU General Public License
|
|
|
58ec093 |
along with this program; if not, write to the Free Software
|
|
|
58ec093 |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
58ec093 |
*/
|
|
|
58ec093 |
|
|
|
58ec093 |
#include "setoper.h"
|
|
|
58ec093 |
#include "cdd.h"
|
|
|
58ec093 |
#include <stdio.h>
|
|
|
58ec093 |
#include <stdlib.h>
|
|
|
58ec093 |
#include <time.h>
|
|
|
58ec093 |
#include <math.h>
|
|
|
58ec093 |
#include <string.h>
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
void compute_adjacency(dd_MatrixPtr Rep, dd_ErrorType* err_ptr)
|
|
|
58ec093 |
{
|
|
|
58ec093 |
dd_SetFamilyPtr AdjacencyGraph;
|
|
|
58ec093 |
if (*err_ptr != dd_NoError) return;
|
|
|
58ec093 |
|
|
|
58ec093 |
switch (Rep->representation) {
|
|
|
58ec093 |
case dd_Inequality:
|
|
|
58ec093 |
printf("Facet graph\n");
|
|
|
58ec093 |
break;
|
|
|
58ec093 |
case dd_Generator:
|
|
|
58ec093 |
printf("Vertex graph\n");
|
|
|
58ec093 |
break;
|
|
|
58ec093 |
case dd_Unspecified:
|
|
|
58ec093 |
printf("unknown representation type!\n");
|
|
|
58ec093 |
default:
|
|
|
58ec093 |
printf("This should be unreachable!\n");
|
|
|
58ec093 |
exit(2);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
/* Output adjacency of vertices/rays/lines */
|
|
|
58ec093 |
if (Rep->rowsize > 0) { /* workaround for bug with empty polyhedron */
|
|
|
58ec093 |
/* compute adjacent vertices/rays/lines */
|
|
|
58ec093 |
AdjacencyGraph = dd_Matrix2Adjacency(Rep, err_ptr);
|
|
|
58ec093 |
if (*err_ptr == dd_NoError) {
|
|
|
58ec093 |
dd_WriteSetFamily(stdout,AdjacencyGraph);
|
|
|
58ec093 |
dd_FreeSetFamily(AdjacencyGraph);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
} else {
|
|
|
58ec093 |
printf("begin\n");
|
|
|
58ec093 |
printf(" 0 0\n");
|
|
|
58ec093 |
printf("end\n");
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
printf("\n");
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
void minimal_Vrep_Hrep(dd_MatrixPtr M,
|
|
|
58ec093 |
dd_MatrixPtr* Vrep_ptr, dd_MatrixPtr* Hrep_ptr,
|
|
|
58ec093 |
dd_ErrorType* err_ptr)
|
|
|
58ec093 |
{
|
|
|
58ec093 |
dd_PolyhedraPtr poly;
|
|
|
58ec093 |
dd_rowindex newpos;
|
|
|
58ec093 |
dd_rowset impl_linset,redset;
|
|
|
58ec093 |
dd_MatrixPtr Vrep, Hrep;
|
|
|
58ec093 |
|
|
|
58ec093 |
if (*err_ptr != dd_NoError) return;
|
|
|
58ec093 |
|
|
|
58ec093 |
/* compute the second representation */
|
|
|
58ec093 |
poly = dd_DDMatrix2Poly(M, err_ptr);
|
|
|
58ec093 |
if (*err_ptr != dd_NoError) return;
|
|
|
58ec093 |
|
|
|
58ec093 |
if (*err_ptr == dd_NoError) {
|
|
|
58ec093 |
/* compute canonical H-representation */
|
|
|
58ec093 |
Hrep = dd_CopyInequalities(poly);
|
|
|
58ec093 |
if (Hrep->rowsize > 0) { /* workaround for bug with empty matrix */
|
|
|
58ec093 |
dd_MatrixCanonicalize(&Hrep, &impl_linset, &redset, &newpos, err_ptr);
|
|
|
58ec093 |
if (*err_ptr == dd_NoError) {
|
|
|
58ec093 |
set_free(redset);
|
|
|
58ec093 |
set_free(impl_linset);
|
|
|
58ec093 |
free(newpos);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
}
|
|
|
58ec093 |
if (*err_ptr == dd_NoError) (*Hrep_ptr) = Hrep;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
if (*err_ptr == dd_NoError) {
|
|
|
58ec093 |
/* compute canonical V-representation */
|
|
|
58ec093 |
Vrep = dd_CopyGenerators(poly);
|
|
|
58ec093 |
if (Vrep->rowsize > 0) { /* workaround for bug with empty matrix */
|
|
|
58ec093 |
dd_MatrixCanonicalize(&Vrep, &impl_linset, &redset, &newpos, err_ptr);
|
|
|
58ec093 |
if (*err_ptr == dd_NoError) {
|
|
|
58ec093 |
set_free(redset);
|
|
|
58ec093 |
set_free(impl_linset);
|
|
|
58ec093 |
free(newpos);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
}
|
|
|
58ec093 |
if (*err_ptr == dd_NoError) (*Vrep_ptr) = Vrep;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
dd_FreePolyhedra(poly);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
void print_both_reps(dd_MatrixPtr Vrep, dd_MatrixPtr Hrep)
|
|
|
58ec093 |
{
|
|
|
58ec093 |
/* Output V-representation */
|
|
|
58ec093 |
dd_WriteMatrix(stdout,Vrep);
|
|
|
58ec093 |
printf("\n");
|
|
|
58ec093 |
|
|
|
58ec093 |
/* Output H-representation */
|
|
|
58ec093 |
dd_WriteMatrix(stdout,Hrep);
|
|
|
58ec093 |
printf("\n");
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
void compute_both_reps(dd_MatrixPtr M, dd_ErrorType* err_ptr)
|
|
|
58ec093 |
{
|
|
|
58ec093 |
dd_MatrixPtr Vrep, Hrep;
|
|
|
58ec093 |
minimal_Vrep_Hrep(M, &Vrep, &Hrep, err_ptr);
|
|
|
58ec093 |
if (*err_ptr != dd_NoError) return;
|
|
|
58ec093 |
|
|
|
58ec093 |
print_both_reps(Vrep, Hrep);
|
|
|
58ec093 |
dd_FreeMatrix(Hrep);
|
|
|
58ec093 |
dd_FreeMatrix(Vrep);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
void compute_all(dd_MatrixPtr M, dd_ErrorType* err_ptr)
|
|
|
58ec093 |
{
|
|
|
58ec093 |
dd_MatrixPtr Vrep, Hrep;
|
|
|
58ec093 |
minimal_Vrep_Hrep(M, &Vrep, &Hrep, err_ptr);
|
|
|
58ec093 |
if (*err_ptr != dd_NoError) return;
|
|
|
58ec093 |
|
|
|
58ec093 |
print_both_reps(Vrep, Hrep);
|
|
|
58ec093 |
compute_adjacency(Vrep, err_ptr);
|
|
|
58ec093 |
compute_adjacency(Hrep, err_ptr);
|
|
|
58ec093 |
dd_FreeMatrix(Hrep);
|
|
|
58ec093 |
dd_FreeMatrix(Vrep);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
void usage(char *name)
|
|
|
58ec093 |
{
|
|
|
58ec093 |
printf("No known option specified, I don't know what to do!\n"
|
|
|
58ec093 |
"Usage:\n"
|
|
|
58ec093 |
"%s --option\n"
|
|
|
58ec093 |
"where --option is precisely one of the following:\n\n"
|
|
|
58ec093 |
" --all: Compute everything.\n"
|
|
|
58ec093 |
" This will compute minimal H-,V-representation and vertex and facet graph.\n"
|
|
|
58ec093 |
"\n"
|
|
|
58ec093 |
" --reps: Compute both a minimal H- and minimal V-representation.\n"
|
|
|
58ec093 |
"\n"
|
|
|
58ec093 |
" --adjacency: Compute adjacency information only.\n"
|
|
|
58ec093 |
" The input is assumed to be a minimal representation, as, for example, computed\n"
|
|
|
58ec093 |
" by --reps. Warning, you will not get the correct answer if the input\n"
|
|
|
58ec093 |
" representation is not minimal! The output is the vertex or facet graph,\n"
|
|
|
58ec093 |
" depending on the input.\n"
|
|
|
58ec093 |
"\n"
|
|
|
58ec093 |
"The input data is a H- or V-representation in cdd's ine/ext format and\n"
|
|
|
58ec093 |
"is in each case read from stdin.\n",
|
|
|
58ec093 |
name);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
enum command_line_arguments { ALL, REPS, ADJACENCY };
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
int parse_arguments(char* arg, enum command_line_arguments* option)
|
|
|
58ec093 |
{
|
|
|
58ec093 |
if (strcmp(arg,"--all")==0) {
|
|
|
58ec093 |
*option = ALL;
|
|
|
58ec093 |
return 0;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
if (strcmp(arg,"--reps")==0) {
|
|
|
58ec093 |
*option = REPS;
|
|
|
58ec093 |
return 0;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
if (strcmp(arg,"--adjacency")==0) {
|
|
|
58ec093 |
*option = ADJACENCY;
|
|
|
58ec093 |
return 0;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
printf("Unknown option: %s\n", arg);
|
|
|
58ec093 |
return 1;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
int main(int argc, char *argv[])
|
|
|
58ec093 |
{
|
|
|
58ec093 |
dd_ErrorType err=dd_NoError;
|
|
|
58ec093 |
dd_MatrixPtr M;
|
|
|
58ec093 |
enum command_line_arguments option;
|
|
|
58ec093 |
|
|
|
58ec093 |
if (argc!=2 || parse_arguments(argv[1],&option)) {
|
|
|
58ec093 |
usage(argv[0]);
|
|
|
58ec093 |
return 0;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
dd_set_global_constants();
|
|
|
58ec093 |
|
|
|
58ec093 |
/* Read data from stdin */
|
|
|
58ec093 |
M = dd_PolyFile2Matrix(stdin, &err;;
|
|
|
58ec093 |
if (err != dd_NoError) {
|
|
|
58ec093 |
printf("I was unable to parse the input data!\n");
|
|
|
58ec093 |
dd_WriteErrorMessages(stdout,err);
|
|
|
58ec093 |
dd_free_global_constants();
|
|
|
58ec093 |
return 1;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
switch (option) {
|
|
|
58ec093 |
case ALL:
|
|
|
58ec093 |
compute_all(M,&err;;
|
|
|
58ec093 |
break;
|
|
|
58ec093 |
case REPS:
|
|
|
58ec093 |
compute_both_reps(M,&err;;
|
|
|
58ec093 |
break;
|
|
|
58ec093 |
case ADJACENCY:
|
|
|
58ec093 |
compute_adjacency(M,&err;;
|
|
|
58ec093 |
break;
|
|
|
58ec093 |
default:
|
|
|
58ec093 |
printf("unreachable option %d\n", option);
|
|
|
58ec093 |
exit(3); /* unreachable */
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
/* cleanup */
|
|
|
58ec093 |
dd_FreeMatrix(M);
|
|
|
58ec093 |
if (err != dd_NoError) {
|
|
|
58ec093 |
dd_WriteErrorMessages(stdout,err);
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
dd_free_global_constants();
|
|
|
58ec093 |
return 0;
|
|
|
58ec093 |
}
|
|
|
58ec093 |
|
|
|
58ec093 |
|
|
|
58ec093 |
|