} else {
- if (precedence <= level)
- c.s << "(";
+ if (precedence <= level) {
+ if (is_of_type(c, print_latex))
+ c.s << "{(";
+ else
+ c.s << "(";
+ }
numeric coeff;
bool first = true;
else
coeff.print(c, precedence);
}
- c.s << '*';
+ if (is_of_type(c, print_latex))
+ c.s << ' ';
+ else
+ c.s << '*';
}
it->rest.print(c, precedence);
it++;
}
- if (precedence <= level)
- c.s << ")";
+ if (precedence <= level) {
+ if (is_of_type(c, print_latex))
+ c.s << ")}";
+ else
+ c.s << ")";
+ }
}
}
std::vector<property>::const_iterator i = props.begin(), iend = props.end();
while (i != iend) {
property_type type = i->type;
- string name = a.unatomize(i->name);
+ std::string name = a.unatomize(i->name);
propinfovector::iterator a = v.begin(), aend = v.end();
bool found = false;
#if defined(__GNUC__) && ((__GNUC__ == 2) && (__GNUC_MINOR__ < 97))
typedef std::vector<property_info,malloc_alloc> propinfovector;
#else
- typedef std::vector<ex> propinfovector;
+ typedef std::vector<property_info> propinfovector;
#endif
archive_node() : a(*dummy_ar_creator()), has_expression(false) {} // hack for cint which always requires a default constructor
ex basic::collect(const ex & s) const
{
ex x;
- for (int n=this->ldegree(s); n<=this->degree(s); n++)
+ for (int n=this->ldegree(s); n<=this->degree(s); ++n)
x += this->coeff(s,n)*power(s,n);
- return x;
+ // correct for lost fractional arguments and return
+ return x + (*this - x).expand();
}
/** Perform automatic non-interruptive symbolic evaluation on expression. */
debugmsg("constant print", LOGLEVEL_PRINT);
if (is_of_type(c, print_tree)) {
-
c.s << std::string(level, ' ') << name << " (" << class_name() << ")"
<< std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
<< std::endl;
-
+ } else if (is_of_type(c, print_latex)) {
+ if (name=="Pi")
+ c.s << "\\pi";
+ else if (name=="Euler")
+ c.s << "\\gamma_E";
+ else if (name=="Catalan")
+ c.s << "G";
+ else
+ c.s << "\\mbox{"+name+"}";
} else
c.s << name;
}
class status_flags {
public:
enum {
- dynallocated = 0x0001, ///< Heap-allocated (i.e. created by new if we want to be clever and bypass the stack)
+ dynallocated = 0x0001, ///< Heap-allocated (i.e. created by new if we want to be clever and bypass the stack, @see ex::construct_from_basic() )
evaluated = 0x0002, ///< .eval() has already done its job
expanded = 0x0004, ///< .expand() has already done its job
hash_calculated = 0x0008 ///< .calchash() has already done its job
~function_options();
void initialize(void);
function_options & set_name(std::string const & n, std::string const & tn=std::string());
+ function_options & latex_name(std::string const & tn);
// the following lines have been generated for max. ${maxargs} parameters
$eval_func_interface
$evalf_func_interface
void function_options::initialize(void)
{
- set_name("unnamed_function","\\\\operatorname{unnamed}");
+ set_name("unnamed_function","\\\\mbox{unnamed}");
nparams=0;
eval_f=evalf_f=derivative_f=series_f=0;
evalf_params_first=true;
{
name=n;
if (tn==std::string()) {
- TeX_name="\\\\operatorname{"+name+"}";
+ TeX_name="\\\\mbox{"+name+"}";
} else {
TeX_name=tn;
}
return *this;
}
+function_options & function_options::latex_name(std::string const & tn)
+{
+ TeX_name=tn;
+ return *this;
+}
+
// the following lines have been generated for max. ${maxargs} parameters
$eval_func_implementation
$evalf_func_implementation
}
c.s << ")";
+ } else if is_of_type(c, print_latex) {
+ c.s << registered_functions()[serial].TeX_name;
+ printseq(c, '(', ',', ')', exprseq::precedence, function::precedence);
} else {
c.s << registered_functions()[serial].name;
printseq(c, '(', ',', ')', exprseq::precedence, function::precedence);
REGISTER_FUNCTION(eta, eval_func(eta_eval).
evalf_func(eta_evalf).
- series_func(eta_series));
+ series_func(eta_series).
+ latex_name("\\eta"));
//////////
REGISTER_FUNCTION(Li2, eval_func(Li2_eval).
evalf_func(Li2_evalf).
derivative_func(Li2_deriv).
- series_func(Li2_series));
+ series_func(Li2_series).
+ latex_name("\\mbox{Li}_2"));
//////////
// trilogarithm
return Li3(x).hold();
}
-REGISTER_FUNCTION(Li3, eval_func(Li3_eval));
+REGISTER_FUNCTION(Li3, eval_func(Li3_eval).
+ latex_name("\\mbox{Li}_3"));
//////////
// factorial
// Differentiation is handled in function::derivative because of its special requirements
REGISTER_FUNCTION(Order, eval_func(Order_eval).
- series_func(Order_series));
+ series_func(Order_series).
+ latex_name("\\mathcal{O}"));
//////////
// Inert partial differentiation operator
REGISTER_FUNCTION(lgamma, eval_func(lgamma_eval).
evalf_func(lgamma_evalf).
derivative_func(lgamma_deriv).
- series_func(lgamma_series));
+ series_func(lgamma_series).
+ latex_name("\\log \\Gamma"));
//////////
REGISTER_FUNCTION(tgamma, eval_func(tgamma_eval).
evalf_func(tgamma_evalf).
derivative_func(tgamma_deriv).
- series_func(tgamma_series));
+ series_func(tgamma_series).
+ latex_name("\\Gamma"));
//////////
REGISTER_FUNCTION(beta, eval_func(beta_eval).
evalf_func(beta_evalf).
derivative_func(beta_deriv).
- series_func(beta_series));
+ series_func(beta_series).
+ latex_name("\\mbox{B}"));
//////////
evalf_func(psi2_evalf).
derivative_func(psi2_deriv).
series_func(psi2_series).
+ latex_name("\\psi").
overloaded(2));
REGISTER_FUNCTION(exp, eval_func(exp_eval).
evalf_func(exp_evalf).
- derivative_func(exp_deriv));
+ derivative_func(exp_deriv).
+ latex_name("\\exp"));
//////////
// natural logarithm
REGISTER_FUNCTION(log, eval_func(log_eval).
evalf_func(log_evalf).
derivative_func(log_deriv).
- series_func(log_series));
+ series_func(log_series).
+ latex_name("\\ln"));
//////////
// sine (trigonometric function)
REGISTER_FUNCTION(sin, eval_func(sin_eval).
evalf_func(sin_evalf).
- derivative_func(sin_deriv));
+ derivative_func(sin_deriv).
+ latex_name("\\sin"));
//////////
// cosine (trigonometric function)
REGISTER_FUNCTION(cos, eval_func(cos_eval).
evalf_func(cos_evalf).
- derivative_func(cos_deriv));
+ derivative_func(cos_deriv).
+ latex_name("\\cos"));
//////////
// tangent (trigonometric function)
REGISTER_FUNCTION(tan, eval_func(tan_eval).
evalf_func(tan_evalf).
derivative_func(tan_deriv).
- series_func(tan_series));
+ series_func(tan_series).
+ latex_name("\\tan"));
//////////
// inverse sine (arc sine)
REGISTER_FUNCTION(asin, eval_func(asin_eval).
evalf_func(asin_evalf).
- derivative_func(asin_deriv));
+ derivative_func(asin_deriv).
+ latex_name("\\arcsin"));
//////////
// inverse cosine (arc cosine)
REGISTER_FUNCTION(acos, eval_func(acos_eval).
evalf_func(acos_evalf).
- derivative_func(acos_deriv));
+ derivative_func(acos_deriv).
+ latex_name("\\arccos"));
//////////
// inverse tangent (arc tangent)
REGISTER_FUNCTION(atan, eval_func(atan_eval).
evalf_func(atan_evalf).
derivative_func(atan_deriv).
- series_func(atan_series));
+ series_func(atan_series).
+ latex_name("\\arctan"));
//////////
// inverse tangent (atan2(y,x))
REGISTER_FUNCTION(sinh, eval_func(sinh_eval).
evalf_func(sinh_evalf).
- derivative_func(sinh_deriv));
+ derivative_func(sinh_deriv).
+ latex_name("\\sinh"));
//////////
// hyperbolic cosine (trigonometric function)
REGISTER_FUNCTION(cosh, eval_func(cosh_eval).
evalf_func(cosh_evalf).
- derivative_func(cosh_deriv));
-
+ derivative_func(cosh_deriv).
+ latex_name("\\cosh"));
//////////
// hyperbolic tangent (trigonometric function)
REGISTER_FUNCTION(tanh, eval_func(tanh_eval).
evalf_func(tanh_evalf).
derivative_func(tanh_deriv).
- series_func(tanh_series));
+ series_func(tanh_series).
+ latex_name("\\tanh"));
//////////
// inverse hyperbolic sine (trigonometric function)
eval_func(zeta1_eval).
evalf_func(zeta1_evalf).
derivative_func(zeta1_deriv).
+ latex_name("\\zeta").
overloaded(2));
//////////
} else if (is_of_type(c, print_csrc)) {
- if (precedence <= level)
- c.s << "(";
+ c.s << "(";
if (!overall_coeff.is_equal(_ex1())) {
overall_coeff.bp->print(c, precedence);
} else {
- if (precedence <= level)
- c.s << "(";
+ if (precedence <= level) {
+ if (is_of_type(c, print_latex))
+ c.s << "{(";
+ else
+ c.s << "(";
+ }
bool first = true;
else
coeff.print(c, precedence);
}
- c.s << '*';
+ if (is_of_type(c, print_latex))
+ c.s << ' ';
+ else
+ c.s << '*';
}
// Then proceed with the remaining factors
epvector::const_iterator it = seq.begin(), itend = seq.end();
while (it != itend) {
if (!first) {
- c.s << '*';
+ if (is_of_type(c, print_latex))
+ c.s << ' ';
+ else
+ c.s << '*';
} else {
first = false;
}
it++;
}
- if (precedence <= level)
- c.s << ")";
+ if (precedence <= level) {
+ if (is_of_type(c, print_latex))
+ c.s << ")}";
+ else
+ c.s << ")";
+ }
}
}
c.s.flags(oldflags);
} else {
-
- cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
- cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
+ const std::string par_open = is_of_type(c, print_latex) ? "{(" : "(";
+ const std::string par_close = is_of_type(c, print_latex) ? ")}" : ")";
+ const std::string imag_sym = is_of_type(c, print_latex) ? "i" : "I";
+ const std::string mul_sym = is_of_type(c, print_latex) ? " " : "*";
+ const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
+ const cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
if (cln::zerop(i)) {
// case 1, real: x or -x
if ((precedence <= level) && (!this->is_nonneg_integer())) {
- c.s << "(";
+ c.s << par_open;
print_real_number(c.s, r);
- c.s << ")";
+ c.s << par_close;
} else {
print_real_number(c.s, r);
}
// case 2, imaginary: y*I or -y*I
if ((precedence <= level) && (i < 0)) {
if (i == -1) {
- c.s << "(-I)";
+ c.s << par_open+imag_sym+par_close;
} else {
- c.s << "(";
+ c.s << par_open;
print_real_number(c.s, i);
- c.s << "*I)";
+ c.s << mul_sym+imag_sym+par_close;
}
} else {
if (i == 1) {
- c.s << "I";
+ c.s << imag_sym;
} else {
if (i == -1) {
- c.s << "-I";
+ c.s << "-" << imag_sym;
} else {
print_real_number(c.s, i);
- c.s << "*I";
+ c.s << mul_sym+imag_sym;
}
}
}
} else {
// case 3, complex: x+y*I or x-y*I or -x+y*I or -x-y*I
if (precedence <= level)
- c.s << "(";
+ c.s << par_open;
print_real_number(c.s, r);
if (i < 0) {
if (i == -1) {
- c.s << "-I";
+ c.s << "-"+imag_sym;
} else {
print_real_number(c.s, i);
- c.s << "*I";
+ c.s << mul_sym+imag_sym;
}
} else {
if (i == 1) {
- c.s << "+I";
+ c.s << "+"+imag_sym;
} else {
c.s << "+";
print_real_number(c.s, i);
- c.s << "*I";
+ c.s << mul_sym+imag_sym;
}
}
if (precedence <= level)
- c.s << ")";
+ c.s << par_close;
}
}
}
} else {
if (exponent.is_equal(_ex1_2())) {
- c.s << "sqrt(";
+ if (is_of_type(c, print_latex))
+ c.s << "\\sqrt{";
+ else
+ c.s << "sqrt(";
basis.print(c);
- c.s << ")";
+ if (is_of_type(c, print_latex))
+ c.s << "}";
+ else
+ c.s << ")";
} else {
- if (precedence <= level)
- c.s << "(";
+ if (precedence <= level) {
+ if (is_of_type(c, print_latex))
+ c.s << "{(";
+ else
+ c.s << "(";
+ }
basis.print(c, precedence);
c.s << "^";
exponent.print(c, precedence);
- if (precedence <= level)
- c.s << ")";
+ if (precedence <= level) {
+ if (is_of_type(c, print_latex))
+ c.s << ")}";
+ else
+ c.s << ")";
+ }
}
}
}
virtual void dummy(void) {}
};
+/** Context for latex-parsable output. */
+class print_latex : public print_context
+{
+public:
+ print_latex(std::ostream & os = std::cout)
+ : print_context(os) {}
+};
+
/** Context for tree-like output for debugging. */
class print_tree : public print_context
{
if (precedence <= level)
c.s << "(";
-
+
+ std::string par_open = is_of_type(c, print_latex) ? "{(" : "(";
+ std::string par_close = is_of_type(c, print_latex) ? ")}" : ")";
+
// objects of type pseries must not have any zero entries, so the
// trivial (zero) pseries needs a special treatment here:
if (seq.size() == 0)
i->rest.info(info_flags::positive)) {
i->rest.print(c);
} else {
- c.s << '(';
+ c.s << par_open;
i->rest.print(c);
- c.s << ')';
+ c.s << par_close;
}
// print 'coeff', something like (x-1)^42
if (!i->coeff.is_zero()) {
c.s << '*';
if (!point.is_zero()) {
- c.s << '(';
+ c.s << par_open;
(var-point).print(c);
- c.s << ')';
+ c.s << par_close;
} else
var.print(c);
if (i->coeff.compare(_ex1())) {
c.s << '^';
if (i->coeff.info(info_flags::negative)) {
- c.s << '(';
- i->coeff.print(c);
- c.s << ')';
- } else
+ c.s << par_open;
i->coeff.print(c);
+ c.s << par_close;
+ } else {
+ if (is_of_type(c, print_latex)) {
+ c.s << '{';
+ i->coeff.print(c);
+ c.s << '}';
+ } else
+ i->coeff.print(c);
+ }
}
}
} else
<< std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
<< std::endl;
+ } else if (is_of_type(c, print_latex)) {
+ if (name=="alpha" || name=="beta" || name=="gamma"
+ || name=="delta" || name=="epsilon" || name=="varepsilon"
+ || name=="zeta" || name=="eta" || name=="theta"
+ || name=="vartheta" || name=="iota" || name=="kappa"
+ || name=="lambda" || name=="mu" || name=="nu"
+ || name=="xi" || name=="omicron" || name=="pi"
+ || name=="varpi" || name=="rho" || name=="varrho"
+ || name=="sigma" || name=="varsigma" || name=="tau"
+ || name=="upsilon" || name=="phi" || name=="varphix"
+ || name=="chi" || name=="psi" || name=="omega"
+ || name=="Gamma" || name=="Delta" || name=="Theta"
+ || name=="Lambda" || name=="Xi" || name=="Pi"
+ || name=="Sigma" || name=="Upsilon" || name=="Phi"
+ || name=="Psi" || name=="Omega")
+ c.s << "\\" << name;
+ else
+ c.s << name;
} else
c.s << name;
}