cone.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     cone.cpp -- See declarations in cone.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, 2005--2006
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_cone)
00022 
00023 
00024 #include "vector.hpp"
00025 #include "skeleton.hpp"
00026 
00027 #include "cone.hpp"
00028 
00029 
00030 namespace Arageli
00031 {
00032 
00033 
00034 template <typename T, typename M, typename CFG>
00035 template <typename Cone1>
00036 cone<T, M, CFG>::cone (const Cone1& c, const fromdual_t&) : state(State(0))
00037 {
00038     // WARNING! This implementation is correct if inequation is 'Ax >= 0'.
00039     // If inequation is 'Ax <= 0', we need to flip signs.
00040     // Ehh... Actualy we need unique definition of a dual cone.
00041     
00042     if(c.is_implicit_valid())
00043     {
00044         generatrix_m = c.inequation_matrix();
00045         basis_m = c.equation_matrix();
00046         
00047         if(c.is_implicit_normal())set_flag(STATE_PARAMETRIC);
00048         else set_flag(STATE_PARAMETRIC_VALID);
00049 
00050     }
00051 
00052     if(c.is_parametric_valid())
00053     {
00054         inequation_m = c.generatrix_matrix();
00055         equation_m = c.basis_matrix();
00056         
00057         if(c.is_parametric_normal())set_flag(STATE_IMPLICIT);
00058         else set_flag(STATE_IMPLICIT_VALID);
00059     }
00060 
00061     ARAGELI_ASSERT_1(is_correct_flags());
00062     ARAGELI_ASSERT_0(is_there_valid());
00063 }
00064 
00065 
00066 template <typename T, typename M, typename CFG>
00067 bool cone<T, M, CFG>::is_pointed () const
00068 {
00069     ARAGELI_ASSERT_1(is_correct_flags());
00070     ARAGELI_ASSERT_0(is_there_valid());
00071 
00072     // If a cone doesn't have non-zero subspace, it's a pointed cone.
00073     if(is_parametric_normal())
00074         return basis_m.is_empty();
00075     else if(is_implicit_normal() && inequation_m.is_empty())
00076         return equation_m.is_square();
00077     else if(is_parametric_valid() && !Arageli::is_null(basis_m))
00078         return false;
00079     else
00080     {
00081         normalize_parametric();
00082         return basis_m.is_empty();
00083     }
00084 }
00085 
00086 
00087 template <typename T, typename M, typename CFG>
00088 bool cone<T, M, CFG>::is_subspace () const
00089 {
00090     ARAGELI_ASSERT_1(is_correct_flags());
00091     ARAGELI_ASSERT_0(is_there_valid());
00092 
00093     if(is_implicit_normal())
00094         return inequation_m.is_empty();
00095     else if(is_parametric_normal())
00096         return generatrix_m.is_empty();
00097     else if(is_implicit_valid() && Arageli::is_null(inequation_m))
00098         return true;
00099     else if(is_parametric_valid() && Arageli::is_null(generatrix_m))
00100         return true;
00101     else
00102     {
00103         normalize_implicit();
00104         return inequation_m.is_empty();
00105     }
00106 }
00107 
00108 
00109 template <typename T, typename M, typename CFG>
00110 bool cone<T, M, CFG>::is_space () const
00111 {
00112     ARAGELI_ASSERT_1(is_correct_flags());
00113     ARAGELI_ASSERT_0(is_there_valid());
00114 
00115     if(is_implicit_valid())
00116         return Arageli::is_null(inequation_m) && Arageli::is_null(equation_m);
00117     else if(is_parametric_normal())
00118     {
00119         ARAGELI_ASSERT_1(!basis_m.is_square() || generatrix_m.is_empty());
00120         return basis_m.is_square();
00121     }
00122     else
00123     {
00124         force_normalize_implicit();
00125         return inequation_m.is_empty() && equation_m.is_empty();
00126     }
00127 }
00128 
00129 
00130 template <typename T, typename M, typename CFG>
00131 bool cone<T, M, CFG>::is_null () const
00132 {
00133     // WARNING! This function is completely dual to is_space function.
00134     // TODO: Rewrite these pair of functions as one general.
00135 
00136     ARAGELI_ASSERT_1(is_correct_flags());
00137     ARAGELI_ASSERT_0(is_there_valid());
00138 
00139     if(is_parametric_valid())
00140         return Arageli::is_null(generatrix_m) && Arageli::is_null(basis_m);
00141     else if(is_implicit_normal())
00142     {
00143         ARAGELI_ASSERT_1(!equation_m.is_square() || inequation_m.is_empty());
00144         return equation_m.is_square();
00145     }
00146     else
00147     {
00148         force_normalize_parametric();
00149         return generatrix_m.is_empty() && basis_m.is_empty();
00150     }
00151 }
00152 
00153 
00154 template <typename T, typename M, typename CFG>
00155 typename cone<T, M, CFG>::dim_type
00156 cone<T, M, CFG>::space_dim () const
00157 {
00158     ARAGELI_ASSERT_1(is_correct_flags());
00159     ARAGELI_ASSERT_0(is_there_valid());
00160 
00161     if(is_implicit_valid())
00162         return inequation_m.ncols();
00163     else
00164         return generatrix_m.ncols();
00165 }
00166 
00167 
00168 template <typename T, typename M, typename CFG>
00169 typename cone<T, M, CFG>::dim_type
00170 cone<T, M, CFG>::dim () const
00171 {
00172     ARAGELI_ASSERT_1(is_correct_flags());
00173     ARAGELI_ASSERT_0(is_there_valid());
00174 
00175     normalize_implicit();
00176     return equation_m.ncols() - equation_m.nrows();
00177 }
00178 
00179 
00180 template <typename T, typename M, typename CFG>
00181 bool cone<T, M, CFG>::is_simplicial () const
00182 {
00183     ARAGELI_ASSERT_1(is_correct_flags());
00184     ARAGELI_ASSERT_0(is_there_valid());
00185 
00186     normalize_implicit();
00187     ARAGELI_ASSERT_1(inequation_m.nrows() != equation_m.ncols() || max_embedded_basis().is_empty());
00188     return inequation_m.nrows() == equation_m.ncols() - equation_m.nrows();
00189 }
00190 
00191 
00192 
00193 template <typename T, typename M, typename CFG>
00194 typename cone<T, M, CFG>::inequation_type
00195 cone<T, M, CFG>::inequation () const
00196 {
00197     ARAGELI_ASSERT_1(is_correct_flags());
00198     ARAGELI_ASSERT_0(is_there_valid());
00199 
00200     validate_implicit();
00201 
00202     if(Arageli::is_null(equation_m))
00203         return inequation_m;
00204     else
00205     {
00206         inequation_type res = inequation_m;
00207         extend_rep_matrix(res, equation_m);
00208         return res;
00209     }
00210 }
00211 
00212 
00213 template <typename T, typename M, typename CFG>
00214 typename cone<T, M, CFG>::generatrix_type
00215 cone<T, M, CFG>::generatrix () const
00216 {
00217     // WARNING! This function is completely dual to inequation function.
00218     // TODO: Rewrite these pair of functions as one general.
00219 
00220     ARAGELI_ASSERT_1(is_correct_flags());
00221     ARAGELI_ASSERT_0(is_there_valid());
00222 
00223     validate_parametric();
00224 
00225     if(Arageli::is_null(basis_m))
00226         return generatrix_m;
00227     else
00228     {
00229         generatrix_type res = generatrix_m;
00230         extend_rep_matrix(res, basis_m);
00231         return res;
00232     }
00233 }
00234 
00235 
00236 template <typename T, typename M, typename CFG>
00237 const typename cone<T, M, CFG>::equation_type&
00238 cone<T, M, CFG>::equation () const
00239 {
00240     ARAGELI_ASSERT_1(is_correct_flags());
00241     ARAGELI_ASSERT_0(is_there_valid());
00242 
00243     normalize_implicit();
00244 
00245     if(!is_subspace())throw cannot_represent_cone();
00246     else return equation_m;
00247 }
00248 
00249 
00250 template <typename T, typename M, typename CFG>
00251 const typename cone<T, M, CFG>::basis_type&
00252 cone<T, M, CFG>::basis () const
00253 {
00254     ARAGELI_ASSERT_1(is_correct_flags());
00255     ARAGELI_ASSERT_0(is_there_valid());
00256 
00257     normalize_parametric();
00258 
00259     if(!is_subspace())throw cannot_represent_cone();
00260     else return basis_m;
00261 }
00262 
00263 
00264 template <typename T, typename M, typename CFG>
00265 const typename cone<T, M, CFG>::equation_type&
00266 cone<T, M, CFG>::min_ambient_equation () const
00267 {
00268     ARAGELI_ASSERT_1(is_correct_flags());
00269     ARAGELI_ASSERT_0(is_there_valid());
00270 
00271     normalize_implicit();
00272     return equation_m;
00273 }
00274 
00275 
00276 template <typename T, typename M, typename CFG>
00277 const typename cone<T, M, CFG>::basis_type&
00278 cone<T, M, CFG>::max_embedded_basis () const
00279 {
00280     // WARNING! This function is completely dual to min_ambient_equation function.
00281     // TODO: Rewrite these pair of functions as one general.
00282     
00283     ARAGELI_ASSERT_1(is_correct_flags());
00284     ARAGELI_ASSERT_0(is_there_valid());
00285 
00286     normalize_parametric();
00287     return basis_m;
00288 }
00289 
00290 
00291 template <typename T, typename M, typename CFG>
00292 typename cone<T, M, CFG>::inequation_type cone<T, M, CFG>::min_inequation () const
00293 {
00294     normalize_implicit();
00295 
00296     if(equation_m.is_empty())
00297         return inequation_m;
00298     else
00299     {
00300         inequation_type res = inequation_m;
00301         res.insert_matrix_bottom(equation_m);
00302         vector<T, false> lastrow = equation_m.copy_row(0);
00303 
00304         for(size_type i = 1; i < equation_m.nrows(); ++i)
00305             for(size_type j = 0; j < equation_m.ncols(); ++j)
00306                 lastrow[j] += equation_m(i, j);
00307 
00308         Arageli::opposite(&lastrow);
00309         res.insert_row(res.nrows(), lastrow);
00310 
00311         return res;
00312     }
00313 }
00314 
00315 
00316 template <typename T, typename M, typename CFG>
00317 typename cone<T, M, CFG>::generatrix_type cone<T, M, CFG>::min_generatrix () const
00318 {
00319     // WARNING! This function is completely dual to min_inequation function.
00320     // TODO: Rewrite these pair of functions as one general.
00321     
00322     normalize_parametric();
00323 
00324     if(basis_m.is_empty())
00325         return generatrix_m;
00326     else
00327     {
00328         generatrix_type res = generatrix_m;
00329         res.insert_matrix_bottom(basis_m);
00330         vector<T, false> lastrow = basis_m.copy_row(0);
00331 
00332         for(size_type i = 1; i < basis_m.nrows(); ++i)
00333             for(size_type j = 0; j < basis_m.ncols(); ++j)
00334                 lastrow[j] += basis_m(i, j);
00335 
00336         Arageli::opposite(&lastrow);
00337         res.insert_row(res.nrows(), lastrow);
00338 
00339         return res;
00340     }
00341 }
00342 
00343 
00344 template <typename T, typename M, typename CFG>
00345 template <typename Cone1>
00346 cone<T, M, CFG>& cone<T, M, CFG>::intersection (const Cone1& x)
00347 {
00348     ARAGELI_ASSERT_1(is_correct_flags());
00349     ARAGELI_ASSERT_0(is_there_valid());
00350     ARAGELI_ASSERT_0(space_dim() == x.space_dim());
00351 
00352     if(!x.is_space())   // WARNING! Too expensive because normalization!
00353     {
00354         validate_implicit();
00355         x.validate_implicit();
00356         clear_flag(STATE_PARAMETRIC | STATE_IMPLICIT_NORMAL);
00357         inequation_m.insert_matrix_bottom(x.inequation_matrix());
00358         equation_m.insert_matrix_bottom(x.equation_matrix());
00359     }
00360 
00361     return *this;
00362 }
00363 
00364 
00365 template <typename T, typename M, typename CFG>
00366 template <typename Cone1>
00367 cone<T, M, CFG>& cone<T, M, CFG>::conic_union (const Cone1& x)
00368 {
00369     // WARNING! This function is completely dual to intersection function.
00370     // TODO: Rewrite these pair of functions as one general.
00371     
00372     ARAGELI_ASSERT_1(is_correct_flags());
00373     ARAGELI_ASSERT_0(is_there_valid());
00374     ARAGELI_ASSERT_0(space_dim() == x.space_dim());
00375 
00376     if(!x.is_null())    // WARNING! Too expensive because normalization!
00377     {
00378         validate_parametric();
00379         x.validate_parametric();
00380         clear_flag(STATE_IMPLICIT | STATE_PARAMETRIC_NORMAL);
00381         generatrix_m.insert_matrix_bottom(x.generatrix_matrix());
00382         basis_m.insert_matrix_bottom(x.basis_matrix());
00383     }
00384 
00385     return *this;
00386 }
00387 
00388 
00389 template <typename T, typename M, typename CFG>
00390 void cone<T, M, CFG>::force_validate_implicit () const
00391 {
00392     ARAGELI_ASSERT_1(is_correct_flags());
00393     ARAGELI_ASSERT_0(get_flag(STATE_PARAMETRIC_VALID));
00394 
00395     generatrix_type a = generatrix_m;
00396     extend_rep_matrix(a, basis_m);
00397 
00398     inequation_type q;  // may be it should be saved after the operation?
00399     skeleton(a, inequation_m, q, equation_m);
00400     //output_aligned(std::cout << "\nq =\n", q);
00401 
00402     set_flag(STATE_IMPLICIT);
00403 }
00404 
00405 
00406 template <typename T, typename M, typename CFG>
00407 void cone<T, M, CFG>::force_validate_parametric () const
00408 {
00409     ARAGELI_ASSERT_1(is_correct_flags());
00410     ARAGELI_ASSERT_0(get_flag(STATE_IMPLICIT_VALID));
00411 
00412     inequation_type a = inequation_m;
00413     extend_rep_matrix(a, equation_m);
00414 
00415     generatrix_type q;  // may be it should be saved after the operation?
00416     skeleton(a, generatrix_m, q, basis_m);
00417     //output_aligned(std::cout << "\nq =\n", q);
00418 
00419     set_flag(STATE_PARAMETRIC);
00420 }
00421 
00422 
00423 template <typename T, typename M, typename CFG>
00424 void cone<T, M, CFG>::force_normalize_implicit () const
00425 {
00426     // WARNING! Slow implementation.
00427     // TODO: Make it faster!
00428 
00429     validate_parametric();
00430     force_validate_implicit();
00431 }
00432 
00433 
00434 template <typename T, typename M, typename CFG>
00435 void cone<T, M, CFG>::force_normalize_parametric () const
00436 {
00437     // WARNING! Slow implementation.
00438     // TODO: Make it faster!
00439 
00440     validate_implicit();
00441     force_validate_parametric();
00442 }
00443 
00444 
00445 template <typename T, typename M, typename CFG>
00446 void cone<T, M, CFG>::force_normalize_all () const
00447 {
00448     // WARNING! Slow implementation.
00449     // TODO: Make it faster!
00450 
00451     if(get_flag(STATE_IMPLICIT_VALID))
00452     {
00453         force_validate_parametric();
00454         force_validate_implicit();
00455     }
00456     else
00457     {
00458         ARAGELI_ASSERT_0(get_flag(STATE_PARAMETRIC_VALID));
00459         
00460         force_validate_implicit();
00461         force_validate_parametric();
00462     }
00463 }
00464 
00465 
00466 template <typename Out, typename T, typename M, typename CFG>
00467 void output_list (Out& out, const cone<T, M, CFG>& x)
00468 {
00469     out << "(" << x.state << ", " << x.space_dim() << ", ";
00470     output_list(out, x.inequation_m);
00471     out << ", ";
00472     output_list(out, x.equation_m);
00473     out << ", ";
00474     output_list(out, x.generatrix_m);
00475     out << ", ";
00476     output_list(out, x.basis_m);
00477     out << ")";
00478 }
00479 
00480 
00481 }
00482 
00483 
00484 #else   // #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || ...
00485 
00486 
00487 namespace Arageli
00488 {
00489 
00490 // PLACE ALL NOT TEMPLATE NOT INLINE IMPLEMENTATIONS HERE
00491 
00492 }
00493 
00494 
00495 #endif  // #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || ...

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