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