00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef _ARAGELI_CTRL_SLOG_HPP_
00015 #define _ARAGELI_CTRL_SLOG_HPP_
00016
00017
00028 #include "config.hpp"
00029
00030 #include "factory.hpp"
00031 #include "exception.hpp"
00032 #include "gauss.hpp"
00033 #include "simplex_method.hpp"
00034 #include "matrix.hpp"
00035 #include "motzkin_burger.hpp"
00036 #include "skeleton.hpp"
00037
00038 #include "std_import.hpp"
00039
00040 namespace Arageli
00041 {
00042 namespace ctrl
00043 {
00044
00045 template <typename Stream>
00046 struct rref_gauss_field_slog : public rref_gauss_field_idler
00047 {
00048 class abort : public rref_gauss_field_idler::abort {};
00049
00050 Stream& stream_m;
00051 bool preamble_on, conclusion_on;
00052
00053 rref_gauss_field_slog
00054 (
00055 Stream& stream_a,
00056 bool preamble_on_a = true,
00057 bool conclusion_on_a = true
00058 ) :
00059 stream_m(stream_a),
00060 preamble_on(preamble_on_a),
00061 conclusion_on(conclusion_on_a)
00062 {}
00063
00064 template <typename A>
00065 void preamble (const A& a) const
00066 {
00067 if(!preamble_on)return;
00068
00069 title();
00070 stream() << '\n';
00071 output_aligned(stream(), a);
00072 stream();
00073 finish_preamble();
00074 stream() << '\n';
00075 }
00076
00077 template <typename B, typename Q, typename Det, typename Basis>
00078 void conclusion (const B& b, const Q& q, const Det& det, const Basis& basis) const
00079 {
00080 if(conclusion_on)
00081 {
00082 output_aligned_hor_pair(stream(), b, q);
00083 begin_conclusion(); stream() << ' ';
00084 rref_name();
00085 output_aligned(stream() << '\n', b);
00086 inverse_name();
00087 output_aligned(stream() << '\n', q);
00088 }
00089 else
00090 {
00091 output_aligned_hor_pair(stream(), b, q);
00092 }
00093
00094 basis_name();
00095 stream() << ' ' << basis+1 << '\n';
00096 det_name();
00097 stream() << ' ' << det << '\n';
00098 }
00099
00100 template <typename B, typename Q, typename Det, typename Basis>
00101 void before_iter (const B& b, const Q& q, const Det& det, const Basis& basis) const
00102 {
00103 output_aligned_hor_pair(stream(), b, q);
00104 basis_name();
00105 stream() << ' ' << basis+1 << '\n';
00106 det_name();
00107 stream() << ' ' << det << '\n';
00108 }
00109
00110 template <typename B, typename Q, typename Det, typename Basis>
00111 void after_iter (const B& b, const Q& q, const Det& det, const Basis& basis) const {}
00112
00113 template <typename J>
00114 void find_biggest_in_col (const J& j) const
00115 {
00116 find_biggest_in_col_name();
00117 stream() << ' ' << j+1 << '\n';
00118 }
00119
00120 template <typename J>
00121 void negligible_col (const J& j) const
00122 {
00123 col_name();
00124 stream() << ' ' << j+1 << ' ';
00125 is_negligible_name();
00126 stream() << '\n';
00127 }
00128
00129 template <typename I, typename J>
00130 void pivot_item (const I& i, const J& j) const
00131 {
00132 pivot_item_name();
00133 stream() << " (" << i+1 << ", " << j+1 << ")\n";
00134 }
00135
00136 template <typename I1, typename I2, typename B, typename Q, typename Det>
00137 void swap_rows (const I1& i1, const I2& i2, const B& b, const Q& q, const Det& det) const
00138 {
00139 swap_rows_name();
00140 stream() << ' ' << i1+1 << ", " << i2+1 << '\n';
00141 output_aligned_hor_pair(stream(), b, q);
00142 det_name();
00143 stream() << ' ' << det << '\n';
00144 }
00145
00146 template <typename J>
00147 void eliminate_col (const J& j) const
00148 {
00149 eliminate_col_name();
00150 stream() << ' ' << j+1 << '\n';
00151 }
00152
00153 template <typename B, typename Q, typename Det>
00154 void after_elimination (const B& b, const Q& q, const Det& det) const
00155 {
00156
00157
00158
00159 }
00160
00161 protected:
00162
00163 virtual std::ostream& stream () const { return stream_m; }
00164
00165 virtual void title () const
00166 { stream() << "Producing of reduced row echelon form for matrix"; }
00167
00168 virtual void begin_conclusion () const
00169 { stream() << "The task has been solved. "; }
00170
00171 virtual void finish_preamble () const
00172 {
00173 stream() << "Lets write additionaly an unitary matrix "
00174 "and produce gauss iterations. ";
00175 }
00176
00177 virtual void find_biggest_in_col_name () const
00178 { stream() << "Find the biggest (in absolute value) entry in a column"; }
00179
00180 virtual void det_name () const { stream() << "Determinant is"; }
00181 virtual void basis_name () const { stream() << "Basis is"; }
00182 virtual void col_name () const { stream() << "Column"; }
00183 virtual void is_negligible_name () const { stream() << "is negligible"; }
00184 virtual void pivot_item_name () const { stream() << "Pivot item is"; }
00185 virtual void swap_rows_name () const { stream() << "Swap rows"; }
00186 virtual void eliminate_col_name () const { stream() << "Eliminate in column"; }
00187 virtual void rref_name () const { stream() << "Found reduced row echelon form is"; }
00188 virtual void inverse_name () const { stream() << "Inverse of input matrix is"; }
00189 };
00190
00191
00192 template <typename Stream>
00193 inline rref_gauss_field_slog<Stream> make_rref_gauss_field_slog
00194 (Stream& stream, bool preamble = true, bool conclusion = true)
00195 { return rref_gauss_field_slog<Stream>(stream, preamble, conclusion); }
00196
00197
00198 template <typename Stream>
00199 struct rref_gauss_bareiss_slog : public rref_gauss_field_slog<Stream>
00200 {
00201 protected:
00202
00203 using rref_gauss_field_slog<Stream>::stream;
00204
00205 public:
00206
00207 class abort : public rref_gauss_bareiss_idler::abort {};
00208
00209 rref_gauss_bareiss_slog
00210 (
00211 Stream& stream_a,
00212 bool preamble_on_a = true,
00213 bool conclusion_on_a = true
00214 ) : rref_gauss_field_slog<Stream>(stream_a, preamble_on_a, conclusion_on_a) {}
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 template
00225 <
00226 typename B, typename Q, typename Det,
00227 typename Basis, typename Det_denom
00228 >
00229 void before_iter
00230 (
00231 const B& b, const Q& q, const Det& det,
00232 const Basis& basis, const Det_denom& det_denom
00233 ) const
00234 {
00235 rref_gauss_field_slog<Stream>::before_iter(b, q, det, basis);
00236 det_denom_name();
00237 stream() << ' ' << det_denom << '\n';
00238 }
00239
00240 template
00241 <
00242 typename B, typename Q, typename Det,
00243 typename Basis, typename Det_denom
00244 >
00245 void after_iter
00246 (
00247 const B& b, const Q& q, const Det& det,
00248 const Basis& basis, const Det_denom& det_denom
00249 ) const
00250 { rref_gauss_field_slog<Stream>::after_iter(b, q, det, basis); }
00251
00252 template
00253 <
00254 typename I1, typename I2, typename B,
00255 typename Q, typename Det, typename Det_denom
00256 >
00257 void swap_rows
00258 (
00259 const I1& i1, const I2& i2, const B& b,
00260 const Q& q, const Det& det, const Det_denom& det_denom
00261 ) const
00262 {
00263 rref_gauss_field_slog<Stream>::swap_rows(i1, i2, b, q, det);
00264 det_denom_name();
00265 stream() << ' ' << det_denom << '\n';
00266 }
00267
00268 template <typename B, typename Q, typename Det, typename Det_denom>
00269 void after_elimination
00270 (
00271 const B& b, const Q& q, const Det& det,
00272 const Det_denom& det_denom
00273 ) const
00274 {
00275
00276
00277
00278 }
00279
00280 template <typename J>
00281 void find_nonzero_in_col (const J& j) const
00282 {
00283 find_nonzero_in_col_name();
00284 stream() << ' ' << j+1 << '\n';
00285 }
00286
00287 protected:
00288
00289 virtual void title () const
00290 { stream() << "Producing of reduced row echelon form for integer matrix"; }
00291
00292 virtual void find_nonzero_in_col_name () const
00293 { stream() << "Find nonzero entry in a column"; }
00294
00295 virtual void det_denom_name () const
00296 { stream() << "Determinant denominator"; }
00297
00298 virtual void det_name () const
00299 { stream() << "Determinant numerator"; }
00300
00301 };
00302
00303
00304 template <typename Stream>
00305 inline rref_gauss_bareiss_slog<Stream> make_rref_gauss_bareiss_slog
00306 (Stream& stream, bool preamble = true, bool conclusion = true)
00307 { return rref_gauss_bareiss_slog<Stream>(stream, preamble, conclusion); }
00308
00309
00310 template <typename Stream>
00311 struct rref_field_slog : public rref_field_idler
00312 {
00313 class abort : public rref_field_idler::abort {};
00314
00315 Stream& stream_m;
00316 bool preamble_on, conclusion_on;
00317
00318 rref_field_slog
00319 (
00320 Stream& stream_a,
00321 bool preamble_on_a = true,
00322 bool conclusion_on_a = true
00323 ) :
00324 stream_m(stream_a),
00325 preamble_on(preamble_on_a),
00326 conclusion_on(conclusion_on_a)
00327 {}
00328
00329 rref_gauss_field_slog<Stream> ctrl_rref_gauss_field () const
00330 { return rref_gauss_field_slog<Stream>(stream_m, preamble_on, conclusion_on); }
00331 };
00332
00333
00334 template <typename Stream>
00335 inline rref_field_slog<Stream> make_rref_field_slog
00336 (Stream& stream, bool preamble = true, bool conclusion = true)
00337 { return rref_field_slog<Stream>(stream, preamble, conclusion); }
00338
00339
00340 template <typename Stream>
00341 struct rref_int_slog : public rref_int_idler
00342 {
00343 class abort : public rref_int_idler::abort {};
00344
00345 Stream& stream_m;
00346 bool preamble_on, conclusion_on;
00347
00348 rref_int_slog
00349 (
00350 Stream& stream_a,
00351 bool preamble_on_a = true,
00352 bool conclusion_on_a = true
00353 ) :
00354 stream_m(stream_a),
00355 preamble_on(preamble_on_a),
00356 conclusion_on(conclusion_on_a)
00357 {}
00358
00359 rref_gauss_bareiss_slog<Stream> ctrl_rref_gauss_bareiss () const
00360 { return rref_gauss_bareiss_slog<Stream>(stream_m, preamble_on, conclusion_on); }
00361 };
00362
00363
00364 template <typename Stream>
00365 inline rref_int_slog<Stream> make_rref_int_slog
00366 (Stream& stream, bool preamble = true, bool conclusion = true)
00367 { return rref_int_slog<Stream>(stream, preamble, conclusion); }
00368
00369
00370 template <typename Stream>
00371 struct rref_slog : public rref_idler
00372 {
00373 class abort : public rref_idler::abort {};
00374
00375 Stream& stream_m;
00376 bool preamble_on, conclusion_on;
00377
00378 rref_slog
00379 (
00380 Stream& stream_a,
00381 bool preamble_on_a = true,
00382 bool conclusion_on_a = true
00383 ) :
00384 stream_m(stream_a),
00385 preamble_on(preamble_on_a),
00386 conclusion_on(conclusion_on_a)
00387 {}
00388
00389 rref_field_slog<Stream> ctrl_rref_field () const
00390 { return rref_field_slog<Stream>(stream_m, preamble_on, conclusion_on); }
00391
00392 rref_int_slog<Stream> ctrl_rref_int () const
00393 { return rref_int_slog<Stream>(stream_m, preamble_on, conclusion_on); }
00394 };
00395
00396
00397 template <typename Stream>
00398 inline rref_slog<Stream> make_rref_slog
00399 (Stream& stream, bool preamble = true, bool conclusion = true)
00400 { return rref_slog<Stream>(stream, preamble, conclusion); }
00401
00402
00403 template <typename Stream>
00404 struct smith_slog
00405 {
00406 Stream& stream;
00407
00408 smith_slog (Stream& stream_a) : stream(stream_a) {}
00409
00410 void preamble ()
00411 { stream << "Smith's normal diagonal form\n"; }
00412
00413 void conclusion ()
00414 {}
00415
00416 template <typename Q, typename B, typename P>
00417 void current_matrices (const Q& q, const B& b, const P& p)
00418 { output_aligned_corner_triplet_br(stream, q, b, p); }
00419
00420 template <typename I, typename J>
00421 void find_smallest_nonzero (const I& i, const J& j)
00422 {
00423 stream << "The smallest (in absolute value) non-zero entry: ("
00424 << i << ", " << j << ")\n";
00425 }
00426
00427 template <typename I, typename J>
00428 void pivot_item (const I& i, const J& j)
00429 { stream << "Pivoting item: (" << i << ", " << j << ")\n"; }
00430
00431 void after_pivoting () { stream << "After pivoting step:\n"; }
00432
00433 template <typename I, typename J>
00434 void nondivisor_entry (const I& k, const I& i, const J& l)
00435 {
00436 stream
00437 << "Non-divisor entry: (" << k << ", " << l << ")\n"
00438 << "Add the " << k << "-th row to the " << i
00439 << "-th row\n";
00440 }
00441
00442 void pivot_adjustment ()
00443 { stream << "After pivot item adjustment:\n"; }
00444
00445 template <typename C, typename I, typename J, typename Q, typename B, typename P>
00446 bool stop (const C& corner, const I& i, const J& j, const Q& q, const B& b, const P& p)
00447 { return false; }
00448 };
00449
00450
00451 template <typename Stream>
00452 inline smith_slog<Stream> make_smith_slog (Stream& stream)
00453 { return smith_slog<Stream>(stream); }
00454
00455
00456 namespace simplex_method
00457 {
00458
00459
00460
00461
00463 template <typename Stream>
00464 struct primal_col_iters_slog
00465 {
00466 Stream& stream;
00467
00468 primal_col_iters_slog (Stream& stream_a)
00469 : stream(stream_a) {}
00470
00471 void preamble () const { stream << "Direct column simplex method iterations.\n"; }
00472 void conclusion () const {}
00473
00474 primal_col_iter_slog<Stream> iter_ctrl () const
00475 { return primal_col_iter_slog<Stream>(stream); }
00476
00477 template <typename TQ, typename Tb>
00478 bool stop (const TQ&, const Tb&) const { return false; }
00479 };
00480
00481
00483 template <typename Stream>
00484 struct dual_col_iters_slog
00485 {
00486 Stream& stream;
00487
00488 dual_col_iters_slog (Stream& stream_a)
00489 : stream(stream_a) {}
00490
00491 void preamble () const { stream << "Direct column simplex method iterations.\n"; }
00492 void conclusion () const {}
00493
00494 dual_col_iter_slog<Stream> iter_ctrl () const
00495 { return dual_col_iter_slog<Stream>(stream); }
00496
00497 template <typename TQ, typename Tb>
00498 bool stop (const TQ&, const Tb&) const { return false; }
00499 };
00500
00501
00503 template <typename Stream>
00504 struct primal_row_iters_slog : public primal_row_iters_idler
00505 {
00506 class abort : public primal_row_iters_idler::abort {};
00507
00508 Stream& stream;
00509 bool preamble_on, conclusion_on;
00510
00511 primal_row_iters_slog
00512 (
00513 Stream& stream_a,
00514 bool preamble_on_a = true,
00515 bool conclusion_on_a = true
00516 ) :
00517 stream(stream_a),
00518 preamble_on(preamble_on_a),
00519 conclusion_on(conclusion_on_a)
00520 {}
00521
00522 template <typename Q, typename Basis>
00523 void preamble (const Q& q, const Basis& basis) const
00524 {
00525 if(!preamble_on)return;
00526
00527 stream << begin_preamble();
00528 if(*begin_preamble())stream << '\n';
00529 stream << finish_preamble();
00530 if(*finish_preamble())stream << '\n';
00531 }
00532
00533 template <typename Q, typename Basis>
00534 void conclusion (const Q& q, const Basis& basis, result_kind rk) const
00535 {
00536 stream << result_name(rk) << ".\n";
00537 if(!conclusion_on)return;
00538 stream << finish_conclusion() << ".\n";
00539 }
00540
00541 template <typename Q, typename Basis>
00542 void before_iter (const Q& q, const Basis& basis) const
00543 {
00544 output_aligned(stream, q);
00545 stream << basis_name() << ' ' << basis << '\n';
00546 }
00547
00548 template <typename Q, typename Basis, typename Pivot>
00549 void after_iter
00550 (
00551 const Q& q, const Basis& basis,
00552 Pivot prow, Pivot pcol,
00553 result_kind rk
00554 ) const
00555 {
00556 ARAGELI_ASSERT_0(rk != rk_empty);
00557
00558 switch(rk)
00559 {
00560 case rk_infinite:
00561 stream << pivot_col_name() << ' ' << pcol << '\n';
00562 break;
00563 case rk_nonoptimal:
00564 stream
00565 << pivot_item_name()
00566 << " (" << prow << ", " << pcol << ")\n";
00567 break;
00568 }
00569 }
00570
00571 protected:
00572
00573 virtual const char* begin_preamble () const
00574 { return "The primal row iterations on simplex table"; }
00575
00576 virtual const char* finish_preamble () const { return ""; }
00577 virtual const char* basis_name () const { return "Basis is"; }
00578
00579 virtual const char* finish_conclusion () const
00580 { return "The task has been solved"; }
00581
00582 virtual const char* result_name (result_kind rk) const
00583 {
00584 static const char* rns[] =
00585 {
00586 "An optimum is found",
00587 "The set of feasible points is empty",
00588 "The criterion function is unbounded",
00589 "The table is nonoptimal"
00590 };
00591
00592 return rns[rk];
00593 }
00594
00595 virtual const char* pivot_col_name () const { return "Pivot column is"; }
00596 virtual const char* pivot_item_name () const { return "Pivot item is"; }
00597 };
00598
00599
00601 template <typename Stream>
00602 struct basis_create_by_artificial_slog : public basis_create_by_artificial_idler
00603 {
00604 class abort : public basis_create_by_artificial_idler::abort {};
00605
00606 Stream& stream;
00607 bool preamble_on, conclusion_on;
00608
00609 basis_create_by_artificial_slog
00610 (
00611 Stream& stream_a,
00612 bool preamble_on_a = true,
00613 bool conclusion_on_a = true
00614 ) :
00615 stream(stream_a),
00616 preamble_on(preamble_on_a),
00617 conclusion_on(conclusion_on_a)
00618 {}
00619
00620 template <typename Q, typename Basis>
00621 void preamble (const Q& q, const Basis& basis) const
00622 {
00623 if(!preamble_on)return;
00624
00625 stream << begin_preamble();
00626 if(*begin_preamble())stream << '\n';
00627 output_aligned(stream, q);
00628 stream << basis_name() << ' ' << basis << '\n';
00629 stream << finish_preamble();
00630 if(*finish_preamble())stream << '\n';
00631 }
00632
00633 template <typename Q, typename Basis>
00634 void conclusion (const Q& q, const Basis& basis) const
00635 {
00636 if(!conclusion_on)return;
00637
00638 stream << built_table_name() << '\n';
00639 output_aligned(stream, q);
00640 stream << basis_name() << ' ' << basis << '\n';
00641 stream << finish_conclusion() << ".\n";
00642 }
00643
00644 template <typename Q, typename Basis, typename Index>
00645 void artif_in_basis
00646 (const Q& q, const Basis& basis, const Index& index) const
00647 {
00648 output_aligned(stream, q);
00649 stream << basis_name() << ' ' << basis << '\n';
00650 stream << artif_in_basis_name() << ' ' << basis[index] << ".\n";
00651 }
00652
00653 template <typename I>
00654 void negligible_row (const I& i) const
00655 {
00656 stream
00657 << row_name() << ' ' << i << ' '
00658 << is_negligible_name() << ".\n";
00659 }
00660
00661 template <typename Q, typename Basis, typename Index>
00662 void replace_basis_item
00663 (
00664 const Q& q, const Basis& basis,
00665 const Index& iold, const Index& r, const Index& inew
00666 ) const
00667 {
00668 stream
00669 << replace_basis_item_name() << ' ' << basis[iold]
00670 << ' ' << to_name() << ' ' << inew << '\n';
00671 stream << pivot_item_name() << " (" << r << ", " << inew << '\n';
00672 }
00673
00674 template <typename Q, typename Basis>
00675 void before_erase_artif (const Q& q, const Basis& basis) const
00676 {
00677 output_aligned(stream, q);
00678 stream << basis_name() << ' ' << basis << '\n';
00679 }
00680
00681 protected:
00682
00683 virtual const char* begin_preamble () const
00684 { return "Eliminating of artificial variables out of basis"; }
00685
00686 virtual const char* finish_preamble () const { return ""; }
00687 virtual const char* basis_name () const { return "Basis is"; }
00688
00689 virtual const char* built_table_name () const
00690 { return "The resulting table is"; }
00691
00692 virtual const char* finish_conclusion () const
00693 { return "The task has been solved"; }
00694
00695 virtual const char* artif_in_basis_name () const
00696 { return "Artificial variable in basis is"; }
00697
00698 virtual const char* row_name () const { return "Row"; }
00699 virtual const char* is_negligible_name () const { return "is negligible"; }
00700 virtual const char* pivot_item_name () const { return "Pivot item is"; }
00701
00702 virtual const char* replace_basis_item_name () const
00703 { return "Replace artificial variable"; }
00704
00705 virtual const char* to_name () const
00706 { return "to"; }
00707 };
00708
00709
00711 template <typename Stream>
00712 struct basis_artificial_slog : public basis_artificial_idler
00713 {
00714 class abort : public basis_artificial_idler::abort {};
00715
00716 Stream& stream;
00717 bool preamble_on, conclusion_on;
00718
00719 basis_artificial_slog
00720 (
00721 Stream& stream_a,
00722 bool preamble_on_a = true,
00723 bool conclusion_on_a = true
00724 ) :
00725 stream(stream_a),
00726 preamble_on(preamble_on_a),
00727 conclusion_on(conclusion_on_a)
00728 {}
00729
00730 template <typename Q>
00731 void preamble (const Q& q) const
00732 {
00733 if(!preamble_on)return;
00734
00735 stream << begin_preamble();
00736 if(*begin_preamble())stream << '\n';
00737 output_aligned(stream, q);
00738 stream << finish_preamble();
00739 if(*finish_preamble())stream << '\n';
00740 }
00741
00742 template <typename Q, typename Basis>
00743 void conclusion (const Q& q, const Basis& basis, result_kind rk) const
00744 {
00745 ARAGELI_ASSERT_0(rk == rk_found || rk == rk_empty);
00746
00747 if(rk == rk_empty)
00748 {
00749 stream << conclusion_empty_name() << ".\n";
00750 stream << finish_conclusion() << ".\n";
00751 }
00752
00753 if(rk == rk_found && conclusion_on)
00754 {
00755 stream << built_table_name() << '\n';
00756 output_aligned(stream, q);
00757 stream << basis_name() << ' ' << basis << '\n';
00758 stream << finish_conclusion() << ".\n";
00759 }
00760 }
00761
00762 primal_row_iters_slog<Stream>
00763 ctrl_primal_row_iters () const
00764 { return primal_row_iters_slog<Stream>(stream, false, false); }
00765
00766 basis_create_by_artificial_slog<Stream>
00767 ctrl_basis_create_by_artificial () const
00768 { return basis_create_by_artificial_slog<Stream>(stream, false, false); }
00769
00770 template <typename Q, typename Basis>
00771 void after_artif (const Q& q, const Basis& basis) const
00772 {
00773 stream << table_with_artif_name() << '\n';
00774
00775
00776 }
00777
00778 template <typename Q, typename Basis>
00779 void before_iters (const Q& q, const Basis& basis) const
00780 { stream << optimize_artif_name() << '\n'; }
00781
00782 template <typename Q, typename Basis>
00783 void after_iters (const Q& q, const Basis& basis) const {}
00784
00785 template <typename Q, typename Basis>
00786 void before_orig (const Q& q, const Basis& basis) const
00787 { stream << eliminate_artif_name() << '\n'; }
00788
00789 template <typename Q, typename Basis>
00790 void after_orig (const Q& q, const Basis& basis) const {}
00791
00792 protected:
00793
00794 virtual const char* begin_preamble () const
00795 { return "Building a primal feasible basis of a simplex table"; }
00796
00797 virtual const char* finish_preamble () const { return ""; }
00798 virtual const char* basis_name () const { return "Basis is"; }
00799
00800 virtual const char* conclusion_empty_name () const
00801 { return "Set of feseable points is empty"; }
00802
00803 virtual const char* built_table_name () const
00804 { return "The resulting table is"; }
00805
00806 virtual const char* finish_conclusion () const
00807 { return "The task has been solved"; }
00808
00809 virtual const char* table_with_artif_name () const
00810 { return "Table with artificial variables"; }
00811
00812 virtual const char* optimize_artif_name () const
00813 { return "Optimization of table with artificial variables"; }
00814
00815 virtual const char* eliminate_artif_name () const
00816 { return "Elimination artificial variables from basis"; }
00817 };
00818
00820 template <typename Stream>
00821 struct primal_row_with_artificial_basis_slog
00822 {
00823 Stream& stream;
00824
00825 primal_row_with_artificial_basis_slog (Stream& stream_a)
00826 : stream(stream_a) {}
00827
00828 void preamble () const
00829 {
00830 stream
00831 << "The primal simple method with building the first "
00832 << "allowable table via the artificial basis method.\n";
00833 }
00834
00835 template <typename A, typename B, typename C>
00836 void input_data (const A& a, const B& b, const C& c) const
00837 {
00838 stream << "Initial data:\nA =\n";
00839 output_aligned(stream, a);
00840 stream << "b = " << b << "\nc = " << c << "\n";
00841 }
00842
00843 template <typename T>
00844 void table_for_artificial (const T& table) const
00845 {
00846 stream << "Table for artificial:\n";
00847 output_aligned(stream, table);
00848 stream << "\n";
00849 }
00850
00851 template <typename T, typename B>
00852 void artificial_table (const T& table, const B& basis) const
00853 {
00854 stream << "Artificial table:\n";
00855 output_aligned(stream, table);
00856 stream << "basis = " << basis << "\n";
00857 }
00858
00859 ctrl::simplex_method::primal_row_iters_slog<Stream> ctrl_for_artificial () const
00860 { return ctrl::simplex_method::primal_row_iters_slog<Stream>(stream); }
00861
00862 template <typename T, typename B>
00863 void optimal_artificial_table (const T& table, const B& basis) const
00864 {
00865 stream << "Optimal artificial table:\n";
00866 output_aligned(stream, table);
00867 stream << "basis = " << basis << "\n";
00868 }
00869
00870 ctrl::simplex_method::basis_create_by_artificial_slog<Stream>
00871 ctrl_for_basis_create_by_artificial () const
00872 { return ctrl::simplex_method::basis_create_by_artificial_slog<Stream>(stream); }
00873
00874
00875
00876
00877
00878
00879
00880
00881 template <typename T>
00882 void pre_first_table (const T& table) const
00883 {
00884 stream << "The pre-first allowable table:\n";
00885 output_aligned(stream, table);
00886 }
00887
00888
00889 ctrl::simplex_method::primal_row_iters_slog<Stream>
00890 ctrl_for_main_row_iters () const
00891 { return ctrl::simplex_method::primal_row_iters_slog<Stream>(stream); }
00892
00893 void result (result_kind rk) const
00894 {
00895 const char* status[] = {"FOUND", "EMPTY", "INFINITE", "NONOPTIMAL"};
00896 stream << "\nStatus: " << status[rk] << "\n";
00897 }
00898
00899 void conclusion () const { stream << "\nDone.\n"; }
00900 };
00901
00902
00904 template <typename Stream>
00905 struct gomory1_iter_slog : public gomory1_iter_idler
00906 {
00907 class abort : public gomory1_iter_idler::abort {};
00908
00909 Stream& stream;
00910 bool preamble_on, conclusion_on;
00911
00912 gomory1_iter_slog
00913 (
00914 Stream& stream_a,
00915 bool preamble_on_a = true,
00916 bool conclusion_on_a = true
00917 ) : stream(stream_a),
00918 preamble_on(preamble_on_a),
00919 conclusion_on(conclusion_on_a)
00920 {}
00921
00922 template <typename T, typename Nonbasis>
00923 void preamble (const T& t, const Nonbasis& nonbasis) const {}
00924
00925 template <typename T, typename Nonbasis>
00926 void conclusion (const T& t, const Nonbasis& nonbasis, result_kind rk) const {}
00927
00928 template <typename T, typename Prow>
00929 void after_gomory1_clip (const T& t, Prow prow, result_kind rk) const
00930 {
00931 if(rk == rk_nonoptimal)
00932 stream << "Номер производящей строки " << prow << ".\n";
00933 }
00934
00935 dual_col_iters_slog<Stream> ctrl_for_dual_col_iters () const
00936 { return dual_col_iters_slog<Stream>(stream); }
00937 };
00938
00939 }
00940
00941
00942 template <typename Stream>
00943 struct skeleton_motzkin_burger_slog : public skeleton_motzkin_burger_idler
00944 {
00945 class abort : public skeleton_motzkin_burger_idler::abort {};
00946
00947 Stream& stream;
00948 bool output_top, preamble_on, conclusion_on;
00949
00950 skeleton_motzkin_burger_slog
00951 (
00952 Stream& stream_a,
00953 bool output_top_a = true,
00954 bool preamble_on_a = true,
00955 bool conclusion_on_a = true
00956 ) :
00957 stream(stream_a),
00958 output_top(output_top_a),
00959 preamble_on(preamble_on_a),
00960 conclusion_on(conclusion_on_a)
00961 {}
00962
00963 template <typename A, typename F, typename Q, typename E>
00964 void preamble (const A& a, const F& f, const Q& q, const E& e) const
00965 {
00966 if(!preamble_on)return;
00967 stream << "Motzkin-Burger algorithm start of work with:\n";
00968 output_aligned(stream << "\nA =\n", a);
00969 output_aligned(stream << "\nF =\n", f);
00970 output_aligned(stream << "\nQ =\n", q);
00971 output_aligned(stream << "\nE =\n", e);
00972 }
00973
00974 void begin_gauss () const
00975 {
00976 stream
00977 << "1. Gaussian algorithm\n"
00978 << " ******************\n";
00979 }
00980
00981 void end_gauss () const {}
00982
00983 template <typename I>
00984 void find_non_zero (const I& i) const
00985 {
00986 stream
00987 << "Current row: " << i
00988 << "\nFind non-zero entry in the " << i
00989 << "-th row beginning from " << i << "-th entry\n";
00990 }
00991
00992 void zero_row () const
00993 { stream << "Zero row. Matrix is not of full rank.\n"; }
00994
00995 template <typename I, typename J>
00996 void swap_cols_rows (const I& i, const J& j) const
00997 {
00998 stream << "Swap " << i << "-th and " << j << "-th columns:\n";
00999 }
01000
01001 template <typename J>
01002 void eliminate_col (const J& j) const
01003 { stream << "Gaussian elimination in the " << j << "-th column: \n"; }
01004
01005
01006 template <typename A, typename F, typename Q>
01007 void show_matrices (const A& a, const F& f, const Q& q) const
01008 {
01009 if(output_top)
01010 output_aligned_corner_triplet_br(stream, transpose(a), q, f);
01011 else
01012 output_aligned(stream, q);
01013 }
01014
01015 void begin_motzkin () const
01016 {
01017 stream
01018 << "2. Motzkin algorithm\n"
01019 << " *****************\n";
01020 }
01021
01022 void end_motzkin () const {}
01023
01024 template <typename I1, typename I2>
01025 void select_col (const I1& current_column, const I2& new_column) const
01026 {
01027 stream << "Current column: " << current_column << '\n';
01028 stream << "New column: " << new_column << '\n';
01029 }
01030
01031 void zero_solution () const
01032 { stream << "No solution exept zero\n"; }
01033
01034 void corollary_inequality () const
01035 { stream << "This inequality is a corollary\n"; }
01036
01037 void begin_row_balancing () const
01038 { stream << "Balanced rows: "; }
01039
01040 template <typename I, typename J>
01041 void balanced_rows (const I& j_p, const J& j_m) const
01042 { stream << "(" << j_p << ", " << j_m << ") "; }
01043
01044 void end_row_balancing () const
01045 { stream << '\n'; }
01046
01047 void delete_negates () const
01048 { stream << "Delete negative rows:\n"; }
01049
01050 template <typename A, typename F, typename Q, typename E>
01051 void conclusion (const A& a, const F& f, const Q& q, const E& e) const
01052 {
01053 if(!conclusion_on)return;
01054 stream << "Motzkin-Burger is finished. Output matrices are:\n";
01055 output_aligned(stream << "\nA =\n", a);
01056 output_aligned(stream << "\nF =\n", f);
01057 output_aligned(stream << "\nQ =\n", q);
01058 output_aligned(stream << "\nE =\n", e);
01059 }
01060 };
01061
01062
01063 template <typename Stream>
01064 inline skeleton_motzkin_burger_slog<Stream>
01065 make_skeleton_motzkin_burger_slog
01066 (Stream& stream, bool output_top = true, bool preamble_on = true, bool conclusion_on = true)
01067 { return skeleton_motzkin_burger_slog<Stream>(stream, output_top, preamble_on, conclusion_on); }
01068
01069
01070 template <typename Stream>
01071 struct skeleton_slog : public skeleton_idler
01072 {
01073 class abort : public skeleton_idler::abort {};
01074
01075 Stream& stream;
01076 bool output_top, preamble_on, conclusion_on;
01077
01078 skeleton_slog
01079 (
01080 Stream& stream_a,
01081 bool output_top_a,
01082 bool preamble_on_a = true,
01083 bool conclusion_on_a = true
01084 ) :
01085 stream(stream_a),
01086 output_top(output_top_a),
01087 preamble_on(preamble_on_a),
01088 conclusion_on(conclusion_on_a)
01089 {}
01090
01091 skeleton_motzkin_burger_slog<Stream> motzkin_burger_ctrl () const
01092 { return make_skeleton_motzkin_burger_slog(stream, output_top, preamble_on, conclusion_on); }
01093
01094 };
01095
01096
01097 template <typename Stream>
01098 inline skeleton_slog<Stream>
01099 make_skeleton_slog
01100 (Stream& stream, bool output_top = true, bool preamble_on = true, bool conclusion_on = true)
01101 { return skeleton_slog<Stream>(stream, output_top, preamble_on, conclusion_on); }
01102
01103
01104 }
01105
01106 }
01107
01108
01109 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
01110 #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_CTRL_SLOG
01111
01112 #undef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_CTRL_SLOG
01113 #endif
01114
01115
01116 #endif