File: implementconstant.tex

package info (click to toggle)
sollya 8.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 17,592 kB
  • sloc: ansic: 124,655; yacc: 7,543; lex: 2,440; makefile: 888; cpp: 77
file content (291 lines) | stat: -rw-r--r-- 11,304 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
\subsection{implementconstant}
\label{labimplementconstant}
\noindent Name: \textbf{implementconstant}\\
\phantom{aaa}implements a constant in arbitrary precision\\[0.2cm]
\noindent Library names:\\
\verb|   void sollya_lib_implementconstant(sollya_obj_t, ...);|\\
\verb|   void sollya_lib_v_implementconstant(sollya_obj_t, va_list);|\\[0.2cm]
\noindent Usage: 
\begin{center}
\textbf{implementconstant}(\emph{expr}) : \textsf{constant} $\rightarrow$ \textsf{void}\\
\textbf{implementconstant}(\emph{expr},\emph{filename}) : (\textsf{constant}, \textsf{string}) $\rightarrow$ \textsf{void}\\
\textbf{implementconstant}(\emph{expr},\emph{filename},\emph{functionname}) : (\textsf{constant}, \textsf{string}, \textsf{string}) $\rightarrow$ \textsf{void}\\
\end{center}
\noindent Description: \begin{itemize}

\item The command \textbf{implementconstant} implements the constant expression \emph{expr} in 
   arbitrary precision. More precisely, it generates the source code (written
   in C, and using MPFR) of a C function \texttt{const\_something} with the following
   signature:
   \begin{center}
   \texttt{void const\_something (mpfr\_ptr y, mp\_prec\_t prec)}
   \end{center}
   Let us denote by $c$ the exact mathematical value of the constant defined by
   the expression \emph{expr}. When called with arguments $y$ and prec (where the
   variable $y$ is supposed to be already initialized), the function
   \texttt{mpfr\_const\_something} sets the precision of $y$ to a suitable precision and
   stores in it an approximate value of $c$ such that
   $$|y-c| \le |c|\,2^{1-\mathrm{prec}}.$$

\item When no filename \emph{filename} is given or if \textbf{default} is given as
   \emph{filename}, the source code produced by \textbf{implementconstant} is printed on
   standard output. Otherwise, when \emph{filename} is given as a 
   string of characters, the source code is output to a file 
   named \emph{filename}. If that file cannot be opened and/or 
   written to, \textbf{implementconstant} fails and has no other effect.

\item When \emph{functionname} is given as an argument to \textbf{implementconstant} and
   \emph{functionname} evaluates to a string of characters, the default name
   for the C function \texttt{const\_something} is
   replaced by \emph{functionname}. When \textbf{default} is given as \emph{functionname},
   the default name is used nevertheless, as if no \emph{functionname}
   argument were given.  When choosing a character sequence for
   \emph{functionname}, the user should keep attention to the fact that
   \emph{functionname} must be a valid C identifier in order to enable
   error-free compilation of the produced code.

\item If \emph{expr} refers to a constant defined with \textbf{libraryconstant}, the produced
   code uses the external code implementing this constant. The user should
   keep in mind that it is up to them to make sure the symbol for that 
   external code can get resolved when the newly generated code is to 
   be loaded.

\item If a subexpression of \emph{expr} evaluates to $0$, \textbf{implementconstant} will most
   likely fail with an error message.

\item \textbf{implementconstant} is unable to implement constant expressions \emph{expr} that
   contain procedure-based functions, i.e. functions created from \sollya
   procedures using the \textbf{function} construct. If \emph{expr} contains such a
   procedure-based function, \textbf{implementconstant} prints a warning and fails
   silently. The reason for this lack of functionality is that the
   produced C source code, which is supposed to be compiled, would have
   to call back to the \sollya interpreter in order to evaluate the
   procedure-based function.

\item Similarly, \textbf{implementconstant} is currently unable to implement constant
   expressions \emph{expr} that contain library-based functions, i.e.
   functions dynamically bound to \sollya using the \textbf{library} construct.
   If \emph{expr} contains such a library-based function, \textbf{implementconstant} prints
   a warning and fails silently. Support for this feature is in principle
   feasible from a technical standpoint and might be added in a future
   release of \sollya.

\item Currently, non-differentiable functions such as \textbf{double}, \textbf{doubledouble},
   \textbf{tripledouble}, \textbf{single}, \textbf{halfprecision}, \textbf{quad}, \textbf{doubleextended}, 
   \textbf{floor}, \textbf{ceil}, \textbf{nearestint} are not supported by \textbf{implementconstant}. 
   If \textbf{implementconstant} encounters one of them, a warning message is displayed 
   and no code is produced. However, if \textbf{autosimplify} equals on, it is 
   possible that \sollya silently simplifies subexpressions of \emph{expr} 
   containing such functions and that \textbf{implementconstant} successfully produces 
   code for evaluating \emph{expr}.

\item While it produces an MPFR-based C source code for \emph{expr}, \textbf{implementconstant}
   takes architectural and system-dependent parameters into account.  For
   example, it checks whether literal constants figuring in \emph{expr} can be
   represented on a C \texttt{long int} type or if they must
   be stored in a different manner not to affect their accuracy. These
   tests, performed by \sollya during execution of \textbf{implementconstant}, depend
   themselves on the architecture \sollya is running on. Users should
   keep this matter in mind, especially when trying to compile source
   code on one machine whilst it has been produced on another.
\end{itemize}
\noindent Example 1: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single,commandchars=\\\|\~]
> implementconstant(exp(1)+log(2)/sqrt(1/10)); 
                   \alert|\textrm|\emph|[ The first 100 lines of the output have been removed ]~~~
    modify or redistribute this generated code itself, or its skeleton,
    you may (at your option) remove this special exception, which will
    cause this generated code and its skeleton and the resulting Sollya
    output files to be licensed under the CeCILL-C licence without this
    special exception.
    
    This special exception was added by the Sollya copyright holders in
    version 4.1 of Sollya.
    
*/


#include <mpfr.h>

void
const_something (mpfr_ptr y, mp_prec_t prec)
{
  /* Declarations */
  mpfr_t tmp1;
  mpfr_t tmp2;
  mpfr_t tmp3;
  mpfr_t tmp4;
  mpfr_t tmp5;
  mpfr_t tmp6;
  mpfr_t tmp7;

  /* Initializations */
  mpfr_init2 (tmp2, prec+5);
  mpfr_init2 (tmp1, prec+3);
  mpfr_init2 (tmp4, prec+8);
  mpfr_init2 (tmp3, prec+7);
  mpfr_init2 (tmp6, prec+11);
  mpfr_init2 (tmp7, prec+11);
  mpfr_init2 (tmp5, prec+11);

  /* Core */
  mpfr_set_prec (tmp2, prec+4);
  mpfr_set_ui (tmp2, 1, MPFR_RNDN);
  mpfr_set_prec (tmp1, prec+3);
  mpfr_exp (tmp1, tmp2, MPFR_RNDN);
  mpfr_set_prec (tmp4, prec+8);
  mpfr_set_ui (tmp4, 2, MPFR_RNDN);
  mpfr_set_prec (tmp3, prec+7);
  mpfr_log (tmp3, tmp4, MPFR_RNDN);
  mpfr_set_prec (tmp6, prec+11);
  mpfr_set_ui (tmp6, 1, MPFR_RNDN);
  mpfr_set_prec (tmp7, prec+11);
  mpfr_set_ui (tmp7, 10, MPFR_RNDN);
  mpfr_set_prec (tmp5, prec+11);
  mpfr_div (tmp5, tmp6, tmp7, MPFR_RNDN);
  mpfr_set_prec (tmp4, prec+7);
  mpfr_sqrt (tmp4, tmp5, MPFR_RNDN);
  mpfr_set_prec (tmp2, prec+5);
  mpfr_div (tmp2, tmp3, tmp4, MPFR_RNDN);
  mpfr_set_prec (y, prec+3);
  mpfr_add (y, tmp1, tmp2, MPFR_RNDN);

  /* Cleaning stuff */
  mpfr_clear(tmp1);
  mpfr_clear(tmp2);
  mpfr_clear(tmp3);
  mpfr_clear(tmp4);
  mpfr_clear(tmp5);
  mpfr_clear(tmp6);
  mpfr_clear(tmp7);
}
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 2: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single,commandchars=\\\|\~]
> implementconstant(sin(13/17),"sine_of_thirteen_seventeenth.c");
> bashevaluate("tail -n 30 sine_of_thirteen_seventeenth.c");
#include <mpfr.h>

void
const_something (mpfr_ptr y, mp_prec_t prec)
{
  /* Declarations */
  mpfr_t tmp1;
  mpfr_t tmp2;
  mpfr_t tmp3;

  /* Initializations */
  mpfr_init2 (tmp2, prec+6);
  mpfr_init2 (tmp3, prec+6);
  mpfr_init2 (tmp1, prec+6);

  /* Core */
  mpfr_set_prec (tmp2, prec+6);
  mpfr_set_ui (tmp2, 13, MPFR_RNDN);
  mpfr_set_prec (tmp3, prec+6);
  mpfr_set_ui (tmp3, 17, MPFR_RNDN);
  mpfr_set_prec (tmp1, prec+6);
  mpfr_div (tmp1, tmp2, tmp3, MPFR_RNDN);
  mpfr_set_prec (y, prec+2);
  mpfr_sin (y, tmp1, MPFR_RNDN);

  /* Cleaning stuff */
  mpfr_clear(tmp1);
  mpfr_clear(tmp2);
  mpfr_clear(tmp3);
}
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 3: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single,commandchars=\\\|\~]
> implementconstant(asin(1/3 * pi),default,"arcsin_of_one_third_pi"); 
                   \alert|\textrm|\emph|[ The first 100 lines of the output have been removed ]~~~
    modify or redistribute this generated code itself, or its skeleton,
    you may (at your option) remove this special exception, which will
    cause this generated code and its skeleton and the resulting Sollya
    output files to be licensed under the CeCILL-C licence without this
    special exception.
    
    This special exception was added by the Sollya copyright holders in
    version 4.1 of Sollya.
    
*/


#include <mpfr.h>

void
arcsin_of_one_third_pi (mpfr_ptr y, mp_prec_t prec)
{
  /* Declarations */
  mpfr_t tmp1;
  mpfr_t tmp2;
  mpfr_t tmp3;

  /* Initializations */
  mpfr_init2 (tmp2, prec+8);
  mpfr_init2 (tmp3, prec+8);
  mpfr_init2 (tmp1, prec+8);

  /* Core */
  mpfr_set_prec (tmp2, prec+8);
  mpfr_const_pi (tmp2, MPFR_RNDN);
  mpfr_set_prec (tmp3, prec+8);
  mpfr_set_ui (tmp3, 3, MPFR_RNDN);
  mpfr_set_prec (tmp1, prec+8);
  mpfr_div (tmp1, tmp2, tmp3, MPFR_RNDN);
  mpfr_set_prec (y, prec+2);
  mpfr_asin (y, tmp1, MPFR_RNDN);

  /* Cleaning stuff */
  mpfr_clear(tmp1);
  mpfr_clear(tmp2);
  mpfr_clear(tmp3);
}
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 4: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single,commandchars=\\\|\~]
> implementconstant(ceil(log(19 + 1/3)),"constant_code.c","magic_constant");
> bashevaluate("tail -n -9 constant_code.c");
void
magic_constant (mpfr_ptr y, mp_prec_t prec)
{
  /* Initializations */

  /* Core */
  mpfr_set_prec (y, prec);
  mpfr_set_ui (y, 3, MPFR_RNDN);
}
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 5: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single,commandchars=\\\|\~]
> bashexecute("gcc -fPIC -Wall -c libraryconstantexample.c -I$HOME/.local/includ
e");
> bashexecute("gcc -shared -o libraryconstantexample libraryconstantexample.o -l
gmp -lmpfr");
> euler_gamma = libraryconstant("./libraryconstantexample");
> implementconstant(euler_gamma^(1/3), "euler.c");
> bashevaluate("tail -n -17 euler.c");
void
const_something (mpfr_ptr y, mp_prec_t prec)
{
  /* Declarations */
  mpfr_t tmp1;

  /* Initializations */
  mpfr_init2 (tmp1, prec+1);

  /* Core */
  euler_gamma (tmp1, prec+1);
  mpfr_set_prec (y, prec+2);
  mpfr_root (y, tmp1, 3, MPFR_RNDN);

  /* Cleaning stuff */
  mpfr_clear(tmp1);
}
\end{Verbatim}
\end{minipage}\end{center}
See also: \textbf{implementpoly} (\ref{labimplementpoly}), \textbf{libraryconstant} (\ref{lablibraryconstant}), \textbf{library} (\ref{lablibrary}), \textbf{function} (\ref{labfunction}), \textbf{bashevaluate} (\ref{labbashevaluate})