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})
|