* M_APM - mapmgues.c
*
* Copyright (C) 1999 - 2007 Michael C. Ring
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted. Permission to distribute
* the modified code is granted. Modifications are to be distributed by
* using the file 'license.txt' as a template to modify the file header.
* 'license.txt' is available in the official MAPM distribution.
*
* This software is provided "as is" without express or implied warranty.
*/
* $Id: mapmgues.c,v 1.20 2007/12/03 01:52:55 mike Exp $
*
* This file contains the functions that generate the initial
* 'guesses' for the sqrt, cbrt, log, arcsin, and arccos functions.
*
* $Log: mapmgues.c,v $
* Revision 1.20 2007/12/03 01:52:55 mike
* Update license
*
* Revision 1.19 2003/07/21 20:03:49 mike
* check for invalid inputs to _set_double
*
* Revision 1.18 2003/05/01 21:58:45 mike
* remove math.h
*
* Revision 1.17 2003/04/16 16:52:47 mike
* change cbrt guess to use reciprocal value for new cbrt algorithm
*
* Revision 1.16 2003/04/11 14:18:13 mike
* add comments
*
* Revision 1.15 2003/04/10 22:28:35 mike
* .
*
* Revision 1.14 2003/04/09 21:33:19 mike
* induce same error for asin and acos
*
* Revision 1.13 2003/04/09 20:11:38 mike
* induce error of 10 ^ -5 in log guess for known starting
* point in the iterative algorithm
*
* Revision 1.12 2003/03/27 19:32:59 mike
* simplify log guess since caller guarantee's limited input magnitude
*
* Revision 1.11 2002/11/03 21:45:53 mike
* Updated function parameters to use the modern style
*
* Revision 1.10 2001/03/20 22:08:27 mike
* delete unneeded logic in asin guess
*
* Revision 1.9 2000/09/26 17:05:11 mike
* guess 1/sqrt instead of sqrt due to new sqrt algorithm
*
* Revision 1.8 2000/04/10 21:13:13 mike
* minor tweaks to log_guess
*
* Revision 1.7 2000/04/03 17:25:45 mike
* added function to estimate the cube root (cbrt)
*
* Revision 1.6 1999/07/18 01:57:35 mike
* adjust arc-sin guess for small exponents
*
* Revision 1.5 1999/07/09 22:32:50 mike
* optimize some functions
*
* Revision 1.4 1999/05/12 21:22:27 mike
* add more comments
*
* Revision 1.3 1999/05/12 21:00:51 mike
* added new sqrt guess function
*
* Revision 1.2 1999/05/11 02:10:12 mike
* added some comments
*
* Revision 1.1 1999/05/10 20:56:31 mike
* Initial revision
*/
#include "m_apm_lc.h"
void M_get_sqrt_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
m_apm_set_double(r, (1.0 / sqrt(dd)));
}
* for cbrt, log, asin, and acos we induce an error of 10 ^ -5.
* this enables the iterative routine to be more efficient
* by knowing exactly how accurate the initial guess is.
*
* this also prevents some corner conditions where the iterative
* functions may terminate too soon.
*/
void M_get_cbrt_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
dd = log(dd) / 3.0;
m_apm_set_double(r, (1.00001 / exp(dd)));
}
void M_get_log_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
m_apm_set_double(r, (1.00001 * log(dd)));
}
* the implementation of the asin & acos functions
* guarantee that 'a' is always < 0.85, so it is
* safe to multiply by a number > 1
*/
void M_get_asin_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
m_apm_set_double(r, (1.00001 * asin(dd)));
}
void M_get_acos_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
m_apm_set_double(r, (1.00001 * acos(dd)));
}
convert a C 'double' into an M_APM value.
*/
void m_apm_set_double(M_APM atmp, double dd)
{
char *cp, *p, *ps, buf[64];
if (dd == 0.0)
M_set_to_zero(atmp);
else
{
sprintf(buf, "%.14E", dd);
if ((cp = strstr(buf, "E")) == NULL)
{
M_apm_log_error_msg(M_APM_RETURN,
"\'m_apm_set_double\', Invalid double input (likely a NAN or +/- INF)");
M_set_to_zero(atmp);
return;
}
if (atoi(cp + sizeof(char)) == 0)
*cp = '\0';
p = cp;
while (TRUE)
{
p--;
if (*p == '0' || *p == '.')
*p = ' ';
else
break;
}
ps = buf;
p = buf;
while (TRUE)
{
if ((*p = *ps) == '\0')
break;
if (*ps++ != ' ')
p++;
}
m_apm_set_string(atmp, buf);
}
}