00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "config.hpp"
00014
00015 #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || \
00016 defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_TEXOUT)
00017
00018 #include <cstddef>
00019 #include <sstream>
00020
00021 #include "texout.hpp"
00022
00023
00024 namespace Arageli
00025 {
00026
00027
00028 template <typename Out, typename T>
00029 void output_latex
00030 (
00031 Out& out,
00032 const rational<T>& x,
00033 bool in_math,
00034 ex_environ_priority eep,
00035 std::size_t maxlensimple,
00036 bool externsign
00037 )
00038 {
00039 if(!in_math)out << '$';
00040
00041 if(x.is_null())out << '0';
00042 else if(is_unit(x.denominator()))
00043 output_latex(out, x.numerator(), true, eep);
00044 else
00045 {
00046 std::ostringstream buf;
00047 std::string sn, sd;
00048 bool minus = false;
00049
00050 if(externsign && is_negative(x.numerator()))
00051 {
00052 minus = true;
00053 output_latex(buf, -x.numerator(), true, eep_mul);
00054 }
00055 else output_latex(buf, x.numerator(), true, eep_mul);
00056
00057 sn = buf.str();
00058 buf.str(std::string());
00059
00060 output_latex(buf, x.denominator(), true, eep_mul);
00061 sd = buf.str();
00062 buf.str(std::string());
00063
00064 if(sn.length() + sd.length() > maxlensimple)
00065 {
00066 if(minus)out << '-';
00067 out << "\\frac{";
00068 output_latex(out, minus ? -x.numerator() : x.numerator(), true, eep_alone);
00069 out << "}{";
00070 output_latex(out, x.denominator(), true, eep_alone);
00071 out << "}";
00072 }
00073 else if(eep == eep_mul)
00074 {
00075 out << '(';
00076 if(minus)out << '-';
00077 out << sn << '/' << sd << ')';
00078 }
00079 else
00080 {
00081 if(minus)out << '-';
00082 out << sn << '/' << sd;
00083 }
00084 }
00085
00086 if(!in_math)out << '$';
00087 }
00088
00089
00090 template <typename Out, typename T, bool REFCNT>
00091 void output_latex
00092 (
00093 Out& out,
00094 const vector<T, REFCNT>& x,
00095 bool in_math,
00096 ex_environ_priority eep,
00097 bool hor,
00098 const char* first_bracket,
00099 const char* second_bracket,
00100 const char* delim
00101 )
00102 {
00103 if(!in_math)out << '$';
00104
00105 out << "\\left" << first_bracket;
00106
00107 if(!x.is_empty())
00108 if(hor)
00109 {
00110 output_latex(out, x[0], true);
00111 for(typename vector<T, REFCNT>::size_type i = 1; i < x.size(); ++i)
00112 output_latex(out << delim, x[i], true);
00113 }
00114 else
00115 {
00116 out << "\\begin{tabular}{c}";
00117
00118 output_latex(out, x[0], false);
00119 for(typename vector<T, REFCNT>::size_type i = 1; i < x.size(); ++i)
00120 output_latex(out << " \\\\[3pt] ", x[i], false);
00121
00122 out << "\\end{tabular}";
00123 }
00124
00125 out << "\\right" << second_bracket;
00126
00127 if(!in_math)out << '$';
00128 }
00129
00130
00131 template <typename Out, typename T, bool REFCNT>
00132 void output_latex
00133 (
00134 Out& out,
00135 const matrix<T, REFCNT>& xx,
00136 bool in_math,
00137 ex_environ_priority eep,
00138 bool transposed,
00139 const char* first_bracket,
00140 const char* second_bracket
00141 )
00142 {
00143 if(!in_math)out << '$';
00144
00145 matrix<T, REFCNT> x = xx;
00146 if(transposed)x.transpose();
00147
00148 out << "\\left" << first_bracket;
00149
00150 if(!x.is_empty())
00151 {
00152 out
00153 << "\\begin{tabular}{"
00154 << std::string(x.ncols(), 'c')
00155 << "}";
00156
00157 typedef typename vector<T, REFCNT>::size_type size_type;
00158
00159 output_latex(out, x(0, 0), false);
00160 for(size_type j = 1; j < x.ncols(); ++j)
00161 output_latex(out << " & ", x(0, j), false);
00162
00163 for(size_type i = 1; i < x.nrows(); ++i)
00164 {
00165 output_latex(out << " \\\\[3pt] ", x(i, 0), false);
00166 for(size_type j = 1; j < x.ncols(); ++j)
00167 output_latex(out << " & ", x(i, j), false);
00168 }
00169
00170 out << "\\end{tabular}";
00171 }
00172
00173 out << "\\right" << second_bracket;
00174
00175 if(!in_math)out << '$';
00176 }
00177
00178
00179 template <typename Out, typename F, typename I>
00180 void output_latex
00181 (
00182 Out& out,
00183 const monom<F, I>& x,
00184 bool in_math,
00185 ex_environ_priority eep,
00186 bool first,
00187 const char* var
00188 )
00189 {
00190 if(!in_math)out << '$';
00191
00192 if(x.is_const())
00193 if(first)
00194 output_latex(out, x.coef(), true, eep);
00195 else
00196 {
00197 if(is_negative(x.coef()))
00198 output_latex(out << '-', -x.coef(), true, eep);
00199 else
00200 output_latex(out << '+', x.coef(), true, eep);
00201 }
00202 else
00203 {
00204 if(is_opposite_unit(x.coef()))
00205 out << '-';
00206 else if(is_unit(x.coef()))
00207 { if(!first)out << '+'; }
00208 else if(first)
00209 {
00210 output_latex(out, x.coef(), true, eep_mul);
00211 }
00212 else
00213 {
00214 if(is_negative(x.coef()))
00215 output_latex(out << '-', -x.coef(), true, eep_mul);
00216 else
00217 output_latex(out << '+', x.coef(), true, eep_mul);
00218 }
00219
00220 out << var;
00221 if(!is_unit(x.degree()))
00222 {
00223 out << "^{";
00224 output_latex(out, x.degree(), true);
00225 out << "}";
00226 }
00227 }
00228
00229 if(!in_math)out << '$';
00230 }
00231
00232
00233 template <typename Out, typename F, typename I, bool REFCNT>
00234 void output_latex
00235 (
00236 Out& out,
00237 const sparse_polynom<F, I, REFCNT>& x,
00238 bool in_math,
00239 ex_environ_priority eep,
00240 const char* var
00241 )
00242 {
00243 typedef typename
00244 std::reverse_iterator
00245 <typename sparse_polynom<F, I, REFCNT>::monom_const_iterator>
00246 Ri;
00247 Ri
00248 begin = Ri(x.monoms_end()),
00249 end = Ri(x.monoms_begin());
00250
00251 if(!in_math)out << '$';
00252 if(begin == end)out << '0';
00253 else
00254 {
00255 ++begin;
00256 if(begin == end)
00257 {
00258 --begin;
00259 output_latex(out, *begin, true, eep, true, var);
00260 }
00261 else
00262 {
00263 --begin;
00264 if(eep == eep_mul)out << "\\left(";
00265 output_latex(out, *begin, true, eep_add, true, var);
00266
00267 for(++begin; begin != end; ++begin)
00268 output_latex(out, *begin, true, eep_add, false, var);
00269
00270 if(eep == eep_mul)out << "\\right)";
00271 }
00272 }
00273 if(!in_math)out << '$';
00274 }
00275
00276
00277 namespace _Internal
00278 {
00279
00280 template <typename Stream>
00281 void mlt_output (matrix_line_type mlt, Stream& out, bool ver = false)
00282 {
00283 switch(mlt)
00284 {
00285 case mlt_solid:
00286 if(ver)out << '|';
00287 else out << '-';
00288 break;
00289 case mlt_dot: out << '.'; break;
00290 case mlt_hatch: out << ':'; break;
00291 case mlt_chain: out << ';'; break;
00292 default: ARAGELI_ASSERT_ALWAYS(!"Not appropriate value of mtl.");
00293 }
00294 }
00295
00296 }
00297
00298 template
00299 <
00300 typename T, bool REFCNT, typename Ch, typename ChT,
00301 typename In_hor, typename In_ver, typename In_box
00302 >
00303 void output_latex_matrix_frames
00304 (
00305 std::basic_ostream<Ch, ChT>& out,
00306 const matrix<T, REFCNT>& xx,
00307 const matrix_frames<In_hor, In_ver, In_box>& mf,
00308 bool in_math,
00309 bool transposed,
00310 const char* first_bracket,
00311 const char* second_bracket
00312 )
00313 {
00314 if(!in_math)out << '$';
00315
00316 matrix<T, REFCNT> x = xx;
00317 if(transposed)x.transpose();
00318
00319 out << "\\left" << first_bracket;
00320
00321 if(!x.is_empty())
00322 {
00323 out << "\\begin{MAT}(b,0.7cm,0.7cm){";
00324
00325 In_ver curver = mf.vers_first;
00326 for(std::size_t i = 0; i < x.ncols(); ++i)
00327 {
00328 if(curver != mf.vers_last && curver->pos == i)
00329 {
00330 _Internal::mlt_output(curver->mlt, out, true);
00331 ++curver;
00332 }
00333
00334 out << 'c';
00335 }
00336
00337 if(curver != mf.vers_last && curver->pos == x.ncols())
00338 {
00339 _Internal::mlt_output(curver->mlt, out, true);
00340 ++curver;
00341 }
00342
00343 out << "}\n";
00344
00345 typedef typename vector<T, REFCNT>::size_type size_type;
00346
00347 In_hor curhor = mf.hors_first;
00348
00349
00350 ARAGELI_ASSERT_0(!(curhor != mf.hors_last && curhor->pos == 0));
00351
00352
00353
00354
00355
00356
00357 In_box curbox = mf.boxes_first;
00358
00359 if(curbox != mf.boxes_last && curbox->row == 0 && curbox->col == 0)
00360 {
00361 out << "\\fbox{";
00362 output_latex(out, x(0, 0), true);
00363 out << "}";
00364 ++curbox;
00365 }
00366 else
00367 output_latex(out, x(0, 0), true);
00368
00369 for(size_type j = 1; j < x.ncols(); ++j)
00370 if(curbox != mf.boxes_last && curbox->row == 0 && curbox->col == j)
00371 {
00372 out << " & \\fbox{";
00373 output_latex(out, x(0, j), true);
00374 out << "}";
00375 ++curbox;
00376 }
00377 else
00378 output_latex(out << " & ", x(0, j), true);
00379
00380 for(size_type i = 1; i < x.nrows(); ++i)
00381 {
00382
00383 out << " \\\\";
00384
00385 if(curhor != mf.hors_last && curhor->pos == i)
00386 {
00387
00388 _Internal::mlt_output(curhor->mlt, out);
00389 ++curhor;
00390 }
00391
00392 out << '\n';
00393
00394 if(curbox != mf.boxes_last && curbox->row == i && curbox->col == 0)
00395 {
00396 out << "\\fbox{";
00397 output_latex(out, x(i, 0), true);
00398 out << "}";
00399 ++curbox;
00400 }
00401 else
00402 output_latex(out, x(i, 0), true);
00403
00404 for(size_type j = 1; j < x.ncols(); ++j)
00405 if(curbox != mf.boxes_last && curbox->row == i && curbox->col == j)
00406 {
00407 out << " & \\fbox{";
00408 output_latex(out, x(i, j), true);
00409 out << "}";
00410 ++curbox;
00411 }
00412 else
00413 output_latex(out << " & ", x(i, j), true);
00414 }
00415
00416 out << " \\\\";
00417
00418 if(curhor != mf.hors_last && curhor->pos == x.ncols())
00419 {
00420
00421 _Internal::mlt_output(curhor->mlt, out);
00422 ++curhor;
00423 }
00424
00425 out << "\n\\end{MAT}";
00426 }
00427
00428 out << "\\right" << second_bracket;
00429
00430 if(!in_math)out << '$';
00431 }
00432
00433
00434
00435 }
00436
00437 #endif // #ifndef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE