FAUST compiler  0.9.9.6b8
doc_Text.cpp
Go to the documentation of this file.
1 /************************************************************************
2  ************************************************************************
3  FAUST compiler
4  Copyright (C) 2003-2004 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 
23 
24 #include <stdio.h>
25 #include <string.h>
26 #include "doc_Text.hh"
27 #include "compatibility.hh"
28 #include <string>
29 #include <vector>
30 #include <iostream>
31 #include <sstream>
32 #include <assert.h>
33 #include <cmath>
34 #include <stdlib.h>
35 
36 #include "floats.hh"
37 
38 #ifndef M_PI
39 #define M_PI 3.14159265358979323846
40 #endif
41 
42 #ifndef M_PI_2
43 #define M_PI_2 1.57079632679489661923
44 #endif
45 
46 #ifndef M_PI_4
47 #define M_PI_4 0.785398163397448309616
48 #endif
49 
50 #ifndef M_E
51 #define M_E 2.71828182845904523536
52 #endif
53 
54 extern bool gInternDoubleSwitch;
55 const string symbolicNumber (double n);
56 
57 
58 
59 #if 0
60 
66 static void zdel(char* c)
67 {
68  int l = strlen(c) - 1;
69  bool f = (c[l] == 'f');
70 
71  if (f) c[l--] = 0; // remove trailing if any f
72  while ( l>1 && c[l-1] != '.' && c[l] == '0') c[l--] = 0;
73  if (f) c[++l] = 'f'; // restaure trailing f if needed
74 }
75 #endif
76 
77 string docT (char* c) { return string(c); }
78 string docT (int n) { char c[64]; snprintf(c, 63, "%d",n); return string(c); }
79 string docT (long n) { char c[64]; snprintf(c, 63, "%ld",n); return string(c); }
80 string docT (double n) { return symbolicNumber(n); }
81 
82 
83 //
84 //*****************************SYMBOLIC NUMBER REPRESENTATION*******************
85 //
86 
91 float fltEpsilon()
92 {
93  float machEps = 1.0f;
94  do {
95  machEps /= 2.0f;
96  } while ((float)(1.0 + (machEps/2.0)) != 1.0);
97  return machEps;
98 }
99 
100 
105 double dblEpsilon()
106 {
107  double machEps = 1.0f;
108  do {
109  machEps /= 2.0f;
110  } while ((1.0 + (machEps/2.0)) != 1.0);
111  return machEps;
112 }
113 
114 
119 static bool AlmostEqual(double A, double B)
120 {
121  double maxRelativeError = 2*dblEpsilon();
122  double maxAbsoluteError = maxRelativeError;
123 
124 
125  if (fabs(A - B) < maxAbsoluteError)
126  return true;
127  double relativeError;
128  if (fabs(B) > fabs(A))
129  relativeError = fabs((A - B) / B);
130  else
131  relativeError = fabs((A - B) / A);
132  if (relativeError <= maxRelativeError)
133  return true;
134  return false;
135 }
136 
137 
143 bool isPiPower (double n, string& s)
144 {
145  assert(n>0);
146  stringstream ss (stringstream::out|stringstream::in);
147  int k = (int)floor(log(n)/log(M_PI));
148  if ( AlmostEqual(n, exp(k * log(M_PI))) && (k!=0) && (abs(k)<5.0) ) {
149  ss << "\\pi";
150  if (k!=1) ss << "^{"<< k <<"}";
151  s = ss.str();
152  return true;
153  } else {
154  return false;
155  }
156 }
157 
158 
163 bool isExpPower (double n, string& s)
164 {
165  assert(n>0);
166  stringstream ss (stringstream::out|stringstream::in);
167  int k = (int)floor(log(n));
168  if ( AlmostEqual(n, exp(k)) && (k!=0) && (abs(k)<5.0) ) {
169  ss << "e";
170  if (k!=1) ss << "^{"<< k <<"}";
171  s = ss.str();
172  return true;
173  } else {
174  return false;
175  }
176 }
177 
178 
183 bool isSymbolicPower (double n, string& s)
184 {
185  assert(n>0);
186  if (isPiPower(n,s)) {
187  return true;
188  } else if (isExpPower(n,s)) {
189  return true;
190  } else {
191  return false;
192  }
193 }
194 
195 
199 const string addFraction (int num, int denom, const string& exp)
200 {
201  stringstream ss (stringstream::out|stringstream::in);
202 
203  if ((num==1) & (denom==1)) {
204  ss << exp;
205  } else if ((num==1) & (denom!=1)) {
206  ss << "\\frac{"<< exp << "}{" << denom << "}";
207  } else if ((num!=1) & (denom==1)) {
208  ss << num << "*" << exp;
209  } else {
210  ss << "\\frac{"<< num << "}{" << denom << "}*" << exp;
211  }
212  return ss.str();
213 }
214 
215 
219 const string positiveSymbolicNumber (double n)
220 {
221  string s;
222  assert(n>0);
223 
224  // Try to find a symbolic representation
225 
226  for (int i=1;i<10;i++) {
227  for(int j=1;j<10;j++) {
228  if (isSymbolicPower(i*n/j,s)) {
229  return addFraction(j,i,s);
230  }
231  }
232  }
233 
234  // No symbolic representation,
235  // Then numerical representation x.10^k
236 
237  char tmp[64];
238  string entree = " * 10^{";
239  char sortie = '}';
240  string::size_type ps;
241 
242  snprintf(tmp, 63, "%.15g", n); // Warning: over 15 decimals, results are wrong !!
243  s = tmp;
244  ps = s.find('e');
245 
246  if (ps != string::npos) {
247  s.replace(ps, 1, "");
248  s.insert(ps, entree);
249  s += sortie;
250  }
251 
252  return s;
253 
254 }
255 
256 
260 const string symbolicNumber (double n)
261 {
262  if (n>0.0) {
263  return positiveSymbolicNumber(n);
264  } else if (n<0.0) {
265  return string("-") + positiveSymbolicNumber(-n);
266  } else {
267  return "0";
268  }
269 }
string docT(char *c)
Definition: doc_Text.cpp:77
bool isPiPower(double n, string &s)
Return true if n>0 is equal to PI^k for some small integer k.
Definition: doc_Text.cpp:143
const string positiveSymbolicNumber(double n)
Return symbolic or numerical representation of n>0.
Definition: doc_Text.cpp:219
Definition: num.hh:58
bool gInternDoubleSwitch
static bool AlmostEqual(double A, double B)
Check if two floating point numbers are (almost) equal Abs(x-y) < epsilon.
Definition: doc_Text.cpp:119
interval abs(const interval &x)
Definition: interval.hh:226
float fltEpsilon()
Compute the smallest float representable difference epsilon such that 1 != 1+epsilon.
Definition: doc_Text.cpp:91
#define M_PI
Definition: doc_Text.cpp:39
double dblEpsilon()
Compute the smallest double representable difference epsilon such that 1 != 1+epsilon.
Definition: doc_Text.cpp:105
bool isExpPower(double n, string &s)
Return true if n>0 is equal to e^k for some small integer k.
Definition: doc_Text.cpp:163
const string symbolicNumber(double n)
Return symbolic or numerical representation of n.
Definition: doc_Text.cpp:260
bool isSymbolicPower(double n, string &s)
Return true if n>0 is equal to e^k or PI^k for some integer k The symbolic latex representation is re...
Definition: doc_Text.cpp:183
const string addFraction(int num, int denom, const string &exp)
Return exp or num.exp, or exp/denom, or num/denom.exp.
Definition: doc_Text.cpp:199