/* 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.
*/

#ifndef _POLYMAKE_TRANSFORM_H
#define _POLYMAKE_TRANSFORM_H "$Project: polymake $$Id: transform.h,v 1.14 2004/09/20 16:15:07 gawrilow Exp $"

#include <Poly.h>
#include <IncidenceMatrix.h>
#include <linalg.h>
#include <Array.h>
#include <Matrix.h>

namespace polymake { namespace polytope {

std::string transform_comment(const char* program, const char* in_name);

/** Transform a coordinate section by applying a given transformation matrix.
    @param p_out destination file
    @param p_in source file
    @param section_req read request for the section to be transformed
    @param comment are written verbatim in every output section
    @param tau transformation matrix
*/
template <typename TransMatrix>
void transform_section (Poly& p_out, Poly& p_in,
			const char* section_req,
			const std::string& comment,
			const GenericMatrix<TransMatrix>& tau)
{
   Matrix<typename TransMatrix::element_type> M;
   if (p_in.lookup(section_req) >> M)
      p_out.take(p_in.given().c_str()) << comment << M*tau;
}

void transform_copy_labels (Poly& p_out, Poly& p_in,
			    const std::string& comment,
			    const char* out_section, const char* in_section=0);

/** Transform all coordinate sections according to the given transformation matrix.
    @param p_out destination file
    @param p_in source file
    @param comment are written verbatim in every output section
    @param tau transformation matrix for points
*/
template <typename TransMatrix>
void transform (Poly& p_out, Poly& p_in,
		const std::string& comment,
		const GenericMatrix<TransMatrix>& tau)
{
   typename TransMatrix::persistent_type tau_inv=inv(tau);

   transform_section(p_out, p_in, "VERTICES | POINTS", comment, tau);
   transform_section(p_out, p_in, "FACETS | INEQUALITIES", comment, T(tau_inv));
   transform_section(p_out, p_in, "AFFINE_HULL | EQUATIONS", comment, T(tau_inv));
   transform_section(p_out, p_in, "LINEAR_OBJECTIVE", comment, T(tau_inv));

   IncidenceMatrix<> VIF;
   if (p_in.lookup("VERTICES_IN_FACETS") >> VIF)
      p_out.take("VERTICES_IN_FACETS") << comment << VIF;

   Matrix<typename TransMatrix::element_type> tau_rev;
   if (p_in.lookup("REVERSE_TRANSFORMATION") >> tau_rev)
      tau_rev= tau_inv * tau_rev;
   else
      tau_rev= tau_inv;

   p_out.take("REVERSE_TRANSFORMATION") << comment << tau_rev;

   transform_copy_labels(p_out, p_in, comment, "VERTEX_LABELS");
   transform_copy_labels(p_out, p_in, comment, "FACET_LABELS");
}

} } // end namespace polymake

#endif // _POLYMAKE_TRANSFORM_H

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