00001
00002
00003
00004
00005
00006
00007
00008
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
00039
00040
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
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
00134
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
00218
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
00281
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
00320
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())
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
00370
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())
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;
00399 skeleton(a, inequation_m, q, equation_m);
00400
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;
00416 skeleton(a, generatrix_m, q, basis_m);
00417
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
00427
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
00438
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
00449
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
00491
00492 }
00493
00494
00495 #endif // #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || ...