1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 #ifndef __MTERM__
23 #define __MTERM__
24
25 #include <stdio.h>
26 #include <list>
27 #include <map>
28
29 #include "exception.hh"
30 #include "garbageable.hh"
31 #include "normalize.hh"
32 #include "signals.hh"
33 #include "sigorderrules.hh"
34 #include "sigprint.hh"
35 #include "simplify.hh"
36 #include "tlib.hh"
37
38 using namespace std;
39
40 /**
41 * Implements a multiplicative term, a term of type
42 * k*x^n*y^m*... and its arithmetic.
43 */
44
45 struct CompareTree {
operator ()CompareTree46 bool operator()(Tree t1, Tree t2) const { return t1->serial() < t2->serial(); }
47 };
48
49 class mterm : public virtual Garbageable {
50 Tree fCoef; ///< constant part of the term (usually 1 or -1)
51 map<Tree, int, CompareTree> fFactors; ///< non constant terms and their power
52
53 public:
54 mterm(); ///< create a 0 mterm
55 mterm(int k); ///< create a simple integer mterm
56 mterm(double k); ///< create a simple float mterm
57 mterm(Tree t); ///< create a mterm from a multiplicative exp
58 mterm(const mterm& m); ///< create a copy of a mterm
59
60 void cleanup(); ///< remove used factors
61 bool isNotZero() const; ///< true if mterm doesn't represent number 0
62 bool isNegative() const; ///< true if mterm has a negative coefficient
63
64 const mterm& operator=(const mterm& m); ///< replace the content with a copy of m
65
66 const mterm& operator*=(Tree m); ///< multiply in place by a multiplicative exp
67 const mterm& operator/=(Tree m); ///< divide in place by a multiplicative exp
68
69 const mterm& operator+=(const mterm& m); ///< add in place an mterm of same signature
70 const mterm& operator-=(const mterm& m); ///< add in place an mterm of same signature
71
72 const mterm& operator*=(const mterm& m); ///< multiply in place by a mterm
73 const mterm& operator/=(const mterm& m); ///< divide in place by a mterm
74
75 mterm operator*(const mterm& m) const; ///< mterms multiplication
76 mterm operator/(const mterm& m) const; ///< mterms division
77 ostream& print(ostream& dst) const; ///< print a mterm k*x1**n1*x2**n2...
78
79 int complexity() const; ///< return an evaluation of the complexity
80 Tree normalizedTree(bool sign = false,
81 bool neg = false) const; ///< return the normalized tree of the mterm
82 Tree signatureTree() const; ///< return a signature (a normalized tree)
83
84 bool hasDivisor(const mterm& n) const; ///< return true if this can be divided by n
85 friend mterm gcd(const mterm& m1, const mterm& m2); /// greatest common divisor of two mterms
86 };
87
operator <<(ostream & s,const mterm & m)88 inline ostream& operator<<(ostream& s, const mterm& m)
89 {
90 return m.print(s);
91 }
92
93 #endif
94