00001 #ifndef VIENNAMATH_MANIPULATION_LATEX_HPP
00002 #define VIENNAMATH_MANIPULATION_LATEX_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <map>
00021
00022 #include "viennamath/forwards.h"
00023 #include "viennamath/runtime/unary_expr.hpp"
00024 #include "viennamath/compiletime/unary_op_tags.hpp"
00025
00030 namespace viennamath
00031 {
00032
00033
00034
00035 template <typename InterfaceType = default_interface_type>
00036 class rt_latex_translator;
00037
00038 template <typename InterfaceType = default_interface_type>
00039 class rt_latex_binary_expr_processor;
00040
00041 template <typename InterfaceType = default_interface_type>
00042 class rt_latex_unary_expr_processor;
00043
00044 template <typename InterfaceType = default_interface_type>
00045 class rt_latex_constant_processor;
00046
00047 template <typename InterfaceType = default_interface_type>
00048 class rt_latex_variable_processor;
00049
00050 template <typename InterfaceType = default_interface_type>
00051 class rt_latex_function_symbol_processor;
00052
00053
00054
00059 template <typename InterfaceType = default_interface_type>
00060 class rt_latex_processor_interface
00061 {
00062 public:
00069 virtual std::string process(InterfaceType const * e,
00070 bool use_parenthesis,
00071 rt_latex_translator<InterfaceType> const & trans) const = 0;
00072
00078 virtual bool customize(InterfaceType const * e, std::string const & str) { return false; }
00079 };
00080
00081
00086 template <typename InterfaceType>
00087 class rt_latex_translator
00088 {
00089 typedef typename InterfaceType::numeric_type NumericType;
00090
00091 typedef viennamath::rt_binary_expr<InterfaceType> BinaryExpr;
00092 typedef viennamath::rt_unary_expr<InterfaceType> UnaryExpr;
00093 typedef viennamath::rt_constant<default_numeric_type, InterfaceType> Constant;
00094 typedef viennamath::rt_variable<InterfaceType> Variable;
00095 typedef viennamath::rt_function_symbol<InterfaceType> FuncSymbol;
00096 typedef viennamath::rt_equation<InterfaceType> Equation;
00097 typedef viennamath::rt_interval<InterfaceType> Interval;
00098
00099 typedef rt_latex_processor_interface<InterfaceType> ProcessorInterface;
00100 typedef std::vector< ProcessorInterface *> ProcessorArray;
00101
00102 public:
00103
00104 rt_latex_translator()
00105 {
00106 processors_.push_back(new rt_latex_binary_expr_processor<InterfaceType>());
00107 processors_.push_back(new rt_latex_unary_expr_processor<InterfaceType>());
00108 processors_.push_back(new rt_latex_constant_processor<InterfaceType>());
00109 processors_.push_back(new rt_latex_variable_processor<InterfaceType>());
00110 processors_.push_back(new rt_latex_function_symbol_processor<InterfaceType>());
00111 }
00112
00113 ~rt_latex_translator()
00114 {
00115 for (typename ProcessorArray::iterator it = processors_.begin();
00116 it != processors_.end();
00117 ++it)
00118 {
00119 delete *it;
00120 }
00121 }
00122
00123
00124
00125
00126 std::string operator()(viennamath::rt_expr<InterfaceType> const & e,
00127 bool use_parenthesis = false) const
00128 {
00129 return process_impl(e.get(), use_parenthesis);
00130 }
00131
00132 std::string operator()(BinaryExpr const & e, bool use_parenthesis = false) const { return process_impl(&e, use_parenthesis); }
00133 std::string operator()(UnaryExpr const & e, bool use_parenthesis = false) const { return process_impl(&e, use_parenthesis); }
00134
00135 template <typename ScalarType>
00136 std::string operator()(viennamath::rt_constant<ScalarType, InterfaceType> const & e, bool use_parenthesis = false) const { return process_impl(e, use_parenthesis); }
00137 std::string operator()(Variable const & e, bool use_parenthesis = false) const { return process_impl(&e, use_parenthesis); }
00138 std::string operator()(FuncSymbol const & e, bool use_parenthesis = false) const { return process_impl(&e, use_parenthesis); }
00139 std::string operator()(Equation const & e, bool use_parenthesis = false) const
00140 {
00141 std::stringstream ss;
00142 ss << operator()(e.lhs()) << " = " << operator()(e.rhs());
00143 return ss.str();
00144 }
00145 std::string operator()(Interval const & e, bool use_parenthesis = false) const
00146 {
00147 std::stringstream ss;
00148 ss << " [ " << operator()(e.lower()) << "; " << operator()(e.upper()) << " ] ";
00149 return ss.str();
00150 }
00151
00157 template <typename ExpressionType>
00158 void customize(ExpressionType const & e, std::string output)
00159 {
00160 bool found = false;
00161 for (typename ProcessorArray::const_iterator it = processors_.begin();
00162 it != processors_.end();
00163 ++it)
00164 {
00165 found |= (*it)->customize(&e, output);
00166 }
00167
00168 if (!found)
00169 std::cerr << "Warning: Cannot customize LaTeX translator for " << e << " (no suitable processor found)" << std::endl;
00170
00171 }
00172
00174 void add_processor(ProcessorInterface * proc_ptr)
00175 {
00176 processors_.push_back(proc_ptr);
00177 }
00178
00179 private:
00180
00181 std::string process_impl(InterfaceType const * ptr,
00182 bool use_parenthesis = false) const
00183 {
00184 std::string ret;
00185
00186 for (typename ProcessorArray::const_iterator it = processors_.begin();
00187 it != processors_.end();
00188 ++it)
00189 {
00190 ret = (*it)->process(ptr, use_parenthesis, *this);
00191 if (ret.size() > 0)
00192 return ret;
00193 }
00194
00195 std::cerr << "ViennaMath: Warning: Unknown type in latex translator: " << ptr << std::endl;
00196
00197 return " \\chi_{\\mathrm{unknown}} ";
00198 }
00199
00200 ProcessorArray processors_;
00201 };
00202
00204 typedef rt_latex_translator<> latex_translator;
00205
00206
00207
00208
00209
00210
00215 template <typename InterfaceType>
00216 class rt_latex_binary_expr_processor : public rt_latex_processor_interface<InterfaceType>
00217 {
00218 typedef typename InterfaceType::numeric_type NumericType;
00219 typedef viennamath::rt_binary_expr<InterfaceType> BinaryExpr;
00220
00221 public:
00222
00223 std::string process(InterfaceType const * ptr, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00224 {
00225 if (dynamic_cast< const BinaryExpr * >(ptr) != NULL)
00226 {
00227 const BinaryExpr * temp = dynamic_cast< const BinaryExpr * >(ptr);
00228 return process_impl(*temp, use_parenthesis, translator);
00229 }
00230
00231 return "";
00232 }
00233
00234 private:
00235
00236 std::string process_impl(BinaryExpr const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00237 {
00238 std::stringstream ss;
00239 viennamath::rt_expr<InterfaceType> lhs(e.lhs()->clone());
00240 viennamath::rt_expr<InterfaceType> rhs(e.rhs()->clone());
00241
00242 if (dynamic_cast< const op_binary<op_div<NumericType>, InterfaceType> * >(e.op()) != NULL)
00243 {
00244 if (use_parenthesis)
00245 ss << " \\left( ";
00246 ss << " \\frac{" << translator(lhs) << "}{" << translator(rhs) << "} ";
00247 if (use_parenthesis)
00248 ss << " \\right) ";
00249 }
00250 else
00251 {
00252 bool is_op_mult = false;
00253 if (dynamic_cast< const op_binary<op_mult<NumericType>, InterfaceType> * >(e.op()) != NULL)
00254 is_op_mult = true;
00255
00256 bool is_op_minus = false;
00257 if (dynamic_cast< const op_binary<op_minus<NumericType>, InterfaceType> * >(e.op()) != NULL)
00258 is_op_minus = true;
00259
00260 if (use_parenthesis)
00261 ss << "(";
00262 ss << translator(lhs, is_op_mult);
00263 if (is_op_mult)
00264 ss << " \\cdot ";
00265 else
00266 ss << " " << e.op()->str() << " ";
00267 ss << translator(rhs, is_op_mult || is_op_minus);
00268 if (use_parenthesis)
00269 ss << ")";
00270 }
00271
00272 return ss.str();
00273 }
00274
00275 };
00276
00277
00278
00279
00280
00281
00286 template <typename InterfaceType>
00287 class rt_latex_unary_expr_processor : public rt_latex_processor_interface<InterfaceType>
00288 {
00289 typedef typename InterfaceType::numeric_type NumericType;
00290 typedef viennamath::rt_unary_expr<InterfaceType> UnaryExpr;
00291
00292 public:
00293
00294 std::string process(InterfaceType const * ptr, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00295 {
00296 if (dynamic_cast< const UnaryExpr * >(ptr) != NULL)
00297 {
00298 const UnaryExpr * temp = dynamic_cast< const UnaryExpr * >(ptr);
00299 return process_impl(*temp, use_parenthesis, translator);
00300 }
00301
00302 return "";
00303 }
00304
00305 private:
00306
00307 std::string process_impl(UnaryExpr const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00308 {
00309 typedef op_unary<op_id<NumericType>, InterfaceType> OpId;
00310 typedef op_unary<op_exp<NumericType>, InterfaceType> OpExp;
00311 typedef op_unary<op_sin<NumericType>, InterfaceType> OpSin;
00312 typedef op_unary<op_cos<NumericType>, InterfaceType> OpCos;
00313 typedef op_unary<op_tan<NumericType>, InterfaceType> OpTan;
00314 typedef op_unary<op_fabs<NumericType>, InterfaceType> OpFabs;
00315 typedef op_unary<op_sqrt<NumericType>, InterfaceType> OpSqrt;
00316 typedef op_unary<op_log<NumericType>, InterfaceType> OpLog;
00317 typedef op_unary<op_log10<NumericType>, InterfaceType> OpLog10;
00318
00319
00320 typedef op_unary<op_gradient<NumericType>, InterfaceType> OpGradient;
00321 typedef op_unary<op_divergence<NumericType>, InterfaceType> OpDivergence;
00322 typedef op_unary<op_partial_deriv<NumericType>, InterfaceType> OpPartialDeriv;
00323 typedef op_unary<op_rt_integral<InterfaceType>, InterfaceType> OpRuntimeIntegration;
00324 typedef op_unary<op_rt_symbolic_integral<InterfaceType>, InterfaceType> OpSymbolicIntegration;
00325
00326 std::stringstream ss;
00327 viennamath::rt_expr<InterfaceType> lhs(e.lhs()->clone());
00328
00329 if (dynamic_cast< const OpId * >(e.op()) != NULL)
00330 ss << translator(lhs, use_parenthesis);
00331 else if (dynamic_cast< const OpExp * >(e.op()) != NULL)
00332 ss << " \\exp " << translator(lhs, true) << " ";
00333 else if (dynamic_cast< const OpSin * >(e.op()) != NULL)
00334 ss << " \\sin " << translator(lhs, true) << " ";
00335 else if (dynamic_cast< const OpCos * >(e.op()) != NULL)
00336 ss << " \\cos " << translator(lhs, true) << " ";
00337 else if (dynamic_cast< const OpTan * >(e.op()) != NULL)
00338 ss << " \\tan " << translator(lhs, true) << " ";
00339 else if (dynamic_cast< const OpFabs * >(e.op()) != NULL)
00340 ss << " \\left|" << translator(lhs) << "\\right| ";
00341 else if (dynamic_cast< const OpSqrt * >(e.op()) != NULL)
00342 ss << " \\sqrt{" << translator(lhs) << "} ";
00343 else if (dynamic_cast< const OpLog * >(e.op()) != NULL)
00344 ss << " \\ln " << translator(lhs, true) << " ";
00345 else if (dynamic_cast< const OpLog10 * >(e.op()) != NULL)
00346 ss << " \\log " << translator(lhs, true) << " ";
00347
00348 else if (dynamic_cast< const OpGradient * >(e.op()) != NULL)
00349 ss << " \\nabla " << translator(lhs, true) << " ";
00350 else if (dynamic_cast< const OpDivergence * >(e.op()) != NULL)
00351 ss << " \\nabla \\cdot " << translator(lhs, true) << " ";
00352 else if (dynamic_cast< const OpPartialDeriv * >(e.op()) != NULL)
00353 {
00354 const OpPartialDeriv * tmp = dynamic_cast< const OpPartialDeriv * >(e.op());
00355 viennamath::rt_variable<InterfaceType> var(tmp->op().id());
00356 ss << " \\frac{\\partial " << translator(lhs, true) << "}{\\partial " << translator(var) << "} ";
00357 }
00358 else if (dynamic_cast< const OpRuntimeIntegration * >(e.op()) != NULL)
00359 {
00360 const OpRuntimeIntegration * op_integral = dynamic_cast< const OpRuntimeIntegration * >(e.op());
00361
00362 ss << " \\int_{ " << translator(op_integral->op().interval()) << " } ";
00363 ss << translator(lhs) << " ";
00364 ss << " \\: \\mathrm{d} " << translator(op_integral->op().variable()) << " ";
00365 }
00366 else if (dynamic_cast< const OpSymbolicIntegration * >(e.op()) != NULL)
00367 {
00368 const OpSymbolicIntegration * op_integral = dynamic_cast< const OpSymbolicIntegration * >(e.op());
00369
00370 ss << " \\int_{\\Omega_{" << op_integral->op().interval().id() << "}} ";
00371 ss << translator(lhs) << " ";
00372 ss << " \\: \\mathrm{d} \\Omega ";
00373 }
00374 else
00375 {
00376 std::cout << "Operator not supported: " << e.op()->str() << std::endl;
00377 throw "Not supported!";
00378 }
00379
00380 return ss.str();
00381 }
00382
00383 };
00384
00385
00386
00387
00388
00393 template <typename InterfaceType>
00394 class rt_latex_constant_processor : public rt_latex_processor_interface<InterfaceType>
00395 {
00396 typedef typename InterfaceType::numeric_type NumericType;
00397 typedef viennamath::rt_constant<default_numeric_type, InterfaceType> Constant;
00398
00399 public:
00400
00401 std::string process(InterfaceType const * ptr, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00402 {
00403 if (dynamic_cast< const Constant * >(ptr) != NULL)
00404 {
00405 const Constant * temp = dynamic_cast< const Constant * >(ptr);
00406 return process_impl(*temp, use_parenthesis, translator);
00407 }
00408
00409 return "";
00410 }
00411
00412 private:
00413
00414 std::string process_impl(Constant const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00415 {
00416 std::stringstream ss;
00417 ss << " " << static_cast<NumericType>(e) << " ";
00418 return ss.str();
00419 }
00420
00421 };
00422
00423
00424
00425
00426
00431 template <typename InterfaceType>
00432 class rt_latex_variable_processor : public rt_latex_processor_interface<InterfaceType>
00433 {
00434 typedef typename InterfaceType::numeric_type NumericType;
00435 typedef viennamath::rt_variable<InterfaceType> Variable;
00436
00437 public:
00438
00439 std::string process(InterfaceType const * ptr, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00440 {
00441 if (dynamic_cast< const Variable * >(ptr) != NULL)
00442 {
00443 const Variable * temp = dynamic_cast< const Variable * >(ptr);
00444 return process_impl(*temp, use_parenthesis, translator);
00445 }
00446
00447 return "";
00448 }
00449
00450 bool customize(InterfaceType const * ptr, std::string const & str)
00451 {
00452 if (dynamic_cast< const Variable * >(ptr) != NULL)
00453 {
00454 const Variable * temp = dynamic_cast< const Variable * >(ptr);
00455 variable_strings_[temp->id()] = str;
00456 return true;
00457 }
00458 return false;
00459 }
00460
00461 private:
00462
00463 std::string process_impl(Variable const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00464 {
00465 std::stringstream ss;
00466
00467 std::map<id_type, std::string>::const_iterator it = variable_strings_.find(e.id());
00468 if (it != variable_strings_.end())
00469 ss << it->second;
00470 else
00471 ss << " x_{" << e.id() << "} ";
00472
00473 return ss.str();
00474 }
00475
00476 std::map<id_type, std::string> variable_strings_;
00477 };
00478
00479
00480
00481
00486 template <typename InterfaceType>
00487 class rt_latex_function_symbol_processor : public rt_latex_processor_interface<InterfaceType>
00488 {
00489 typedef typename InterfaceType::numeric_type NumericType;
00490 typedef viennamath::rt_function_symbol<InterfaceType> FuncSymbol;
00491 typedef std::pair<id_type, id_type> KeyType;
00492
00493 public:
00494
00495 std::string process(InterfaceType const * ptr, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00496 {
00497 if (dynamic_cast< const FuncSymbol * >(ptr) != NULL)
00498 {
00499 const FuncSymbol * temp = dynamic_cast< const FuncSymbol * >(ptr);
00500 return process_impl(*temp, use_parenthesis, translator);
00501 }
00502
00503 return "";
00504 }
00505
00506 bool customize(InterfaceType const * ptr, std::string const & str)
00507 {
00508 if (dynamic_cast< const FuncSymbol * >(ptr) != NULL)
00509 {
00510 const FuncSymbol * temp = dynamic_cast< const FuncSymbol * >(ptr);
00511 KeyType key(temp->id(), temp->tag_id());
00512 function_symbol_strings_[key] = str;
00513 return true;
00514 }
00515 return false;
00516 }
00517
00518 private:
00519
00520 std::string process_impl(FuncSymbol const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
00521 {
00522 std::stringstream ss;
00523
00524 KeyType func_symb_id(e.id(), e.tag_id());
00525 std::map<KeyType, std::string>::const_iterator it = function_symbol_strings_.find(func_symb_id);
00526 if (it != function_symbol_strings_.end())
00527 {
00528 ss << it->second;
00529 }
00530 else
00531 {
00532 if (e.tag_id() == test_tag<>::tag_id())
00533 ss << " v_{" << e.id() << "} ";
00534 else
00535 ss << " u_{" << e.id() << "} ";
00536 }
00537
00538 return ss.str();
00539 }
00540
00541 std::map<KeyType, std::string> function_symbol_strings_;
00542
00543 };
00544
00545
00546
00547 }
00548
00549 #endif