File: separating_hyperplane.h

package info (click to toggle)
polymake 4.3-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 31,528 kB
  • sloc: cpp: 152,204; perl: 43,222; javascript: 30,700; ansic: 2,937; java: 2,654; python: 641; sh: 244; xml: 117; makefile: 62
file content (67 lines) | stat: -rw-r--r-- 2,628 bytes parent folder | download
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
/* Copyright (c) 1997-2020
   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.
--------------------------------------------------------------------------------
*/

#ifndef POLYMAKE_POLYTOPE_SEPARATING_HYPERPLANE_H
#define POLYMAKE_POLYTOPE_SEPARATING_HYPERPLANE_H

#include "polymake/Vector.h"
#include "polymake/Matrix.h"
#include "polymake/linalg.h"
#include "polymake/polytope/solve_LP.h"

namespace polymake { namespace polytope {

template <typename Scalar, typename VectorType, typename MatrixType>
Vector<Scalar> separating_hyperplane(const GenericVector<VectorType, Scalar>& q, 
                                     const GenericMatrix<MatrixType, Scalar>& points)
{
   /*
     construction of LP according to cdd redundancy check for points, see
     http://www.ifor.math.ethz.ch/~fukuda/polyfaq/node22.html#polytope:Vredundancy
    */
   const Matrix<Scalar> 
      ineqs(  (zero_vector<Scalar>() | (ones_vector<Scalar>() | -points.minor(All, range(1,points.cols()-1))))
              // z^t p_i - z_0 <= 0; CAUTION: p_i is affine part of i-th point! 
              / (ones_vector<Scalar>(2) | -q.slice(range_from(1))) ),
              // z^t q - z_0 <= 1, prevents unboundedness
      affine_hull(null_space(points/q)),
      extension2(affine_hull.rows(), 2);
   Matrix<Scalar>
      affine_hull_minor(affine_hull.rows(), affine_hull.cols()-1);
   if (affine_hull.cols() > 1) {
      affine_hull_minor = affine_hull.minor(All, range(1, affine_hull.cols()-1));
   }
   const Matrix<Scalar> eqs(extension2 | -affine_hull_minor);
   const Vector<Scalar> obj(zero_vector<Scalar>(1) | -ones_vector<Scalar>(1) | q.slice(range_from(1))); // z^t q - z_0

   const auto S = solve_LP(ineqs, eqs, obj, true);
   if (S.status != LP_status::valid || S.objective_value <= 0) //q non-red. <=> obj_val > 0
      throw infeasible();

   // H: z^t x = z_0, i.e., z_0 - z^t x = 0
   return S.solution[1] | -S.solution.slice(range_from(2));
}

}}

#endif

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