/*------------------------------------------------------------------------------*
 *	File Name: 	Math.h	     													*
 *	Purpose:	Math function prototypes for calling standard C functions		*
 *				in msvcrt.dll and etc.											*
 *  Creation:	Feb 11, 2001 by CPY												* 
 *  Copyright (c) OriginLab Corp. 2001, 2002, 2003								*
 *	All Rights Reserved															*
 *------------------------------------------------------------------------------*/  
#ifndef _MATH_H
#define _MATH_H


// Origin's internal missing value
#define		NANUM		get_missing_value()

#define		PI			3.1415926535897932384626
#define		Pi	PI
#define		pi	PI


// The following functions are implemented in internal.c
/** >Mathematical
		Returns the larger of two doubles.
	Paramaters:
		da, db = the two double values whose maximum is sought
	Returns:
		the greater of the two values supplied
	Example:
		void	run_max()
		{
			double		r1 = 7., r2 = 9.;
			
			double		rmax = max(r1, r2);
			
			printf("max of %f and %f is %f\n", r1, r2, rmax);
		}
*/
double max(double da, double db);

/** >Mathematical
		Returns the larger of two floats.
	Paramaters:
		fa, fb = the two float values whose maximum is sought
	Returns:
		the greater of the two values supplied
	Example:
		void	run_max()
		{
			float		r1 = 7., r2 = 9.;
			
			float		rmax = max(r1, r2);
			
			printf("max of %f and %f is %f\n", r1, r2, rmax);
		}
*/
float max(float fa, float fb);

/** >Mathematical
		Returns the larger of two ints.
	Paramaters:
		ia, ib = the two integer values whose maximum is sought
	Returns:
		the greater of the two values supplied
	Example:
		void	run_max()
		{
			int		n1 = 7, n2 = 9;
			
			int		nmax = max(n1, n2);
			
			printf("max of %d and %d is %d\n", n1, n2, nmax);
		}
*/
int max(int ia, int ib);

/** >Mathematical
		Returns the larger of two uints.
	Paramaters:
		na, nb = the two unsigned integer values whose maximum is sought
	Returns:
		the greater of the two values supplied
	Example:
		void	run_max()
		{
			uint		n1 = 7, n2 = 9;
			
			uint		nmax = max(n1, n2);
			
			printf("max of %d and %d is %d\n", n1, n2, nmax);
		}
*/
uint max(uint na, uint nb);

/** >Mathematical
		Returns the larger of two shorts.
	Paramaters:
		na, nb = the two short values whose maximum is sought
	Returns:
		the greater of the two values supplied
	Example:
		void	run_max()
		{
			short	n1 = 7, n2 = 9;
			
			short	nmax = max(n1, n2);
			
			printf("max of %d and %d is %d\n", n1, n2, nmax);
		}

*/
short max(short na, short nb);

/** >Mathematical
		Returns the larger of two ushorts.
	Paramaters:
		wa, wb = the two unsigned short values whose maximum is sought
	Returns:
		the greater of the two values supplied
	Example:
		void	run_max()
		{
			short	n1 = 7, n2 = 9;
			
			short	nmax = max(n1, n2);
			
			printf("max of %d and %d is %d\n", n1, n2, nmax);
		}
*/
ushort max(ushort wa, ushort wb);

/** >Mathematical
		Returns the smaller of two doubles.
	Paramaters:
		da, db = the two double values whose minimum is sought
	Returns:
		the smaller of the two values supplied
	Example:
		void	run_min()
		{
			double		r1 = 7., r2 = 9.;
			
			double		rmin = min(r1, r2);
			
			printf("min of %f and %f is %f\n", r1, r2, rmin);
		}
*/
double min(double da, double db);

/** >Mathematical
		Returns the smaller of two floats.
	Paramaters:
		fa, fb = the two float values whose minimum is sought
	Returns:
		the smaller of the two values supplied
	Example:
		void	run_min()
		{
			float		r1 = 7., r2 = 9.;
			
			float		rmin = min(r1, r2);
			
			printf("min of %f and %f is %f\n", r1, r2, rmin);
		}
*/
float min(float fa, float fb);

/** >Mathematical
		Returns the smaller of two ints.
	Paramaters:
		ia, ib = the two integer values whose minimum is sought
	Returns:
		the smaller of the two values supplied
	Example:
		void	run_min()
		{
			int			n1 = 7, n2 = 9;
			
			int			nmin = min(n1, n2);
			
			printf("min of %d and %d is %d\n", n1, n2, nmin);
		}
*/
int min(int ia, int ib);

/** >Mathematical
		Returns the smaller of two uints.
	Paramaters:
		na, nb = the two unsigned integer values whose minimum is sought
	Returns:
		the smaller of the two values supplied
	Example:
		void	run_min()
		{
			uint		n1 = 7, n2 = 9;
			
			uint		nmin = min(n1, n2);
			
			printf("min of %d and %d is %d\n", n1, n2, nmin);
		}
*/
uint min(uint na, uint nb);

/** >Mathematical
		Returns the smaller of two shorts.
	Paramaters:
		na, nb = the two short values whose minimum is sought
	Returns:
		the smaller of the two values supplied
	Example:
		void	run_min()
		{
			short			n1 = 7, n2 = 9;
			
			short			nmin = min(n1, n2);
			
			printf("min of %d and %d is %d\n", n1, n2, nmin);
		}
*/
short min(short na, short nb);

/** >Mathematical
		Returns the smaller of two ushorts.
	Paramaters:
		wa, wb = the two unsigned short values whose minimum is sought
	Returns:
		the smaller of the two values supplied
	Example:
		void	run_min()
		{
			ushort			n1 = 7, n2 = 9;
			
			ushort			nmin = min(n1, n2);
			
			printf("min of %d and %d is %d\n", n1, n2, nmin);
		}
*/
ushort min(ushort wa, ushort wb);

/** >Mathematical
		Absolute value of a floating-point (double). This function is implemented in internal.c
		as a compatibility function for the labtalk version of abs(x) function. Please note that
		this function will simply call the fabs(x) function
	Paramaters:
		x=Input value whose absolute value is returned
	Return:
		Returns the absolute value of x.
	Example:
		void	run_abs()
		{
			double		x = -5.9;
			double		val = abs(x);
			
			printf("abs(%f) = %f\n", x, val);
		}
	SeeAlso:
		fabs
*/
double	abs(double x);


#pragma dll(@OUTL)

/** >Mathematical
		Calculates x raised to the power of y.
	Parameters:
		x = base
		y = exponent
	Returns:
		x to the power of y
	Examples:
		void run_pow( void )
		{
		   double x = 2.0, y = 3.0, z;
		
		   z = pow( x, y );
		   printf( "%.1f to the power of %.1f is %.1f\n", x, y, z );
		}

		Output
		2.0 to the power of 3.0 is 8.0
*/
double pow(double x, double y);

/** >Mathematical
		Also defined as ran(_nSeed).
		On every call it generates a random double value between 0. and 1.
	Parameters:
		nSeed = (optional) pass any nonzero value to set the seed for random number generation, or 0
				to use the current seed.
	Returns:
		A uniformly random number between 0. and 1.
	Example:
		// The example displays 10 random numbers between 0. and 1.
		void	run_rnd()
		{
			for (int ii = 0; ii < 10; ii++)
			{
				double	rr = rnd();
				out_double("value = ", rr);
			}
		}
*/
double rnd(int nSeed=0);
// the ran function is implemented in sys_utils.c, so must move to sys_utils.h
//#define ran(_nSeed) rnd(_nSeed)


/** >Mathematical
		On every call it generates a normally distributed random double value with mean = 0. and
		standard deviation = 1.
	Parameters:
		nSeed = (optional) pass any nonzero value to set the seed for random number generation, or 0
				to use the current seed.
	Returns:
		A normally distributed random number.
	Example:
		// The example displays 10 normally distributes random numbers with mean=0 and
		// standard deviation = 1.
		void	run_grnd()
		{
			for (int ii = 0; ii < 10; ii++)
			{
				double	rr = grnd();
				out_double("value = ", rr);
			}
		}
*/
double grnd(int nSeed=0);	// normally distributed random number with mean=0 and sd=1, nSeed > 0 to set random seed (returns 0)

/** >Mathematical
		Test given double value to determine whether it is a missing value recorgnized by Origin
	Parameters:
		x = the double value to test
	Return: 
		TRUE if missing value, otherwise FALSE.
	Example:
		void	run_is_missing_value()
		{
			// Deliberately generate a missing value:
			double		rr = 7./0.;
			
			if (is_missing_value(rr))
				out_str("Missing value!");
			else
				out_str("Not missing value");
		}
*/
BOOL	is_missing_value(double x); // return TRUE if given value is a missing value

/** >Mathematical
		Used to get the missing value as a value recognized by Origin.
	Parameters:
		nOption = (optional) not used, must be 0
	Returns: 
		the missing value as a double value recognized by Origin.
	Example:
		void	run_get_missing_value()
		{
			// Deliberately generate a missing value:
			double		rr = 7./0.;
			
			if (get_missing_value() == rr)
				out_str("Missing value!");
			else
				out_str("Not missing value");
		}
*/
double get_missing_value(int nOption =0);

/** >Mathematical
		Divides x by y and returns the remainder.
	Parameter:
		x = dividend
		y = divisor
	Returns:
		remainder of division of x by y
	Example:
		void	run_mod()
		{
			int		m = 36, n = 10;
			int		nmod = mod(m, n);
			
			printf("mod(%d, %d) = %d\n", m, n, nmod);
		}
*/
long mod( long x, long y );  

/** >Mathematical
		Returns the closest int to the double argument.
	Parameter:
		x = double value the nearest integer to which is sought.
	Returns:
		the nearest integer to x
	Example:
		void	run_nint()
		{
			double	r1 = 3.6;
			double	r2 = 3.4;
			
			printf("nearest integer to %f is %d\nnearest integer to %f is %d\n", r1, nint(r1), r2, nint(r2));
		}
*/
int nint( double x );

/** >Mathematical
		Returns the phase (angle) in radians of a planar vector with coordinates (x, y)
	Parameter:
		x = x-coordinate
		y = y-coordinate
	Returns:
		the phase (angle)
	Example:
		void	run_angle()
		{
			double		x = 1.;
			double		y = 1.;
			double		rAngle = angle(x, y);
			printf("angle(%f, %f) = %f\n", x, y, rAngle);
		}
*/
double angle( double x, double y);

/** >Mathematical
		Divides double x by double y and returns the remainder.
	Parameters:
		x = dividend
		y = divisor
	Example:
		void	run_rmod()
		{
			double		x = 6.9, y = 2.1;
			double		val = rmod(x, y);
			printf("rmod(%f, %f) = %f\n", x, y, val);
		}
*/
double rmod( double x, double y ); 

/** >Mathematical
		This function returns the natural logarithm of the gamma function.
	Parameters:
		x = the double value
	Returns:
		the natural logarithm of the gamma function of x.
	Example:
		void	run_gammaln()
		{
			double		x = 17.;
			double		val = gammaln(x);
			printf("gammaln(%f) = %f\n", x, val);
		}
*/
double gammaln( double x );

/** >Mathematical
		Computes the incomplete beta function.
	Parameters:
		x, a, b are standard arguments of incomplete beta function
	Returns:
		incomplete beta function of x, a, b
	Example:
		void	run_incbeta()
		{
			double	x = 0.5., a = 3, b = 5.;
			double	val = incbeta(x, a, b);
			printf("incomplete beta(%f, %f, %f) = %f\n", x, a, b, val);
		}
*/
double incbeta( double x, double a, double b );

/** >Mathematical
		computes the beta function
	Parameters:
		a, b are standard arguments of beta function
	Returns:
		beta function of a, b
	Example:
		void	run_beta()
		{
			double	a = 2, b = 4.;
			double	val = beta(a, b);
			printf("beta(%f, %f) = %f\n", a, b, val);
		}
*/
double beta( double a, double b ); 

/** >Mathematical
		computes the incomplete gamma function.
	Parameters:
		x, a are standard arguments of incomplete gamma function
	Returns:
		incomplete gamma function of x, a
	Example:
		void	run_incgamma()
		{
			double	a = 2, x = .5;
			double	val = incgamma(x, a);
			printf("incgamma(%f, %f) = %f\n", x, a, val);
		}
*/
double incgamma( double x, double a );

/** >Mathematical
		Compute the Bessel function of the first kind of order n.
	Parameters:
		x = independent variable
		n = order
	Returns:
		Jn(x)
	Example:
		void	run_Jn()
		{
			double		x = 4.;
			int			n = 2;
			double		val = Jn(x, n);
			
			printf("Jn(%f, %d) = %f\n", x, n, val);
		}
*/
double Jn( double x, int n ); 

/** >Mathematical
		Compute the Bessel function of the first kind of order 0.
	Parameters:
		x = independent variable
	Returns:
		J0(x)
	Example:
		void	run_J0()
		{
			double		x = 4.;
			double		val = J0(x);
			
			printf("J0(%f) = %f\n", x, val);
		}
*/
double J0( double x );			 

/** >Mathematical
		Compute the Bessel function of the first kind of order 1.
	Parameters:
		x = independent variable
	Returns:
		J1(x)
	Example:
		void	run_J1()
		{
			double		x = 4.;
			double		val = J1(x);
			
			printf("J1(%f) = %f\n", x, val);
		}
*/
double J1( double x );			 

/** >Mathematical
		Compute the Bessel function of the second kind of order n.
	Parameters:
		x = independent variable
		n = order
	Returns:
		Yn(x)
	Example:
		void	run_Yn()
		{
			double		x = 4.;
			int			n = 2;
			double		val = Yn(x, n);
			
			printf("Yn(%f, %d) = %f\n", x, n, val);
		}
*/
double Yn( double x, int n);	 

/** >Mathematical
		Compute the Bessel function of the second kind of order 0.
	Parameters:
		x = independent variable
	Returns:
		Y0(x)
	Example:
		void	run_Y0()
		{
			double		x = 4.;
			double		val = Y0(x);
			
			printf("Y0(%f) = %f\n", x, val);
		}
*/
double Y0( double x );			 

/** >Mathematical
		Compute the Bessel function of the second kind of order 1.
	Parameters:
		x = independent variable
	Returns:
		Y1(x)
	Example:
		void	run_Y1()
		{
			double		x = 4.;
			double		val = Y1(x);
			
			printf("Y1(%f) = %f\n", x, val);
		}
*/
double Y1( double x );			

/** >Mathematical
		Calculate the arccosine.
	Paramaters:
		x = independent variable
	Returns:
		acos(x)
	Example:
		void	run_acos()
		{
			double		x = -1.;
			double		val = acos(x);
			
			printf("acos(%f) = %f\n", x, val);
		}
*/
double	acos(double x);

/** >Mathematical
		Calculate the arcsine.
	Paramaters:
		x = independent variable
	Returns:
		asin(x)
	Example:
		void	run_asin()
		{
			double		x = -1.;
			double		val = asin(x);
			
			printf("asin(%f) = %f\n", x, val);
		}
*/
double	asin(double x);

/** >Mathematical
		Calculate the exponential (the base of natural logarithm to the power x)
	Paramaters:
		x = independent variable
	Returns:
		exp(x)
	Example:
		void	run_exp()
		{
			double	rExp = 2.;
			double	val = exp(rExp);
			
			printf("exp(%f) = %f\n", rExp, val);
		}
*/
double	exp(double x);


/** >Mathematical
		Natural logarithm.
	Parameters:
		x = independent variable
	Returns:
		log(x)
	Example:
		void	run_log()
		{
			double		x = 7.389056;
			double		val = log(x);
			
			printf("log(%f) = %f\n", x, val);
		}
	SeeAlso:
		ln, log10
*/
double	log(double x); 

/** >Mathematical
		Natural logarithm, same as log(x)
	Parameters:
		x = independent variable
	Returns:
		ln(x)
	Example:
		void	run_ln()
		{
			double		x = 123.;
			double		val = ln(x);
			
			printf("ln(%f) = %f\n", x, val);
		}
	SeeAlso:
		log, log10 
*/
double	ln(double x);

/** >Mathematical
		logarithm of base 10
	Parameters:
		x = independent variable
	Returns:
		log10(x)
	Example:
		void	run_log10()
		{
			double		x = 10000.;
			double		val = log10(x);
			
			printf("log10(%f) = %f\n", x, val);
		}
	SeeAlso:
		ln, log
*/
double	log10(double x); // log base 10; see log or ln functions for log base e

/** >Mathematical
		Calculates the square root.
	Parameters:
		x = independent variable
	Returns:
		square root of x
	Example:
		void	run_sqrt()
		{
			double		rr = 625;
			double		val = sqrt(rr);
			
			printf("sqrt(%f) = %f\n", rr, val);
		}
*/
double	sqrt(double x);

/** >Mathematical
		Calculates the hypotenuse (the longest side) of a right triangle given
		the two sides of the right angle
	Parameters:
		x, y = two sides of the right angle of a right triangle
	Returns:
		hypotenuse
	Examples:
		void	run_hypot()
		{
			double		x = 3., y = 4.;
			double		val = _hypot(x, y);
			
			printf("_hypot(%f, %f) = %f\n", x, y, val);	// the result should be 5.
		}

*/
double	_hypot(double x, double y);

// the following functions will leading to INF.
/** >Mathematical
		Calculates hyperbolic cosine.
	Paramaters:
		x = independent variable
	Returns:
		cosh(x)
	Example:
		void	run_cosh()
		{
			double		x = 2.;
			double		val = cosh(x);
			printf("cosh(%f) = %f\n", x, val);
		}
*/
double	cosh(double x);

/** >Mathematical
		Calculates hyperbolic sine.
	Paramaters:
		x = independent variable
	Returns:
		sinh(x)
	Example:
		void	run_sinh()
		{
			double		x = 2.;
			double		val = sinh(x);
			printf("sinh(%f) = %f\n", x, val);
		}
*/
double	sinh(double x);

/** >Mathematical
		Absolute value of a floating-point (double).
	Paramaters:
		x=Input value whose absolute value is returned
	Return:
		Returns the absolute value of x.
	Example:
		void	run_fabs()
		{
			double		x = -5.9;
			double		val = fabs(x);
			
			printf("fabs(%f) = %f\n", x, val);
		}
	SeeAlso:
		abs
*/
double	fabs(double x);

/** >Mathematical
		Calculates the trigonometric tangent.
	Paramaters:
		x = independent variable
	Returns:
		tan(x)
	Example:
		void	run_tan()
		{
			double		x = 0.78;
			double		val = tan(x);
			
			printf("tan(%f) = %f\n", x, val);
		}
*/
double	tan(double x);

/** >Mathematical
		Calculates the double value corresponding to the smallest integer
		that is greater than or equal to x.
	Paramaters:
		x = independent variable
	Returns:
		ceil(x)
	Example:
		void	run_ceil()
		{
			double	x1 = -4.6, x2 = 4.6;
			
			printf("ceil(%f) = %f\nceil(%f) = %f\n", x1, ceil(x1), x2, ceil(x2));
		}
*/
double	ceil( double x );

/** >Mathematical
		Calculates the double value corresponding to the largest integer
		that is less than or equal to x.
	Paramaters:
		x = independent variable
	Returns:
		floor(x)
	Example:
		void	run_floor()
		{
			double	x1 = -4.6, x2 = 4.6;
			
			printf("floor(%f) = %f\nfloor(%f) = %f\n", x1, floor(x1), x2, floor(x2));
		}
*/
double	floor( double x );

/** >Mathematical
		compare two double values and see if they are equal or not equal in the
		same sense as in LabTalk.
		This function uses the LabTalk system variable @ND to test if
		(abs(x)-abs(y))/((abs(x)+abs(y))
		is less then @ND or not. If @ND = 0, it does standard arithmetic comparison x == y.
	Parameters:
		nCode = '=' for testing for equality; any other value will test for inequality.
	Example:
		void	run_is_equal()
		{
			double		a = 1.;
			
			// add 1.e-17:
			a += 1.e-17;
			
			// Compare with 1.:
			if (is_equal(a, 1.))
			{
				// If @ND still has the default value, which is 1.e-16, this will be true.
				out_str("a is 1.");
			}
			else
			{
				out_str("a is not 1.");
			}
			
			// add 1.e-14
			a += 1.e-14;
			if (is_equal(a, 1.))
			{
				// If @ND still has the default value, which is 1.e-16, this will be false.
				out_str("a is 1.");
			}
			else
			{
				out_str("a is not 1.");
			}
		}
*/
BOOL is_equal(double x, double y, int nCode='=');

// the following are from Ok70.dll
#pragma dll(@OK)

/** >Mathematical
		Calculates a double value which is equal to x up to nSignificantDigits significant digits
	Parameter:
		x = independent variable
	Returns:
		x with the precision of nSignificantDigits significant digits.
	Example:
		void	run_prec()
		{
			double		x = 34.56789;
			int			nSignificantDigits = 5;
			
			printf("prec(%f, %d) = %f", x, nSignificantDigits, prec(x, nSignificantDigits));
		}
*/
double prec(double x, int nSignificantDigits);

/** >Mathematical
		Calculates a double value which is equal to x up to nDecimalPlaces decimal places
	Parameter:
		x = independent variable
	Returns:
		x with nDecimalPlaces decimal places.
	Example:
		void	run_round()
		{
			double		x = 34.56789;
			int			nDecimalPlaces = 3;
			
			printf("round(%f, %d) = %f", x, nDecimalPlaces, round(x, nDecimalPlaces));
		}
*/
double round( double x, int nDecimalPlaces );	// force given value to be nDecimalPlaces

/** >Mathematical
		Test given string to determine whether it is a numeric string
	Parameters:
		lpcstr = the alpha numeric string to test
		bThousoudSeparatorOK = to decide if thousand's separator can be used, like 1,234,567
		bLeadZeroOK = to decide if 01060 is a number (TRUE) or it should be considered not a number (bLeadZeroOK=FALSE)
	Return: 
		TRUE if given string is numeric, otherwise FALSE.
	Example:
		double	convert_str_to_num(string str)
		{			
			if (is_numeric(str))
				return atof(str);
			else
				return NANUM;
		}
	
*/
BOOL is_numeric(LPCSTR lpcstr, BOOL bThousoudSeparatorOK = TRUE, BOOL bLeadZeroOK = TRUE);

#include <msmath.h>


#endif  //_MATH_H

