ctrl_slog.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     ctrl_slog.hpp -- Collection of simple loggers for contolled algorithm
00004         functions.
00005 
00006     This file is part of Arageli library.
00007 
00008     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00009     Copyright (C) Sergey S. Lyalin, 2005
00010     University of Nizhni Novgorod, Russia
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         //output_aligned_hor_pair(stream(), b, q);
00157         //det_name();
00158         //stream() << det << '\n';
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     //template <typename B, typename Q, typename Det, typename Basis>
00218     //void conclusion
00219     //(const B& b, const Q& q, const Det& det, const Basis& basis) const
00220     //{
00221     //  rref_slog<Stream>::conclusion(b, q, det, basis);
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         //rref_slog<Stream>::after_elimination(b, q, det);
00276         //det_denom_name();
00277         //stream() << ' ' << det_denom << '\n';
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 //using namespace Arageli::simplex_method;
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         //output_aligned(stream, q);
00775         //stream << basis_name() << ' ' << basis << '\n';
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     //template <typename T>
00875     //void first_table (const T& table) const
00876     //{
00877     //  stream << "The first allowable table:\n";
00878     //  output_aligned(table);
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 } // namespace simplex_method
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 } // namespace ctrl
01105 
01106 } // namespace Arageli
01107 
01108 
01109 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
01110     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_CTRL_SLOG
01111     //#include "ctrl_slog.cpp"
01112     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_CTRL_SLOG
01113 #endif
01114 
01115 
01116 #endif

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