Loading...
Searching...
No Matches
SymEngine::NumerDenomVisitor Class Reference
+ Inheritance diagram for SymEngine::NumerDenomVisitor:
+ Collaboration diagram for SymEngine::NumerDenomVisitor:

Public Member Functions

 NumerDenomVisitor (const Ptr< RCP< const Basic > > &numer, const Ptr< RCP< const Basic > > &denom)
 
void apply (const Basic &b)
 
void bvisit (const Mul &x)
 
void bvisit (const Add &x)
 
void bvisit (const Pow &x)
 
void bvisit (const Complex &x)
 
void bvisit (const Rational &x)
 
void bvisit (const Basic &x)
 

Private Attributes

Ptr< RCP< const Basic > > numer_
 
Ptr< RCP< const Basic > > denom_
 

Detailed Description

Definition at line 6 of file numer_denom.cpp.

Constructor & Destructor Documentation

◆ NumerDenomVisitor()

SymEngine::NumerDenomVisitor::NumerDenomVisitor ( const Ptr< RCP< const Basic > > &  numer,
const Ptr< RCP< const Basic > > &  denom 
)
inline

Definition at line 12 of file numer_denom.cpp.

14 : numer_{numer}, denom_{denom}
15 {
16 }

Member Function Documentation

◆ apply()

void SymEngine::NumerDenomVisitor::apply ( const Basic b)
inline

Definition at line 18 of file numer_denom.cpp.

19 {
20 b.accept(*this);
21 }

◆ bvisit() [1/6]

void SymEngine::NumerDenomVisitor::bvisit ( const Add x)
inline

Definition at line 49 of file numer_denom.cpp.

50 {
51
52 RCP<const Basic> curr_num = zero;
53 RCP<const Basic> curr_den = one;
54 RCP<const Basic> arg_num, arg_den, den_mul, divx;
55 RCP<const Basic> divx_num, divx_den;
56
57 for (const auto &arg : x.get_args()) {
58 // TODO: This is naive and slow. Fix it
59 as_numer_denom(arg, outArg(arg_num), outArg(arg_den));
60
61 divx = div(arg_den, curr_den);
62 as_numer_denom(divx, outArg(divx_num), outArg(divx_den));
63 if (eq(*divx_den, *one)) {
64 // the curr_den completely divides the arg_den
65 curr_den = arg_den;
66 curr_num = add(mul(curr_num, divx), arg_num);
67 continue;
68 }
69
70 divx = div(curr_den, arg_den);
71 as_numer_denom(divx, outArg(divx_num), outArg(divx_den));
72 // the below two lines, cover the general case, as well as the case
73 // where arg_den completely divides curr_den
74 curr_den = mul(curr_den, divx_den);
75 curr_num = add(mul(curr_num, divx_den), mul(arg_num, divx_num));
76 }
77
78 *numer_ = curr_num;
79 *denom_ = curr_den;
80 }
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
Definition: mul.cpp:431
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
Definition: add.cpp:425

◆ bvisit() [2/6]

void SymEngine::NumerDenomVisitor::bvisit ( const Basic x)
inline

Definition at line 126 of file numer_denom.cpp.

127 {
128 *numer_ = x.rcp_from_this();
129 *denom_ = one;
130 }

◆ bvisit() [3/6]

void SymEngine::NumerDenomVisitor::bvisit ( const Complex x)
inline

Definition at line 100 of file numer_denom.cpp.

101 {
102
103 RCP<const Integer> den, den1, den2;
104 RCP<const Integer> num1, num2;
105
106 num1 = integer(get_num(x.real_));
107 num2 = integer(get_num(x.imaginary_));
108
109 den1 = integer(get_den(x.real_));
110 den2 = integer(get_den(x.imaginary_));
111 den = lcm(*den1, *den2);
112
113 num1 = rcp_static_cast<const Integer>(mul(num1, div(den, den1)));
114 num2 = rcp_static_cast<const Integer>(mul(num2, div(den, den2)));
115
116 *numer_ = Complex::from_two_nums(*num1, *num2);
117 *denom_ = den;
118 }
static RCP< const Number > from_two_nums(const Number &re, const Number &im)
Definition: complex.cpp:109
RCP< const Integer > lcm(const Integer &a, const Integer &b)
Least Common Multiple.
Definition: ntheory.cpp:49
std::enable_if< std::is_integral< T >::value, RCP< constInteger > >::type integer(T i)
Definition: integer.h:197

◆ bvisit() [4/6]

void SymEngine::NumerDenomVisitor::bvisit ( const Mul x)
inline

Definition at line 23 of file numer_denom.cpp.

24 {
25 RCP<const Basic> curr = one;
26 RCP<const Basic> arg_num, arg_den, t;
27
28 for (const auto &arg : x.get_args()) {
29 as_numer_denom(arg, outArg(arg_num), outArg(arg_den));
30 curr = div(mul(curr, arg_num), arg_den);
31 }
32
33 if (not is_a<Mul>(*curr)) {
34 apply(*curr);
35 return;
36 }
37
38 RCP<const Basic> curr_num = one, curr_den = one;
39 for (const auto &arg : curr->get_args()) {
40 as_numer_denom(arg, outArg(arg_num), outArg(arg_den));
41 curr_num = mul(curr_num, arg_num);
42 curr_den = mul(curr_den, arg_den);
43 }
44
45 *numer_ = curr_num;
46 *denom_ = curr_den;
47 }

◆ bvisit() [5/6]

void SymEngine::NumerDenomVisitor::bvisit ( const Pow x)
inline

Definition at line 82 of file numer_denom.cpp.

83 {
84
85 RCP<const Basic> base_, exp_, num, den;
86 base_ = x.get_base();
87 exp_ = x.get_exp();
88 as_numer_denom(base_, outArg(num), outArg(den));
89
90 // if the exp is a negative numer, or is intuitively 'negative'
91 if (handle_minus(exp_, outArg(exp_))) {
92 *numer_ = pow(den, exp_);
93 *denom_ = pow(num, exp_);
94 } else {
95 *numer_ = pow(num, exp_);
96 *denom_ = pow(den, exp_);
97 }
98 }
T pow(T... args)

◆ bvisit() [6/6]

void SymEngine::NumerDenomVisitor::bvisit ( const Rational x)
inline

Definition at line 120 of file numer_denom.cpp.

121 {
122 *numer_ = x.get_num();
123 *denom_ = x.get_den();
124 }

Field Documentation

◆ denom_

Ptr<RCP<const Basic> > SymEngine::NumerDenomVisitor::denom_
private

Definition at line 9 of file numer_denom.cpp.

◆ numer_

Ptr<RCP<const Basic> > SymEngine::NumerDenomVisitor::numer_
private

Definition at line 9 of file numer_denom.cpp.


The documentation for this class was generated from the following file: