/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by John E. Lloyd.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

/*=~=~=~=~ McGill-Computer-Vision-and-Robotics-Laboratory--C-Module ~=~=~=~=
 *		
 * MODULE NAME:	scalarFunc
 *
 * DESCRIPTION:	Module which implements the various scalar math functions.
 * 
 * AUTHOR/DATE:	John Lloyd, Summer 1987.
 *
 *~=~=~=~=~=~= McGill-Computer-Vision-and-Robotics-Laboratory ~=~=~=~=~=~=*/

#include <math.h>
#include <errno.h>
#include "cdefs.h"
#include "types.h"
#include "parameters.h"

extern int errno;

sinM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{	
	r->val.d = sin (a[0].val.d);
	return (1);
}

cosM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	r->val.d = cos (a[0].val.d);
	return (1);
}

tanM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	r->val.d = tan (a[0].val.d);
	return (1);
}

logM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	if (a[0].val.d < SMALLEST)
	 { error (0, "log -- argument too small\n");
	   return (-1);
	 }
	r->val.d = log (a[0].val.d);
	return (1);
}

log10M (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	if (a[0].val.d <= SMALLEST)
	 { error (0, "log10 -- argument too small\n");
	   return (-1);
	 }
	r->val.d = log10 (a[0].val.d);
	return (1);
}

expM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	if (a[0].val.d > MAXEXP)
	 { error (0, "exp -- floating overflow\n");
	   return (-1);
	 }
	r->val.d = exp (a[0].val.d);
	return (1);
}

sinhM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	if (fabs (a[0].val.d) > MAXEXP)
	 { error (0, "sinh -- floating overflow\n");
	   return (-1);
	 }
	r->val.d = sinh (a[0].val.d);
	return (1);
}

coshM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	if (fabs (a[0].val.d) > MAXEXP)
	 { error (0, "cosh -- floating overflow\n");
	   return (-1);
	 }
	r->val.d = cosh (a[0].val.d);
	return (1);
}

tanhM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	r->val.d = tanh (a[0].val.d);
	return (1);
}

atanM(r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	r->val.d = atan (a[0].val.d);
	return (1);
}

asinM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	if (fabs (a[0].val.d) > 1.0)
	 { error (0, "asin -- argument out of range\n");
	   return (-1);
	 }
	r->val.d = asin (a[0].val.d);
	return (1);
}

acosM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	if (fabs (a[0].val.d) > 1.0)
	 { error (0, "acos -- argument out of range\n");
	   return (-1);
	 }
	r->val.d = acos (a[0].val.d);
	return (1);
}

sqrtM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{	
	if (a[0].val.d < 0.0)
	 { error (0, "sqrt -- argument less than 0.0\n");
	   return (-1);
	 }
	r->val.d = sqrt (a[0].val.d);
	return (1);
}

powM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	errno = 0;
	pow (a[0].val.d, a[1].val.d);
	if (errno == ERANGE)
	 { error (0, "power -- result out of range\n");
	   return (-1);
	 }
 	else if (errno == EDOM)
	 { error (0, "power -- x < 0 and y is non-integer\n");
	   return (-1);
	 }
	r->val.d = pow (a[0].val.d, a[1].val.d);
	return (1);
}

atan2M (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	r->val.d = atan2 (a[0].val.d, a[1].val.d);
	return (1);
}

hypotM (r, n, a)
GTYPE *r;
int n;
GTYPE *a;
{
	r->val.d = hypot (a[0].val.d, a[1].val.d);
	return (1);
}
