00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00024 #ifndef _ARAGELI_CTRL_LATEXLOG_HPP_
00025 #define _ARAGELI_CTRL_LATEXLOG_HPP_
00026
00027 #include "config.hpp"
00028
00029 #include <cstddef>
00030
00031 #include "factory.hpp"
00032 #include "exception.hpp"
00033 #include "gauss.hpp"
00034 #include "simplex_method.hpp"
00035 #include "texout.hpp"
00036 #include "ctrl_slog.hpp"
00037
00038 #include "std_import.hpp"
00039
00040 namespace Arageli
00041 {
00042 namespace ctrl
00043 {
00044
00045 namespace _Internal
00046 {
00047
00048
00049
00050 extern int table_on_one_line;
00051
00052 }
00053
00054 template <typename Stream>
00055 struct rref_latexlog : public rref_slog<Stream>
00056 {
00057 class abort : public rref_int_idler::abort {};
00058
00059 using rref_slog<Stream>::stream_m;
00060 using rref_slog<Stream>::preamble_on;
00061 using rref_slog<Stream>::conclusion_on;
00062 using rref_slog<Stream>::begin_conclusion;
00063 using rref_slog<Stream>::rref_name;
00064 using rref_slog<Stream>::inverse_name;
00065 using rref_slog<Stream>::basis_name;
00066 using rref_slog<Stream>::det_name;
00067 using rref_slog<Stream>::title;
00068 using rref_slog<Stream>::finish_preamble;
00069 using rref_slog<Stream>::find_biggest_in_col_name;
00070 using rref_slog<Stream>::col_name;
00071 using rref_slog<Stream>::is_negligible_name;
00072 using rref_slog<Stream>::pivot_item_name;
00073 using rref_slog<Stream>::swap_rows_name;
00074 using rref_slog<Stream>::eliminate_col_name;
00075
00076
00077 private:
00078
00079 mutable refcntr_proxy<std::ostringstream> buffer;
00080
00081 struct Matrix_wrapper
00082 {
00083 virtual void output (Stream& stream) const = 0;
00084 virtual void output (Stream& stream, std::size_t i, std::size_t j) const = 0;
00085 };
00086
00087 template <typename M>
00088 struct Custom_matrix_wrapper : public Matrix_wrapper
00089 {
00090 M m;
00091 std::size_t verpos;
00092
00093 Custom_matrix_wrapper (const M& m_a, std::size_t verpos_a)
00094 : m(m_a), verpos(verpos_a) {}
00095
00096 virtual void output (Stream& stream) const
00097 {
00098 stream << " $$";
00099 matrix_line v(verpos);
00100 output_latex_matrix_frames(stream, m, make_matrix_vers(&v, &v + 1), true);
00101 stream << "$$\n";
00102 }
00103
00104 virtual void output (Stream& stream, std::size_t i, std::size_t j) const
00105 {
00106 stream << " $$";
00107 matrix_line ver(verpos);
00108 matrix_box box(i, j);
00109
00110 output_latex_matrix_frames
00111 (
00112 stream, m,
00113 make_matrix_vers_boxes(&ver, &ver + 1, &box, &box + 1),
00114 true
00115 );
00116
00117 stream << "$$\n";
00118 }
00119 };
00120
00121 mutable Matrix_wrapper* m;
00122
00123
00124
00125 void flush_buffer () const
00126 {
00127 stream_m << buffer.value().str();
00128 buffer.value().str("");
00129 }
00130
00131 void flush_matrix () const
00132 {
00133 if(m)
00134 {
00135 m->output(stream_m);
00136 delete m;
00137 m = 0;
00138 }
00139 }
00140
00141 void flush_matrix (std::size_t i, std::size_t j) const
00142 {
00143 if(m)
00144 {
00145 m->output(stream_m, i, j);
00146 delete m;
00147 m = 0;
00148 }
00149 }
00150
00151 template <typename B, typename Q>
00152 void current_matrices (const B& b, const Q& q) const
00153 {
00154 B temp(b.nrows(), b.ncols() + q.ncols(), fromsize);
00155
00156 for(std::size_t i = 0; i < b.nrows(); ++i)
00157 {
00158 for(std::size_t j = 0; j < b.ncols(); ++j)
00159 temp(i, j) = b(i, j);
00160 for(std::size_t j = 0; j < q.ncols(); ++j)
00161 temp(i, j + b.ncols()) = q(i, j);
00162 }
00163
00164
00165
00166
00167
00168
00169 flush_matrix();
00170 flush_buffer();
00171 m = new Custom_matrix_wrapper<B>(temp, b.ncols());
00172
00173
00174 }
00175
00176 public:
00177
00178 rref_latexlog
00179 (
00180 Stream& stream_a,
00181 bool preamble_on_a = true,
00182 bool conclusion_on_a = true
00183 ) : rref_slog<Stream>(stream_a, preamble_on_a, conclusion_on_a), m(0) {}
00184
00185 ~rref_latexlog ()
00186 {
00187 delete m;
00188 }
00189
00190 template <typename A>
00191 void preamble (const A& a) const
00192 {
00193 if(!preamble_on)return;
00194
00195 title();
00196 stream() << "\n$$";
00197 output_latex(stream(), a, true);
00198 stream() << "$$\n";
00199 finish_preamble();
00200 stream() << '\n';
00201 }
00202
00203 template <typename B, typename Q, typename Det, typename Basis>
00204 void conclusion
00205 (const B& b, const Q& q, const Det& det, const Basis& basis) const
00206 {
00207 if(conclusion_on)
00208 {
00209 current_matrices(b, q);
00210 begin_conclusion();
00211 rref_name();
00212 output_latex(stream() << "\n$$", b, true);
00213 stream() << "$$";
00214 inverse_name();
00215 output_latex(stream() << "\n$$", q, true);
00216 stream() << "$$";
00217 }
00218 else
00219 {
00220 current_matrices(b, q);
00221 }
00222
00223 basis_name();
00224 output_latex(stream() << " ", basis+1, false, eep_alone, true);
00225 stream() << ".\n";
00226 det_name();
00227 stream() << " $" << det << "$.\n";
00228
00229 flush_matrix();
00230 flush_buffer();
00231 }
00232
00233
00234 template <typename B, typename Q, typename Det, typename Basis>
00235 void before_iter (const B& b, const Q& q, const Det& det, const Basis& basis) const
00236 {
00237 current_matrices(b, q);
00238
00239 basis_name();
00240 output_latex(stream() << " ", basis+1, false, eep_alone, true);
00241 stream() << ".\n";
00242 det_name();
00243 stream() << " $" << det << "$.\n";
00244 }
00245
00246 template <typename B, typename Q, typename Det, typename Basis>
00247 void after_iter (const B& b, const Q& q, const Det& det, const Basis& basis) const {}
00248
00249 template <typename J>
00250 void find_biggest_in_col (const J& j) const
00251 {
00252 find_biggest_in_col_name();
00253 stream() << " $" << j+1 << "$.\n";
00254 }
00255
00256 template <typename J>
00257 void negligible_col (const J& j) const
00258 {
00259 col_name();
00260 stream() << " $" << j+1 << "$ ";
00261 is_negligible_name();
00262 stream() << ".\n";
00263 }
00264
00265 template <typename I, typename J>
00266 void pivot_item (const I& i, const J& j) const
00267 {
00268 flush_matrix(i, j);
00269 pivot_item_name();
00270 stream() << " $(" << i+1 << "$, $" << j+1 << ")$.\n";
00271 flush_buffer();
00272 }
00273
00274 template <typename I1, typename I2, typename B, typename Q, typename Det>
00275 void swap_rows (const I1& i1, const I2& i2, const B& b, const Q& q, const Det& det) const
00276 {
00277 swap_rows_name();
00278 stream() << " $" << i1+1 << "$, $" << i2+1 << "$.\n";
00279 current_matrices(b, q);
00280 det_name();
00281 stream() << " $" << det << "$.\n";
00282 }
00283
00284 template <typename J>
00285 void eliminate_col (const J& j) const
00286 {
00287 eliminate_col_name();
00288 stream() << " $" << j+1 << "$.\n";
00289 }
00290
00291 template <typename B, typename Q, typename Det>
00292 void after_elimination (const B& b, const Q& q, const Det& det) const
00293 {
00294
00295
00296
00297 }
00298
00299 protected:
00300
00301 virtual std::ostream& stream () const { return buffer.value(); }
00302
00303
00304 };
00305
00306
00307 template <typename Stream>
00308 inline rref_latexlog<Stream> make_rref_latexlog (Stream& stream)
00309 { return rref_latexlog<Stream>(stream); }
00310
00311
00312 namespace simplex_method
00313 {
00314
00315
00316 inline const matrix_frames<const matrix_line*, const matrix_line*>& table_frames ()
00317 {
00318 static const matrix_line hf(1), vf(1);
00319 static const matrix_frames<const matrix_line*, const matrix_line*>
00320 frames = make_matrix_frames(&hf, &hf + 1, &vf, &vf + 1);
00321 return frames;
00322 }
00323
00324
00326 template <typename Stream>
00327 struct primal_row_iters_latexlog : public primal_row_iters_slog<Stream>
00328 {
00329 protected:
00330
00331 using primal_row_iters_slog<Stream>::stream;
00332
00333
00334 public:
00335 class abort : public primal_row_iters_slog<Stream>::abort {};
00336
00337 primal_row_iters_latexlog
00338 (
00339 Stream& stream_a,
00340 bool preamble_on_a = true,
00341 bool conclusion_on_a = true
00342 ) : primal_row_iters_slog<Stream>
00343 (stream_a, preamble_on_a, conclusion_on_a)
00344 {}
00345
00346 template <typename Q, typename Basis>
00347 void preamble (const Q& q, const Basis& basis) const
00348 {
00349
00350
00351 }
00352
00353 template <typename Q, typename Basis>
00354 void conclusion (const Q& q, const Basis& basis, result_kind rk) const
00355 {
00356
00357
00358 }
00359
00360 template <typename Q, typename Basis>
00361 void before_iter (const Q& q, const Basis& basis) const
00362 {
00363 stream << "\n$$\n";
00364 output_latex_matrix_frames(stream, q, table_frames(), true);
00365 stream << "\n$$\n";
00366 stream << basis_name() << " $" << basis << "$. \n";
00367 }
00368
00369 template <typename Q, typename Basis, typename Pivot>
00370 void after_iter
00371 (
00372 const Q& q, const Basis& basis,
00373 Pivot prow, Pivot pcol,
00374 result_kind rk
00375 ) const
00376 {
00377 ARAGELI_ASSERT_0(rk != rk_empty);
00378
00379 switch(rk)
00380 {
00381 case rk_infinite:
00382 stream << pivot_col_name() << ' ' << pcol << '\n';
00383 break;
00384 case rk_nonoptimal:
00385 stream
00386 << pivot_item_name()
00387 << " (" << prow << ", " << pcol << ")\n";
00388 break;
00389 }
00390 }
00391
00392 protected:
00393
00394 virtual const char* basis_name () const { return "$\\cal B = $"; }
00395 virtual const char* pivot_col_name () const { return "Текущий столбец: "; }
00396 virtual const char* pivot_item_name () const { return "Текущий элемент: "; }
00397
00398 private:
00399
00400
00401
00402
00403 };
00404
00405
00407 template <typename Stream>
00408 struct basis_create_by_artificial_latexlog
00409 : public basis_create_by_artificial_slog<Stream>
00410 {
00411 class abort : public basis_create_by_artificial_slog<Stream> {};
00412
00413 basis_create_by_artificial_latexlog
00414 (
00415 Stream& stream_a,
00416 bool preamble_on_a = true,
00417 bool conclusion_on_a = true
00418 ) : basis_create_by_artificial_slog<Stream>(stream_a, preamble_on_a, conclusion_on_a)
00419 {}
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 template <typename Q, typename Basis>
00476 void before_erase_artif (const Q& q, const Basis& basis) const
00477 {
00478
00479
00480 }
00481
00482 protected:
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 };
00509
00510
00511
00512 template <typename Stream>
00513 struct basis_artificial_latexlog : public basis_artificial_slog<Stream>
00514 {
00515 protected:
00516
00517 using basis_artificial_slog<Stream>::stream;
00518
00519 public:
00520
00521 class abort : public basis_artificial_slog<Stream>::abort {};
00522
00523 basis_artificial_latexlog
00524 (
00525 Stream& stream_a,
00526 bool preamble_on_a = true,
00527 bool conclusion_on_a = true
00528 ) : basis_artificial_slog<Stream>
00529 (stream_a, preamble_on_a, conclusion_on_a)
00530 {}
00531
00532 template <typename Q>
00533 void preamble (const Q& q) const
00534 {
00535
00536
00537 }
00538
00539 template <typename Q, typename Basis>
00540 void conclusion (const Q& q, const Basis& basis, result_kind rk) const
00541 {
00542
00543
00544 }
00545
00546 primal_row_iters_latexlog<Stream> ctrl_primal_row_iters () const
00547 { return primal_row_iters_latexlog<Stream>(stream, false, false); }
00548
00549 basis_create_by_artificial_latexlog<Stream>
00550 ctrl_basis_create_by_artificial () const
00551 { return basis_create_by_artificial_latexlog<Stream>(stream, false, false); }
00552
00553 protected:
00554
00555 virtual const char* table_with_artif_name () const
00556 { return "Таблица с искуственными переменными"; }
00557
00558 };
00559
00560
00562 template <typename Stream>
00563 struct dual_col_iter_latexlog : public dual_col_iter_slog<Stream>
00564 {
00565 protected:
00566
00567 using dual_col_iter_slog<Stream>::stream;
00568
00569 public:
00570
00571
00572
00573 dual_col_iter_latexlog (Stream& stream_a)
00574 : dual_col_iter_slog<Stream>(stream_a) {}
00575
00576 void preamble () const
00577 { }
00578
00579 void conclusion () const
00580 {}
00581
00582 template <typename Q, typename Nonbasis>
00583 void current_table (const Q& q, const Nonbasis& nonbasis) const
00584 {
00585 stream << "\n$$\n";
00586 output_latex_matrix_frames(stream, q, table_frames(), true);
00587 stream << "\n$$\n";
00588
00589 }
00590
00591 template <typename R, typename S>
00592 void pivot_item (const R& r, const S& s) const
00593 { stream << "Текущий элемент $" << r << ", " << s << "$.\n"; }
00594
00595 void found () const { stream << "The table is optimal.\n"; }
00596 void infinite () const { stream << "The function isn't limited.\n"; }
00597 void nonoptimal () const {}
00598 void empty () const { stream << "Set of allowable vectors is empty."; }
00599 };
00600
00601
00602
00603
00605 template <typename Stream>
00606 struct dual_col_iters_latexlog : public dual_col_iters_slog<Stream>
00607 {
00608 protected:
00609
00610 using dual_col_iters_slog<Stream>::stream;
00611
00612 public:
00613
00614
00615
00616 dual_col_iters_latexlog
00617 (
00618 Stream& stream_a,
00619 bool preamble_on_a = true,
00620 bool conclusion_on_a = true
00621 ) : dual_col_iters_slog<Stream>(stream_a)
00622
00623
00624 {}
00625
00626
00627
00628
00629 void conclusion () const
00630 { }
00631
00632 dual_col_iter_latexlog<Stream> iter_ctrl () const
00633 { return dual_col_iter_latexlog<Stream>(stream); }
00634
00635 template <typename TQ, typename Tb>
00636 bool stop (const TQ&, const Tb&) const { return false; }
00637 };
00638
00639
00641 template <typename Stream>
00642 struct gomory1_iter_latexlog : public gomory1_iter_slog<Stream>
00643 {
00644 protected:
00645
00646 using gomory1_iter_slog<Stream>::stream;
00647
00648 public:
00649
00650 class abort : public gomory1_iter_slog<Stream>::abort {};
00651
00652
00653
00654
00655 gomory1_iter_latexlog
00656 (
00657 Stream& stream_a,
00658 bool preamble_on_a = true,
00659 bool conclusion_on_a = true
00660 ) : gomory1_iter_slog<Stream>(stream_a, preamble_on_a, conclusion_on_a)
00661 {}
00662
00663
00664
00665
00666
00667
00668
00669 template <typename T, typename Prow>
00670 void after_gomory1_clip (const T& t, Prow prow, result_kind rk) const
00671 {
00672 if(rk == rk_nonoptimal)
00673 stream << "Номер производящей строки " << prow << ".\n";
00674 }
00675
00676 dual_col_iters_latexlog<Stream> ctrl_for_dual_col_iters () const
00677 { return dual_col_iters_latexlog<Stream>(stream); }
00678 };
00679
00680
00682 template <typename Stream>
00683 struct gomory1_iters_latexlog : public gomory1_iters_idler
00684 {
00685 class abort : public gomory1_iters_idler::abort {};
00686
00687 Stream& stream;
00688 bool preamble_on, conclusion_on;
00689
00690 gomory1_iters_latexlog
00691 (
00692 Stream& stream_a,
00693 bool preamble_on_a = true,
00694 bool conclusion_on_a = true
00695 ) : stream(stream_a),
00696 preamble_on(preamble_on_a),
00697 conclusion_on(conclusion_on_a)
00698 {}
00699
00700 template <typename T, typename Nonbasis>
00701 void preamble (const T& t, const Nonbasis& nonbasis) const
00702 {
00703
00704 output_latex_matrix_frames(stream, t, table_frames());
00705 }
00706
00707 template <typename T, typename Nonbasis>
00708 void conclusion (const T& t, const Nonbasis& nonbasis, result_kind rk) const
00709 { }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 gomory1_iter_latexlog<Stream> ctrl_for_gomory1_iter () const
00722 { return gomory1_iter_latexlog<Stream>(stream); }
00723 };
00724
00725
00726
00727 }
00728 }
00729 }
00730
00731
00732 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00733 #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_CTRL_LATEXLOG
00734
00735 #undef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_CTRL_LATEXLOG
00736 #endif
00737
00738
00739 #endif