/* Copyright 1989-93 GROUPE BULL -- See license conditions in file COPYRIGHT */
/*****************************************************************************\
*                                                                             *
* 				    math.c                                    *
*                                                                             *
* 		     a library of math functions for klone                     *
*                                                                             *
\*****************************************************************************/
/* requires to be linked with -lm
 * you must init it by calling KlMathInit() in your main program after
 * having initialized klone
 * 
 * NOTE: this library is not complete, but provide enough functions so that the
 * rest can be coded in Klone. The goal being able to get the result, even with
 * some small round-up error and some slowness
 *
 * In case of errors (log -1), etc... a Klone error 
 * Error: Numeric Error (floating point exception) is raised
 * KlE_NUMERIC_ERROR Errors:NumericError
 */

#include <stdio.h>
#include <math.h>
#include "klone.h"
#include "kl_atom.h"
#include "kl_string.h"
#include "kl_list.h"
#include "kl_number.h"

#ifndef M_PI
#define     M_PI    3.14159265358979323846
#endif /* !M_PI */
#ifndef M_E
#define     M_E             2.7182818284590452354
#endif /* !M_E */

/* expt: power elevation (expt base power) CL p300
 * always returns a real
 */

KlO
KlExpt(x1, x2)
    KlReal x1, x2;
{
    KlMustBeNumber(x1, 0);
    KlMustBeNumber(x2, 1);
    return (KlO) KlRealMake(pow(KlNumberRealValue(x1), KlNumberRealValue(x2)));
}

/* log: (log number) CL p301
 * natural logarythm
 */

KlO
KlLog(x)
    KlO x;
{
    double tmp;

    KlMustBeNumber(x, 0);
    tmp = KlNumberRealValue(x);
    tmp = log(tmp);
    return (KlO) KlRealMake(tmp);
}

/* sinus and cosinus
 * (sin x) (cos x) CL p304
 */

KlO
KlSin(x)
    KlReal x;
{
    KlMustBeNumber(x, 0);
    return (KlO) KlRealMake(sin(KlNumberRealValue(x)));
}

KlO
KlCos(x)
    KlReal x;
{
    KlMustBeNumber(x, 0);
    return (KlO) KlRealMake(cos(KlNumberRealValue(x)));
}

/* arc sines and cosines: asin acos atan
 * (asin x) (acos x) CL p305 
 * in fact acos = (pi/2) -asin(x)
 */

KlO
KlASin(x)
    KlReal x;
{
    KlMustBeNumber(x, 0);
    return (KlO) KlRealMake(asin(KlNumberRealValue(x)));
}

KlO
KlATan(x)
    KlReal x;
{
    KlMustBeNumber(x, 0);
    return (KlO) KlRealMake(atan(KlNumberRealValue(x)));
}



/*****************************************************************************\
* 				     Init                                     *
\*****************************************************************************/

KlMathInit()
{
    KlDeclareSubr(KlExpt, "expt", 2);
    KlDeclareSubr(KlLog, "log", 1);
    KlDeclareSubr(KlSin, "sin", 1);
    KlDeclareSubr(KlCos, "cos", 1);
    KlDeclareSubr(KlASin, "asin", 1);
    KlDeclareSubr(KlATan, "atan", 1);

    KlDeclareAtom("pi", KlRealMake(M_PI));
    KlDeclareAtom("e", KlRealMake(M_E));
    KlDeclareAtom("*PI*", KlRealMake(M_PI));
    KlDeclareAtom("*E*", KlRealMake(M_E));
}


syntax highlighted by Code2HTML, v. 0.9.1