Program Listing for File functions.h¶
↰ Return to documentation for file (symengine/symengine/functions.h
)
#ifndef SYMENGINE_FUNCTIONS_H
#define SYMENGINE_FUNCTIONS_H
#include <symengine/basic.h>
#include <symengine/symengine_casts.h>
#include <symengine/constants.h>
namespace SymEngine
{
class Function : public Basic
{
};
class OneArgFunction : public Function
{
private:
RCP<const Basic> arg_;
public:
OneArgFunction(const RCP<const Basic> &arg) : arg_{arg} {};
inline hash_t __hash__() const
{
hash_t seed = this->get_type_code();
hash_combine<Basic>(seed, *arg_);
return seed;
}
inline RCP<const Basic> get_arg() const
{
return arg_;
}
virtual inline vec_basic get_args() const
{
return {arg_};
}
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const = 0;
inline RCP<const Basic> create(const vec_basic &b) const
{
SYMENGINE_ASSERT(b.size() == 1);
return create(b[0]);
}
virtual inline bool __eq__(const Basic &o) const
{
return is_same_type(*this, o)
and eq(*get_arg(),
*down_cast<const OneArgFunction &>(o).get_arg());
}
virtual inline int compare(const Basic &o) const
{
SYMENGINE_ASSERT(is_same_type(*this, o))
return get_arg()->__cmp__(
*(down_cast<const OneArgFunction &>(o).get_arg()));
}
};
template <class BaseClass>
class TwoArgBasic : public BaseClass
{
private:
RCP<const Basic> a_;
RCP<const Basic> b_;
public:
TwoArgBasic(const RCP<const Basic> &a, const RCP<const Basic> &b)
: a_{a}, b_{b} {};
inline hash_t __hash__() const
{
hash_t seed = this->get_type_code();
hash_combine<Basic>(seed, *a_);
hash_combine<Basic>(seed, *b_);
return seed;
}
inline RCP<const Basic> get_arg1() const
{
return a_;
}
inline RCP<const Basic> get_arg2() const
{
return b_;
}
virtual inline vec_basic get_args() const
{
return {a_, b_};
}
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const = 0;
inline RCP<const Basic> create(const vec_basic &b) const
{
SYMENGINE_ASSERT(b.size() == 2);
return create(b[0], b[1]);
}
virtual inline bool __eq__(const Basic &o) const
{
return is_same_type(*this, o)
and eq(*get_arg1(),
*down_cast<const TwoArgBasic &>(o).get_arg1())
and eq(*get_arg2(),
*down_cast<const TwoArgBasic &>(o).get_arg2());
}
virtual inline int compare(const Basic &o) const
{
SYMENGINE_ASSERT(is_same_type(*this, o))
const TwoArgBasic &t = down_cast<const TwoArgBasic &>(o);
if (neq(*get_arg1(), *(t.get_arg1()))) {
return get_arg1()->__cmp__(
*(down_cast<const TwoArgBasic &>(o).get_arg1()));
} else {
return get_arg2()->__cmp__(
*(down_cast<const TwoArgBasic &>(o).get_arg2()));
}
}
};
typedef TwoArgBasic<Function> TwoArgFunction;
class MultiArgFunction : public Function
{
private:
vec_basic arg_;
public:
MultiArgFunction(const vec_basic &arg) : arg_{arg} {};
inline hash_t __hash__() const
{
hash_t seed = this->get_type_code();
for (const auto &a : arg_)
hash_combine<Basic>(seed, *a);
return seed;
}
virtual inline vec_basic get_args() const
{
return arg_;
}
inline const vec_basic &get_vec() const
{
return arg_;
}
virtual RCP<const Basic> create(const vec_basic &v) const = 0;
virtual inline bool __eq__(const Basic &o) const
{
return is_same_type(*this, o)
and unified_eq(get_vec(),
down_cast<const MultiArgFunction &>(o).get_vec());
}
virtual inline int compare(const Basic &o) const
{
SYMENGINE_ASSERT(is_same_type(*this, o))
return unified_compare(
get_vec(), down_cast<const MultiArgFunction &>(o).get_vec());
}
};
class Sign : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_SIGN)
Sign(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> sign(const RCP<const Basic> &arg);
class Floor : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_FLOOR)
Floor(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> floor(const RCP<const Basic> &arg);
class Ceiling : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_CEILING)
Ceiling(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> ceiling(const RCP<const Basic> &arg);
class Truncate : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_TRUNCATE)
Truncate(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> truncate(const RCP<const Basic> &arg);
class Conjugate : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_CONJUGATE)
Conjugate(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> conjugate(const RCP<const Basic> &arg);
class TrigBase : public OneArgFunction
{
public:
TrigBase(RCP<const Basic> arg) : OneArgFunction(arg){};
};
class TrigFunction : public TrigBase
{
public:
TrigFunction(RCP<const Basic> arg) : TrigBase(arg){};
};
class InverseTrigFunction : public TrigBase
{
public:
InverseTrigFunction(RCP<const Basic> arg) : TrigBase(arg){};
};
bool get_pi_shift(const RCP<const Basic> &arg, const Ptr<RCP<const Number>> &n,
const Ptr<RCP<const Basic>> &m);
bool could_extract_minus(const Basic &arg);
bool handle_minus(const RCP<const Basic> &arg,
const Ptr<RCP<const Basic>> &rarg);
bool inverse_lookup(umap_basic_basic &d, const RCP<const Basic> &t,
const Ptr<RCP<const Basic>> &index);
// \return true of conjugate has to be returned finally else false
bool trig_simplify(const RCP<const Basic> &arg, unsigned period, bool odd,
bool conj_odd, // input
const Ptr<RCP<const Basic>> &rarg, int &index,
int &sign); // output
RCP<const Basic> sqrt(const RCP<const Basic> &arg);
RCP<const Basic> cbrt(const RCP<const Basic> &arg);
class Sin : public TrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_SIN)
Sin(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> sin(const RCP<const Basic> &arg);
class Cos : public TrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_COS)
Cos(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> cos(const RCP<const Basic> &arg);
class Tan : public TrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_TAN)
Tan(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> tan(const RCP<const Basic> &arg);
class Cot : public TrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_COT)
Cot(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> cot(const RCP<const Basic> &arg);
class Csc : public TrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_CSC)
Csc(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> csc(const RCP<const Basic> &arg);
class Sec : public TrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_SEC)
Sec(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> sec(const RCP<const Basic> &arg);
class ASin : public InverseTrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ASIN)
ASin(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> asin(const RCP<const Basic> &arg);
class ACos : public InverseTrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ACOS)
ACos(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> acos(const RCP<const Basic> &arg);
class ASec : public InverseTrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ASEC)
ASec(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> asec(const RCP<const Basic> &arg);
class ACsc : public InverseTrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ACSC)
ACsc(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> acsc(const RCP<const Basic> &arg);
class ATan : public InverseTrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ATAN)
ATan(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> atan(const RCP<const Basic> &arg);
class ACot : public InverseTrigFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ACOT)
ACot(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> acot(const RCP<const Basic> &arg);
class ATan2 : public TwoArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ATAN2)
ATan2(const RCP<const Basic> &num, const RCP<const Basic> &den);
bool is_canonical(const RCP<const Basic> &num,
const RCP<const Basic> &den) const;
inline RCP<const Basic> get_num() const
{
return get_arg1();
}
inline RCP<const Basic> get_den() const
{
return get_arg2();
}
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const;
};
RCP<const Basic> atan2(const RCP<const Basic> &num,
const RCP<const Basic> &den);
class Log : public OneArgFunction
{
// Logarithms are taken with the natural base, `e`. To get
// a logarithm of a different base `b`, use `log(x, b)`,
// which is essentially short-hand for `log(x)/log(b)`.
public:
IMPLEMENT_TYPEID(SYMENGINE_LOG)
Log(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> log(const RCP<const Basic> &arg);
RCP<const Basic> log(const RCP<const Basic> &arg, const RCP<const Basic> &b);
class LambertW : public OneArgFunction
{
// Lambert W function, defined as the inverse function of
// x*exp(x). This function represents the principal branch
// of this inverse function, which is multivalued.
// For more information, see:
// http://en.wikipedia.org/wiki/Lambert_W_function
public:
IMPLEMENT_TYPEID(SYMENGINE_LAMBERTW)
LambertW(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> lambertw(const RCP<const Basic> &arg);
class Zeta : public TwoArgFunction
{
// Hurwitz zeta function (or Riemann zeta function).
//
// For `\operatorname{Re}(a) > 0` and `\operatorname{Re}(s) > 1`, this
// function is defined as
//
// .. math:: \zeta(s, a) = \sum_{n=0}^\infty \frac{1}{(n + a)^s},
//
// where the standard choice of argument for :math:`n + a` is used.
// If no value is passed for :math:`a`, by this function assumes a default
// value
// of :math:`a = 1`, yielding the Riemann zeta function.
public:
using TwoArgFunction::create;
IMPLEMENT_TYPEID(SYMENGINE_ZETA)
Zeta(const RCP<const Basic> &s, const RCP<const Basic> &a);
Zeta(const RCP<const Basic> &s);
inline RCP<const Basic> get_s() const
{
return get_arg1();
}
inline RCP<const Basic> get_a() const
{
return get_arg2();
}
bool is_canonical(const RCP<const Basic> &s,
const RCP<const Basic> &a) const;
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const;
};
RCP<const Basic> zeta(const RCP<const Basic> &s, const RCP<const Basic> &a);
RCP<const Basic> zeta(const RCP<const Basic> &s);
class Dirichlet_eta : public OneArgFunction
{
// See http://en.wikipedia.org/wiki/Dirichlet_eta_function
public:
IMPLEMENT_TYPEID(SYMENGINE_DIRICHLET_ETA)
Dirichlet_eta(const RCP<const Basic> &s);
inline RCP<const Basic> get_s() const
{
return get_arg();
}
bool is_canonical(const RCP<const Basic> &s) const;
RCP<const Basic> rewrite_as_zeta() const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
using OneArgFunction::create;
};
RCP<const Basic> dirichlet_eta(const RCP<const Basic> &s);
class FunctionSymbol : public MultiArgFunction
{
protected:
std::string name_;
public:
IMPLEMENT_TYPEID(SYMENGINE_FUNCTIONSYMBOL)
FunctionSymbol(std::string name, const vec_basic &arg);
FunctionSymbol(std::string name, const RCP<const Basic> &arg);
virtual hash_t __hash__() const;
virtual bool __eq__(const Basic &o) const;
virtual int compare(const Basic &o) const;
inline const std::string &get_name() const
{
return name_;
}
bool is_canonical(const vec_basic &arg) const;
virtual RCP<const Basic> create(const vec_basic &x) const;
};
RCP<const Basic> function_symbol(std::string name, const RCP<const Basic> &arg);
RCP<const Basic> function_symbol(std::string name, const vec_basic &arg);
class FunctionWrapper : public FunctionSymbol
{
public:
IMPLEMENT_TYPEID(SYMENGINE_FUNCTIONWRAPPER)
FunctionWrapper(std::string name, const vec_basic &arg);
FunctionWrapper(std::string name, const RCP<const Basic> &arg);
virtual RCP<const Basic> create(const vec_basic &v) const = 0;
virtual RCP<const Number> eval(long bits) const = 0;
virtual RCP<const Basic> diff_impl(const RCP<const Symbol> &s) const = 0;
};
class Derivative : public Basic
{
private:
RCP<const Basic> arg_;
// The symbols are declared as Basic (and checked by is_canonical() below),
// to avoid issues with converting vector<RCP<Symbol>> to
// vector<RCP<Basic>>, see [1], [2]. The problem is that even though Symbol
// inherits from Basic, vector<RCP<Symbol>> does not inherit from
// vector<RCP<Basic>>, so the compiler can't cast the derived type to the
// base type when calling functions like unified_eq() that are only
// defined for the base type vector<RCP<Basic>>.
// [1]
// http://stackoverflow.com/questions/14964909/how-to-cast-a-vector-of-shared-ptrs-of-a-derived-class-to-a-vector-of-share-ptrs
// [2]
// http://stackoverflow.com/questions/114819/getting-a-vectorderived-into-a-function-that-expects-a-vectorbase
multiset_basic x_;
public:
IMPLEMENT_TYPEID(SYMENGINE_DERIVATIVE)
Derivative(const RCP<const Basic> &arg, const multiset_basic &x);
static RCP<const Derivative> create(const RCP<const Basic> &arg,
const multiset_basic &x)
{
return make_rcp<const Derivative>(arg, x);
}
virtual hash_t __hash__() const;
virtual bool __eq__(const Basic &o) const;
virtual int compare(const Basic &o) const;
inline RCP<const Basic> get_arg() const
{
return arg_;
}
inline const multiset_basic &get_symbols() const
{
return x_;
}
virtual vec_basic get_args() const
{
vec_basic args = {arg_};
args.insert(args.end(), x_.begin(), x_.end());
return args;
}
bool is_canonical(const RCP<const Basic> &arg,
const multiset_basic &x) const;
};
class Subs : public Basic
{
private:
RCP<const Basic> arg_;
map_basic_basic dict_;
public:
IMPLEMENT_TYPEID(SYMENGINE_SUBS)
Subs(const RCP<const Basic> &arg, const map_basic_basic &x);
static RCP<const Subs> create(const RCP<const Basic> &arg,
const map_basic_basic &x)
{
return make_rcp<const Subs>(arg, x);
}
virtual hash_t __hash__() const;
virtual bool __eq__(const Basic &o) const;
virtual int compare(const Basic &o) const;
inline const RCP<const Basic> &get_arg() const
{
return arg_;
}
inline const map_basic_basic &get_dict() const
{
return dict_;
};
virtual vec_basic get_variables() const;
virtual vec_basic get_point() const;
virtual vec_basic get_args() const;
bool is_canonical(const RCP<const Basic> &arg,
const map_basic_basic &x) const;
};
class HyperbolicBase : public OneArgFunction
{
public:
HyperbolicBase(RCP<const Basic> arg) : OneArgFunction{arg} {};
};
class HyperbolicFunction : public HyperbolicBase
{
public:
HyperbolicFunction(RCP<const Basic> arg) : HyperbolicBase{arg} {};
};
class InverseHyperbolicFunction : public HyperbolicBase
{
public:
InverseHyperbolicFunction(RCP<const Basic> arg) : HyperbolicBase{arg} {};
};
class Sinh : public HyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_SINH)
Sinh(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> sinh(const RCP<const Basic> &arg);
class Csch : public HyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_CSCH)
Csch(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> csch(const RCP<const Basic> &arg);
class Cosh : public HyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_COSH)
Cosh(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> cosh(const RCP<const Basic> &arg);
class Sech : public HyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_SECH)
Sech(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> sech(const RCP<const Basic> &arg);
class Tanh : public HyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_TANH)
Tanh(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> tanh(const RCP<const Basic> &arg);
class Coth : public HyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_COTH)
Coth(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> coth(const RCP<const Basic> &arg);
class ASinh : public InverseHyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ASINH)
ASinh(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> asinh(const RCP<const Basic> &arg);
class ACsch : public InverseHyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ACSCH)
ACsch(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> acsch(const RCP<const Basic> &arg);
class ACosh : public InverseHyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ACOSH)
ACosh(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> acosh(const RCP<const Basic> &arg);
class ATanh : public InverseHyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ATANH)
ATanh(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> atanh(const RCP<const Basic> &arg);
class ACoth : public InverseHyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ACOTH)
ACoth(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> acoth(const RCP<const Basic> &arg);
class ASech : public InverseHyperbolicFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ASECH)
ASech(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> asech(const RCP<const Basic> &arg);
class KroneckerDelta : public TwoArgFunction
{
public:
using TwoArgFunction::create;
IMPLEMENT_TYPEID(SYMENGINE_KRONECKERDELTA)
KroneckerDelta(const RCP<const Basic> &i, const RCP<const Basic> &j);
bool is_canonical(const RCP<const Basic> &i,
const RCP<const Basic> &j) const;
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const;
};
RCP<const Basic> kronecker_delta(const RCP<const Basic> &i,
const RCP<const Basic> &j);
class LeviCivita : public MultiArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_LEVICIVITA)
LeviCivita(const vec_basic &&arg);
bool is_canonical(const vec_basic &arg) const;
virtual RCP<const Basic> create(const vec_basic &arg) const;
};
RCP<const Basic> levi_civita(const vec_basic &arg);
class Erf : public OneArgFunction
{
/* The Gauss error function. This function is defined as:
*
* .. math::
* \mathrm{erf}(x) = \frac{2}{\sqrt{\pi}} \int_0^x e^{-t^2}
*\mathrm{d}t.
**/
public:
IMPLEMENT_TYPEID(SYMENGINE_ERF)
Erf(const RCP<const Basic> &arg) : OneArgFunction(arg)
{
SYMENGINE_ASSIGN_TYPEID()
SYMENGINE_ASSERT(is_canonical(arg))
}
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> erf(const RCP<const Basic> &arg);
class Erfc : public OneArgFunction
{
/* The complementary error function. This function is defined as:
*
* .. math::
* \mathrm{erfc}(x) = 1 - \frac{2}{\sqrt{\pi}} \int_0^x e^{-t^2}
* \mathrm{d}t.
**/
public:
IMPLEMENT_TYPEID(SYMENGINE_ERFC)
Erfc(const RCP<const Basic> &arg) : OneArgFunction(arg)
{
SYMENGINE_ASSIGN_TYPEID()
SYMENGINE_ASSERT(is_canonical(arg))
}
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> erfc(const RCP<const Basic> &arg);
class Gamma : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_GAMMA)
Gamma(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> gamma(const RCP<const Basic> &arg);
class LowerGamma : public TwoArgFunction
{
public:
using TwoArgFunction::create;
IMPLEMENT_TYPEID(SYMENGINE_LOWERGAMMA)
LowerGamma(const RCP<const Basic> &s, const RCP<const Basic> &x);
bool is_canonical(const RCP<const Basic> &s,
const RCP<const Basic> &x) const;
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const;
};
RCP<const Basic> lowergamma(const RCP<const Basic> &s,
const RCP<const Basic> &x);
class UpperGamma : public TwoArgFunction
{
public:
using TwoArgFunction::create;
IMPLEMENT_TYPEID(SYMENGINE_UPPERGAMMA)
UpperGamma(const RCP<const Basic> &s, const RCP<const Basic> &x);
bool is_canonical(const RCP<const Basic> &s,
const RCP<const Basic> &x) const;
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const;
};
RCP<const Basic> uppergamma(const RCP<const Basic> &s,
const RCP<const Basic> &x);
class LogGamma : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_LOGGAMMA)
LogGamma(const RCP<const Basic> &arg) : OneArgFunction(arg)
{
SYMENGINE_ASSIGN_TYPEID()
SYMENGINE_ASSERT(is_canonical(arg))
}
bool is_canonical(const RCP<const Basic> &arg) const;
RCP<const Basic> rewrite_as_gamma() const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> loggamma(const RCP<const Basic> &arg);
class Beta : public TwoArgFunction
{
public:
using TwoArgFunction::create;
IMPLEMENT_TYPEID(SYMENGINE_BETA)
Beta(const RCP<const Basic> &x, const RCP<const Basic> &y)
: TwoArgFunction(x, y)
{
SYMENGINE_ASSIGN_TYPEID()
SYMENGINE_ASSERT(is_canonical(x, y))
}
static RCP<const Beta> from_two_basic(const RCP<const Basic> &x,
const RCP<const Basic> &y);
bool is_canonical(const RCP<const Basic> &s, const RCP<const Basic> &x);
RCP<const Basic> rewrite_as_gamma() const;
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const;
};
RCP<const Basic> beta(const RCP<const Basic> &x, const RCP<const Basic> &y);
class PolyGamma : public TwoArgFunction
{
public:
using TwoArgFunction::create;
IMPLEMENT_TYPEID(SYMENGINE_POLYGAMMA)
PolyGamma(const RCP<const Basic> &n, const RCP<const Basic> &x)
: TwoArgFunction(n, x)
{
SYMENGINE_ASSIGN_TYPEID()
SYMENGINE_ASSERT(is_canonical(n, x))
}
bool is_canonical(const RCP<const Basic> &n, const RCP<const Basic> &x);
RCP<const Basic> rewrite_as_zeta() const;
virtual RCP<const Basic> create(const RCP<const Basic> &a,
const RCP<const Basic> &b) const;
};
RCP<const Basic> polygamma(const RCP<const Basic> &n,
const RCP<const Basic> &x);
RCP<const Basic> digamma(const RCP<const Basic> &x);
RCP<const Basic> trigamma(const RCP<const Basic> &x);
class Abs : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_ABS)
Abs(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> abs(const RCP<const Basic> &arg);
class Max : public MultiArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_MAX)
Max(const vec_basic &&arg);
bool is_canonical(const vec_basic &arg) const;
virtual RCP<const Basic> create(const vec_basic &arg) const;
};
RCP<const Basic> max(const vec_basic &arg);
class Min : public MultiArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_MIN)
Min(const vec_basic &&arg);
bool is_canonical(const vec_basic &arg) const;
virtual RCP<const Basic> create(const vec_basic &arg) const;
};
RCP<const Basic> min(const vec_basic &arg);
RCP<const Basic> trig_to_sqrt(const RCP<const Basic> &arg);
class UnevaluatedExpr : public OneArgFunction
{
public:
IMPLEMENT_TYPEID(SYMENGINE_UNEVALUATED_EXPR)
UnevaluatedExpr(const RCP<const Basic> &arg);
bool is_canonical(const RCP<const Basic> &arg) const;
virtual RCP<const Basic> create(const RCP<const Basic> &arg) const;
};
RCP<const Basic> unevaluated_expr(const RCP<const Basic> &arg);
} // SymEngine
#endif