1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
# Copyright (c) 1997-2024
# Ewgenij Gawrilow, Michael Joswig, and the polymake team
# Technische Universität Berlin, Germany
# https://polymake.org
#
# 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.
#-------------------------------------------------------------------------------
CREDIT porta
PORTA is a collection of routines for analyzing polytopes and polyhedra.
Copyright by Thomas Christof and Andreas Loebel.
http://www.iwr.uni-heidelberg.de/groups/comopt/software/PORTA/
# path to the xporta executable
custom $xporta;
CONFIGURE {
find_program($xporta, "xporta");
}
require PortaParser;
INCLUDE
# porta_convexhull.rules
# @category Transformations
# Primal transformation via porta. Computes facets and affine hull from
# vertices or points.
user_function porta_primal {
my($p) = @_;
my $dim = $p->CONE_AMBIENT_DIM;
my $pts = $p->give("VERTICES | POINTS");
my $has_far_facet = $p->has_far_facet;
my $tempname=new Tempfile;
my $converter=new PortaConverter("$tempname.poi");
$converter->print_dim($dim-1);
$converter->print_points($pts);
$converter->finish;
my $command="$xporta -l -T $tempname.poi";
$command.=" >/dev/null 2>&1" unless $DebugLevel;
system($command) and die "porta exited with error code\n";
my $parser=new PortaParser("$tempname.poi.ieq");
if ($has_far_facet) {
push @{$parser->Ineq}, [ 1, (0) x ($dim-1) ];
}
my $facets = @{$parser->Ineq} > 0 ?
$parser->Ineq :
new Matrix(0,$dim);
my $affine_hull = @{$parser->Eq} > 0 ?
$parser->Eq :
new Matrix(0,$dim);
unlink "porta.log";
return ($facets, $affine_hull);
}
# @category Transformations
# Dual transformation via porta. Computes vertices and lineality space from
# inequalities and equations.
user_function porta_dual {
my($p) = @_;
my $dim = $p->CONE_AMBIENT_DIM;
my $validpt = $p->VALID_POINT;
my $ineq = $p->give("FACETS | INEQUALITIES");
my $eq = $p->lookup("AFFINE_HULL | EQUATIONS");
my $tempname=new Tempfile;
my $converter=new PortaConverter("$tempname.ieq");
$converter->print_dim($dim-1);
$converter->print_valid_point($validpt);
$converter->print_inequalities($ineq, $eq);
$converter->finish;
my $command="$xporta -l -T $tempname.ieq";
$command.=" >/dev/null 2>&1" unless $DebugLevel;
system($command) and die "xporta exited with error code\n";
my $parser=new PortaParser("$tempname.ieq.poi");
my $vertices = @{$parser->Points} > 0 ?
$parser->Points :
new Matrix(0,$dim);
my $lineality =new Matrix<Rational>(0,$dim);
unlink "porta.log";
return ($vertices, $lineality);
}
# @category Optimization
# take a rational polytope and write a porta input file (.ieq or .poi)
# @param Polytope<Rational> p
# @param String file filename for the porta file (.ieq or .poi) or an open IO handle
# @option Bool primal true if points should be written, false if inequalities should be written (default is true)
user_function poly2porta(Polytope<Rational>, $, {primal=>1} ) {
require PortaParser;
my ($p, $filename, $options) = @_;
my $converter=new PortaConverter($filename);
if ( $options->{primal} ) {
$converter->print_dim($p->CONE_AMBIENT_DIM-1);
$converter->print_points($p->give("VERTICES | POINTS"), $p->lookup("LINEALITY_SPACE | INPUT_LINEALITY"));
} else {
$converter->print_dim($p->CONE_AMBIENT_DIM-1);
$converter->print_valid_point($p->VALID_POINT);
$converter->print_inequalities($p->give("FACETS | INEQUALITIES"), $p->lookup("AFFINE_HULL | EQUATIONS"));
}
$converter->finish;
}
# Local Variables:
# mode: perl
# cperl-indent-level:3
# indent-tabs-mode:nil
# End:
|