/* Copyright (c) 1997-2010
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Darmstadt, Germany)
   http://www.polymake.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.
--------------------------------------------------------------------------------
   $Project: polymake $$Id: 600-cell.cc 10061 2011-03-16 12:46:53Z herr $
*/

#include "polymake/client.h"
#include "polymake/Vector.h"
#include "polymake/Matrix.h"
#include "polymake/vector"
#include "polymake/permutations.h"
#include "polymake/AccurateFloat.h"

namespace polymake { namespace polytope {

perl::Object create_600_cell()
{
   const AccurateFloat tau=2*cos(AccurateFloat::pi()/5); // golden ratio
   const int dim=4;

   Matrix<Rational> Vertices(120,dim+1);
   Rows< Matrix<Rational> >::iterator v=rows(Vertices).begin();

   Vector<Rational> vertex(dim);
   // 96 vertices of the snub-24-cell s{3,4,3}
   AllPermutations<> perms(dim);
   for (AllPermutations<>::const_iterator perm=entire(perms);
        !perm.at_end(); ++perm, ++perm)  // every second permutation (including the initial one) is even
      for (int i=1; i>=-1; i-=2)
         for (int j=1; j>=-1; j-=2)
            for (int k=1; k>=-1; k-=2, ++v) {
               vertex[0]=i*tau; vertex[1]=j; vertex[2]=k/tau;
               *v= 1 | vertex.slice(*perm);
            }

   // 8 more vertices
   for (int n=1; n<5; ++n)
      for (int i=1; i>=-1; i-=2, ++v) {
         (*v)[0]=1;
         (*v)[n]=2*i;
      }

   // and finally 16 vertices
   for (int i=1; i>=-1; i-=2)
      for (int j=1; j>=-1; j-=2)
         for (int k=1; k>=-1; k-=2)
            for (int l=1; l>=-1; l-=2, ++v) {
               (*v)[0]=1; (*v)[1]=i; (*v)[2]=j; (*v)[3]=k; (*v)[4]=l;
            }

   perl::Object p("Polytope<Rational>");
   p.set_description() << "the 600-cell polytope" << endl;

   p.take("CONE_AMBIENT_DIM") << dim+1;
   p.take("CONE_DIM") << dim+1;
   p.take("VERTICES") << Vertices;
   return p;
}

UserFunction4perl("# @category Producing from scratch"
                  "# Create the 600-cell polytope."
                  "# Cf. Coxeter, Introduction to Geometry, pp 403-404."
                  "# @return Polytope",
                  &create_600_cell, "create_600_cell()");
} }

// Local Variables:
// mode:C++
// c-basic-offset:3
// indent-tabs-mode:nil
// End:
