Rename interpretor to interpreter.
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / compiler / normalize / mterm.cpp
diff --git a/interpretor/preprocessor/faust-0.9.47mr3/compiler/normalize/mterm.cpp b/interpretor/preprocessor/faust-0.9.47mr3/compiler/normalize/mterm.cpp
deleted file mode 100644 (file)
index 1f8bd2d..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-#include "mterm.hh"
-#include "signals.hh"
-#include "ppsig.hh"
-#include "xtended.hh"
-#include <assert.h>
-//static void collectMulTerms (Tree& coef, map<Tree,int>& M, Tree t, bool invflag=false);
-
-#undef TRACE
-
-using namespace std;
-
-typedef map<Tree,int> MP;
-
-mterm::mterm ()                        : fCoef(sigInt(0)) {}
-mterm::mterm (int k)            : fCoef(sigInt(k)) {}
-mterm::mterm (double k)         : fCoef(sigReal(k)) {} // cerr << "DOUBLE " << endl; }
-mterm::mterm (const mterm& m)   : fCoef(m.fCoef), fFactors(m.fFactors) {}
-
-/**
- * create a mterm from a tree sexpression
- */
-mterm::mterm (Tree t) : fCoef(sigInt(1))
-{
-    //cerr << "mterm::mterm (Tree t) : " << ppsig(t) << endl;
-       *this *= t; 
-       //cerr << "MTERM(" << ppsig(t) << ") -> " << *this << endl;
-}
-
-/**
- * true if mterm doesn't represent number 0
- */
-bool mterm::isNotZero() const
-{
-       return !isZero(fCoef);
-}
-
-/**
- * true if mterm doesn't represent number 0
- */
-bool mterm::isNegative() const
-{
-       return !isGEZero(fCoef);
-}
-
-/**
- * print a mterm in a human readable format
- */
-ostream& mterm::print(ostream& dst) const
-{
-       const char* sep = "";
-       if (!isOne(fCoef) || fFactors.empty()) { dst << ppsig(fCoef); sep = " * "; }
-       //if (true) { dst << ppsig(fCoef); sep = " * "; }
-       for (MP::const_iterator p = fFactors.begin(); p != fFactors.end(); p++) {
-               dst << sep << ppsig(p->first);
-               if (p->second != 1) dst << "**" << p->second;
-               sep = " * ";
-       }
-       return dst;
-}
-
-/**
- * Compute the "complexity" of a mterm, that is the number of
- * factors it contains (weighted by the importance of these factors)
- */
-int mterm::complexity() const
-{
-       int c = isOne(fCoef) ? 0 : 1;
-       for (MP::const_iterator p = fFactors.begin(); p != fFactors.end(); ++p) {
-               c += (1+getSigOrder(p->first))*abs(p->second);
-       }
-       return c;
-}
-
-/**
- * match x^p with p:int
- */
-static bool isSigPow(Tree sig, Tree& x, int& n)
-{
-       //cerr << "isSigPow("<< *sig << ')' << endl;
-       xtended* p = (xtended*) getUserData(sig);
-       if (p == gPowPrim) {
-       if (isSigInt(sig->branch(1), &n)) {
-                       x = sig->branch(0);
-                       //cerr << "factor of isSigPow " << *x << endl;
-                       return true;
-               }
-       }
-       return false;
-}
-
-/**
- * produce x^p with p:int
- */
-static Tree sigPow(Tree x, int p)
-{
-       return tree(gPowPrim->symbol(), x, sigInt(p));
-}
-
-/**
- * Multiple a mterm by an expression tree t. Go down recursively looking 
- * for multiplications and divisions
- */
-const mterm& mterm::operator *= (Tree t)
-{
-       int             op, n;
-       Tree    x,y;
-
-       assert(t!=0);
-
-       if (isNum(t)) {
-               fCoef = mulNums(fCoef,t);
-
-       } else if (isSigBinOp(t, &op, x, y) && (op == kMul)) {
-               *this *= x;
-               *this *= y;
-
-       } else if (isSigBinOp(t, &op, x, y) && (op == kDiv)) {
-               *this *= x;
-               *this /= y;
-
-       } else {
-               if (isSigPow(t,x,n)) {
-                       fFactors[x] += n;
-               } else {
-                       fFactors[t] += 1;
-               }
-       }
-    return *this;
-}
-
-/**
- * Divide a mterm by an expression tree t. Go down recursively looking 
- * for multiplications and divisions
- */
-const mterm& mterm::operator /= (Tree t)
-{
-       //cerr << "division en place : " << *this << " / " << ppsig(t) << endl;
-       int             op,n;
-       Tree    x,y;
-
-       assert(t!=0);
-
-       if (isNum(t)) {
-               fCoef = divExtendedNums(fCoef,t);
-
-       } else if (isSigBinOp(t, &op, x, y) && (op == kMul)) {
-               *this /= x;
-               *this /= y;
-
-       } else if (isSigBinOp(t, &op, x, y) && (op == kDiv)) {
-               *this /= x;
-               *this *= y;
-
-       } else {
-               if (isSigPow(t,x,n)) {
-                       fFactors[x] -= n;
-               } else {
-                       fFactors[t] -= 1;
-               }
-       }
-    return *this;
-}
-
-/**
- * replace the content with a copy of m
- */
-const mterm& mterm::operator = (const mterm& m)
-{
-       fCoef = m.fCoef;
-       fFactors = m.fFactors;
-    return *this;
-}
-
-/**
- * Clean a mterm by removing x**0 factors 
- */
-void mterm::cleanup()
-{
-       if (isZero(fCoef)) {
-               fFactors.clear();
-       } else {
-               for (MP::iterator p = fFactors.begin(); p != fFactors.end(); ) {
-                       if (p->second == 0) {
-                               fFactors.erase(p++);
-                       } else {
-                               p++;
-                       }
-               }
-       }
-}
-
-/**
- * Add in place an mterm. As we want the result to be
- * a mterm therefore essentially mterms of same signature can be added
- */
-const mterm& mterm::operator += (const mterm& m)
-{
-       if (isZero(m.fCoef)) {
-               // nothing to do
-       } else if (isZero(fCoef))       {
-               // copy of m
-               fCoef = m.fCoef;
-               fFactors = m.fFactors;
-       } else {
-               // only add mterms of same signature
-               assert(signatureTree() == m.signatureTree());
-               fCoef = addNums(fCoef, m.fCoef);
-       }
-       cleanup();
-    return *this;
-}
-
-/**
- * Substract in place an mterm. As we want the result to be
- * a mterm therefore essentially mterms of same signature can be substracted
- */
-const mterm& mterm::operator -= (const mterm& m)
-{
-       if (isZero(m.fCoef)) {
-               // nothing to do
-       } else if (isZero(fCoef))       {
-               // minus of m
-               fCoef = minusNum(m.fCoef);
-               fFactors = m.fFactors;
-       } else {
-               // only add mterms of same signature
-               assert(signatureTree() == m.signatureTree());
-               fCoef = subNums(fCoef, m.fCoef);
-       }
-       cleanup();
-    return *this;
-}
-
-/**
- * Multiply a mterm by the content of another mterm
- */
-const mterm& mterm::operator *= (const mterm& m)
-{
-       fCoef = mulNums(fCoef,m.fCoef);
-       for (MP::const_iterator p = m.fFactors.begin(); p != m.fFactors.end(); p++) {
-               fFactors[p->first] += p->second;
-       }
-       cleanup();
-    return *this;
-}
-
-/**
- * Divide a mterm by the content of another mterm
- */
-const mterm& mterm::operator /= (const mterm& m)
-{
-       //cerr << "division en place : " << *this << " / " << m << endl;
-       fCoef = divExtendedNums(fCoef,m.fCoef);
-       for (MP::const_iterator p = m.fFactors.begin(); p != m.fFactors.end(); p++) {
-               fFactors[p->first] -= p->second;
-       }
-       cleanup();
-    return *this;
-}
-
-/**
- * Multiply two mterms
- */
-mterm mterm::operator * (const mterm& m) const
-{
-    mterm r(*this);
-    r *= m;
-    return r;
-}
-
-/**
- * Divide two mterms
- */
-mterm mterm::operator / (const mterm& m) const
-{
-    mterm r(*this);
-    r /= m;
-    return r;
-}
-
-/**
- * return the "common quantity" of two numbers
- */
-static int common(int a, int b)
-{
-    if (a > 0 & b > 0) {
-        return min(a,b);
-    } else if (a < 0 & b < 0) {
-        return max(a,b);
-    } else {
-        return 0;
-    }
-}
-
-
-/**
- * return a mterm that is the greatest common divisor of two mterms
- */
-mterm gcd (const mterm& m1, const mterm& m2)
-{
-       //cerr << "GCD of " << m1 << " and " << m2 << endl;
-
-       Tree c = (m1.fCoef == m2.fCoef) ? m1.fCoef : tree(1);           // common coefficient (real gcd not needed)
-       mterm R(c);
-       for (MP::const_iterator p1 = m1.fFactors.begin(); p1 != m1.fFactors.end(); p1++) {
-        Tree t = p1->first;
-               MP::const_iterator p2 = m2.fFactors.find(t);
-               if (p2 != m2.fFactors.end()) {
-                       int v1 = p1->second;
-                       int v2 = p2->second;
-            int c = common(v1,v2);
-            if (c != 0) {
-                R.fFactors[t] = c;
-            }
-        }
-    }
-       //cerr << "GCD of " << m1 << " and " << m2 << " is : " << R << endl;
-       return R;
-}
-
-/**
- * We say that a "contains" b if a/b > 0. For example 3 contains 2 and
- * -4 contains -2, but 3 doesn't contains -2 and -3 doesn't contains 1
- */
-static bool contains(int a, int b)
-{
-       return (b == 0) || (a/b > 0);
-}
-
-/**
- * Check if M accept N has a divisor. We can say that N is
- * a divisor of M if M = N*Q and the complexity is preserved :
- * complexity(M) = complexity(N)+complexity(Q)
- * x**u has divisor x**v if u >= v
- * x**-u has divisor x**-v if -u <= -v
- */
-bool mterm::hasDivisor (const mterm& n) const
-{
-       for (MP::const_iterator p1 = n.fFactors.begin(); p1 != n.fFactors.end(); p1++) {
-               // for each factor f**q of m
-        Tree   f = p1->first;  
-               int     v = p1->second;
-               
-               // check that f is also a factor of *this
-               MP::const_iterator p2 = fFactors.find(f);
-               if (p2 == fFactors.end()) return false;
-               
-               // analyze quantities
-               int u = p2->second;
-               if (! contains(u,v) ) return false;
-    }
-       return true;
-}
-
-/**
- * produce the canonical tree correspoding to a mterm
- */
-/**
- * Build a power term of type f**q -> (((f.f).f)..f) with q>0
- */
-static Tree buildPowTerm(Tree f, int q)
-{
-       assert(f);
-       assert(q>0);
-       if (q>1) {
-               return sigPow(f, q);
-       } else {
-               return f;
-       }
-}
-
-/**
- * Combine R and A doing R = R*A or R = A
- */
-static void combineMulLeft(Tree& R, Tree A)
-{
-       if (R && A)     R = sigMul(R,A);
-       else if (A)             R = A;
-    else exit(1);
-}
-
-/**
- * Combine R and A doing R = R*A or R = A
- */
-static void combineDivLeft(Tree& R, Tree A)
-{
-       if (R && A)     R = sigDiv(R,A);
-       else if (A)             R = sigDiv(tree(1.0f),A);
-    else exit(1);
-}
-
-/**    
- * Do M = M * f**q or D = D * f**-q
- */
-static void combineMulDiv(Tree& M, Tree& D, Tree f, int q)
-{
-       #ifdef TRACE
-       cerr << "combineMulDiv (" << M << "/"  << D << "*" << ppsig(f)<< "**" << q << endl;
-       #endif
-       if (f) {
-        assert(q != 0);
-               if (q > 0) {
-                       combineMulLeft(M, buildPowTerm(f,q));
-               } else if (q < 0) {
-                       combineMulLeft(D, buildPowTerm(f,-q));
-               }
-       }
-}      
-       
-                       
-/**
- * returns a normalized (canonical) tree expression of structure :
- *             ((v1/v2)*(c1/c2))*(s1/s2)
- */
-Tree mterm::signatureTree() const
-{
-       return normalizedTree(true);
-}
-       
-/**
- * returns a normalized (canonical) tree expression of structure :
- *             ((k*(v1/v2))*(c1/c2))*(s1/s2)
- * In signature mode the fCoef factor is ommited
- * In negativeMode the sign of the fCoef factor is inverted
- */
-Tree mterm::normalizedTree(bool signatureMode, bool negativeMode) const
-{
-       if (fFactors.empty() || isZero(fCoef)) {
-               // it's a pure number
-               if (signatureMode)      return tree(1);
-               if (negativeMode)       return minusNum(fCoef);
-               else                            return fCoef;
-       } else {
-               // it's not a pure number, it has factors
-               Tree A[4], B[4];
-               
-               // group by order
-               for (int order = 0; order < 4; order++) {
-                       A[order] = 0; B[order] = 0;
-                       for (MP::const_iterator p = fFactors.begin(); p != fFactors.end(); p++) {
-                               Tree    f = p->first;           // f = factor
-                               int             q = p->second;          // q = power of f
-                               if (f && q && getSigOrder(f)==order) {
-                                       
-                                       combineMulDiv (A[order], B[order], f, q);
-                               }
-                       }
-               }
-               if (A[0] != 0) cerr << "A[0] == " << *A[0] << endl; 
-               if (B[0] != 0) cerr << "B[0] == " << *B[0] << endl; 
-               // en principe ici l'order zero est vide car il correspond au coef numerique
-               assert(A[0] == 0);
-               assert(B[0] == 0);
-               
-               // we only use a coeficient if it differes from 1 and if we are not in signature mode
-               if (! (signatureMode | isOne(fCoef))) {
-                       A[0] = (negativeMode) ? minusNum(fCoef) : fCoef;
-               }
-               
-               if (signatureMode) {
-                       A[0] = 0;
-               } else if (negativeMode) {
-                       if (isMinusOne(fCoef)) { A[0] = 0; } else { A[0] = minusNum(fCoef); }
-               } else if (isOne(fCoef)) {
-                       A[0] = 0;
-               } else {
-                       A[0] = fCoef;
-               }
-                                       
-               // combine each order separately : R[i] = A[i]/B[i]
-               Tree RR = 0;
-               for (int order = 0; order < 4; order++) {
-                       if (A[order] && B[order])       combineMulLeft(RR,sigDiv(A[order],B[order]));
-                       else if (A[order])                      combineMulLeft(RR,A[order]);
-                       else if (B[order])                      combineDivLeft(RR,B[order]);
-               }
-               if (RR == 0) RR = tree(1); // a verifier *******************
-                       
-               assert(RR);
-        //cerr << "Normalized Tree of " << *this << " is " << ppsig(RR) << endl;
-               return RR;
-       }
-}
-