/* Copyright (c) 1997-2004
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
*/

#ident "$Project: polymake $$Id: cyclic.cc,v 1.22 2005/07/28 18:03:50 gawrilow Exp $"

#include <cstdlib>
#include <Poly.h>
#include <Rational.h>
#include <Matrix.h>

namespace polymake {
namespace polytope {

void cyclic(Poly& p, int d, int n, int x_start)
{
   p.take("AMBIENT_DIM") << d;
   p.take("DIM") << d;
   p.take("N_VERTICES") << n;

   Matrix<Rational> vertices(n,d+1);
   Rational* v=concat_rows(vertices).begin();

   // and now we compute n points (x_i^1,..,x_i^d) on the momentum curve in R^d
   for (int i=0, x=x_start;  i<n;  ++i, ++x) {
      *v++ = 1;
      Integer power_of_x(1);
      for (int j = 1; j <= d; ++j) {
	 power_of_x *= x;
	 *v++ = power_of_x;
      }
   }
   p.take("VERTICES") << vertices;

   p.take("BOUNDED") << true;
}

} }

using namespace polymake;

/** @file cyclic
 *
 *  Produce a $d$-dimensional cyclic polytope with $n$ points.
 *  Prototypical example of a neighborly polytope.  Combinatorics completely known
 *  due to Gale's evenness criterion.  Coordinates are chosen on the moment curve.
 *
 *  @synopsis cyclic <file> <d> <n> [<x start value>]
 *
 *  @writing  AMBIENT_DIM, DIM, VERTICES, N_VERTICES, BOUNDED
 *
 *  @index clients Producing from scratch
 */

int main(int argc, char *argv[]) {
   if (argc < 4 || argc > 5) {
      cerr << "usage: " << argv[0] << " <file> <dimension> <number of points> [<x start value>]" << endl;
      return 1;
   }
   try {
      int d = atoi(argv[2]),			// projective dimension
	  n = atoi(argv[3]),			// number of points/inequalities
          x_start = argc==5 ? atoi(argv[4]) : 0;	// start value for x

      // there is a certain restriction on the parameters
      if ((d < 2) || (d >= n)) {
	 cerr << argv[0] << ": (d >= 2) && (n > d)\n";
	 return 1;
      }

      Poly p(argv[1], ios::out | ios::trunc);
      polytope::cyclic(p, d, n, x_start);
   }
   catch (const std::exception& e) {
      cerr << e.what() << endl;
      return 1;
   }
   return 0;
}
