1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4 *
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
13 *
14 */
15
16 #include <cmath>
17 #include <functional>
18
19 #include "gvn/MultivariateMonomial.hxx"
20
21 namespace analysis
22 {
23
contains(const uint64_t var) const24 bool MultivariateMonomial::contains(const uint64_t var) const
25 {
26 return monomial.find(var) != monomial.end();
27 }
28
checkVariable(const uint64_t max) const29 bool MultivariateMonomial::checkVariable(const uint64_t max) const
30 {
31 return std::prev(monomial.end())->var <= max;
32 }
33
exponent() const34 unsigned int MultivariateMonomial::exponent() const
35 {
36 unsigned int exp = 0;
37 for (const auto & ve : monomial)
38 {
39 exp += ve.exp;
40 }
41 return exp;
42 }
43
add(const VarExp & ve)44 MultivariateMonomial & MultivariateMonomial::add(const VarExp & ve)
45 {
46 Monomial::iterator i = monomial.find(ve);
47 if (i == monomial.end())
48 {
49 monomial.insert(ve);
50 }
51 else
52 {
53 i->exp += ve.exp;
54 }
55 return *this;
56 }
57
add(VarExp && ve)58 MultivariateMonomial & MultivariateMonomial::add(VarExp && ve)
59 {
60 Monomial::iterator i = monomial.find(ve);
61 if (i == monomial.end())
62 {
63 monomial.emplace(std::move(ve));
64 }
65 else
66 {
67 i->exp += ve.exp;
68 }
69 return *this;
70 }
71
operator *(const MultivariateMonomial & R) const72 MultivariateMonomial MultivariateMonomial::operator*(const MultivariateMonomial & R) const
73 {
74 MultivariateMonomial res(*this);
75 res.coeff *= R.coeff;
76 for (const auto & ve : R.monomial)
77 {
78 res.add(ve);
79 }
80 return res;
81 }
82
operator *=(const MultivariateMonomial & R)83 MultivariateMonomial & MultivariateMonomial::operator*=(const MultivariateMonomial & R)
84 {
85 coeff *= R.coeff;
86 for (const auto & ve : R.monomial)
87 {
88 add(ve);
89 }
90 return *this;
91 }
92
operator *(const int64_t L,const MultivariateMonomial & R)93 MultivariateMonomial operator*(const int64_t L, const MultivariateMonomial & R)
94 {
95 return R * L;
96 }
97
operator *(const int64_t R) const98 MultivariateMonomial MultivariateMonomial::operator*(const int64_t R) const
99 {
100 MultivariateMonomial res(*this);
101 res.coeff *= R;
102 return res;
103 }
104
operator *=(const int64_t R)105 MultivariateMonomial & MultivariateMonomial::operator*=(const int64_t R)
106 {
107 coeff *= R;
108 return *this;
109 }
110
operator /(const int64_t R) const111 MultivariateMonomial MultivariateMonomial::operator/(const int64_t R) const
112 {
113 MultivariateMonomial res(*this);
114 res.coeff /= R;
115 return res;
116 }
117
operator /=(const int64_t R)118 MultivariateMonomial & MultivariateMonomial::operator/=(const int64_t R)
119 {
120 coeff /= R;
121 return *this;
122 }
123
operator ^(unsigned int R) const124 MultivariateMonomial MultivariateMonomial::operator^(unsigned int R) const
125 {
126 MultivariateMonomial res(*this);
127 if (R > 1)
128 {
129 coeff = std::pow(coeff, R);
130 for (auto & ve : res.monomial)
131 {
132 ve.exp *= R;
133 }
134 }
135 return res;
136 }
137
operator ==(const MultivariateMonomial & R) const138 bool MultivariateMonomial::operator==(const MultivariateMonomial & R) const
139 {
140 return coeff == R.coeff && monomial == R.monomial;
141 }
142
print(const std::map<uint64_t,std::wstring> & vars) const143 const std::wstring MultivariateMonomial::print(const std::map<uint64_t, std::wstring> & vars) const
144 {
145 std::wostringstream wos;
146 if (coeff == -1 || coeff == 1)
147 {
148 if (coeff == -1)
149 {
150 wos << L'-';
151 }
152 if (!monomial.empty())
153 {
154 wos << monomial.begin()->print(vars);
155 for (auto i = std::next(monomial.begin()), e = monomial.end(); i != e; ++i)
156 {
157 wos << L"*" << i->print(vars);
158 }
159 }
160 }
161 else
162 {
163 wos << coeff;
164 for (const auto & ve : monomial)
165 {
166 wos << L"*" << ve.print(vars);
167 }
168 }
169 return wos.str();
170 }
171
operator <<(std::wostream & out,const MultivariateMonomial & m)172 std::wostream & operator<<(std::wostream & out, const MultivariateMonomial & m)
173 {
174 const std::map<uint64_t, std::wstring> vars;
175 out << m.print(vars);
176
177 return out;
178 }
179
operator ()(const MultivariateMonomial & L,const MultivariateMonomial & R) const180 bool MultivariateMonomial::Compare::operator()(const MultivariateMonomial & L, const MultivariateMonomial & R) const
181 {
182 const unsigned int le = L.exponent();
183 const unsigned int re = R.exponent();
184 if (le < re)
185 {
186 return true;
187 }
188 else if (le == re)
189 {
190 const unsigned int ls = static_cast<unsigned int>(L.monomial.size());
191 const unsigned int rs = static_cast<unsigned int>(R.monomial.size());
192 if (ls > rs)
193 {
194 return true;
195 }
196 else if (ls == rs)
197 {
198 for (Monomial::const_iterator i = L.monomial.begin(), j = R.monomial.begin(), e = L.monomial.end(); i != e; ++i, ++j)
199 {
200 if (VarExp::Compare()(*i, *j))
201 {
202 return true;
203 }
204 else if (!VarExp::Eq()(*i, *j))
205 {
206 return false;
207 }
208 }
209
210 for (Monomial::const_iterator i = L.monomial.begin(), j = R.monomial.begin(), e = L.monomial.end(); i != e; ++i, ++j)
211 {
212 if (i->exp < j->exp)
213 {
214 return true;
215 }
216 else if (i->exp > j->exp)
217 {
218 return false;
219 }
220 }
221
222 }
223 }
224 return false;
225 }
226
227 } // namespace analysis
228