intconvex.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     intconvex.cpp -- See declarations in intconvex.hpp.
00004 
00005     This file is a part of the Arageli library.
00006 
00007     Copyright (C) Sergey S. Lyalin, 2006
00008     University of Nizhni Novgorod, Russia
00009 
00010 *****************************************************************************/
00011 
00018 #include "config.hpp"
00019 
00020 #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || \
00021     defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_intconvex)
00022 
00023 #include <limits>
00024 
00025 #include "type_traits.hpp"
00026 #include "exception.hpp"
00027 #include "big_int.hpp"
00028 #include "vector.hpp"
00029 #include "skeleton.hpp"
00030 
00031 #include "intconvex.hpp"
00032 
00033 
00034 namespace Arageli
00035 {
00036 
00037 template <typename Gen, typename IntGen>
00038 void intconvex_simple (const Gen& gen, IntGen& intgen)
00039 {
00040     // Note, there is a difference between notation used here and
00041     // in the source of the idea (Emelichev V.A., Kovalev M.M...).
00042     // In the book a polyhedron is extended to a cone by adding the last
00043     // component in coordinate. But here we extend by the first component.
00044 
00046     std::cout << "\nDebug output for intconvex_simple.";
00048     
00049     ARAGELI_ASSERT_0(gen.ncols() > 0);
00050     
00051     typedef typename Gen::element_type T;
00052     typedef typename Gen::size_type size_type;
00053     typedef vector<T, false> Vec;
00054     typedef vector<size_type, false> Idxvec;
00055 
00056     ARAGELI_ASSERT_0(type_traits<T>::is_integer_number);    // temporary limitation
00057 
00058     size_type d = gen.ncols()-1;    // dimention of the space with polyhedron
00059 
00061     std::cout << "\nd = " << d;
00063 
00064     
00065     // Separate vertices and directions of recession in gen.
00066 
00067     Gen verts;  // firstly, here the vertices from gen will be stored
00068     Idxvec reces;   // indeces of the directions of recession in gen
00069     intgen.assign(0, gen.ncols());
00070 
00071     for(size_type i = 0; i < gen.nrows(); ++i)
00072     {
00073         ARAGELI_ASSERT_0(!is_negative(gen(i, 0)));
00074         if(!is_null(gen(i, 0))) // if i-th generatrix is a vertex
00075             verts.insert_row(verts.nrows(), gen.copy_row(i));
00076         else    // if i-th generatirx is a direction of recession
00077         {
00078             reces.push_back(i);
00079             intgen.insert_row(intgen.nrows(), gen.copy_row(i));
00080         }
00081     }
00082 
00084     std::cout
00085         << "\nverts.nrows() = " << verts.nrows()
00086         << "\nreces.size() = " << reces.size()
00087         << "\nreces = " << reces;
00089 
00090 
00091     // Build in verts parametric representaion (points) of an intersection
00092     // of set Q' = closing(union(Q, q^1, ..., q^t)) (p. 107, bottom)
00093     // and hyperplane x0 = 1.
00094 
00095     ARAGELI_ASSERT_0
00096     (
00097         verts.nrows()*pow(big_int(2), reces.size()) <=
00098         big_int(std::numeric_limits<size_type>::max())
00099     );
00100 
00101     vector<bool, false> reces_mask(reces.size());
00102     size_type nreccomb = power(size_type(2), reces_mask.size());    // WARNING! Way not pow?
00103     size_type norigverts = verts.nrows();
00104     //verts.reserve(norigverts*nreccomb, verts.ncols());
00105     
00106     // pass the first combination because already done:
00107     if(!reces_mask.is_empty())reces_mask[0] = true;
00108 
00110     std::cout << "\nnreccomb = " << nreccomb;
00112 
00113     
00114     for(size_type i = 1; i < nreccomb; ++i) // along to all possible reces_mask
00115     {
00116         Vec reccomb(verts.ncols());
00117         for(size_type j = 0; j < reces_mask.size(); ++j)
00118             if(reces_mask[j])reccomb += gen.copy_row(reces[j]);
00119 
00120         for(size_type j = 0; j < norigverts; ++j)
00121             verts.insert_row
00122             (
00123                 verts.nrows(),
00124                 verts.copy_row(j) + verts(j, 0)*reccomb
00125             );
00126 
00127         // move to the next combination
00128         for(size_type j = 0; j < reces_mask.size(); ++j)
00129             if(reces_mask[j])reces_mask[j] = false;
00130             else
00131             {
00132                 reces_mask[j] = true;
00133                 break;
00134             }
00135     }
00136 
00137 
00138     // Build minimal implicit representation of the polytope
00139     // with vertices verts.
00140     // At the same time system verts is being partially reduced.
00141 
00143     std::cout
00144         << "\nbefore skeleton: verts.nrows() = " << verts.nrows();
00146 
00147     Gen ineqs, q, eqs;
00148     skeleton(verts, ineqs, q, eqs);
00149 
00151     std::cout
00152         << "\nafter skeleton: verts.nrows() = " << verts.nrows()
00153         << "\nineqs.nrows() = " << ineqs.nrows()
00154         << "\neqs.nrows() = " << eqs.nrows();
00156 
00157 
00158     // Build bounding box for set G (1.6).
00159     
00160     Vec minlim(d), maxlim(d);   // limits of the bounding box
00161 
00162     for(size_type i = 0; i < verts.nrows(); ++i)
00163     {
00164         Vec v = verts.copy_row(i);
00165         v /= safe_reference(v.front()); // note, round to zero
00166 
00167         for(size_type j = 0; j < minlim.size(); ++j)
00168         {
00169             if(v[j+1] < minlim[j])minlim[j] = v[j+1];
00170             if(v[j+1] > maxlim[j])maxlim[j] = v[j+1];
00171         }
00172     }
00173 
00175     std::cout
00176         << "\nminlim = " << minlim
00177         << "\nmaxlim = " << maxlim
00178         << "\nsize box = " << maxlim - minlim + 1;
00180 
00181 
00182     // Look at any integer point in the bounding box (BB) and determine
00183     // whether G includes it with the help of the system of inequation ineqs.
00184     // Add all such points to intgen.
00185 
00186     // the number of integer points in the bounding box
00187     T nbb = product(maxlim - minlim + unit<T>());
00188 
00190     std::cout << "\nnbb = " << nbb;
00192 
00193     Vec point = minlim;
00194     point.push_front(unit<T>());    // the first component is always 1
00195 
00196     for(T i = 0; i < nbb; ++i)  // through all integer points in the BB
00197     {
00198         // determine if G includes this point
00199         if
00200         (
00201             all_greater_equal(ineqs*point, null<T>()) &&
00202             is_null(eqs*point)
00203         )
00204             intgen.insert_row(intgen.nrows(), point);
00205 
00206         // move to the next point in BB
00207         for(size_type j = 1; j < point.size(); ++j)
00208             if(point[j] == maxlim[j-1])point[j] = minlim[j-1];
00209             else
00210             {
00211                 ++point[j];
00212                 break;
00213             }
00214     }
00215 
00217     std::cout << "\nintgen.nrows() = " << intgen.nrows();
00219 
00220 }
00221 
00222 }
00223 
00224 
00225 #if ARAGELI_DEBUG_LEVEL > 3
00226 
00227 #include "matrix.hpp"
00228 
00229 namespace Arageli
00230 {
00231 
00232 template void intconvex_simple
00233 (
00234     const matrix<big_int, true>& gen,
00235     matrix<big_int, true>& intgen
00236 );
00237 
00238 
00239 template void intconvex_simple
00240 (
00241     const matrix<big_int, false>& gen,
00242     matrix<big_int, false>& intgen
00243 );
00244 
00245 
00246 template void intconvex_simple
00247 (
00248     const matrix<int, true>& gen,
00249     matrix<int, true>& intgen
00250 );
00251 
00252 
00253 template void intconvex_simple
00254 (
00255     const matrix<int, false>& gen,
00256     matrix<int, false>& intgen
00257 );
00258 
00259 
00260 }
00261 
00262 #endif
00263 
00264 
00265 #endif  // #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || ...

Generated on Thu Aug 31 17:38:06 2006 for Arageli by  doxygen 1.4.7