/*------------------------------------------------------------------------------*
 *	File Name: 	ocMath.h								 						*
 *	Purpose:	C math functions, mostly general purpose					   	*
 *				Thisheader is used in VC ocMath DLL as well as in OC files		*
 *  Creation:	12/20/2003, Dr. C. P. Yang										* 
 *  	Copyright Originlab Corp. 2003, 2004,									*
 *	Modification log	                                                        *
 *	AW 01/20/04 QA70-5831 v7.0805 ADD_PERCENTILE_FILTER							*
 *	CPY 3/10/04 QA70-6077 v7.5836 PICK_PEAKS_AND_RELATED_SUPPORT				*
 *  Skip 04/19/04 v7.5860 ADD_OCMATH_NORM                                       *
 *	Jean 04/26/04 TPS															*
 *  Forest 05/04/04 QA70-6322 ADD_MATRIX_INVERSE								*
 *  Sonic 05/06/05 v7.5866 CHANGE_TYPE_OF_NBINS									*
 *  Forest 05/06/04 QA70-4447 ADD_MATRIX_QR                                     *
 *  Forest 05/25/04 QA70-6445 ADD_FUNCTIONS_REMOVED_FROM_NAG                    *
 *  Forest 06/17/04 QA70-6445 ADD_SPLINE_STURCTURES                             * 
 *  Forest 06/17/04 QA70-6445 ADD_OCMATH_FREE                                   * 
 *  Soapy  06/17/04  QA70-6421 COMBINE_MODIFIED_SHEPARD_AND_RENKACLINE          * 
 *	Forest 07/02/04 QA70-6445 SPLINE_FUNCTIONS_ERR_RETURN                       *
 *	CPY 7/10/04 CONTOUR_SHAPE_BASIC_CHARACTERISTICS								*
 *	AW 07/19/04 QA70-6445 v8.0911 REMOVE_NAG_DLL								*
 *	Soapy  07/30/04  QA70-6421 ADD_DERIVATION_TO_FITTING_STRUCTURE				*
 *  Forest 08/12/04  QA70-6785 LLVC_FOR_INTERPOLATION                           *
 *	ML 9/21/2004 QA70-6799 OCLT_FUNCTIONS										*
 *	Forest 10/14/04	 QA70-6671 LLVC_FOR_AVERAGE_MULTIPLE_CURVES					*
 *	RVD 10/18/2004 QA70-6954 v8.0146 TRI_CONTOUR_PLOT							*
 *  Forest 10/19/04  QA70-7032 LLVC_FOR_2D_BINNING								*
 *  Forest 01/18/04  QA70-7281 BIN_WIDTH_CALCULATION_RULE						*
 *	Forest 02/03/05	QA70-7374 ADD_PARAMETRIC_INTERPOLATION						*
 *  Forest 03/11/05 QA70-7491 LLVC_IS_VECTOR_MONOTONIC							*
 *  Soapy 03/23/05 MOVE_TO_WKS2MAT_H											*
 *  Soapy 05/14/05 QA7697 SEPERATE_XY_IN_GROUP_BY_X								*
 *  Leo 05/18/05 OCMATH_POLYNOMIAL_FIT											*
 *  Leo 05/31/05 OCMATH_DATATYPE_COPY											*
 *  Soapy 07/30/05 QA75-7865 ADD_2D_SHIFT_CORRELATION							*
 *	Leo 2005-9-19 QA70-8103 ADD_OCMATH_COUNT									*
 *	Mouqx/Leo 2005-12-02 QA70-2063 LLVC_IMAGE_LINE_PROFILE						*
 *	Leo 2006-1-19 REWRITE_AVERAGE_MULTIPLE_CURVES								*
 *	Roy 2006-3-01 REWRITE_AVERAGE_MULTIPLE_CURVES_ON_NOT_INTERP					*
 *	Roy 2006-3-17 ADD_DOUBLEPT													*
 *  SY 03/17/2006 QA70-7813 IMPORT_NETCDF_INTO_ORIGIN							*
 *	Leo 2006-3-20 LLVC_NUMERIC_INTEGRAL											*
 *	Leo 2006-3-27 LLVC_ROUND_RANGE												*
 *	Leo 2006-3-27 LLVC_ROUND_WITH_TOLERANCE										*
 *	Cheney 2006-3-28 LLVC_MEAN_INCREMENT										*
 *	Cheney 2006-4-12 LLVC_CURVE_LENGTH											*
 *	Cheney 2006-4-12 LLVC_CUMULATIVE_CURVE_LENGTH								*
 *	Cheney 2006-4-18 LLVC_AVE_MULTIPLE_CURVES_BY_LENGTH_PARAMETER				*
 *	Cheney 2006-4-24 LLVC_FOR_CHECK_ORDER										*
 *	Cheney 2006-4-26 LLVC_OCMATH_CHECK_ORDER_MULTIPLE_CURVES					*
 *	Cheney 2006-5-18 LLVC_ROW_DESC_STATS										*
 *	Cheney 2006-5-19 LLVC_ROW_QUANTILES											*
 *	Cheney 2006-5-25 QA70-5831 LLVC_FIND_XS										*
 *	CPY 5/27/06 CHECK_ORDER_RET_VALUE_INCONSISTENT								*
 *	Cheney 2006-5-29 LLVC_T_TEST_ONE_SAMPLE										*
 *	Cheney 2006-5-29 LLVC_CHECK_ORDER_CURVE										*
 *	Arvin 2006-6-19	QA70-6445 REDEFINE_SPLINE_STRUCTS_OF_NAG					*
 *	Arvin 2006-6-20 QA70-6445 ADD_FREE_SPLINE_STRUCT							*
 *	Arvin 2006-6-20 QA70-6445 ADD_FREE_COMM_STRUCT								*
 *	Arvin 2006-6-20 QA70-6445 ADD_FREE_2DSPLINE_STRUCT							*
 *	Arvin 2006-7-3	LLVC_OUTPUT_COEFFICIENTS_OF_INTERPOLATE						*
 *	Arvin 2006-8-04 USE_STRUCT_OCMATH_INTEGRESULT								*
 *	Arvin 2006-8-08 QA70-8419 LLVC_XY_REMOVE_DUPLICATES							*
 *	Cheney 2006-08-15 LLVC_SMOOTH												*
 *	Cheney 2006-08-28 LLVC_AVE_REPLICA_DATA_FOR_MULTIPLE_CURVES					*
 *  Sandy 2006-9-6 ADD_NEW_ALGORITHM_FOR_FINDING_PEAK_WITH_LOCAL_MAXIMUM		*
 *  Sandy 2006-9-29 ADD_NEW_ALGORITHM_FOR_FINDING_PEAK_WITH_SEARCH_WINDOW		*
 *	CPY 12/7/06 DATA_MAT_TO_IMAGE_CONVERT										*
 *	Arvin 01/18/06 ADD_SORTING_FLAG												*
 *	Echo 1/27/07 ADD_SIMPLE_MATH												*
 *  Justin 2007-03-26 MODIFY_CATEGORY											*
 *	Cloud 03/30/07 QA80-9408 ADD_NO_PADDING_CASE_FOR_SMOOTH						*
 *  Justin 2007-04-03 v8.0595 NO_NEED_TO_CHECK_X_PRECISIION_IF_INTERATION_IS_SUITABLE
 *	Cloud 04/06/2007 FIND_MARKER_BY_FULL_WIDTH									*
 *	Cloud 04/09/2007 FIX_DATA_TYPE_IN_SEARCH_WINDOW_METHOD						*
 *	Echo 4/26/07 MOVED_TO_OCSTATS												*
 *	Cloud 05/17/2007 FIND_MARKER_BY_2ND_DERIVATIVE								*
 *	Cloud 05/18/2007 ADD_CONTROL_TO_OBTAIN_FORWARD_OR_BACKWARD_DERIVATIVE		*
 *	Cloud 05/18/2007 MOVE_DATASET_FUNCTIONS_TO_OCMATH							*
 *	Cloud 05/21/2007 REPLACE_DATA_MATCHING_CONDITION_WITH_SPECIFIED_NUM			*
 *  Justin 2007-06-22 QA-9951 FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION *
 *	Cloud 07/05/2007 NOISE_ESTIMATED_FOR_FLAT_PART								*
 *	Cloud 07/10/2007 IMPORT_FIND_INFLECTION_POINT_FROM_OLD_PFM					*
 *	Cloud 09/29/2007 TRIM_COLINEAR_POINTS_FROM_POLYGON							*
 *	Cloud 10/17/2007 QA80-10492 1D_RESAMPLING									*
 *	Cloud 11/10/2007 FIND_BASELINE_PART_IN_SMOOTH_CURVE							*
 *	Cloud 12/07/2007 QA80-10788 FIND_BASELINE_PARTION							*
 *	Folger 12/10/07 FIND_PEAKS_SHOULD_RETURN_OCMATH_ERROR_CODE					*						
 *	Cloud 12/10/2007 QA80-10788 MOVE_FROM_CURVE_UTILS							*
 *	Cloud 12/24/2007 QA80-10864 CUT_DATA_INTO_PARTS_BY_HEIGHT					*
 *	Cloud 01/11/2008 WRAP_FOR_OCMATHSP											*
 *	Arvin 01/25/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS_OF_POLYNOMIAL_FIT
 *  Jack 21/3/2008 ADD_ERR_ENUM_LOCAL_PTS_EXCEED_MAT_DATA_SIZE					*
 *	Cloud 03/26/2008 FIX_BUG_OF_NORMALIZING_TOO_EASILY							*
 *  Jack 03/31/2008 MOVE_BASELINE_BY_SMALL_CURVATURE_METHOD_FROM_OC				*
 *  Jack 10/04/2008 IMPROVE_NOISE_ESTIMATED_WITH_GAMMA_TEST_BY_NEAREST_NEIGHBORS*
 *  Jack 04/18/08  ADD_BOUNDARY_CONDITION_TYPE_FOR_SPLINE						*
 *  Jack 28/04/2008 ADD_REDUCE_2D_MATRIX_DATA									*
 *	Jack 29/4/2008 ADD_ERR_ENUM_FOR_MATRIX_DATA_SHRINK							*
 *	Cloud 05/16/2008 CATEGORY_UPDATE											*
 *	Jack 06/11/2008 ADD_NORMAL_INTEGRAL_FUNCTION								*
 *	Jack 21/10/2008 QA80-12405 REDUCE_DATA_XF									*
 *	Fisher 2008/10/28 QA80-12458 ADDITIONAL_OUTPUT_FOR_SINGAL_PROCESSING_TOOL	*
 *	Fisher 2008-11-7 QA80-12546 ADD_BACK_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL	*
 *	Kyle 11/12/2008 QA80-12578 NEED_TO_HANDLE_SIZE_OF_THE_SOURCE_VECTOR			*
 *  Sandy 2008-11-14 MOVE_FROM_FFTW_FOR_SPREAD_USEAGE							*
 *	Jack 11/14/2008  INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD
 *	Jack 12/04/2008	ADD_DATA_INTEGRATE_WITH_BOUNDS								*
 *	Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS										*
 *	Jack	12/26/2008 CHANGE_BOOL_CONTROL_INTO_DWORD_OPTIONS_CTRL				*
 *	Fisher 1/7/09 QA80-12727 AVECURVES_RESULTS_NOT_GOOD_WHEN_CURVES_HAVE_MISSING_VALUES
 *	Jack 01/07/2008 SKIP_POINTS_IN_VECTOR										*
 *	Kyle 01/15/2009 BRING_BACK_FIRST_SAMPLING_METHOD							*
 *	Kyle 01/21/2009 REMOVE_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL					*
 *	Kyle 03/11/2009 QA80-13251 ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET			*
 *	Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS							*
 *	Fisher 07/22/09 AREA_OF_3D_SURFACE											*
 *	Fisher 07/23/09	QA80-13994 OCMATH_FUNCTION_TO_SUPPORT_SAME_BSPLINE_AS_DRAWING_CODE
 *	CPY 7/24/09 QA70-14007-P2 BSPLINE_FOR_ORIGIN_INTERNAL_USE_FOR_FASTER_LABTALK_CALL
 *	Kyle 09/29/2009 QA80-6671-S1 MIN_AND_MAX_FOR_EACH_ROW_OF_DATA_FOR_AVERAGE_CURVES
 *	Fisher QA80-14626 2009/11/10 MISSING_VALUE_HANDLING_FOR_ROOT_FINDING_FUNC	*
 *	Hong 11/11/09 QA80-6671-S1 AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME		*
 *	Fisher 04/29/10 Qa81-15371 REWRITE_OCMATH_INTEG_WITH_BOUNDS					*
 *	Folger 05/06/10 QA81-10201-P2 PROPER_ERROR_FOR_LT_EXT_MATH_FUNCTION			*
 *	Kyle 05/21/2010 OGR-98 IMAGE_PROFILE_SPEED_IMPROVMENT						*
 *	Kyle 06/29/2010 ORG-209 REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN
 *	Kyle 08/03/2010 ORG-693-P2 WRONG_Z1_Z2_ON_SWITCH_DATA_TYPE_TO_LONG_ETC		*
 *	Gareth 8/12/2010 ORG-57 CUMULATIVE_CURVE_LENGTH_3D							*
 *	Folger 09/27/2010 ORG-1159 MOVE_match_peaks_centers_by_index_TO_VC_AS_OCMATH_FUNCTION
 *------------------------------------------------------------------------------*/      

#ifndef _OC_MATH_H
#define _OC_MATH_H

#ifdef __AFX_H__	   //VC
	/// TD 8-29-05 HELP_LINK_MIN_OK
	//#ifdef OCMATH_EXPORTS
	#ifdef MIN_OK_VERSION
		#define  OCMATH_API
	#elif defined(OCMATH_EXPORTS)
	/// end HELP_LINK_MIN_OK
		#define OCMATH_API __declspec(dllexport)
	#else
		#define OCMATH_API __declspec(dllimport)
		#pragma message("In some other DLL")
	#endif
	
	//--- CPY 3/31/05 moved back here for ocmath dll to compile
	#include "stats_types.h" ///Forest 01/18/04 ///Moved to origin.h by Leo
	//---
	#include "oc_types.h"	//CPY 12/22/06 Arvin 12/19/06 PRODUCE_STREL_STRUCT_FOR_MORPHOLOGIC_OPERATION
	///-------- AW 07/19/04 QA70-6445 v8.0911 REMOVE_NAG_DLL
	typedef struct {
		double 	re;
		double 	im;
	} d_complex;
	///-------- end REMOVE_NAG_DLL

	#define uint UINT

	/// ML 9/21/2004 QA70-6799 OCLT_FUNCTIONS
	// msg:
	enum {
		OCMATHLT_GET_FUNCTION					 = 1,
		OCMATHLT_GET_VALUE,
		///------ Folger 05/06/10 QA81-10201-P2 PROPER_ERROR_FOR_LT_EXT_MATH_FUNCTION
		OCMATHLT_GET_NUM_ARGS,
		OCMATHLT_GET_NAME,
		///------ End PROPER_ERROR_FOR_LT_EXT_MATH_FUNCTION
	};
	OCMATH_API	int PASCAL ocmath_LT_functions(UINT msg, LPSTR pcszName, DWORD *pdwCookie, double *prArguments, double *prResult);
	/// end OCLT_FUNCTIONS
	extern "C" {
#else //__AFX_H__
	#define OCMATH_API
	#pragma dll(ocMath)	// Assoicate all functions below to ocMath.dll which must be in the Origin EXE folder
	#define d_complex complex
#endif	//!_MSC_VER

//#include "stats_types.h" ///Forest 01/18/04 ///Moved to origin.h by Leo

//---CPY 12/7/06 DATA_MAT_TO_IMAGE_CONVERT
#define	__NANUM		(-1.23456789E-300)
//---

///Arvin 01/18/06 ADD_SORTING_FLAG	
#define OCMATH_SRCDATA_X_MONOTONIC  0x10000000 
///-----
#define SMOOTH_LEVEL 25   ///Comments last updated by Joseph on 2006-12-23
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
enum{
	OE_NOERROR = 0,
	OE_UNKOWN_ERROR = -1,
	OE_SIZE_LT = -2,
	OE_RANGE_ZERO = -3,
	OE_INVALID_WINSIZE = -4,
	OE_INVALID_SIZE = -5,
	OE_INVALID_RANGE = -6,
	OE_LACKPOINTS = -7,
	OE_INVALID_POINT = -8,
	OE_SMOOTHPTS_LT_ZERO = -9,
	OE_UNKNOWN_METHOD = -10,
	OE_NULL_POINTER = -11,
	OE_INVALID_DIMENSION = -12,
	OE_INVALID_DATASIZE = -13,

	OE_REAL_ARG_LT = -14,
	OE_INT_ARG_LT = -15,
	OE_NOT_INCREASING = -16,
	OE_NOT_STRICTLY_INCREASING = -17,
	OE_BAD_PARAM = -18,
	OE_ALLOC_FAIL = -19,
	OE_ABSCI_OUTSIDE_KNOT_INTVL = - 20,
	OE_WEIGHTS_NOT_POSITIVE = - 21,
	OE_DATA_ILL_CONDITIONED = - 22,
	OE_COEFF_CONV = - 23,
	OE_END_KNOTS_CONS = -24,
	OE_POINT_OUTSIDE_RECT = -25,
	OE_NUM_KNOTS_1D_GT = -26,
	OE_ENUMTYPE_WARM = -27,
	OE_SF_D_K_CONS = -28,
	OE_RANGE_INVALID = -29,

	OE_INCOMPATIBLE_X_COL = -30,
	OE_DEVIDED_BY_ZERO	= -31,
	OE_NOT_SPACED_EQUALLY = -32,
    OE_CANNOT_SORT = -33,
	OE_DUPLICATE_POINT = -34,
	OE_TPS_INVALID_SMOOTH = -35,
	OE_TPS_INVALID_FIT = -36,
	OE_INVALID_PARAMETERS = -37,
	OE_KRIG_SOLVE_LINEAR_SYSTEM_FAIL = -38,
	OE_AVMC_NO_OVERLAPPED_PTS = -39,
	OE_AVMC_BUFFER_TOO_SMALL = -40,
	OE_UNDERFLOW = -41,
	OE_OVERFLOW = -42,

	OE_VALUE_TOO_SMALL = -50,//------ CPY 5/28/06 FFT_SAMPLE_INTERVAL_MOVED_TO_OCMATH
	OE_ERROR_SETTING = -51,//----- Cheney 5/29/06 OCMATH_T_TEST_ONE_SAMPLE
	///Arvin 12/19/06 PRODUCE_STREL_STRUCT_FOR_MORPHOLOGIC_OPERATION
	OE_INVALID_NHOOD_MATRIX = -52, 
	OE_HEIGHT_SHOULD_SAME_SIZE_AS_NHOOD = -53,
	OE_NHOOD_SIZE_TOO_SMALL = -54,
	///----
	
	//------ Folger 12/10/07 FIND_PEAKS_SHOULD_RETURN_OCMATH_ERROR_CODE
	OE_NO_PEAK_FOUND	= -55,
	//------
	
	OE_OUTPUT_BUFFER_TOO_SMALL = -56, //----- CPY 12/11/07 BETTER_VEC_USE_NO_COPY_AT_END
	///Arvin 12/18/07 CENTRALIZE_FINDING_PEAK_BY_1ST_AND_2ND_DRIVATIVE
	OE_FIND_PEAK_1ST_FAILED_TO_CALC_DERIV = -57, 
	OE_SOME_NASTY_ERROR = -58,
	///end CENTRALIZE_FINDING_PEAK_BY_1ST_AND_2ND_DRIVATIVE

	///Jack 21/3/2008 ADD_ERR_ENUM_LOCAL_PTS_EXCEED_MAT_DATA_SIZE
	OE_NUM_LOCAL_PTS_EXCEED_MAT_DATA_SIZE = -59,
	/// End ADD_ERR_ENUM_LOCAL_PTS_EXCEED_MAT_DATA_SIZE

	///Jack 29/4/2008 ADD_ERR_ENUM_FOR_MATRIX_DATA_SHRINK
	OE_MATRIX_DATA_SHRINK = -60,
	/// End ADD_ERR_ENUM_FOR_MATRIX_DATA_SHRINK

	///Jack 5/5/2008 ADD_ERR_ENUM_FOR_TRIM_MISSING_NUMBER_TO_NO_PTS
	OE_TRIM_NAN_TO_NO_PTS = -61,
	/// End ADD_ERR_ENUM_FOR_TRIM_MISSING_NUMBER_TO_NO_PTS

	/// Jack ADD_LOGISTICS_REGRESSION
	OE_SINGULAR_MATRIX_INVERSION = -62,
	OE_MAX_ITER_NUM = -63,
	///	End ADD_LOGISTICS_REGRESSION

	///Jack 21/10/2008 QA80-12405 REDUCE_DATA_XF
	OE_GET_BOUND_INDEX = -64,
	OE_GET_MEDIAN = -65,
	/// End REDUCE_DATA_XF

	/// Fisher 11/10/2008 QA80-12507 	OSCILLOSCOPE_SIGNAL_PROCESSING_FEATURES
	OE_NO_BASE_FOUND = -100,
	OE_ONLY_ONE_BASE_FOUND = -101,
	/// End OSCILLOSCOPE_SIGNAL_PROCESSING_FEATURES

	///Jack 11/11/2008	ADD_EMPIRICAL_MODE_DECOMPOSITION
	OE_TOO_SMALL_EXTREME_PTS = -102,
	///End ADD_EMPIRICAL_MODE_DECOMPOSITION

	///Sandy 2008-11-14	ADD
	OE_INVALID_INTERVAL = -103,	  //invalid interval -- the interval is less than 1e-20, using in  ocmath_check_interval(...)
	OE_UNEVENLY_SPACE   = -104,   //unevenly spaced values, used in ocmath_check_interval(...)
	///END

	///Jack 11/27/2008	ADD_EMPIRICAL_MODE_DECOMPOSITION
	OE_EMD_STOP_STATUS_SMALL_EXTREME_PTS = -105,
	OE_EMD_STOP_STATUS_TOO_SMALL_AMP = -106,
	OE_EMD_STOP_STATUS_TOO_MUCH_ITERATION = -107,
//	OE_EMD_STOP_STATUS_ERROR = -108,
	OE_EMD_STOP_SIFTING_ERROR = -109,	
	OE_GET_ENVELOPE = -110,
	///End ADD_EMPIRICAL_MODE_DECOMPOSITION

	/// Jack 01/07/2008 SKIP_POINTS_IN_VECTOR
	OE_SKIP_VEC_PTS = -111,
	/// ENd SKIP_POINTS_IN_VECTOR

	/// Fisher 4/1/2009 SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
	OE_NOT_CONVERGENCE = -112,
	/// End SUPPORT_LINEAR_FIT_WITH_ERROR_BAR

	OE_NON_MONOTONIC = -113,		/// Fisher 04/29/10 Qa81-15371 REWRITE_OCMATH_INTEG_WITH_BOUNDS
};
///End TO_CENTRALIZE_ERROR_CODES_IN_OCMATH

/// Cloud 03/26/2008 FIX_BUG_OF_NORMALIZING_TOO_EASILY
#define LARGE_X_NORMALIZED	1
/// End FIX_BUG_OF_NORMALIZING_TOO_EASILY

typedef struct  tagFLOATPT 
{ 
	float x;
	float y;
} FLOATPT;

/// Roy 2006-3-17 ADD_DOUBLEPT
typedef struct  tagDOUBLEPT 
{ 
	double x;
	double y;
} DOUBLEPT;
/// end ADD_DOUBLEPT

typedef struct tagFLOATRECT
{
    float    left;
    float    top;
    float    right;
    float    bottom;
} FLOATRECT;

/// AW 01/20/04 QA70-5831 v7.0805 ADD_PERCENTILE_FILTER
enum{	FILTERSHAPE_SQUARE, 
		FILTERSHAPE_CIRCULAR, 
		FILTERSHAPE_STRAIGHT_CROSS, 
		FILTERSHAPE_DIAGONAL_CROSS
};		
/// END ADD_PERCENTILE_FILTER

///Arvin 07/31/07 QUIKE_METHOD_OF_PEAK_MOMENTS_AND_INTEGRAL_EVALUATION
enum{
	OCMATH_PEAK_CENTRAL_MOMENT,
	OCMATH_PEAK_ZERO_POINT_MOMENT,
};
///END 	QUIKE_METHOD_OF_PEAK_MOMENTS_AND_INTEGRAL_EVALUATION

///	Jack 11/14/2008  INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD
enum{
///Jack	11/19/2008 ADD_NORMAL_SECOND_DERIVATIVE_WITHOUT_SMOOTH
	DERIVATIVE_WITHOUT_SMOOTH = 0,
///End ADD_NORMAL_SECOND_DERIVATIVE_WITHOUT_SMOOTH
	DERIVATIVE_WITH_ADJ_SMOOTH,
	DERIVATIVE_USE_SG_SECOND_DERIV,
	DERIVATIVE_WITH_CONTINUOUS_SG_FIRST_DER_SMOOTH,
};

enum{
	FIRST_DERIV_FILTER_OF_PEAK = 0,
	SECOND_DERIV_FILTER_OF_PEAK,
	SG_FIRST_DERIV_FILTER_OF_PEAK,
	SG_SECOND_DERIV_FILTER_OF_PEAK,
};
/// End INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD


//Forest 06/17/04 QA70-6445 ADD_SPLINE_STURCTURES
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_2dSpline
*/
typedef struct
{
	long nx;//the total number of knots of the computed spline with respect to the x variable
	double* lamda;//pointer to the complete set of knots associated with the x variable
	long ny;//the total number of knots of the computed spline with respect to the y variable
	double* mu;//pointer to the complete set of knots associated with the y variable
	double* c;//pointer to the coefficients of the spline interpolant.
}ocmath_2dSpline;

//typedef enum
//{
//	ocmath_Cold,//cold start
//	ocmath_Warm //warm start
//}ocmath_Start;

//typedef enum
//{ 
//	ocmath_LeftDerivs,
//	ocmath_RightDerivs
//}ocmath_DerivType;

///Forest 07/19/04 using proper enum name, ALL UPPER CASE
typedef enum
{
	START_COLD,//cold start
	START_WARM //warm start
}OCMATH_START;

typedef enum
{ 
	DERIVTYPE_LEFTDERIVS,
	DERIVTYPE_RIGHTDERIVS
}OCMATH_DERIVTYPE;

//------Arvin 2006-6-19	QA70-6445 REDEFINE_SPLINE_STRUCTS_OF_NAG
//typedef struct
//{
//	double *ocmath_w;  //ocmath workspace 
//	long   *ocmath_iw; //ocmath integer workspace 
//}ocmath_Comm;

//typedef struct
//{
//	long   n;//the total number of knots of the computed spline
//	double *lamda;//pointer to the positions of the knots
//	double *c;//pointer to the coefficients of the B-spline representation
//}ocmath_Spline;
//End ADD_SPLINE_STURCTURES

//Redefine the types Boolean and pointer of NAG 
#undef OCMATH_CHAR_BOOL
#define OCMATH_INT_BOOL
#ifdef OCMATH_INT_BOOL
  typedef int Boolean;
#else
#ifdef OCMATH_CHAR_BOOL
  typedef char Boolean;
#else
  typedef signed char Boolean;
#endif
#endif

#define OCMATH_VOID_STAR
#ifdef OCMATH_VOID_STAR
  typedef void * Pointer;          /* Generic pointer */
# define OCMATH_Pointer void *
#else
  typedef char * Pointer;
# define OCMATH_Pointer char *
#endif

//Redefine the stuct Nag_Comm
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_Comm
*/
typedef struct
{
	long    flag;   /* user error flag set to 0 before each call to lsqfun, test for != 0 on exit */
    Boolean first;  /* TRUE on first call to objective (and constraint) function, FALSE after */
    Boolean last;   /* TRUE on last call to objective (and constraint) function, FALSE before */
    long    nf;     /* output: number of function evaluations or number of times residuals have been calculated. Calls to objective function */
    Boolean it_prt; /* ocmath_Iteration print */
    Boolean it_maj_prt; /* ocmath major iteration print (e04ucc) */
    Boolean sol_sqp_prt;/* Solution print (e04ucc)*/
    Boolean sol_prt;/* Solution print or, for e04ucc, major itn. sol. print */
    Boolean rootnode_sol_prt; /* Solution at rootnode of Branch & Bound */
    Boolean node_prt; /* Summary of node solution in B&B */
    Boolean rootnode_prt;  /* Summary of root node solution in B&B */
    Boolean g_prt;  /* Derivative check info. from e04ucy available */
    Boolean new_lm; /* New Lagrange multipliers calculated */

    long    needf;  /* Added at Mark 6 to pass to the obj function in e04unc */

    /* User workspace pointers */
    Pointer p;      /* generic pointer to user workspace */
    long    *iuser; /* user workspace */
    double  *user;   /* user workspace */

    Pointer ocmath_p;  /* ocmath generic workspace */

    double  *ocmath_print_w;
    long    *ocmath_print_iw;

    long    nrealloc;  
	double  *ocmath_w;  //ocmath workspace 
	long    *ocmath_iw; //ocmath integer workspace 
}ocmath_Comm;

//Redefine the struct Nag_Spline
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_Spline
*/
typedef struct
{
	long   n;//the total number of knots of the computed spline
	double *lamda;//pointer to the positions of the knots
	double *c;//pointer to the coefficients of the B-spline representation
	long   init1;
    long   init2;  
}ocmath_Spline;
//------End REDEFINE_SPLINE_STRUCTS_OF_NAG

///Forest 08/12/04  QA70-6785 LLVC_FOR_INTERPOLATION
typedef enum
{
	INTERP_TYPE_LINEAR,
	INTERP_TYPE_SPLINE,
	INTERP_TYPE_BSPLINE
}INTERP_TYPE;
///End LLVC_FOR_INTERPOLATION

///Gareth 4/27/2010 ADD_INTERPOLATE_3D_TYPE_LINEAR
typedef enum
{
	INTERP3D_TYPE_LINEAR
}INTERP3D_TYPE;

///Jack 04/18/08  ADD_BOUNDARY_CONDITION_TYPE_FOR_SPLINE
// for INTERP_TYPE_SPLINE only
typedef enum
{
	SPLINE_BOUNDARY_TYPE_NATURAL = 0,
	SPLINE_BOUNDARY_TYPE_NOT_A_KNOT,
}SPLINE_BOUNDARY_TYPE;
///End ADD_BOUNDARY_CONDITION_TYPE_FOR_SPLINE


///Echo 1/27/07 ADD_FOR_SIMPLE_MATH
typedef enum 
{
	MATHTOOL_OPT_ADD = 0,
	MATHTOOL_OPT_SUB,
	MATHTOOL_OPT_DIV,
	MATHTOOL_OPT_MUL,
	MATHTOOL_OPT_EXP
}MATHTOOL_OPERATOR;

typedef enum 
{
	MATHTOOL_RNG_CUV = 0,
	MATHTOOL_RNG_COM,
	MATHTOOL_RNG_UD,
}MATHTOOL_RANGE;
///end ADD_FOR_SIMPLE_MATH

#ifndef _VC_EDGEPAD_DEF
#define _VC_EDGEPAD_DEF

///Sandy 2006-8-4 REORDER_EDGEPAD
/// Leo 08/16/05 QA70-4435 BOUNDARY_CONDITION_FOR_ADJAVE_SMOOTH
/// The enum will be used in ocmath_adjave_smooth and ocmath_savitsky_golay
//enum {EDGEPAD_ZERO, EDGEPAD_REFLECT, EDGEPAD_REPEAT, EDGEPAD_EXTRAPOLATE, EDGEPAD_PERIODIC};
/// Cloud 03/30/2007 QA80-9408 ADD_NO_PADDING_CASE_FOR_SMOOTH
//enum {EDGEPAD_ZERO, EDGEPAD_REFLECT, EDGEPAD_REPEAT, EDGEPAD_PERIODIC, EDGEPAD_EXTRAPOLATE};
enum {EDGEPAD_NONE, EDGEPAD_REFLECT, EDGEPAD_REPEAT, EDGEPAD_PERIODIC, EDGEPAD_EXTRAPOLATE, EDGEPAD_ZERO};
/// End ADD_NO_PADDING_CASE_FOR_SMOOTH
/// End BOUNDARY_CONDITION_FOR_ADJAVE_SMOOTH
#endif

///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//Forest 07/02/04 QA70-6445 SPLINE_FUNCTIONS_ERR_RETURN
//typedef enum
//{
//	ERR_SPLINE_SUCCESS = 0,
//	ERR_SPLINE_REAL_ARG_LT = 5,
//	ERR_SPLINE_INT_ARG_LT = 11,
//	ERR_SPLINE_NOT_INCREASING = 62,
//	ERR_SPLINE_NOT_STRICTLY_INCREASING = 63,
//	ERR_SPLINE_BAD_PARAM = 70,
//	ERR_SPLINE_ALLOC_FAIL = 73,
//	ERR_SPLINE_ABSCI_OUTSIDE_KNOT_INTVL = 238,
//	ERR_SPLINE_WEIGHTS_NOT_POSITIVE = 240,
//	ERR_SPLINE_DATA_ILL_CONDITIONED = 243,
//	ERR_SPLINE_COEFF_CONV = 254,
//	ERR_SPLINE_END_KNOTS_CONS = 255,
//	ERR_SPLINE_POINT_OUTSIDE_RECT = 257,
//	ERR_SPLINE_NUM_KNOTS_1D_GT = 264,
//	ERR_SPLINE_ENUMTYPE_WARM = 266,
//	ERR_SPLINE_SF_D_K_CONS = 268,
//	ERR_SPLINE_RANGE_INVALID = 269,
//}Err_Spline;
//End SPLINE_FUNCTIONS_ERR_RETURN
///End TO_CENTRALIZE_ERROR_CODES_IN_OCMATH

///Soapy 03/23/05 MOVE_TO_WKS2MAT_H
/// The following codes are move to wks2mat.h
/*
///Soapy  06/17/04  QA70-6421 COMBINE_MODIFIED_SHEPARD_AND_RENKACLINE
// Method used in the 2d scatter interpolation
typedef enum {ocmath_2d_Scat_RC = 0, ocmath_2d_Scat_Shep} ocmath_2d_Scat_Method;
typedef enum {  // Error return by ocmath_2d_scat_interpolant()
	Err_Intp_No_Error = 0,
	Err_Intp_Mem_Fail, 
	Err_Intp_Method,
	Err_Intp_Invalid_Point,
	Err_Intp_Duplicate_Point
}Err_Intp; 

typedef struct{
	int exit_status; // specifies the status of calling ocmath_2d_scat_interpolant()
	ocmath_2d_Scat_Method method;  
	double *x;  // the position and the value of the scattering points
	double *y;
	double *f;
	int np;     // the number of scatter points

	// For Modified Shepard's Method
	int nr;    
	int nq;
	int nw;

	double xmin;
	double ymin;
	double dx;
	double dy;
	double rmax;

	int* pLCell;
	int* pLNext;
	double* pRsq;
	double* a;

	// For Renka and Cline's Method
	int *iadj;
	int *iend;
	double *zxzy; ///Soapy  07/30/04  QA70-6421 ADD_DERIVATION_TO_FITTING_STRUCTURE
} ocmath_Scat_Struct;

typedef struct{
  int nw;
  int nq;
} ocmath_Scat_Opt;
///END COMBINE_MODIFIED_SHEPARD_AND_RENKACLINE
*/
///END Soapy 03/23/05 MOVE_TO_WKS2MAT_H

///Forest 10/14/04	 QA70-6671 LLVC_FOR_AVERAGE_MULTIPLE_CURVES
///Leo 2006-1-19 REWRITE_AVERAGE_MULTIPLE_CURVES
typedef struct
{
   uint    nSize;	// size of each curve
   double* pX;		// each curve's X data pointer
   double* pY;		// each curve's Y data pointer
   double* pErr;	// each curve's Err bar data pointer, = NULL if no Err bars
} OneCurveData;

///Kyle 09/29/2009 QA80-6671-S1 MIN_AND_MAX_FOR_EACH_ROW_OF_DATA_FOR_AVERAGE_CURVES
//enum {AVMC_SE, AVMC_SD};
/// Hong 11/11/09 QA80-6671-S1 AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
//enum {AVMC_SE, AVMC_SD, AVMC_MIN, AVMC_MAX};
enum {AVMC_SE, AVMC_SD};
/// end AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
///End MIN_AND_MAX_FOR_EACH_ROW_OF_DATA_FOR_AVERAGE_CURVES

///Leo 2006-1-19 TO_AVOID_HARD_CODED_NUMBERS
/* 
#define MAX_MULTI_CUV 50

typedef struct
{
   double* pX[MAX_MULTI_CUV];// each curve's X data pointer
   double* pY[MAX_MULTI_CUV];// each curve's Y data pointer
   double* pErr[MAX_MULTI_CUV];// each curve's Err bar data pointer, = NULL if no Err bars
   uint    nSize[MAX_MULTI_CUV];// size of each curve
}MultiCurves;

enum {AVMC_ERR_BUFFER_TOO_SMALL = -1, AVMC_ERR_NO_OVERLAPPED = -2, AVMC_ERR_CURVE_NUMBER_LT = -3, AVMC_ERR_INTERP = -4, AVMC_ERR_INVALID_ERR_TYPE = -5};
*/
///End	LLVC_FOR_AVERAGE_MULTIPLE_CURVES

///Forest 10/19/04  QA70-7032 LLVC_FOR_2D_BINNING
typedef struct
{
   double    dMin;    // the minimum of the range
   double    dMax;    // the maximum of the range
   double    dInc;    // the bin increment of the range
   int		 wIncludeOutliers;    // flag indicating whether or not to include outliers in first and last bins, values are defined in enum FrequncyCounOutBin, default value is FCB_INCLUDE_OUTLIERS
   double	 dPeriod;			///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
   /// Hong 09/09/09 QA90-14287 2DBINNING_SUPPORT_HANDLE_MIN_MAX
   int		 wIncludeMinMax; // reuse flag in wIncludeOutliers, left for Min, right for Max
   /// end 2DBINNING_SUPPORT_HANDLE_MIN_MAX
}BinningOption;

typedef struct
{ 
	int	  iMatSize;	//(input)actual size of pMatrix
	int    iSizeX;    // (output)X size of the result matrix
	int    iSizeY;    // (output)Y size of the result matrix
	///Kyle 06/29/2010 ORG-209 REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN
	double	dMinX;		// (output)
	double	dMaxX;		// (output)
	double	dMinY;		// (output)
	double	dMaxY;		// (output)
	///End REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN
	uint*  pMatrix;   // (output)result matrix, with row number iSizeX, column number iSizeY, row-wise storage, caller should assign enough memory space for this array
}BinningResult;

///Arvin 12/19/06 PRODUCE_STREL_STRUCT_FOR_MORPHOLOGIC_OPERATION
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:StrelParams
*/
typedef struct
{
	uint nRows;	//for rectangle and arbitrary
	uint nCols;	//for rectangle and arbitrary 
	double* pNHood; //for arbitrary 
	double* pHeight; //for arbitrary
	uint nWidth; //for square
	uint nRadius; //for diamond and octagon
	int rowOffset; //for pair and periodicline
	int colOffset; //for pair and periodicline
	uint nP; //for periodicline
	uint nLen;	//for line
	double thetaDeg; //for line
}StrelParams;

enum
{
	ARBITRARY_SHAPE,
	//BALL_SHAPE,
	DIAMOND_SHAPE,
	//DISK_SHAPE,
	LINE_SHAPE,
	OCTAGON_SHAPE,
	PAIR_SHAPE,
	PERIODICLINE_SHAPE,
	RECTANGLE_SHAPE,
	SQUARE_SHAPE,
};
///---------

///Kyle 05/11/2009 QA80-13521 SUPPORT_PERIODICAL_BINS
//enum{BINNING_ERR_SIZE = 1, BINNING_ERR_RANGE, BINNING_ERR_INC, BINNING_ERR_FLAG, BINNING_ERR_BUFFER_TOO_SMALL};
enum{BINNING_ERR_SIZE = 1, BINNING_ERR_RANGE, BINNING_ERR_INC, BINNING_ERR_FLAG, BINNING_ERR_BUFFER_TOO_SMALL, BINNING_ERR_PERIOD};
///End SUPPORT_PERIODICAL_BINS
///End LLVC_FOR_2D_BINNING

///Forest 01/18/04  QA70-7281 BIN_WIDTH_CALCULATION_RULE
enum
{
   BIN_RULE_FREEDMAN_DIACONIS,    //Width = 2*IQR*N^(-1/3)
   BIN_RULE_SCOTT,    //Width = 3.49*SD*N^(-1/3)
   BIN_RULE_STURGES //Bins = 1+log2(N)
};
///End BIN_WIDTH_CALCULATION_RULE

///Forest 02/03/05	QA70-7374 ADD_PARAMETRIC_INTERPOLATION
enum{PARA_INTERP_RANGE_INDEX, PARA_INTERP_RANGE_EUGENE};
///End ADD_PARAMETRIC_INTERPOLATION

///Forest 03/11/05 QA70-7491 LLVC_IS_VECTOR_MONOTONIC
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//enum{MONO_ERROR = -2, MONO_DECREASE = -1, MONO_NOT = 0, MONO_INCREASE = 1};
///End TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
///End LLVC_IS_VECTOR_MONOTONIC

///Leo 2005-9-19 QA70-8103 ADD_OCMATH_COUNT
enum {COUNT_GREATER_EQUAL, COUNT_GREATER, COUNT_LESS_EQUAL, COUNT_LESS, COUNT_EQUAL, COUNT_UNEQUAL};
///End ADD_OCMATH_COUNT

///Cheney 2006-4-14 ADD_OCMATH_CUMULATIVE_CURVE_LENGTH
enum{	NOT_KEEP_STRICT_INCRECE, 
		KEEP_STRICT_INCRECE
};
///end ADD_OCMATH_CUMULATIVE_CURVE_LENGTH


///END FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION
//---- CPY 5/27/06 CHECK_ORDER_RET_VALUE_INCONSISTENT
//1. remove  CO_MONO*, change  MONO_ to be 0,1,2
//2. change MCO_MONO_CONSISTENT to 0
//3. change CO_MONO_NOT to 0 and then CO_MONO_INCREASE to 2
enum{MONO_NOT = 0, MONO_DECREASE, MONO_INCREASE};
//enum {	
//		CO_MONO_NOT,
//		CO_MONO_DECREASE,
//		CO_MONO_INCREASE
//};
///Cheney 2006-4-26 ADD_OCMATH_CHECK_ORDER_MULTIPLE_CURVES
enum{	MCO_MONO_CONSISTENT,
		MCO_MONO_NOT_CONSISTENT,
		MCO_NOT_CONSISTENT 
};
///end ADD_OCMATH_CUMULATIVE_CURVE_LENGTH

///Cheney 2006-5-30 ADD_OCMATH_T_TEST_ONE_SAMPLE
enum{	MIN_NOT_EQUAL_TO_MAX = 0,
		MIN_EQUAL_TO_MAX
};
///end ADD_OCMATH_T_TEST_ONE_SAMPLE

///Arvin 2006-8-08 QA70-8419 LLVC_XY_REMOVE_DUPLICATES	
//Method in removing the duplicates, where 0 means replace with mean, 1=median, 2=min, 3=max, 4=sum
enum {
	Replace_With_Mean,
	Replace_With_Median,
	Replace_With_Min,
	Replace_With_Max,
	Replace_With_Sum
};
///END LLVC_XY_REMOVE_DUPLICATES

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//				Basic functions: sum, average, mean, SD, variance, min, max, round   									
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_sum_(global_function)
*/
OCMATH_API double ocmath_d_sum(double* pData, uint nSize, double* pmin = NULL, double* pmax = NULL, uint* pnmin =NULL, uint* pnmax =NULL, uint* pnCount = NULL);
OCMATH_API double ocmath_f_sum(float* pData, uint nSize, float* pmin = NULL, float* pmax = NULL, uint* pnmin =NULL, uint* pnmax =NULL);
OCMATH_API double ocmath_ui_sum(uint* pData, uint nSize, uint* pmin = NULL,	uint* pmax = NULL, uint* pnmin =NULL, uint* pnmax =NULL);
OCMATH_API double ocmath_us_sum(USHORT* pData,	uint nSize, USHORT* pmin = NULL, USHORT* pmax = NULL, uint* pnmin =NULL, uint* pnmax =NULL);
OCMATH_API double ocmath_b_sum(	BYTE* pData, uint nSize, BYTE* pmin = NULL,	BYTE* pmax = NULL, uint* pnmin =NULL, uint* pnmax =NULL);


//---- CPY 12/7/06 DATA_MAT_TO_IMAGE_CONVERT
enum {
	LNTR_NO_ROUND_NEAREST_INT	= 0x0001,
	LNTR_NO_FLOOR				= 0x0002,
	LNTR_NO_CEILING				= 0x0004,
};
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_linear_transform_(global_function)
*/
OCMATH_API int ocmath_linear_transform(double* pData, uint i1, uint i2, int nMin, int nMax, double dMin = __NANUM, double dMax = __NANUM, DWORD dwCntrl = 0);
//----
 
///Arvin 2006-3-23 LLVC_CUMULATIVE_SUM
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_us_cumulative_sum_(global_function)
*/
OCMATH_API uint ocmath_us_cumulative_sum(const USHORT* pData, uint i1, uint i2, USHORT* pCumSum, const USHORT* pMissing = NULL);

// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_i_cumulative_sum_(global_function)
*/
//Arvin 04/14/08 QA70-8752-P18 ADD_MISSING_VALUE_ARGUMENT
//OCMATH_API uint ocmath_i_cumulative_sum(const int* pData, uint i1, uint i2, int* pCumSum);
//OCMATH_API uint ocmath_d_cumulative_sum(const double* pData, uint i1, uint i2, double* pCumSum);
OCMATH_API uint ocmath_i_cumulative_sum(const int* pData, uint i1, uint i2, int* pCumSum, const int* pMissing = NULL);
OCMATH_API uint ocmath_d_cumulative_sum(const double* pData, uint i1, uint i2, double* pCumSum, const double* pMissing = NULL);
///end ADD_MISSING_VALUE_ARGUMENT
OCMATH_API uint ocmath_b_cumulative_sum(const BYTE* pData, uint i1, uint i2, BYTE* pCumSum, const BYTE* pMissing = NULL);
OCMATH_API uint ocmath_f_cumulative_sum(const float* pData, uint i1, uint i2, float* pCumSum, const float* pMissing = NULL);
///end LLVC_CUMULATIVE_SUM

//OCMATH_API double ocmath_angle_diff(double dx1, double dy1, double dx2, double dy2, BOOL bCvtDeg = false);

//Comment last updated by Joseph on 07/26/2007
//Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_running_ave_circular_(global_function)
*/
OCMATH_API int ocmath_d_running_ave_circular(const double* pX, uint nSize, uint nSegmentSize, double* pMeans, double* pSDs, uint nInc = 1);

// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_mean_variance_(global_function)
*/
OCMATH_API double ocmath_d_mean_variance(const double* pData, UINT nSize, double *prVariance, UINT* pnActualSampleSize = NULL);
OCMATH_API double ocmath_f_mean_variance(const float* pData, UINT nSize, double *prVariance, UINT* pnActualSampleSize = NULL, const float *pNAN = NULL);
OCMATH_API double ocmath_us_mean_variance(const USHORT* pData, UINT nSize, double *prVariance, UINT* pnActualSampleSize = NULL, const USHORT *pNAN = NULL);
OCMATH_API double ocmath_b_mean_variance(const BYTE* pData, UINT nSize, double *prVariance, UINT* pnActualSampleSize = NULL, const BYTE *pNAN = NULL);

//--------

// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_minmax_(global_function)
*/
OCMATH_API uint ocmath_d_minmax(const double* pData, uint i1, uint i2, uint* pnmin = NULL, uint* pnmax = NULL);

//Comment last updated by Cloud on 04/03/2008
//Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_f_minmax_(global_function)
*/
OCMATH_API uint ocmath_f_minmax(const float* pData, uint i1, uint i2, const float* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_i_minmax(const int* pData, uint i1, uint i2, const int* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_b_minmax(const BYTE* pData, uint i1, uint i2, const BYTE* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_us_minmax(const USHORT* pData, uint i1, uint i2, const USHORT* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);

///Kyle 08/03/2010 ORG-693-P2 WRONG_Z1_Z2_ON_SWITCH_DATA_TYPE_TO_LONG_ETC
OCMATH_API uint ocmath_s_minmax(const SHORT* pData, uint i1, uint i2, const SHORT* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_c_minmax(const char* pData, uint i1, uint i2, const char* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
///End WRONG_Z1_Z2_ON_SWITCH_DATA_TYPE_TO_LONG_ETC


// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_minmax_in_range_(global_function)
*/
OCMATH_API uint ocmath_d_minmax_in_range(const double* pData, int nCount, double dRangeMin, double dRangeMax, const double* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_f_minmax_in_range(const float* pData, int nCount, double dRangeMin, double dRangeMax, const float* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_i_minmax_in_range(const int* pData, int nCount, double dRangeMin, double dRangeMax, const int* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_b_minmax_in_range(const BYTE* pData, int nCount, double dRangeMin, double dRangeMax, const BYTE* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);
OCMATH_API uint ocmath_us_minmax_in_range(const USHORT* pData, int nCount, double dRangeMin, double dRangeMax, const USHORT* pMissing, uint* pnmin = NULL, uint* pnmax = NULL);

// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_z_minmax_(global_function)
*/
OCMATH_API uint ocmath_z_minmax(const d_complex* pData, uint i1, uint i2, uint* pnmin = NULL, uint* pnmax = NULL);

// Comments last updated by Arvin 2006-5-12
/**#
	Remarks:
		If nn < 0, return the internal value; else return 0
	Example1:
		void ocmath_internal_ex1(int nn)
		{
			DWORD ret = ocmath_internal(nn);
		}

	Parameters:
		nn = nn < 0 to get, 0 , 1 to set
	Return:
		If nn < 0, return the internal value; else return 0;
*/
OCMATH_API DWORD ocmath_internal(int nn);  // CPY 5/30/05 nn < 0 to set, 0 , 1 to set , but we don't want to give the specific name

// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_round_range_(global_function)
*/
OCMATH_API int ocmath_round_range(double* pMin, double* pMax, double* pInc, int nSteps = 8);

///Leo 2006-3-27 LLVC_ROUND_WITH_TOLERANCE	
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_round_with_tolerance_(global_function)
*/
OCMATH_API int ocmath_round_with_tolerance(int nSize, double* pData, double dTol);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//			Space(polygon) Functions: 	polygon diagonal distances, parallel increment, polygon area, polyline curvatures  								
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// Cloud 09/29/2007 TRIM_COLINEAR_POINTS_FROM_POLYGON
/**# >Mathematics>Geometry
*/ 
OCMATH_API int ocmath_trim_colinear_points_from_polygon(uint* pnSize, const double* pX, double* pY);
/// End TRIM_COLINEAR_POINTS_FROM_POLYGON

///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API BOOL ocmath_polygon_diagonal_distances(const float* pX, const float* pY,	uint nSize, double* pDist, uint nDistSize, int nOffset = 0);
// Category last updated by Cloud on 05/16/2008
/**# >Mathematics>Geometry
	Remarks:
		calculate polygon diagonal distances. Find the two end points of every diagonals that are the exact opposites of each other,
		and then calculate distance between the two points.
		This function can be used to estimate the roundness of a polygon be examining the ratio between the min max of these distances.
	Keywords:
		
	Example1:
		void ocmath_polygon_diagonal_distances_ex1()
		{
			vector<float> vx = {0,2,2,1.5,1,0};
			vector<float> vy = {0,0,2,4,6,5};
			uint nSize = vx.GetSize();
			uint nDistSize = nSize;
			vector vDist;
			vDist.SetSize(nDistSize);
			int nOffset = 0;
			int nRet = ocmath_polygon_diagonal_distances(vx, vy, nSize, vDist, nDistSize, nOffset);
			if( nRet != OE_NOERROR)
				printf(" Error!")
		}	
	Parameters:
		pX = [input] buffer containing X data of polygon vertexes
		pY = [input] buffer containing Y data of polygon vertexes
		nSize = [input] size of pX, pY
		pDist = [output] buffer containing distances
		nDistSize = [input] size of pDist
		nOffset = [input] offset 
	Return:
		Return OE_NOERROR if succeed, otherwise, OE_SIZE_LT is returned.
	SeeAlso:
		ocmath_polygon_diagonal_distances_parallel_increment
*/
OCMATH_API int ocmath_polygon_diagonal_distances(const float* pX, const float* pY,	uint nSize, double* pDist, uint nDistSize, int nOffset = 0);

///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API BOOL ocmath_polygon_diagonal_distances_parallel_increment(const float* pX, const float* pY,	uint nSize, UINT nStartIndex, double* pDist, uint nDistSize, int nOffsetLeft = 3, int nOffset = 0);
// Category last updated by Cloud on 05/16/2008
/**# >Mathematics>Geometry
	Remarks:
		from nStartIndex, goes back -nOffsetLeft and +nOffsetRight and calculate each distances by moving the opposite points in reverse direction, so the 
		begin and end points in distance calculation will move in parallel, this will provide estimate on the sides of polygon to be parallel or not
		nOffsetRight is determined by nDistSize 
	Keywords:
		
	Example1:
		void ocmath_polygon_diagonal_distances_parallel_increment_ex1()
		{
			vector<float> vx = {0,2,2,1.5,1,0};
			vector<float> vy = {0,0,2,4,6,5};
			uint nSize = vx.GetSize();
			uint nDistSize = nSize;
			vector vDist;
			vDist.SetSize(nDistSize);
			int nStartIndex = 0;
			int noffsetLeft = 3;
			int nOffset = 0;
			int nRet = ocmath_polygon_diagonal_distances_parallel_increment(vx, vy, nSize, nStartIndex, vDist, nDistSize, noffsetLeft, nOffset);
			if( nRet != OE_NOERROR)
				printf(" Error!")
		}	
	Parameters:
		pX = [input] buffer containing X data of polygon vertexes
		pY = [input] buffer containing Y data of polygon vertexes
		nSize = [input] size of pX, pY
		nStartIndex = [input] start point index
		pDist = [output] buffer containing distances
		nDistSize = [input] size of pDist
		noffsetLeft = [input] left offset, initial value is 3
		nOffset = [input] offset, initial value is 0 
	Return:
		Return OE_NOERROR if succeed, otherwise, OE_SIZE_LT is returned.
	SeeAlso:
		ocmath_polygon_diagonal_distances
*/
OCMATH_API int ocmath_polygon_diagonal_distances_parallel_increment(const float* pX, const float* pY, uint nSize, UINT nStartIndex, double* pDist, uint nDistSize, int nOffsetLeft = 3, int nOffset = 0);

///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API BOOL ocmath_polyline_curvatures(const float* pX, const float* pY, double*pCuv, uint nSize, int nRange = 2, BOOL bAbs = false, BOOL bCircular =true);
// Category last updated by Cloud on 05/16/2008
/**# >Mathematics>Geometry
	Remarks:
		Calculate polyline curvatures on every point (pX[ii], pY[ii]). For every point (pX[ii], pY[ii]),
		calculate the curvature between (pX[ii-nRange], pY[ii-nRange]) and (pX[ii+nRange], pY[ii+nRange]).
		if bCircular is false, the polyline is not circular,and fill missing values on both ends.
	Keywords:
		
	Example1:
		void ocmath_polyline_curvatures_ex1()
		{
			vector<float> vx = {0,1,2,2,1.5,1,0};
			vector<float> vy = {0,-2,0,2,4,6,5};
			uint nSize = vx.GetSize();
			vector vCuv;
			vCuv.SetSize(nSize);
			int nRange = 2;
			BOOL bAbs = false;
			BOOL bCircular =true;
			int nRet = ocmath_polyline_curvatures(vx, vy, vCuv, nSize, nRange, bAbs, bCircular);
			if( nRet != OE_NOERROR)
				printf(" Error!")
		}	
	Parameters:
		pX = [input] buffer containing X data 
		pY = [input] buffer containing Y data 
		pCuv = [output] buffer containing polyline curvatures
		nSize = [input] size of pX, pY, pCuv
		nRange = [input] range 
		bAbs = [input] true, calculate the abs of polyline curvatures
		               false, calculate polyline curvatures
					   initial value is false
		bCircular = [input] true or false, initial value is true
							true, is circular; false, is not circular.
	Return:
		Return OE_NOERROR if succeed, otherwise, OE_SIZE_LT is returned.
	SeeAlso:
*/
OCMATH_API int ocmath_polyline_curvatures(const float* pX, const float* pY, double*pCuv, uint nSize, int nRange = 2, BOOL bAbs = false, BOOL bCircular =true);

//OCMATH_API int ocmath_check_smoothed_segment(const double* pX, uint nSize, uint nSegmentSize, double dSignificance, double dTestVal = 0, uint nMovingStepSize = 1, uint* pnActualSegmSize = NULL);

// Category last updated by Cloud on 05/16/2008
/**# >Mathematics>Geometry
	Remarks:
		In this function, divide the polygon into trapezias by both ends of polygon's borders,
		then for every trapezia, calculate its area by (y1+y2)*(x2-x1)/2.
		Data types supported
		double:			ocmath_d_polygon_area
		float: 			ocmath_f_polygon_area
		POINT:			ocmath_l_polygon_area
	Keywords:
		
	Example1:
		void ocmath_f_mean_variance_ex1()
		{
			Worksheet wks = Project.ActiveLayer();
			wks.SetSize(-1,2);
			DataRange dr;
			dr.Add("X", wks, 0, 0, -1, 0);
			dr.Add("Y", wks, 0, 1, -1, 1);
			
			vector vxData, vyData;
			DWORD dwPlotID;
	        if(dr.GetData(DRR_GET_MISSING | DRR_GET_DEPENDENT | DRR_NO_FACTORS, 0, &dwPlotID, NULL, &vyData, &vxData) < 0)
	        {
	        		printf("get data failed!");
	        		return;
	        }
	        
			uint nSize = vxData.GetSize();
			double  area = ocmath_d_polygon_area(vxData, vyData, nSize);
		}
	Parameters:
		pX = [input] buffer containing X data of polygon vertexes
		pY = [input] buffer containing Y data of polygon vertexes
		nSize = [input] size of pX, pY
	Return:
		polygon area
	SeeAlso:
		ocmath_f_polygon_area, ocmath_l_polygon_area
*/
OCMATH_API double ocmath_d_polygon_area(double* pX, double* pY, uint nSize);
OCMATH_API float ocmath_f_polygon_area(float* pX, float* pY, uint nSize);

/// RVD 10/18/2004 QA70-6954 v8.0146 TRI_CONTOUR_PLOT
// Category last updated by Cloud on 05/16/2008
 /**# >Mathematics>Geometry
	Remarks:
		calculate polygon area for type POINT. In this function,
		divide the polygon into trapezias by both ends of polygon's borders,
		then for every trapezia, calculate its area by (y1+y2)*(x2-x1)/2.
	Keywords:
		
	Example1:
		void ocmath_l_polygon_area_ex1()
		{
		    POINT	poly[10];
			poly[0].x = 0;
			poly[0].y = 0;
			poly[1].x = 0;
			poly[1].y = 4; // Test if A, B, C, D and E are in the polygon
			poly[2].x = 6; // 5 ________E___
			poly[2].y = 4; // 4 | ______    |
			poly[3].x = 6; // 3 | |     | B |
			poly[3].y = 1; // 2 | | A   |   |
			poly[4].x = 4; // 1 | |___  |___|
			poly[4].y = 1; // 0 | C D    
			poly[5].x = 4; //   0 1 2 3 4 5 6
			poly[5].y = 3; // The closing virtual segment passes between C and D
			poly[6].x = 1;
			poly[6].y = 3;
			poly[7].x = 1;
			poly[7].y = 1;
			poly[8].x = 3;
			poly[8].y = 1;
			poly[9].x = 3; // Do not need to duplicate first point to close the polygon
			poly[9].y = 0; // Closure is assumed to be the virtual segment from here to poly[0]
			uint nSize = 10;
			double  area = ocmath_l_polygon_area(poly, nSize);
		}	
	Parameters:
		pts = [input] buffer containing points
		nSize = [input] size of pX, pY
	Return:
		polygon area
	SeeAlso:
		ocmath_f_polygon_area, ocmath_d_polygon_area
*/
OCMATH_API LONG ocmath_l_polygon_area(const POINT* pts, UINT nSize);
/// end TRI_CONTOUR_PLOT

// Comments last updated by Iris on 07/18/2008, added # to exclude this function from help since result is not correct
/**# >Mathematics>Geometry
	Remarks:
		Test if a given point (x,y) is inside a polygon defined by the given array of points
	Keywords:
		
	Example1:
		// Create a polygon and test five points for inclusion within the polygon
		void	ocmath_f_point_in_polygon_ex1()
		{
			// The points
			FLOATPT		pTest1, pTest2, pTest3, pTest4, pTest5;
			pTest1.x = 2; // Outside
			pTest1.y = 2;
			pTest2.x = 5; // Inside
			pTest2.y = 3;
			pTest3.x = 1; // Inside
			pTest3.y = 1;
			pTest4.x = 2; // Outside
			pTest4.y = 1;
			pTest5.x = 4; // On a line segment, therefore NOT within the polygon
			pTest5.y = 4;
			// The polygon
			FLOATPT	poly[10];
			poly[0].x = 0;
			poly[0].y = 0;
			poly[1].x = 0;
			poly[1].y = 4; // Test if A, B, C, D and E are in the polygon
			poly[2].x = 6; // 5 ________E___
			poly[2].y = 4; // 4 | ______    |
			poly[3].x = 6; // 3 | |     | B |
			poly[3].y = 1; // 2 | | A   |   |
			poly[4].x = 4; // 1 | |___  |___|
			poly[4].y = 1; // 0 | C D    
			poly[5].x = 4; //   0 1 2 3 4 5 6
			poly[5].y = 3; // The closing virtual segment passes between C and D
			poly[6].x = 1;
			poly[6].y = 3;
			poly[7].x = 1;
			poly[7].y = 1;
			poly[8].x = 3;
			poly[8].y = 1;
			poly[9].x = 3; // Do not need to duplicate first point to close the polygon
			poly[9].y = 0; // Closure is assumed to be the virtual segment from here to poly[0]
			// The limiting rectangle - optional, for speed purposes
			FLOATRECT	pRect;
			pRect.left = 0; // left and right are arbitrary in direction, the function works either way
			pRect.top = 0; // top and bottom are arbitrary in direction, the function works either way
			pRect.right = 6;
			pRect.bottom = 4;
			// This first point is outside the polygon
			BOOL bResult = ocmath_f_point_in_polygon(&pTest1, &poly, 10, &pRect);
			if( bResult )
				printf("Things fall apart; the centre cannot hold;\n");
			else
				printf("The point (%f,%f) is NOT within the polygon\n", pTest1.x, pTest1.y);
			// This point is in the polygon
			bResult = ocmath_f_point_in_polygon(&pTest2, &poly, 10, &pRect);
			if( bResult )
				printf("The point (%f,%f) IS within the polygon\n", pTest2.x, pTest2.y);
			else
				printf("Things fall apart; the centre cannot hold;\n");
			// This point is in the polygon (as determined by the virtual line segment closing the polygon)
			bResult = ocmath_f_point_in_polygon(&pTest3, &poly, 10, &pRect);
			if( bResult )
				printf("The point (%f,%f) IS within the polygon\n", pTest3.x, pTest3.y);
			else
				printf("Things fall apart; the centre cannot hold;\n");
			// This point is outside the polygon (as determined by the virtual line segment closing the polygon)
			bResult = ocmath_f_point_in_polygon(&pTest4, &poly, 10, &pRect);
			if( bResult )
				printf("Things fall apart; the centre cannot hold;\n");
			else
				printf("The point (%f,%f) is NOT within the polygon\n", pTest4.x, pTest4.y);
			// This point is on a line segment,
			bResult = ocmath_f_point_in_polygon(&pTest5, &poly, 10, &pRect);
			if( bResult )
				printf("The point (%f,%f) IS within the polygon\n", pTest5.x, pTest5.y);
			else
				printf("The point (%f,%f) is NOT within the polygon\n", pTest5.x, pTest5.y); // ON a segment is NOT WITHIN
		}
	Parameters:
		pcPt = [input] pointer to the point to be tested, must not be NULL
		lpcPts = [input] pointer to array of points to define the polygon
		nCount = [input] number of points in lpcPts
		lpcRectBound = [input] optional bounding rect which can speed up the search if provided, 
	Return:
		return OE_NOERROR if not error.
	SeeAlso:
		
*/
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API BOOL ocmath_f_point_in_polygon(const FLOATPT* pcPt, const FLOATPT* lpcPts, int nCount, FLOATRECT* lpcRectBound = NULL);
OCMATH_API int ocmath_f_point_in_polygon(const FLOATPT* pcPt, const FLOATPT* lpcPts, int nCount, FLOATRECT* lpcRectBound = NULL);

//OCMATH_API BOOL ocmath_f_intersect_rect(FRECT* lpIntersect, const FRECT* lpcr1, const FRECT* lpcr2);

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//			Filter Functions: sampling window, percentile filter, conserve filter, median filter	  								
//
/////////////////////////////////////////////////////////////////////////////////////////////////////

/// AW 01/20/04 QA70-5831 v7.0805 ADD_PERCENTILE_FILTER
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:get_sampling_window_offset_(global_function)
*/
OCMATH_API int get_sampling_window_offset(int* pOffset, int* pXOffSet, int* pYOffSet, int nCols, int nWinSizeX, int nWinSizeY, int nSampling= FILTERSHAPE_SQUARE);

// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_us_percentile_filter_(global_function)
*/
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API bool ocmath_us_percentile_filter(
OCMATH_API int ocmath_us_percentile_filter(
	USHORT* pData,
	int nRows,
	int nCols,
	double dPercent, 
	int nWinSizeX, 
	int nWinSizeY, 
	int nSampling = FILTERSHAPE_SQUARE, 
	double dThreshold = 0, 
	int nRowFrom = 0, int nColFrom = 0, 
	int nRowTo = -1, int nColTo = -1);

/// END ADD_PERCENTILE_FILTER


/// --- AW 01/30/04 QA70-5832 v7.0811 SUPPORT_CONSERVE_FILTER 

// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_us_conserve_filter_(global_function)
*/
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API bool ocmath_us_conserve_filter(
OCMATH_API int ocmath_us_conserve_filter(
	USHORT* pData,
	int nRows,
	int nCols,
	int nWinSizeX, 
	int nWinSizeY,
	int nSampling,
	double dThreshold,
	int nRowFrom,
	int nColFrom,
	int nRowTo,
	int nColTo);
/// --- END SUPPORT_CONSERVE_FILTER 

// Category last updated by Cloud on 04/02/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_median_filter_(global_function)
*/
OCMATH_API int ocmath_median_filter(const int nSize, const double* pIn, double* pOut,  const int nPts, const double dPercent = 50, int nPadding = EDGEPAD_ZERO, bool bAveraging = false);

/////////////////////////////////////////////////////////////////////////////////////
//
//				Calculus Functions: derivative, integrate  								
//
/////////////////////////////////////////////////////////////////////////////////////

//----- CPY 2/23/04 QA70-6035 v7.5825 CALCULUS_LLVC
//dwCntrl options
#define DERV_PEAK_AS_ZERO	0x0001
/// Cloud 05/18/2007 ADD_CONTROL_TO_OBTAIN_FORWARD_OR_BACKWARD_DERIVATIVE
#define DERV_FORWARD		0x0002
#define DERV_BACKWARD		0x0004
/// End ADD_CONTROL_TO_OBTAIN_FORWARD_OR_BACKWARD_DERIVATIVE
// Category last updated by Justin on 03/30/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_derivative_(global_function)
*/
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API bool ocmath_derivative(
/// Fisher 2008-11-7 QA80-12546 ADD_BACK_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL
// OCMATH_API int ocmath_derivative(
// 	const double* pXData,
// 	double* pYData,
// 	uint nSize,
// 	DWORD dwCntrl = 0);
///Kyle 01/21/2009 REMOVE_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL
// The correct smooth derivative should use ocmath_savitsky_golay_derivative(), Separate smooth is not needed in this function.
//OCMATH_API int ocmath_derivative(
//	const double* pXData,
//	double* pYData,
//	uint nSize,
//	DWORD dwCntrl = 0,
//	bool bSmooth = FALSE,
//	UINT nPts = 0,
//	UINT nPolydeg = 0
//	);
OCMATH_API int ocmath_derivative(
	const double* pXData,
	double* pYData,
	uint nSize,
	DWORD dwCntrl = 0
	);
///End REMOVE_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL
/// End ADD_BACK_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL
//#ifdef _OC_TYPES_H ///Iris 7/15/2008 INTEGRATE_NOT_IN_CHM_SO_COMMENT_OUT_THIS_MACRO

///Sandy 2009-2-27 FOUND_dyPeak_IS_HALF_HEIGHT_BUT_NOT_FULL_HEIGHT_FROM_BASE
///Arvin 2006-8-04 USE_STRUCT_OCMATH_INTEGRESULT
/* ocmath_IntegResult members:

    (xPeak, yPeak)____
          /\        | 
         /  \       | dyPeak
        /____\ _____|__
       /|    |\     
______/ |    | \____ 
     i1 |    | i2
     x1 |    | x2
        |    |
      idx1  idx2
        |----|
		dxPeak

*/

///Arvin 2006-9-28 ADD_INTEGRATION_FOR_DIFFERENT_AREA_TYPE
enum{
	MATHEMATICAL_AREA,
	ABSOLUTE_AREA,
};
///END ADD_INTEGRATION_FOR_DIFFERENT_AREA_TYPE

/// Fisher	1/24/2009	QA80-12999 OCMATH_INTEGRATE_COMPUTED_WRONG_VALUE_FOR_FWHM_WITH_MULTIPLE_PEAKS_DATA
enum{
	SEARCH_FROM_BOTH_ENDS = 0,
	SEARCH_FROM_PEAK = 1,
};
/// End OCMATH_INTEGRATE_COMPUTED_WRONG_VALUE_FOR_FWHM_WITH_MULTIPLE_PEAKS_DATA

//Comment last updated by Joseph on 07/26/2007
//Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_integrate_(global_function)
*/
///Arvin 03/19/07 IMPROVE_CALCULATION_CENTROID_METHOD
//OCMATH_API int ocmath_integrate(
//	const double* pXData,	//[in]
//	const double* pYData, //[in]
//	uint i1, uint i2,
//	ocmath_IntegResult* pInteg,
//	double* pIntegral = NULL, // out
//	int areaType = MATHEMATICAL_AREA);
OCMATH_API int ocmath_integrate(
	const double* pXData,	//[in]
	const double* pYData, //[in]
	uint i1, uint i2,
	IntegrationResult* pInteg,
	double* pIntegral = NULL, // out
	int areaType = MATHEMATICAL_AREA,
	const double* pBaseLine = NULL,
	bool bSortAscending = false,
	int nMethodSearchHalfWidth = SEARCH_FROM_BOTH_ENDS	/// Fisher	1/24/2009	QA80-12999 OCMATH_INTEGRATE_COMPUTED_WRONG_VALUE_FOR_FWHM_WITH_MULTIPLE_PEAKS_DATA
	);
///END 	IMPROVE_CALCULATION_CENTROID_METHOD
///end USE_STRUCT_OCMATH_INTEGRESULT

/// Leo 2006-3-20 LLVC_NUMERIC_INTEGRAL
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_numeric_integral_(global_function)
*/
OCMATH_API int ocmath_numeric_integral(double x, double* py, uint npts, const double *pxData, const double *pyData);
///end LLVC_NUMERIC_INTEGRAL

// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_2d_integrate_(global_function)
*/
OCMATH_API double ocmath_2d_integrate(const uint nRows, const uint nCols, const double dXMin, const double dYMin, const double dXMax, const double dYMax, const double* pMat);

//#endif //_OC_TYPES_H ///Iris 7/15/2008 INTEGRATE_NOT_IN_CHM_SO_COMMENT_OUT_THIS_MACRO
//----- end	CALCULUS_LLVC

/////////////////////////////////////////////////////////////////////////////////////
//
//				Smooth Functions: adjave smooth, savitsky golay  								
//
/////////////////////////////////////////////////////////////////////////////////////
// Comments last updated by Arvin on 2006-5-12
//--------- CPY 3/10/04 QA70-6077 v7.5836 BASIC_SMOOTHING_FUNCTIONS
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_adjave_smooth_(global_function)
*/
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API bool ocmath_adjave_smooth(
OCMATH_API int ocmath_adjave_smooth(
	const double* pYData, //[in]
	double* pYSmoothData, //[out]
	uint nSize,
	int nLeftRightPts,
/// Cloud 03/30/2007 QA80-9408 ADD_NO_PADDING_CASE_FOR_SMOOTH
//	int nOption = EDGEPAD_ZERO, bool bWeight = FALSE);
	int nOption = EDGEPAD_NONE, bool bWeight = FALSE);
/// End ADD_NO_PADDING_CASE_FOR_SMOOTH


// Category last updated by Cloud on 04/03/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_savitsky_golay_(global_function)
*/
//OCMATH_API bool ocmath_savitsky_golay(
OCMATH_API int ocmath_savitsky_golay(
	const double* pY,
	double* pYs,
	uint nSize,
	int nLeft,
	int nRight = -1,
	int nPolyDeg = 2,
	int nDervOrder = 0,
	int nPadding = EDGEPAD_EXTRAPOLATE);

enum {SMOOTH_ADJAVE, SMOOTH_SG, SMOOTH_MEDIAN_FILTER};
///Cheney 2006-08-15 LLVC_SMOOTH
// Category last updated by Cloud on 04/02/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_smooth_(global_function)
*/
OCMATH_API int ocmath_smooth(int nSize, const double* pY, double* pSmooth, int nLeftpts,
/// Cloud 03/30/2007 QA80-9408 ADD_NO_PADDING_CASE_FOR_SMOOTH
//							 int nMethod = SMOOTH_SG, int nBoundary = EDGEPAD_ZERO, int nRightpts = -1, 
							 int nMethod = SMOOTH_SG, int nBoundary = EDGEPAD_NONE, int nRightpts = -1, 
/// End ADD_NO_PADDING_CASE_FOR_SMOOTH
							 int nPolydeg = 2, int nDervOrder = 0, double dPercent = 50, bool bWeight = false, bool bAveraging = false);
///end LLVC_SMOOTH


//--------- end	 BASIC_SMOOTHING_FUNCTIONS

/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Matrix and solve linear system Functions: 
//								  norm, inverse, pseudoinverse, Singular-value decomposition 
//								  Gauss-Jordan elimination, QR decomposition,  LU factorization 								
//
/////////////////////////////////////////////////////////////////////////////////////////////

//Skip 04/19/04 v7.5860 ADD_OCMATH_NORM
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_norm_(global_function)
*/
OCMATH_API double ocmath_norm(double* pData, uint nSize);


// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_norm2_(global_function)
*/
OCMATH_API	double ocmath_norm2(double* pData, uint nRows, uint nCols, int np);
//End Skip 04/19/04 v7.5860 ADD_OCMATH_NORM

///Leo 2005-9-17 THIS_HAS_BEEN_IMPLEMENTED_IN_WKS2MAT_H
/////Jean 04/26/04 TPS
///**
//	Remarks:
//		
//	Keywords:
//		
//	Example1:
//		
//	Parameters:
//		px = [input] X value of source
//		py = [input] Y value of source
//		pz = [input] Z value of source
//		nSize = [input] size of source
//		minx = min range of x data, so we can grid the data 
//		maxx = max range of x data, so we can grid the data 
//		miny = min range of y data, so we can grid the data 
//		maxy = max range of y data, so we can grid the data 
//		pResultMat = [output]Result matrix
//		rows =	Result matrix row number
//		cols =	Result matrix col number
//	Return:
//		
//	SeeAlso:
//		
//*/
//OCMATH_API int ocmath_gridding_tps(
//	const double *px,
//	const double *py,
//	const double *pz,
//	uint nSize,
//	double minx,
//	double maxx,
//	double miny,
//	double maxy,
//	double *pResultMat,
//	int rows, int cols);
////end  Jean 04/26/04 TPS

///Leo 06/15/05 QA7715 QA6836 updated
//Forest 05/04/04 QA70-6322 ADD_MATRIX_INVERSE
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_inverse_(global_function)
*/
OCMATH_API int ocmath_inverse(double* pMatIO, int n);

// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_pinv_(global_function)
*/
OCMATH_API int ocmath_pinv(
	const double * pMatI,
	double *pPinv, 
	int m,
	int n,
	double dTol = -1);//pseudoinverse

// Comments last updated by Arvin on 2006-5-12
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_ex_svdcmp_(global_function)
*/
OCMATH_API int ocmath_ex_svdcmp(
	double **ppMat,
	int m,
	int n, 
	double *pW,
	double **ppV);//Singular-value decomposition

// Comments last updated by Arvin on 2006-6-26
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_svd_(global_function)
*/
OCMATH_API int ocmath_svd(int m, int n, double *pSource, double *pU, double *pS, double *pV);

// Comments last updated by Arvin on 2006-6-26
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_svd_complex_(global_function)
*/
OCMATH_API int ocmath_svd_complex(int m, int n, d_complex *pSource, d_complex *pU, double *pS, d_complex *pV);

// Comments last updated by Arvin on 2006-5-12
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_ex_svbksb_(global_function)
*/
OCMATH_API int ocmath_ex_svbksb(
	double **ppu,
	double *pw,
	double **ppv,
	int m,
	int n, 
	double *pb,
	double *px);

// Category last updated by Cloud on 05/16/2008
/** >Mathematics>Linear System
	Remarks:
		Gauss-Jordan elimination with (optional) RHS.
	Keywords:
		
	Example1:
		
	Parameters:
		ppLHS=[modify] On input, pointer to a square matrix in the standard
			   "pointer-to-rows" form (ppLHS points at n pointers to invididual rows of
				the matrix, each of size n). 
				On output, the matrix is replaced with its inverse.
		pRHS=[modify] If it is NULL, only the inversion should be
		     performed. Otherwise on input it points to an array of n values
			 representing the RHS of a linear system. 
			 On output, it should receive the solution of the linear system.
		n = size of the square matrix (number of rows equal to the number of columns).
	Return:
		Returns 0 if OK. 1 if it fails (like due to 0 pivoting - singular matrix).
	SeeAlso:
		
*/
//OCMATH_API int ocmath_gaussj3(double **ppLHS, double *pRHS, int n);
//End ADD_MATRIX_INVERSE

//Forest 05/06/04 QA70-4447 ADD_MATRIX_QR
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_qr_(global_function)
*/
OCMATH_API int ocmath_qr(const double* pMatI, double* pQ, double* pR, int rows, int cols);

//End ADD_MATRIX_QR

//Forest 05/25/04 QA70-6445 ADD_FUNCTIONS_REMOVED_FROM_NAG
// Category last updated by Cloud on 05/16/2008
/** >Analysis>Linear System
	Remarks:
		Calculate complex power of complex number
	Keywords:
		
	Example1:
		complex cBase = 1 + 1i, cPower = -1 - 2i, cResult;
		ocmath_cpow(&cBase, &cPower, &cResult);
		out_complex("Result is ",cResult);
	Parameters:
		pBase = pointer to base
		pPower = pointer to power
		pResult = pointer to result
	Return:
		Returns 0 on success, 1 on error.
		If base is 0, and power is 0, result is 1;
		If base is 0, and power is complex or positive double, result is 0;
		If base is 0, and power is negative double, returns 1(error, result is infinite).
	SeeAlso:
		
*/
//CPY 7/20/04, moved to ocUtils.dll
//OCMATH_API int ocmath_cpow(const d_complex* pBase, const d_complex* pPower, d_complex* pResult);

// Comments last updated by Joseph on 2007-9-12
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_lu_(global_function)
*/
OCMATH_API int ocmath_lu(double* pMatIO, long* pIpiv, int m, int n);

// Comments last updated by Joseph on 2007-07-26
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_lu_solve_(global_function)
*/
OCMATH_API int ocmath_lu_solve(double* pA, double* pB, long* pIpiv, int n, int nRhs = 1);

/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Data fitting funcitons: polynomial_fit, spline fit								 								
//
/////////////////////////////////////////////////////////////////////////////////////////////

// Category last updated by Joseph on 07/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_polynomial_(global_function)
*/
OCMATH_API bool ocmath_polynomial(const double* pX, double* pY, uint nSize, const double* pParas, int nOrder) ;

// Comments last updated by Arvin 2006-5-12
///Leo 05/18/05 OCMATH_POLYNOMIAL_FIT
///Leo 07/05/05 nCovCorrRow, nCovCorrCol are not necessary, deleted.
// Category last updated by Cloud on 03/27/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_polynomial_fit_(global_function)
*/
OCMATH_API int ocmath_polynomial_fit(
	int nSize,
	const double* pX,
	const double* pY,
	const double* pWeightIn,
	int nOrder,
	const LROptions* psLROptions,
	FitParameter* psFitParameter,
	int nSizeFitParams, 
	RegStats* psRegStats = NULL,
	RegANOVA* psRegANOVA = NULL,
	double* pCov = NULL,
	double* pCorr = NULL,
	double* pH = NULL);
///End OCMATH_POLYNOMIAL_FIT

/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Spline funcitons								 								
//
/////////////////////////////////////////////////////////////////////////////////////////////

//comments last updated by Arvin 06/19/06
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_1d_spline_fit_(global_function)
*/
//OCMATH_API int ocmath_1d_spline_fit(ocmath_Start start, int nPoints, const double* pX, const double* pY, const double* pWeights, double dSmoothingFactor, int nest, double *fp, ocmath_Comm *warmstartinf, ocmath_Spline *spline);
OCMATH_API int ocmath_1d_spline_fit(OCMATH_START start, int nPoints, const double* pX, const double* pY, const double* pWeights, double dSmoothingFactor, int nest, double *fp, ocmath_Comm *warmstartinf, ocmath_Spline *spline);

// comments last updated by Arvin on 06/19/06
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_1d_spline_evaluate_(global_function)
*/
OCMATH_API int ocmath_1d_spline_evaluate(double dX, double *pY, ocmath_Spline *spline); 

// comments last updated by Arvin on 06/19/06
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_1d_spline_deriv_(global_function)
*/
//OCMATH_API int ocmath_1d_spline_deriv(ocmath_DerivType derivs, double dX, double* pDeriv, ocmath_Spline *spline);
OCMATH_API int ocmath_1d_spline_deriv(OCMATH_DERIVTYPE derivs, double dX, double* pDeriv, ocmath_Spline *spline);

// comments last updated by Arvin 06/19/06
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_2d_spline_interpolant_(global_function)
*/
OCMATH_API int ocmath_2d_spline_interpolant(int nX, int nY, const double* pX, const double* pY, const double* pZ, ocmath_2dSpline *spline);

// comments last updated by Arvin on 06/19/06
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_2d_spline_eval_(global_function)
*/
OCMATH_API int ocmath_2d_spline_eval(int nEvalPoints ,const double *pX,const double *pY,double *pZ, ocmath_2dSpline *spline);
//End ADD_FUNCTIONS_REMOVED_FROM_NAG

// comments last updated by Arvin 06/19/06
///Leo 06/17/05 QA70-7817 OCMATH_2D_SPLINE_GRID
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_2d_spline_grid_(global_function)
*/
OCMATH_API int ocmath_2d_spline_grid(
	const uint nrSrc, 
	const uint ncSrc, 
	const double* pmatSrc,
	const uint nrDest,
	const uint ncDest,
	double* pmatDest,
	double dSmoothFactor = 0);
///End OCMATH_2D_SPLINE_GRID

// Comments last updated by Arvin on 2006-5-12
//Forest 06/17/04 QA70-6445 ADD_OCMATH_FREE
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_free_(global_function)
*/
OCMATH_API void ocmath_free(void* pvoid);
//End ADD_OCMATH_FREE

//------Arvin 2006-6-20 QA70-6445 ADD_FREE_SPLINE_STRUCT
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_free_spline_struct_(global_function)
*/
OCMATH_API void ocmath_free_spline_struct(ocmath_Spline *spline);
//------end ADD_FREE_SPLINE_STRUCT

//------Arvin 2006-6-20 QA70-6445 ADD_FREE_COMM_STRUCT
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_free_comm_struct_(global_function)
*/
OCMATH_API void ocmath_free_comm_struct(ocmath_Comm *warmstartinf);
//------end ADD_FREE_COMM_STRUCT

//------Arvin 2006-6-20 QA70-6445 ADD_FREE_2DSPLINE_STRUCT
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_free_2dSpline_struct_(global_function)
*/
OCMATH_API void ocmath_free_2dSpline_struct(ocmath_2dSpline* p2dSpline);
//------end ADD_FREE_2DSPLINE_STRUCT

///Soapy 03/23/05 MOVE_TO_WKS2MAT_H
// This following codes are moved to wks2mat.h
///Soapy  06/17/04  QA70-6421 COMBINE_MODIFIED_SHEPARD_AND_RENKACLINE
///*
//   This subroutine generates a two-dimensional surface interpolating 
//   a set of scattered data points, using either the method of Renka 
//   and Cline or a modification of Shepard's method.  
//
//Parameter:
//    METHOD: 
//		OC_2d_Scat_RC FOR RENKA AND CLINE'S METHOD, OR
//		OC_2d_Scat_Shep FOR MODIFIED SHEPARD'S METHOD
//
//	m = NUMBER OF NODES AND ASSOCIATED DATA VALUES. 
//	    m .GE. 6. WHEN METHOD = OC_2d_Scat_Shep OR  
//		m .GE. 3. WHEN METHOD = OC_2d_Scat_RC.  
//
// 	X,Y = ARRAYS OF LENGTH N CONTAINING THE CARTESIAN 
//	      COORDINATES OF THE NODES. 
//
// 	F = ARRAY OF LENGTH N CONTAINING THE DATA VALUES 
//	    IN ONE-TO-ONE CORRESPONDENCE WITH THE NODES. 
//
//
//	comm - OUTPUT, THE STRUCTURE CONTAINS THE RESULT AND THE OPTION
//	           OF THE INTERPOLATION. IT'S NEEDED FOR
//			   FUNCTION ocmath_2d_scat_eval() TO EVALUATE 
//			   PARTICULAR POINTS IN THE PLANE.
//	 
//	optional - INPUT, THE USER SPECIFIED OPTION, ONLY FOR THE MODIFIED SHEPARD'S
//	           METHOD.
//		optional->nq: the number of points involved in the calculation of
//		              the quadratic function.
//					  Constraint: 5 <= nq <= min(40, m-1)
//		optional->nq: the number of points involved in the calculation of
//		              the weight function.
//					  Constraint: 1 <= nw <= min(40, m-1)
//		When optional == NULL, the default value for nq and nw are:
//		    optional->nq = 13;
//			optional->nw = 19;		    
//Example:
//   void test_2d_scat_intp()
//	{
//	    double x[9] = { 0.,1.,1.,0.,.25,.5,.75,.5, 1. };
//		double y[9] = { 0.,0.,1.,1.,.5,.3,.5,.7 , 0.5};
//		double z[9] = { 0, 1, 2, 1, 0.5, 0.59, 1, 0.99, 1.25};
//		double px[5] = { .1,.3,.5,.7,.9 };
//		double py[5] = { .2,.4,.6,.8, .4 };
//		
//		int n = 9;
//
//		ocmath_2d_Scat_Method method = ocmath_2d_Scat_Shep;
//		ocmath_Scat_Opt optional;
//		ocmath_Scat_Struct comm;
//
//		optional.nq = 5;
//		optional.nw = 7;
//		
//		ocmath_2d_scat_interpolant(method, n, x, y, z,&comm, &optional);
//        
//		int m = 5;
//		double pf[5];
//	    ocmath_2d_scat_eval(&comm, m, px, py, pf);
//		for(int i=0; i<m; i++)
//			printf("%g\t%g\t%g\n\n", px[i], py[i], pf[i]);
//
//		ocmath_2d_scat_free(&comm);
//	}		
//		
//Return:
//	Err_Intp_No_Error: No error occur;
//	Err_Intp_Mem_Fail: Fails to allocate memory; 
//	Err_Intp_Method: Invalid input for interpolation method
//	Err_Intp_Invalid_Point: Not enough points or all points collinear
//	Err_Intp_Duplicate_Point: Duplicate points founded
//*/
//OCMATH_API int ocmath_2d_scat_interpolant(ocmath_2d_Scat_Method method, 
//                  int m, double* x,double* y,double* f, 
//				  ocmath_Scat_Struct *comm, ocmath_Scat_Opt *optional);	
//
///*   
//	THIS SUBROUTINE COMPUTES THE VALUE AT GIVEN POINTS
//
//PARAMETER:
//
// 	PX,PY = CARTESIAN COORDINATES OF THE POINTS AT WHICH 
//		Q ARE TO BE EVALUATED. 
//
// 	N = NUMBER OF NODES AND DATA VALUES DEFINING Q. 
// 	   
//	comm: THE STRUCTURE COMPUTED FROM ocmath_2d_scat_interpolant()
//
// 	PF = VALUE OF Q AT (PX,PY).
//
//Return:
//	Err_Intp_No_Error: No error occur;
//	Err_Intp_Mem_Fail: Fails to allocate memory; 
//	Err_Intp_Method: Invalid input for interpolation method
//	Err_Intp_Invalid_Point: Not enough points or all points collinear
//	Err_Intp_Duplicate_Point: Duplicate points founded
//
//See Also:
//	ocmath_2d_scat_interpolant
// */
//OCMATH_API int ocmath_2d_scat_eval(ocmath_Scat_Struct *comm,int n,double* px,double* py,double* pf);
//
///*
//	This function free the memory allocated by ocmath_2d_scat_interpolant().
//See Also:
//	ocmath_2d_scat_interpolant
//*/
//OCMATH_API int ocmath_2d_scat_free(ocmath_Scat_Struct *comm);
///END COMBINE_MODIFIED_SHEPARD_AND_RENKACLINE
/// END Soapy 03/23/05 MOVE_TO_WKS2MAT_H

/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Interpolation funcitons								 								
//
/////////////////////////////////////////////////////////////////////////////////////////////

///Comments last updated by Jack 2008-4-18
///Forest 08/12/04  QA70-6785 LLVC_FOR_INTERPOLATION
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_interpolate_(global_function)
*/
//------Arvin 2006-7-3	LLVC_OUTPUT_COEFFICIENTS_OF_INTERPOLATE	
/*
OCMATH_API int ocmath_interpolate(
	const double* pX,
	double *pY,
	UINT nSize,
	const double* pSrcX,
	const double *pSrcY,
	UINT nSrcSize,
	int nMode = INTERP_TYPE_LINEAR,
	double dSmoothingFactor = 0, 
	const double* pWeights = NULL);
*/
///Arvin 01/18/06 ADD_SORTING_FLAG
/*
OCMATH_API int ocmath_interpolate(
	const double* pX,
	double *pY,
	UINT nSize,
	const double* pSrcX,
	const double *pSrcY,
	UINT nSrcSize,
	int nMode = INTERP_TYPE_LINEAR,
	double dSmoothingFactor = 0, 
	const double* pWeights = NULL,
	double* pCof = NULL);	
*/
OCMATH_API int ocmath_interpolate(
	const double* pX,
	double *pY,
	UINT nSize,
	const double* pSrcX,
	const double *pSrcY,
	UINT nSrcSize,
	int nMode = INTERP_TYPE_LINEAR,
	//double dSmoothingFactor = 0, 
	double dSmoothingFactor = 1, ///Sandy 2008-3-18 MODIFY_DEFAULT_VALUE_SINCE_ZERO_MAKE_NO_DIFFERENCE_BETWEEN_BSPLINE_AND_SPLINE
	const double* pWeights = NULL,
	double* pCof = NULL,
	DWORD dwCntrl = 0,
///Jack 2008-4-18 ADD_BOUNDARY_CONDITION_TYPE_FOR_SPLINE  default use natural boundary condition for consistence with plotting spline
	int nSplBoundType = 0);	
///end ADD_SORTING_FLAG
///End LLVC_FOR_INTERPOLATION

OCMATH_API int ocmath_interp_trace_3d(
									  const double* pSrcX, const double *pSrcY, const double *pSrcZ, UINT nSrcSize, 
									  double* pX, double *pY, double *pZ, UINT nSize, 
									  int nMode = INTERP3D_TYPE_LINEAR);

/// Fisher 07/23/09	QA80-13994 OCMATH_FUNCTION_TO_SUPPORT_SAME_BSPLINE_AS_DRAWING_CODE
OCMATH_API int ocmath_simple_bspline(const double* pX, double *pY, UINT nSize, const double* pSrcX, const double *pSrcY, UINT nSrcSize, UINT nMaxInterpInterval = 30);
OCMATH_API int ocmath_simple_bspline_ex(double* pX, double *pY, UINT nSize, const double* pSrcX, const double *pSrcY, UINT nSrcSize);
/// End OCMATH_FUNCTION_TO_SUPPORT_SAME_BSPLINE_AS_DRAWING_CODE

//---- CPY 7/24/09 QA70-14007-P2 BSPLINE_FOR_ORIGIN_INTERNAL_USE_FOR_FASTER_LABTALK_CALL
/**$
*/
OCMATH_API int ocmath_bspline_prepare(LPVOID* ppNagbspline,
const double* pSrcX, const double *pSrcY, UINT nSrcSize, const double* pWeights=NULL, double dSmoothingFactor=1, DWORD dwCntrl=0);
/**$
*/
OCMATH_API void ocmath_bspline_cleanup(LPVOID* ppNagbspline);
/**$
*/
OCMATH_API int ocmath_bspline_evaluate(LPVOID pNagbspline, double xx, double* py);
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_sort_xy_(global_function)
*/
OCMATH_API void ocmath_sort_xy(double* pX, double* pY, UINT nSize, BOOL bAscending = true);
//-----

///Forest 02/03/05	QA70-7374 ADD_PARAMETRIC_INTERPOLATION
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_parametric_interpolate_range_(global_function)
*/
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API bool ocmath_parametric_interpolate_range(double* pT, const double* pData, UINT nDataSize, UINT nDimension = 2, int nMethod = PARA_INTERP_RANGE_EUGENE);
OCMATH_API int ocmath_parametric_interpolate_range(double* pT, const double* pData, UINT nDataSize, UINT nDimension = 2, int nMethod = PARA_INTERP_RANGE_EUGENE);

///Comments last updated by Arvin 2006-6-2
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_parametric_interpolate_eval_(global_function)
*/
OCMATH_API int ocmath_parametric_interpolate_eval(const double* pEvalT, double *pEvalData, UINT nEvalSize, const double* pT, const double* pData, UINT nDataSize, UINT nDimension = 2, int nMode = INTERP_TYPE_SPLINE, double dSmoothingFactor = 0, const double* pWeights = NULL);
///End ADD_PARAMETRIC_INTERPOLATION

// Comments last updated by Arvin 2006-5-12
// Category last updated by Cloud on 05/16/2008
///Echo 10/25/05 QA70-8099 ADD_3D_INTERPOLATE
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_3d_interpolate_(global_function)
*/
OCMATH_API int ocmath_3d_interpolate(
	const double* pX,
	const double* pY,
	const double* pZ,
	double *pQ,
	UINT nSize,
	const double* pSrcX,
	const double* pSrcY,
	const double* pSrcZ,
	const double* pSrcF,
	UINT nSrcSize);
///end ADD_3D_INTERPOLATE

/**$
*/
OCMATH_API int ocmath_2d_remove_missingvalue(double *pX, double *pY, double *pZ, UINT nRows, UINT nCols);
OCMATH_API int ocmath_1d_remove_missingvalue(double *pX, double *pY, UINT nSize, double dMissingValue = __NANUM, int *pIndices = NULL);		/// Fisher QA80-14626 2009/11/10 MISSING_VALUE_HANDLING_FOR_ROOT_FINDING_FUNC 

///Mouqx/Leo 2005-12-02 QA70-2063 LLVC_IMAGE_LINE_PROFILE
enum{
	INTERP2_NEAREST = 0,
	INTERP2_BILINEAR,
	INTERP2_BICUBIC,
	INTERP2_SPLINE,
	INTERP2_BIQUADRATIC   ///justin 08/26/2006 ADD_PARABOLA_INTERPOLATION
};

// Comments last updated by justin 2006-8-26
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_2d_interpolate_(global_function)
*/
OCMATH_API int ocmath_2d_interpolate(int nSize, double* pX, double* pY, double* pZ,
							UINT nRows, UINT nCols, double* pMat,
							double dxMin, double dxMax, double dyMin, double dyMax,
							int nMethod = INTERP2_NEAREST);
///End OCMATH_2D_INTERPOLATE
enum {
	PROJECTION_NONE = 0,
	PROJECTION_HOR,
	PROJECTION_VER
};
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_image_lines_profile_(global_function)
*/
OCMATH_API int ocmath_image_lines_profile(
	int nRows, int nCols, double* pMat,
	int nVertices, double* pxVertices, double* pyVertices,
	int nPoints,
	double* pxPoints,
	double* pyPoints,
	double* pIntensity,
	double* pError = NULL,
	int nWidth = 1,
	int iMethod = INTERP2_NEAREST,
	int iProjection = PROJECTION_NONE
);
///End LLVC_IMAGE_LINE_PROFILE


/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Bin funcitons: frequency count, find most, binning, bin width 								 								
//
/////////////////////////////////////////////////////////////////////////////////////////////

// commants update CPY 6/5/06, consolidate/remove other overloads, only document double
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_frequency_count_(global_function)
*/
OCMATH_API int ocmath_d_frequency_count(double* pSource, uint nSourceSize, uint* pDest, uint nDestSize, double dbBinBegin, double dbBinIncrement); // Frequency Count for type double
OCMATH_API int ocmath_f_frequency_count(float* pSource, UINT nSourceSize, UINT* pDest, UINT nDestSize, float dbBinBegin, float dbBinIncrement); // Frequency Count for type float
OCMATH_API int ocmath_us_frequency_count(USHORT* pSource, uint nSourceSize, uint* pDest, uint nDestSize, USHORT usBinBegin, USHORT usBinIncrement); // Frequency Count for type ushort
OCMATH_API int ocmath_b_frequency_count(BYTE* pSource, uint nSourceSize, uint* pDest, uint nDestSize, BYTE bBinBegin, BYTE bBinIncrement); // Frequency Count for type byte

// Comments last updated by Arvin on 2006-6-6 consolidate/remove other overloads, only document double
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_find_most_(global_function)
*/
OCMATH_API double ocmath_d_find_most(double* pData, uint nSize, uint nBins, double* pRatio = NULL);
OCMATH_API USHORT ocmath_us_find_most(USHORT* pData, uint nSize, uint nBins, double* pRatio = NULL);

///Kyle 03/11/2009 QA80-13251 ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET
enum{
	OCMATH_2D_BINNING_MIN,
	OCMATH_2D_BINNING_MAX,
	OCMATH_2D_BINNING_MEAN,
	OCMATH_2D_BINNING_SUM,
	OCMATH_2D_BINNING_MEDIAN,
	OCMATH_2D_BINNING_COUNT,		///Kyle 06/29/2010 ORG-209 REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN
	OCMATH_2D_BINNING_PERCENTAGES,
};
typedef struct
{ 
	int	  iMatSize;	//(input)actual size of pMatrix
	int    iSizeX;    // (output)X size of the result matrix
	int    iSizeY;    // (output)Y size of the result matrix
	///Kyle 06/29/2010 ORG-209 REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN
	double	dMinX;		// (output)
	double	dMaxX;		// (output)
	double	dMinY;		// (output)
	double	dMaxY;		// (output)
	///End REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN
	double*  pMatrix;   // (output)result matrix, with row number iSizeX, column number iSizeY, row-wise storage, caller should assign enough memory space for this array
}BinningStatsResult;

///Kyle 06/29/2010 ORG-209 REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN, remove from document
/**$
		Compute descriptive statistics for 2D binning on two arrays pX and pY.

	Remarks:
		This function does not output frequency count, it calculates multiple statistics quantities on each bin according to input variable nStats, for example, minimum, maximum, median etc.

	Paramaters:
		nSize = [input]size of the X and Y array
		pX = [input]pointer to buffer of the X array data
		pY = [input]pointer to buffer of the Y array data, it's also the quantity to communicate except OCMATH_2D_BINNING_COUNT and OCMATH_2D_BINNING_PERCENTAGES
		pResult = [output]pointer to result structure
		nStats = [input]One of the following:
			enum{
			    OCMATH_2D_BINNING_MIN,
			    OCMATH_2D_BINNING_MAX,
			    OCMATH_2D_BINNING_MEAN,
			    OCMATH_2D_BINNING_SUM,
			    OCMATH_2D_BINNING_MEDIAN,
			    OCMATH_2D_BINNING_COUNT,
			    OCMATH_2D_BINNING_PERCENTAGES,
			};
		pOptionX = [input]pointer to the structure of option for X array. If it is NULL(default), the optional parameters are given by the function.
		pOptionY = [input]pointer to the structure of option for Y array. If it is NULL(default), the optional parameters are given by the function.

	Return:
		Returns 0 on success. Otherwise returns error code:
		-1: Empty pointer or invalid value for nStats.
		BINNING_ERR_SIZE: nSize less than 1
		BINNING_ERR_RANGE: range is invalid(dMin > dMax)
		BINNING_ERR_INC: dInc <= 0 or dInc > dMax - dMin
		BINNING_ERR_FLAG: wIncludeOutliers is not defined in the enum
		BINNING_ERR_PERIOD: error period.
		BINNING_ERR_BUFFER_TOO_SMALL: size of pResult->pMatrix is less than needed
*/
OCMATH_API int    ocmath_2d_binning_stats(int nSize, const double *pX, const double *pY,
						 BinningStatsResult* pResult, int nStats,
						 BinningOption* pOptionX = NULL, BinningOption* pOptionY = NULL);
///End ADD_NEW_2D_STATS_AND_OUTPUT_TO_WORKSHEET

///Forest 10/19/04  QA70-7032 LLVC_FOR_2D_BINNING
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_2d_binning_(global_function)
*/
OCMATH_API int    ocmath_2d_binning(int nSize, const double *pX, const double *pY, BinningResult* pResult, BinningOption* pOptionX = NULL, BinningOption* pOptionY = NULL); 
///End LLVC_FOR_2D_BINNING

///Kyle 06/29/2010 ORG-209 REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN
/**
	Compute descriptive statistics for 2D binning on three arrays pX, pY and pQuantity.

	Remarks:
		It calculates multiple statistics quantities on each bin according to input variable nStats, for example, minimum, maximum, median etc.

	Paramaters:
		nSize = [input]size of the X and Y array
		pX = [input]pointer to buffer of the X array data
		pY = [input]pointer to buffer of the Y array data
		pQuantity = [input]pointer to buffer of the quantity to communicate, it can be NULL for nStats equals to OCMATH_2D_BINNING_COUNT or OCMATH_2D_BINNING_PERCENTAGES
		pResult = [output]pointer to result structure
		nStats = [input]One of the following:
			enum{
			    OCMATH_2D_BINNING_MIN,
			    OCMATH_2D_BINNING_MAX,
			    OCMATH_2D_BINNING_MEAN,
			    OCMATH_2D_BINNING_SUM,
			    OCMATH_2D_BINNING_MEDIAN,
			    OCMATH_2D_BINNING_COUNT,
			    OCMATH_2D_BINNING_PERCENTAGES,
			};
		pOptionX = [input]pointer to the structure of option for X array
		pOptionY = [input]pointer to the structure of option for Y array

	Return:
		Returns 0 on success. Otherwise returns error code:
		-1: Empty pointer or invalid value for nStats.
		BINNING_ERR_SIZE: nSize less than 1
		BINNING_ERR_RANGE: range is invalid(dMin > dMax)
		BINNING_ERR_INC: dInc <= 0 or dInc > dMax - dMin
		BINNING_ERR_FLAG: wIncludeOutliers is not defined in the enum
		BINNING_ERR_PERIOD: error period.
		BINNING_ERR_BUFFER_TOO_SMALL: size of pResult->pMatrix is less than needed
*/
OCMATH_API int    ocmath_2d_binning_ex(int nSize, const double *pX, const double *pY, const double *pQuantity,
						 BinningStatsResult* pResult, int nStats,
						 BinningOption* pOptionX = NULL, BinningOption* pOptionY = NULL);
///End REWRITE_2D_BINNING_AND_MAKE_IT_SUPPORT_ADDITIONAL_Y_COLUMN

///Comments last updated by Arvin on 2006-6-2
///Forest 01/18/04  QA70-7281 BIN_WIDTH_CALCULATION_RULE
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_bin_width_(global_function)
*/
OCMATH_API double ocmath_bin_width(const double* pSource, UINT nSourceSize, int nRule = BIN_RULE_FREEDMAN_DIACONIS, int nInterpolatePercentiles = INTERPOLATE_EDF); 
///End BIN_WIDTH_CALCULATION_RULE


/////////////////////////////////////////////////////////////////////////////////////////////////////
//
//		Vector manipulation funcitons: stretch, monotonic, copy, group, count with conditions, mean increment							 								
//
/////////////////////////////////////////////////////////////////////////////////////////////////////

//-------- CPY 7/10/04 CONTOUR_SHAPE_BASIC_CHARACTERISTICS
// Comments last updated by Arvin on 2006-6-6 consolidate/remove other overloads, only document double
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_stretch_(global_function)
*/
///Mouqx/Leo 2005-9-26 QA70-8110 TO_CENTRALIZE_ERROR_CODES_IN_OCMATH
//OCMATH_API BOOL ocmath_d_stretch(double* pX, uint nSize, double low1, double high1, double low2, double high2);
OCMATH_API int ocmath_d_stretch(double* pX, uint nSize, double low1, double high1, double low2, double high2);
OCMATH_API int ocmath_us_stretch(USHORT* pX, uint nSize, USHORT low1, USHORT high1, USHORT low2, USHORT high2);
OCMATH_API int ocmath_f_stretch(float* pX, uint nSize, float low1, float high1, float low2, float high2);

///Comments last updated by Arvin 2006-6-2
///Forest 03/11/05 QA70-7491 LLVC_IS_VECTOR_MONOTONIC
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_is_monotonic_(global_function)
*/
OCMATH_API int ocmath_is_monotonic(const double* pX, uint nSize, bool bIsStrict = true);
///End LLVC_IS_VECTOR_MONOTONIC

/// Comments last updated by Arvin on 2006-6-6
/// SY 03/17/2006 QA70-7813 IMPORT_NETCDF_INTO_ORIGIN
// return 1 if data monotonic increasing with consistent increment (per nTol = 0)
// return -1 of same but decreasing
// return 0 if not monotonic at all, returns 2 or -2 if monotonic but not consistent increment 
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_i_get_vector_inc_(global_function)
*/
OCMATH_API int ocmath_i_get_vector_inc(UINT nPoints, const int* pData, int nTol, int* pBegin, int* pEnd, int* pInc);
OCMATH_API int ocmath_d_get_vector_inc(UINT nPoints, const double* pData, double dTol, double* pBegin, double* pEnd, double* pInc);
/// end IMPORT_NETCDF_INTO_ORIGIN


///Soapy 05/14/05 QA7697 SEPERATE_XY_IN_GROUP_BY_X
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_group_xy_by_x_(global_function)
*/
///Kevin 11/29/05 CHANGE_OCMATH_FUNCTION_TO_LOWER_CASE
//OCMATH_API int ocmath_group_XY_by_X(int nPts, double* pX, double* pY, int nPtCntrl, double* pXCntrl, int* pGrpEnd);
OCMATH_API int ocmath_group_xy_by_x(int nPts, double* pX, double* pY, int nPtCntrl, double* pXCntrl, int* pGrpEnd);
///End CHANGE_OCMATH_FUNCTION_TO_LOWER_CASE
///END SEPERATE_XY_IN_GROUP_BY_X

///Comments last updated by Arvin on 2006-6-6
///Leo 05/31/05 OCMATH_DATATYPE_COPY
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_d_copy_(global_function)
*/
///Kyle 11/12/2008 QA80-12578 NEED_TO_HANDLE_SIZE_OF_THE_SOURCE_VECTOR
//OCMATH_API void ocmath_d_copy(uint nPts, const uint* pIndices, double* pDestX, const double* pSrcX); // Copy a vector of type double with given array of indices.
//OCMATH_API void ocmath_f_copy(uint nPts, const uint* pIndices, float* pDestX, const float* pSrcX); // Copy a vector of type float with given array of indices.
//OCMATH_API void ocmath_ui_copy(uint nPts, const uint* pIndices, UINT* pDestX, const UINT* pSrcX); // Copy a vector of type UINT with given array of indices.
//OCMATH_API void ocmath_us_copy(uint nPts, const uint* pIndices, USHORT* pDestX, const USHORT* pSrcX); // Copy a vector of type USHORT with given array of indices.
//OCMATH_API void ocmath_b_copy(uint nPts, const uint* pIndices, BYTE* pDestX, const BYTE* pSrcX); // Copy a vector of type BYTE with given array of indices.
OCMATH_API void ocmath_d_copy(uint nPts, const uint* pIndices, double* pDestX, const double* pSrcX, int nSrcSize); // Copy a vector of type double with given array of indices.
OCMATH_API void ocmath_f_copy(uint nPts, const uint* pIndices, float* pDestX, const float* pSrcX, int nSrcSize); // Copy a vector of type float with given array of indices.
OCMATH_API void ocmath_ui_copy(uint nPts, const uint* pIndices, UINT* pDestX, const UINT* pSrcX, int nSrcSize); // Copy a vector of type UINT with given array of indices.
OCMATH_API void ocmath_us_copy(uint nPts, const uint* pIndices, USHORT* pDestX, const USHORT* pSrcX, int nSrcSize); // Copy a vector of type USHORT with given array of indices.
OCMATH_API void ocmath_b_copy(uint nPts, const uint* pIndices, BYTE* pDestX, const BYTE* pSrcX, int nSrcSize); // Copy a vector of type BYTE with given array of indices.
///End NEED_TO_HANDLE_SIZE_OF_THE_SOURCE_VECTOR
///End OCMATH_DATATYPE_COPY

///Leo 2005-12-22 SUPERSEDED_BY_OCMATH_COUNT
///**
//	Remarks:
//		Count how many missing values (NANUM) there is in the input double array
//	Parameters:
//		nPts = [input] the size of input array.
//		pX = [input] input array
//	Return:
//		The function returns the number of missing values in the given array.
//*/
//OCMATH_API uint ocmath_count_missing_values(uint nPts, const double* pX);
///END SUPERSEDED_BY_OCMATH_COUNT

///Comments last updated by Arvin 2006-6-2
///Leo 2005-9-19 QA70-8103 ADD_OCMATH_COUNT
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_count_(global_function)
*/
OCMATH_API int ocmath_count(double dValue, uint nPts, const double* pIn, int nCondition = COUNT_EQUAL);
///End ADD_OCMATH_COUNT

///Cheney 2006-4-12 LLVC_MEAN_INCREMENT
// Comments last updated by Cheney on 2006-5-8
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_mean_increment_(global_function)
*/
OCMATH_API int ocmath_mean_increment(UINT nSize, const double* pData, double* pMeanInc, int nSegments = 1, double* pSD = NULL, int* pSegSize = NULL, UINT nPts = 0);

///Cheney 2006-8-24 ADD_FOR_INTERATION_IN_FIND_XS
typedef	bool (*PFN_STR_INT_DOUBLE_DOUBLE_DOUBLEP)(LPCSTR LpcszFuncFileName, int nParamsSize, double *pParams, double dX, double *pY);
///end ADD_FOR_INTERATION_IN_FIND_XS

///Cheney 2006-5-25 QA70-5831 LLVC_FIND_XS
///Comments last updated by Joseph on 2006-12-23
// Category last updated by Cloud on 05/16/2008
/**$ >Analysis>Mathematics
	Remarks:
		find nSize1 x values given y from pX, pY array, results in pX1, pXi get sequence number
		of x values found if fitting done. 
		if y and pY[jj] within specified tolerance dTol, corresponding pX[jj] is put into 
		pX1[ii], pXi[ii] = jj >= 0.
		if pY[jj] outside tolerance from y but pY[jj - 1] < y < pY[jj] or  pY[jj - 1] > y > pY[jj],
		so a interation is performed from pY[jj-1] to pY[jj] and put result into pX1[ii], pXi[ii] = -jj < 0.
		if y is out of curve bound, pX1 will be all NANUM and pXi will be all -nSize.
		if can only find num x values, num < nSize1, pX1[ii] = NANUM, pXi[ii] = -nSize, 
		which ii = num, num + 1, ...., nSize1 - 1.
	Keywords:
		find x
	Example1:
		//assume actived worksheet's 1st column is X data, 2nd column is Y data
		#include <...\originlab\nlsf_utils.h>
		#include <FDFTree.h> 

		void ocmath_find_xs_ex1()
		{
			double y = 5; //find x equal to 5 
			
			Worksheet wks = Project.ActiveLayer();
			if (!wks)
			{
				return;
			}

			//get data to fitting
			DataRange dr;
			dr.Add("X", wks, 0, 0, -1, 0);
			dr.Add("Y", wks, 0, 1, -1, 1);
			vector vDatax, vDatay;
			DWORD dwPlotID;
			if(dr.GetData(DRR_GET_DEPENDENT | DRR_NO_FACTORS, 0, &dwPlotID, NULL, &vDatay, &vDatax) < 0)
			{
				printf("failed to get data");
				return;
			}
			
			//set how many x should be finded
			uint nSize1 = 4;
			vector vFindx;
			vector<int> vFindxNum;
			vFindx.SetSize(nSize1);
			vFindxNum.SetSize(nSize1);
			

			vector vParams = {0, 0, 1}; //fitting function y = x^2
			
			//find _compute_y_by_x function in stats_operations.c
			string strFile = GetOriginPath() + "OriginC\\OriginLab\\nlsf_utils.c";
			PFN_STR_INT_DOUBLE_DOUBLE_DOUBLEP pFunc = Project.FindFunction("compute_y_by_x", strFile, true);
			string strFuncFileName = "POLY"; //fitting function is polynomial function
			
			int nRet = ocmath_find_xs(y, (uint)(vDatay.GetSize()), vDatax, vDatay, nSize1, vFindx, 
							strFuncFileName, vParams.GetSize(), vParams, pFunc, vFindxNum);
			
			//if wks's column number less than 4, expand it
			for( int ii = wks.GetNumCols(); ii < 4; ii = wks.GetNumCols() ) 
			{
				wks.AddCol();
			}
							
			//put result into worksheet's 3rd and 4th column
			DataRange drOut;
			drOut.Add("X", wks, 0, 2, -1, 2);
			drOut.Add("Y", wks, 0, 3, -1, 3);
			drOut.SetData(&vFindxNum, &vFindx);
		}
	Paramaters:
	    y = [input] given y values, then find relative x values.
		nSize = [input] size of pX and pY array.
		pX = [input] pointer to X value array.
		pY = [input] pointer to Y value array.
		nSize1 = [input] size of pX1 array.
		pX1 = [output] pointer to x values found.
		LpcszFuncFileName  = [input]fitting funtion's FDF file name.
		nParamsSize  = [input]size of pParams array.
		pParams  = [input]fitting funtion's Parameters list.
		pFunc = [input] Pointer to the function used to compute y from x 
		pXi = [output] if not NULL, pointer to sequence number of x values found, size should 
					   be nSize1. Its default value is NULL.
		dTol1 = [input] the tolerance of y values to check if y is out of bound, 
						if ymin - y > dTol1 or y - ymax > dTol1, y is out of bound.
						otherwise, if 0 < ymin - y <= dTol1, y will replace by ymin;
									if 0 < y - ymax <= dTol1, y will replace by ymax;
		dTol2 = [input] the tolerance for y values, if abs(y - y0) < dTol2, y and y0 can be 
					   thought to equal. Its default value is 1E-8
		nInteraStep = [input] interation's max step. Its default value is 1000
	Return:
		Return OE_NOERROR if succeed, otherwise, non-zero error code is returned.
*/
///Justin 2007-04-03 v8.0595 NO_NEED_TO_CHECK_X_PRECISIION_IF_INTERATION_IS_SUITABLE
/// 30 means the related precision is about 10E-9 (2E-30)
//OCMATH_API int ocmath_find_xs(double y, UINT nSize, const double* pX, const double* pY, UINT nSize1,
//							  double* pX1, LPCSTR LpcszFuncFileName, int nParamsSize, double* pParams, 
//							  PFN_STR_INT_DOUBLE_DOUBLE_DOUBLEP pFunc, int* pXi = NULL, double dTol1 = 1E-8, 
//							  double dTol2 = 1E-8, UINT nInteraStep = 1000);

OCMATH_API int ocmath_find_xs(double y, UINT nSize, const double* pX, const double* pY, UINT nSize1,
							  double* pX1, LPCSTR LpcszFuncFileName, int nParamsSize, double* pParams, 
							  PFN_STR_INT_DOUBLE_DOUBLE_DOUBLEP pFunc, int* pXi = NULL, double dTol1 = 1E-8, 
							  double dTol2 = 1E-8, UINT nInteraStep = 30);
///End NO_NEED_TO_CHECK_X_PRECISIION_IF_INTERATION_IS_SUITABLE
///end LLVC_FIND_XS

//------ CPY 5/28/06 FFT_SAMPLE_INTERVAL_MOVED_TO_OCMATH
// Category last updated by Cloud on 05/16/2008
//Comment last updated by Joseph 09/12/07
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_sampling_resolution_(global_function)
*/
OCMATH_API int ocmath_sampling_resolution(UINT nSize, const double *pData, double* pMeanInc, double dTol = 0.05);
//------ end FFT_SAMPLE_INTERVAL_MOVED_TO_OCMATH

/////////////////////////////////////////////////////////////////////////////////////////////////////
//
//		Basic statistic funcitons: correlation, T-test, row stats, row quantiles							 								
//
/////////////////////////////////////////////////////////////////////////////////////////////////////

// Comments last updated by Arvin 2006-5-12
///Soapy 07/30/05 QA75-7865 ADD_2D_SHIFT_CORRELATION
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:shift_2d_correlation_circular_(global_function)
*/
///Kevin 11/29/05 CHANGE_OCMATH_FUNCTION_TO_LOWER_CASE
//OCMATH_API int shift_correlation2D_circular(int iRows, int iCols, double *mSig1, double *mSig2, double *mCorrelation);
OCMATH_API int shift_2d_correlation_circular(int iRows, int iCols, double *mSig1, double *mSig2, double *mCorrelation);
///End CHANGE_OCMATH_FUNCTION_TO_LOWER_CASE

// Comments last updated by Arvin 2006-5-12
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:shift_2d_correlation_linear_(global_function)
*/
///Kevin 11/29/05 CHANGE_OCMATH_FUNCTION_TO_LOWER_CASE 
//OCMATH_API int shift_correlation2D_linear(int iRows, int iCols, double *mSig1, double *mSig2, double *mCorrelation);
OCMATH_API int shift_2d_correlation_linear(int iRows, int iCols, double *mSig1, double *mSig2, double *mCorrelation);
///End CHANGE_OCMATH_FUNCTION_TO_LOWER_CASE
///END ADD_2D_SHIFT_CORRELATION

///Echo 4/26/07 MOVED_TO_OCSTATS
///Cheney 2006-5-18  LLVC_ROW_DESC_STATS
//Comments last updated by Cheney on 2006-5-19
// Category last updated by Justin on 03/26/2007
/** >Statistics>Descriptive Statistics
	Remarks:
		get input matrix's each row's mean, standard deviation, se of mean, min, max, sum and 
		total number of data point and put result to relative pointer if the pointer not NULL.
	Keywords:
		row   descriptive statistic
	Example1:
		void ocmath_row_desc_stats_ex1()
		{
			vector vtemp = {1, 2, 3, 4, 5, 6};
			int nRows = 2;
			int nCols = 3;
			vector vMean(nRows);
			vector vSd(nRows);
			ocmath_row_desc_stats(nRows, nCols, vtemp, vMean, vSd);
		}
		// At the end of example: vMean = {2, 5}, vSd = {1, 1}.
	Paramaters:
	    nRows = [input] row number of input matrix.
		nCols = [input] column number of input matrix.
		pMat = [input] pointer to input matrix which will do descriptive statistic.
		pMean = [output] if not NULL, pointer to each row's mean value, its size should
						 be nRows. Its default value is NULL.
		pSd = [output] if not NULL, pointer to each row's standard deviation, its size should 
					   be nRows. Its default value is NULL.
		pSem = [output] if not NULL, pointer to each row's se of mean, its size should be 
						nRows. Its default value is NULL.
		pMin = [output] if not NULL, pointer to each row's min value, its size should be 
						nRows. Its default value is NULL.
		pMax = [output] if not NULL, pointer to each row's max value, its size should be 
						nRows. Its default value is NULL.
		pSum = [output] if not NULL, pointer to each row's sum, its size should be nRows. 
						Its default value is NULL.
		pN = [output] if not NULL, pointer to each row's total number of data point, its size
					  should be nRows. Its default value is NULL.
	Return:
		Return OE_NOERROR if succeed, otherwise, non-zero error code is returned.
	See also:
		ocmath_row_quantiles
*/
//OCMATH_API int ocmath_row_desc_stats(UINT nRows, UINT nCols, const double* pMat, double* pMean = NULL, double* pSd = NULL,  
									 //double* pSem = NULL, double* pMin = NULL, double* pMax = NULL, double* pSum = NULL, double* pN = NULL);

///Cheney 2006-5-19  LLVC_ROW_QUANTILES
//Comments last updated by Cheney on 2006-5-19
// Category last updated by Justin on 03/26/2007
/** >Statistics>Descriptive Statistics
	Remarks:
		get input matrix's each row's min, max, 1st Quartile, median and 3rd Quartile and
		put result to relative pointer if the pointer not NULL.
	Keywords:
		row   quantiles
	Example1:
		void ocmath_row_quantiles_ex1()
		{
			vector vtemp = {1, 2, 3, 4, 5, 6};
			int nRows = 2;
			int nCols = 3;
			vector vMin(nRows);
			vector vMax(nRows);
			vector vQ1(nRows);
			ocmath_row_quantiles(nRows, nCols, vtemp, vMin, vMax, vQ1);
		}
		// At the end of example: vMin = {1, 4}, vMax = {3, 6}, vQ1 = {1, 4}.
	Paramaters:
	    nRows = [input] row number of input matrix.
		nCols = [input] column number of input matrix.
		pMat = [input] pointer to input matrix which will be get quantiles.
		pMin = [output] if not NULL, pointer to each row's min value, its size should
						be nRows. Its default value is NULL.
		pMax = [output] if not NULL, pointer to each row's max value, its size should
						be nRows. Its default value is NULL.
		pQ1 = [output] if not NULL, pointer to each row's 1st Quartile, its size should
					   be nRows. Its default value is NULL.
		pMedian = [output] if not NULL, pointer to each row's miedian value, its size 
						   should be nRows. Its default value is NULL.
		pQ3 = [output] if not NULL, pointer to each row's 3rd Quartile, its size should
					   be nRows. Its default value is NULL.
	Return:
		Return OE_NOERROR if succeed, otherwise, non-zero error code is returned.
	See also:
		ocmath_row_desc_stats
	Reference:
		nag_5pt_summary_stats(g01alc), Nag Manual
*/
//OCMATH_API int ocmath_row_quantiles(UINT nRows, UINT nCols, const double* pMat, double* pMin = NULL,
									//double* pMax = NULL, double* pQ1 = NULL, double* pMedian = NULL, double* pQ3 = NULL);
///end LLVC_ROW_QUANTILES
///end MOVED_TO_OCSTATS

///Cheney 2006-5-29 LLVC_T_TEST_ONE_SAMPLE
///Comments last updated by Cheney on 2006-5-29
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_t_test_one_sample_(global_function)
*/
OCMATH_API int ocmath_t_test_one_sample(UINT nSize, double dMean, double dSD, double* pProb, 
										int nFlag, int* pDOF = NULL, double* pTValue = NULL,
										double dHypotValue = 0.0, int TailType = TAILED_TEST_TWO);

/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Curve Average funcitons								 								
//
///////////////////////////////////////////////////////////////////////////////////////////// 

///Forest 10/14/04	 QA70-6671 LLVC_FOR_AVERAGE_MULTIPLE_CURVES
///Leo 2006-1-19 REWRITE_AVERAGE_MULTIPLE_CURVES
///Roy 2006-3-03 REWRITE_AVERAGE_MULTIPLE_CURVES_ON_NOT_INTERP
///Comments last updated by Joseph on 2006-12-23
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_ave_multiple_curves_(global_function)
*/
//OCMATH_API int ocmath_ave_multiple_curves(const MultiCurves* pMultiCuv, double* pAveX, double *pAveY, uint nSize, double* pAveErr = NULL, int nErrType = AVMC_SD);
//OCMATH_API int ocmath_ave_multiple_curves(uint nSize, const OneCurveData* pCurves,
//	int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, int nErrType = AVMC_SE, bool bInterp = false, int nMethod = INTERP_TYPE_LINEAR);
/// Hong 11/11/09 QA80-6671-S1 AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
//OCMATH_API int ocmath_ave_multiple_curves(uint nSize, const OneCurveData* pCurves,
//	int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, int nErrType = AVMC_SE, bool bInterp = false, int nMethod = INTERP_TYPE_LINEAR,
//	double dTolerance=0.0, int* pAveCount=NULL);
OCMATH_API int ocmath_ave_multiple_curves(uint nSize, const OneCurveData* pCurves,
										  int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, int nErrType = AVMC_SE, bool bInterp = false, int nMethod = INTERP_TYPE_LINEAR,
	double dTolerance=0.0, int* pAveCount=NULL, double* pAveMin = NULL, double* pAveMax = NULL);
/// end AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
///End	LLVC_FOR_AVERAGE_MULTIPLE_CURVES

///Cheney 2006-4-12 LLVC_CURVE_LENGTH
// Comments last updated by Cheney on 2006-5-8
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_curve_length_(global_function)
*/
OCMATH_API int ocmath_curve_length(UINT nSize, const double* pX, const double* pY, double* pLen);

///Cheney 2006-4-12 LLVC_CUMULATIVE_CURVE_LENGTH
// Comments last updated by Cheney on 2006-5-8
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_cumulative_curve_length_(global_function)
*/
OCMATH_API int ocmath_cumulative_curve_length(UINT nSize, double* pCLen, const double* pX, const double* pY, int ntype = NOT_KEEP_STRICT_INCRECE);

/*OCMATH_API int ocmath_find_peaks_1st_derivative(UINT nSize, const double* pSrcX, const double* pSrcY, 
									 double* vxPeaks, double* vyPeaks,
							         int* vnIndices, int nDir, int nPtsSmooth);*/

///Cheney 2006-4-18 LLVC_AVE_MULTIPLE_CURVES_BY_LENGTH_PARAMETER
///Comments last updated by Joseph on 2006-12-23
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_ave_multiple_curves_by_length_parameter_(global_function)
*/
/// Fisher 3/10/09 QA80-13243 REWRITE_OCMATH_AVERAGE_MULTIPLE_CURVES
//OCMATH_API int ocmath_ave_multiple_curves_by_length_parameter(UINT nSize, const OneCurveData* pCurves,
//							int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, 
//							int nErrType = AVMC_SE, int* pAveCount = NULL);
/// Hong 11/11/09 QA80-6671-S1 AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
//OCMATH_API int ocmath_ave_multiple_curves_by_length_parameter(UINT nSize, const OneCurveData* pCurves,
//							int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, 
//							int nErrType = AVMC_SE, int* pAveCount = NULL, int nMethod = INTERP_TYPE_LINEAR);

/// Gareth 8/12/2010 ORG-57 CUMULATIVE_CURVE_LENGTH_3D
OCMATH_API int ocmath_curve_length_3d(UINT nSize, const double* pX, const double* pY, const double* pZ, double* pLen);
OCMATH_API int ocmath_cumulative_curve_length_3d(UINT nSize, double* pCLen, const double* pX, const double* pY, const double* pZ, int ntype = NOT_KEEP_STRICT_INCRECE);
//END CUMULATIVE_CURVE_LENGTH_3D

OCMATH_API int ocmath_ave_multiple_curves_by_length_parameter(UINT nSize, const OneCurveData* pCurves,
															  int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, 
							int nErrType = AVMC_SE, int* pAveCount = NULL, int nMethod = INTERP_TYPE_LINEAR, double* pAveMin = NULL, double* pAveMax = NULL);
/// end AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
/// End REWRITE_OCMATH_AVERAGE_MULTIPLE_CURVES

///Cheney 2006-4-24 LLVC_FOR_CHECK_ORDER
// Comments last updated by Cheney on 2006-5-8
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_check_order_(global_function)
*/
OCMATH_API int ocmath_check_order(UINT nSize, const double *pData, double *pMeanInc = NULL, 
								  double *pSDInc = NULL, int *pSegSize = NULL, double dProb = 0.8);

///Cheney 2006-4-26 LLVC_OCMATH_CHECK_ORDER_MULTIPLE_CURVES
///Comments last updated by Joseph on 2006-12-23
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_check_order_multiple_curves_(global_function)
*/
OCMATH_API int ocmath_check_order_multiple_curves(UINT nSize, const OneCurveData* pCurves, int nSegments = 3, 
												  double* pMeanInc = NULL, double* pSDInc = NULL, int* pSegSize = NULL, double dProb = 0.8);
///Cheney 2006-5-29 LLVC_CHECK_ORDER_CURVE
///Comments last updated by Joseph on 2006-12-23
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_check_order_curve_(global_function)
*/
OCMATH_API int ocmath_check_order_curve(UINT nSize, const double* pData, int nSegments = 3,
										double* pMeanInc = NULL, double* pSDInc = NULL, 
										int* pSegSize = NULL, double dProb = 0.8);

///Cheney 2006-8-28 LLVC_AVE_REPLICA_DATA_FOR_MULTIPLE_CURVES
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_ave_replica_data_for_multiple_curves_(global_function)
*/
/// Hong 11/11/09 QA80-6671-S1 AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
//OCMATH_API int ocmath_ave_replica_data_for_multiple_curves(uint nSize, const OneCurveData* pCurves,
//					int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, 
//					int nErrType = AVMC_SE, int* pAveCount = NULL);
OCMATH_API int ocmath_ave_replica_data_for_multiple_curves(uint nSize, const OneCurveData* pCurves,
														   int* pnAveSize, double* pAveX, double* pAveY, double* pAveErr = NULL, 
					int nErrType = AVMC_SE, int* pAveCount = NULL, double* pAveMin = NULL, double* pAveMax = NULL);
/// end AVERAGE_NEED_GET_MIN_MAX_AT_THE_SAME_TIME
///end LLVC_AVE_REPLICA_DATA_FOR_MULTIPLE_CURVES

/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Finding peak and baseline funcitons								 								
//
///////////////////////////////////////////////////////////////////////////////////////////// 

// Comments last updated by Arvin on 2006-5-12
//--------- CPY 3/13/04 QA70-6036 v7.5836 PICK_PEAKS_AND_RELATED_SUPPORT
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_pick_peaks_(global_function)
*/
OCMATH_API int ocmath_pick_peaks(
	const double *pYData,
	uint i1,
	uint i2,
	uint* pPeaks,
	uint nMaxPeaks,
	uint nPtsLeft,
	double peakMin,
	double peakYMin = 0,
	int nPtsRight = -1);


//----------

// Comments last updated by Cloud on 04/05/2007
///Arvin 2006-4-18 LLVC_FIND_PEAKS_1ST_DERIVATIVE
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_peaks_1st_derivative_(global_function)
*/
///Justin 2007-06-22 QA-9951 FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION
//OCMATH_API int ocmath_find_peaks_1st_derivative(UINT* lSize, const double* pX, const double* pY, double* pXPeaks, 
//												double* pYPeaks, int* pnIndices, int nDir=POSITIVE_DIRECTION, int nPtsSmooth=11);
///Jack	11/14/2008  INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD
//OCMATH_API int ocmath_find_peaks_1st_derivative(UINT* lSize, const double* pX, const double* pY, double* pXPeaks, 
//												double* pYPeaks, int* pnIndices, DWORD dwCtrl=POSITIVE_DIRECTION, int nPtsSmooth=11);
OCMATH_API int ocmath_find_peaks_1st_derivative(UINT* lSize, const double* pX, const double* pY, double* pXPeaks, 
												double* pYPeaks, int* pnIndices, DWORD dwCtrl=POSITIVE_DIRECTION, bool bUseSGderivativeForFindPeak = false, int nPtsSmooth=11, int nPolyOrder=2);
/// End INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD
///END FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION
///END LLVC_FIND_PEAKS_1ST_DERIVATIVE

// Comments last updated by Arvin on 08/05/2006
///Arvin 2006-4-26 LLVC_FIND_PEAKS_2ND_DERIVATIVE
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_peaks_2nd_derivative_(global_function)
*/
///Justin 2007-06-22 QA-9951 FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION
//OCMATH_API int ocmath_find_peaks_2nd_derivative(UINT* lSize, const double* px, const double* py, double* pxPeaks, 
//												double* pyPeaks,  int* pnIndices, int nDir = POSITIVE_DIRECTION, int nPtsSmooth = 11);
///Jack	11/14/2008  INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD
//OCMATH_API int ocmath_find_peaks_2nd_derivative(UINT* lSize, const double* px, const double* py, double* pxPeaks, 
//												double* pyPeaks,  int* pnIndices, DWORD dwCtrl = POSITIVE_DIRECTION, int nPtsSmooth = 11);
///Jack 11/19/2008 OUTPUT_SECOND_DERIVATIVE
//OCMATH_API int ocmath_find_peaks_2nd_derivative(UINT* lSize, const double* px, const double*  py, double* pxPeaks,
//												double* pyPeaks, int* pnIndices, DWORD dwCtrl, int nDerivativeMethod = 0, int nPtsSmooth = 11, int nPolyOrder=2);
OCMATH_API int ocmath_find_peaks_2nd_derivative(UINT* lSize, const double* px, const double*  py, double* pxPeaks,
												double* pyPeaks, int* pnIndices, DWORD dwCtrl, int nDerivativeMethod = 1, double * pSecondDeriv=NULL, int nPtsSmooth = 11, int nPolyOrder=2);
///End OUTPUT_SECOND_DERIVATIVE
///End  INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD
///END FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION
///END LLVC_FIND_PEAKS_2ND_DERIVATIVE


// Comments last updated by Cloud on 04/05/2007
///Arvin 2006-4-21 LLVC_FIND_MARKERS_OF_PEAKS_BY_HEIGHT_AND_WIDTH
// Category last updated by Cloud on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_markers_of_peaks_by_height_and_width_(global_function)
*/
OCMATH_API int ocmath_find_markers_of_peaks_by_height_and_width(UINT lSize, const double* px, const double* py, int nPeakNum, 
														 const int* pPeakIndices, int nMarkersNum, int* pMarkersIndices,  
														 double dMarkerHeight, double dMaxWidth, double dMinWidth);
///END LLVC_FIND_MARKERS_OF_PEAKS_BY_HEIGHT_AND_WIDTH

/* Cloud 11/10/2007
the method of find markers by 2nd derivative has problem, so temporarily comment it.
/// Cloud 05/17/2007 FIND_MARKER_BY_2ND_DERIVATIVE
OCMATH_API int ocmath_find_markers_of_peaks_by_2nd_derivative(UINT lSize, const double* px, const double* py, int nPeakNum,
														 const int* pPeakIndices, int nMarkersNum, int* pMarkersIndices);
/// End FIND_MARKER_BY_2ND_DERIVATIVE
*/

/**$
*/
/// Cloud 11/16/2007 TRIM_PEAK_PART_BY_2ND_DERIVATIVE
OCMATH_API int ocmath_trim_peak_part_by_2nd_derivative(UINT nSize, const double* px, const double* py, int* pBaseIndices);
/// End TRIM_PEAK_PART_BY_2ND_DERIVATIVE

/**$
*/
/// Cloud 11/10/2007 FIND_BASELINE_PART_IN_SMOOTH_CURVE
OCMATH_API int ocmath_find_baseline_part_in_smooth_curve(UINT nSize, const double* px, const double* py, int* pBaseIndices);
/// End FIND_BASELINE_PART_IN_SMOOTH_CURVE

/// Cloud 04/06/2007 FIND_MARKER_BY_FULL_WIDTH

/// Jack 03/31/2008 MOVE_BASELINE_BY_SMALL_CURVATURE_METHOD_FROM_OC
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_baseline_part_by_small_curvature_(global_function)
*/
OCMATH_API int ocmath_find_baseline_part_by_small_curvature(UINT nSize, const double* px, const double* py, double * pBasePtsX, double * pBasePtsY, double dThresh, double dTrimThresh = 0.8);
/// End MOVE_BASELINE_BY_SMALL_CURVATURE_METHOD_FROM_OC

/**$



*/
OCMATH_API int ocmath_find_markers_of_peaks_by_height_and_full_width(UINT lSize, const double* px, const double* py, int nPeakNum, 
														 const int* pPeakIndices, int nMarkersNum, int* pMarkersIndices,  
														 double dMarkerHeight, double* pMaxWidth, double* pMinWidth);
/// End FIND_MARKER_BY_FULL_WIDTH

// Comments last updated by Arvin on 08/05/2006
///Arvin 2006-4-30  LLVC_CREATE_BASELINE_BY_MASKING_PEAKS
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_create_baseline_by_masking_peaks_(global_function)
*/
///Arvin 03/20/08 CLEAN_DIRECTION_CTRL_FOR_FINDING_PEAK_FUNCS
//OCMATH_API int ocmath_create_baseline_by_masking_peaks(UINT lDataSize, const double* px,  const double* py,  UINT lBaselinePoints, double* pxb, double* pyb, int nDir = POSITIVE_DIRECTION);
OCMATH_API int ocmath_create_baseline_by_masking_peaks(UINT lDataSize, const double* px,  const double* py,  UINT lBaselinePoints, double* pxb, double* pyb, DWORD dwCtrl = POSITIVE_DIRECTION);
///END 	 CLEAN_DIRECTION_CTRL_FOR_FINDING_PEAK_FUNCS
///end LLVC_CREATE_BASELINE_BY_MASKING_PEAKS

//Comments last updated by Arvin on 08/05/2006
///Arvin 2006-4-18 LLVC_TEST_PEAKS_BY_NUMBER
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_test_peaks_by_number_(global_function)
*/
OCMATH_API int ocmath_test_peaks_by_number(int nSize, double* pXPeaks, double* pYPeaks, int* pnIndices, int npeakNum);
///END LLVC_TEST_PEAKS_BY_NUMBER

//Comments last updated by Arvin on 08/05/2006
///Arvin 2006-4-19 LLVC_TEST_PEAKS_BY_HEIGHT
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_test_peaks_by_height_(global_function)
*/
OCMATH_API int ocmath_test_peaks_by_height(int* nPeakNum, double* pXPeaks, double* pYPeaks, int* pnIndices, double dMinHeight);
///END LLVC_TEST_PEAKS_BY_HEIGHT

//Comments last updated by Jack on 05/06/2006
///Arvin 2006-4-21 LLVC_GET_NOISE_LEVEL
// Category last updated by Cloud on 05/16/2008
/**$ >Spectroscopy>Peak and Baseline
    Remarks:
		This function estimates the variance of noise of measured signals with Gamma test;
		Supposing y = f(x) + r, where f(x) is a underlying smoothed function and r is noise, this function will estimates standard deviation of r.
		If f(x) is not continuous or smothed, the estimatation maybe amplifies the noise.
	Keywords:
		noise
	Example1:
		void ocmath_get_noise_level_ex1()
		{

			GraphLayer gl = Project.ActiveLayer();
			if (!gl)
			{
				return;
			}
			
			DataPlot dp = gl.DataPlots(0);		
			DataRange dr;
			vector vxData, vyData;
	        if(dp.GetDataRange(dr))
	        {
	        	DWORD dwPlotID;
	        	if(dr.GetData(DRR_GET_DEPENDENT | DRR_NO_FACTORS, 0, &dwPlotID, NULL, &vyData, &vxData) < 0)
	        	{
	        		printf("get_plot_data failed GetData");
	        		return;
	        	}
	        }

			int lSize = vyData.GetSize();

	        double noiseLevel = ocmath_get_noise_level( lSize, vyData);
		}
		// At the end of example:
	Parameters:
		lSize = [input] size of py
		py = [input] pointer to the measured signals.
		px = [input] pointer to the independent variable. if NULL,it's assumed that it's evenly spaced
		bUseNearest = [input] a bool control of the internal algorithm whether to use Nearest Neighbors, 
			if false=bUseNearest	fast but fail to distinguish a multi-peak data with a noise data. Note: not suitable for usage for random x case
			if true=bUseNearest     a more accurate result but slow in calculation for large dataset. Note: can be used for random x (namely, not sorted according x)
	Return:
		Return variance of noise or missing value if error.
*/
///justin 09/06/2006 NOISE_ESTIMATED_WITH_GAMMA_TEST
//OCMATH_API double ocmath_get_noise_level(UINT lSize, const double* py);
/**$
*/
OCMATH_API double ocmath_get_noise_level(UINT lSize, const double* py, const double *px = NULL, bool bUseNearest=false);
//end NOISE_ESTIMATED_WITH_GAMMA_TEST
///END LLVC_GET_NOISE_LEVEL

/// Cloud 07/05/2007 NOISE_ESTIMATED_FOR_FLAT_PART
OCMATH_API int ocmath_split_vector_by_value(UINT lSize, const double *px, const double val, UINT *pMark);
OCMATH_API double ocmath_get_noise_level_of_flat_part(UINT lSize, const double* py, const double *px=NULL);
/// End NOISE_ESTIMATED_FOR_FLAT_PART

//Comments last updated by Arvin on 08/05/2006
///Arvin 2006-4-26 LLVC_IS_INSIDE_RANGE
// Category last updated by Cloud on 05/16/2008
/**$ >Spectroscopy>Peak and Baseline
    Remarks:
		This function test a data whether or not between Value1 and Value2.
		when isInculding = false, test the data wheth or not inside the range (Value1, Value2);
		and while isInculding = true, test the data wheth or not inside the range [Value1, Value2];
	Keywords:
		range
	Example1:
		void ocmath_is_inside_range_ex1(double data, double value1, double value2, bool isInculding)
		{
			bool isIn = ocmath_is_inside_range( data,  value1, value2, isInculding );
		}
		// At the end of example:
	Parameters:
		Data = [input] the data to be test
		Value1 = [input] minimum value in the range
		Value2 = [input] maximum value in the range
		isInculding = [input]
		              true include boundary
					  false exclude boundary
	Return:
		Return true or false.
*/
OCMATH_API bool ocmath_is_inside_range(double Data, double Value1, double Value2, bool isInculding = false);
///END LLVC_IS_INSIDE_RANGE

//Comments last updated by Arvin on 08/05/2006
///Arvin 2006-4-24 LLVC_FIND_PEAKS_PARTITION
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_peaks_partition_(global_function)
*/
OCMATH_API int ocmath_find_peaks_partition(UINT lSize, const double* px, const double* py, double dPeakCenter, int* nStartofPeak, int* nEndofPeak, int nPtsSmooth);
///END LLVC_FIND_PEAKS_PARTITION

//Comments last updated by Arvin on 08/05/2006
///Arvin 2006-4-24 LLVC_INIT_BASELINE_BY_CONNECT_ENDS
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_init_baseline_by_connect_ends_(global_function)
*/
OCMATH_API int ocmath_init_baseline_by_connect_ends(UINT lSize, const double* px, const double* py, UINT lBaselinePoints, double* pbx, double* pby);
///END LLVC_INIT_BASELINE_BY_CONNECT_ENDS

//Comments last updated by Sandy on 06/02/2009
///Arvin 2006-4-24 LLVC_CHECK_LINEAR
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_check_linear_(global_function)
*/
OCMATH_API int ocmath_check_linear(UINT lSize, const double* px, const double* py, int* pNonlinearPoint, double dMaxRatio,  double dR = 1.0, UINT nOffset = 0, bool bDir = true, int nRange0 = 0, int nStep = 0);
///END LLVC_CHECK_LINEAR


/// Raine/Sandy 2006-07-28 MOVE_DATA_H_FUNCTION_TO_OCMATH
/// yatasymt(Curve &cc) From data.h 
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_yatasymt_(global_function)
*/
OCMATH_API int ocmath_yatasymt(UINT nSize, const double* px, const double* py, double* dYAsympt);

/// xatasymt(Curve &cc) From data.h 
///Comments last updated by Joseph on 2006-12-23
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_xatasymt_(global_function)
*/
OCMATH_API int ocmath_xatasymt(UINT nSize, const double* vx, const double* vy, double* dXAsympt);
///end Raine/Sandy 2006-07-28 MOVE_DATA_H_FUNCTION_TO_OCMATH

///Arvin 2006-8-08 QA70-8419 LLVC_XY_REMOVE_DUPLICATES
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_xy_remove_duplicates_(global_function)
*/
///Cheney 2006-12-8 NEED_ADD_OPTION_TO_DECEIDE_IF_SORT_INPUT_DATA
//OCMATH_API int ocmath_xy_remove_duplicates(UINT* nSize, double* px, double* py, int nMethod = Replace_With_Mean, double dPrecision = 1.0e-8);
///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS   
//OCMATH_API int ocmath_xy_remove_duplicates(UINT* nSize, double* px, double* py, int nMethod = Replace_With_Mean, double dPrecision = 1.0e-8, bool bSort = TRUE);
OCMATH_API int ocmath_xy_remove_duplicates(double* px, double* py, UINT nSize, int nMethod = Replace_With_Mean, double dPrecision = 1.0e-8, bool bSort = TRUE, double* duppx = NULL, double * pCounts = NULL, int * pnSizeDuppx = NULL);
///End ADD_COUNTS_FOR_DUPXS   
///end NEED_ADD_OPTION_TO_DECEIDE_IF_SORT_INPUT_DATA
///end LLVC_XY_REMOVE_DUPLICATES

///Sandy 2006-9-6 ADD_NEW_ALGORITHM_FOR_FINDING_PEAK_WITH_LOCAL_MAXIMUM
// Comments last updated by Arvin on 12/27/2006
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_peaks_by_local_maximum_(global_function)
*/
///Justin 2007-06-22 QA-9951 FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION
//OCMATH_API int ocmath_find_peaks_by_local_maximum(UINT* lSize, const double* pX, const double* pY, double* pXPeaks, 
//												double* pYPeaks, int* pnIndices, int nDir, int nLocalPts);
OCMATH_API int ocmath_find_peaks_by_local_maximum(UINT* lSize, const double* pX, const double* pY, double* pXPeaks, 
												double* pYPeaks, int* pnIndices, DWORD dwCtrl, int nLocalPts);
///END FILTER_OUT_PEAKS_THAT_SIGN_NOT_CORRESPONDING_TO_DIRECTION
///end ADD_NEW_ALGORITHM_FOR_FINDING_PEAK_WITH_LOCAL_MAXIMUM





///Jack 11/11/2008	ADD_EMPIRICAL_MODE_DECOMPOSITION
// for local extreme and envelope detection in EMD method
/// Jack 11/01/2008 QA80-12506 ADD_ENVELOPE_DETECT_METHOD
OCMATH_API int ocmath_find_local_extremes(UINT* lSize, const double* pX, const double* pY, double* pXExtreme, double* pYExtreme, int* pnIndices, DWORD dwCtrl, int nLocalPts);
///END ADD_ENVELOPE_DETECT_METHOD


// !!!!!!!!!!!!!Warning!!!!!!!!!!!!!!!!
// In ocmath_emd_get_zero_crossing(), we assume that the buffer size for pRoot, pDir, pXindex are large enough ( at least nSize ) 
// !!!!!!!!!!!!!Warning!!!!!!!!!!!!!!!!
OCMATH_API int ocmath_emd_get_zero_crossing(int nSize, const double *px, const double *py, int* numZeros, double *pRoot = NULL, int *pDir = NULL, int *pXindex = NULL);
OCMATH_API int ocmath_emd_get_upper_lower_envelope(int nSize, double *px, double *py, double *pUpperEnvY, double *pLowerEnvY, int* nExtremeMax, int* nExtremeMin, int nLocalPts=2);
OCMATH_API int ocmath_emd_envelope_mean_amp(int nSize, double *px, double *py, double *pMeanEnv, double *pAmp, int* nExtremeMax, int* nExtremeMin, int nLocalPts=2);
OCMATH_API int ocmath_emd_stop_sifting(int nSize,  double * px, double * py, double dStopParameter1, double dStopParameter2, double tol, double *pxIMF, double *pyIMF, double *pxResidualDetail, double *pyResidualDetail, int nLocalPts=2);
OCMATH_API int ocmath_empirical_mode_decomposition(int nSize,  double * px, double * py, double dStopParameter1, double dStopParameter2, double tol, double * pIMFs, int nMaxIMFs, int * pnIMFs, double * pyResidualDetail, int nLocalPts=2);
///End ADD_EMPIRICAL_MODE_DECOMPOSITION


///Sandy 2006-9-29 ADD_NEW_ALGORITHM_FOR_FINDING_PEAK_WITH_SEARCH_WINDOW
// Comments last updated by Cloud on 04/09/2007
// Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_peaks_by_search_window_(global_function)
*/
OCMATH_API int ocmath_find_peaks_by_search_window(UINT* lSize, const double* pX, const double* pY, 
												  double* pXPeaks, double* pYPeaks, int* pnIndices, 
/// Cloud 04/09/2007 FIX_DATA_TYPE_IN_SEARCH_WINDOW_METHOD
//												  int nDir, int nSearchWidth, int nSearchHeight);
												  int nDir, double dSearchWidth, double dSearchHeight);
/// End FIX_DATA_TYPE_IN_SEARCH_WINDOW_METHOD
///end ADD_NEW_ALGORITHM_FOR_FINDING_PEAK_WITH_SEARCH_WINDOW

/////////////////////////////////////////////////////////////////////////////////////////////
//
//				Image processing: Morphology							 								
//
///////////////////////////////////////////////////////////////////////////////////////////// 

///Sandy 2006-12-5 add for morphological operation
///Comments last updated by Arvin on 2006-12-26
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_dilate_matrix_with_strel_(global_function)
*/
OCMATH_API int ocmath_dilate_matrix_with_strel(int nRows, int nCols, double* pMat, StrelResult* pStrel);

///Comments last updated by Joseph on 2007-07-26
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_erode_matrix_with_strel_(global_function)
*/
OCMATH_API int ocmath_erode_matrix_with_strel(int nRows, int nCols, double* pMat, StrelResult* pStrel);
///end 2006-12-5 add for morphological operation

///Arvin 12/22/06 PRODUCE_STREL_STRUCT_FOR_MORPHOLOGIC_OPERATION
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_make_strel_(global_function)
*/
OCMATH_API int ocmath_make_strel(StrelResult* pStrel, StrelParams* psParams, UINT nShape = SQUARE_SHAPE); 
///end PRODUCE_STREL_STRUCT_FOR_MORPHOLOGIC_OPERATION

///Arvin 01/05/06 COMPARE_TWO_VECTOR_OR_MATRIX
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_compare_data_(global_function)
*/
OCMATH_API int ocmath_compare_data(int nSize, const double* pData1, const double* pData2, bool* bIsSame, double dTolerance = 1e-10);
///end COMPARE_TWO_VECTOR_OR_MATRIX

///Arvin 01/10/06 ADD_REMOVE_XYZV_DUPLICATES_FOR_3D_INTERPOLATION
// Category last updated by Justin on 03/26/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_xyzv_remove_duplicates_(global_function)
*/
OCMATH_API int ocmath_xyzv_remove_duplicates(UINT nSize, double* px, double* py, double* pz, double* pv, int nMethod = Replace_With_Mean, double dPrecision = 1.0e-8, bool bSort = TRUE);
///end ADD_REMOVE_XYZV_DUPLICATES_FOR_3D_INTERPOLATION


///Echo 1/27/07 ADD_SIMPLE_MATH
// Category last updated by Cloud on 06/03/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_simple_math_(global_function)
*/
OCMATH_API int ocmath_simple_math(UINT nSize, double* pX, double* pY, UINT nSrcSize1, const double* pSrcX1, const double* pSrcY1, UINT nSrcSize2, const double* pSrcX2, const double* pSrcY2, int nOperator = MATHTOOL_OPT_ADD, int nRange =MATHTOOL_RNG_CUV, int nMethod = INTERP_TYPE_LINEAR, double dSmoothingFactor = 0);
///end ADD_SIMPLE_MATH

/// Cloud 05/18/2007 MOVE_DATASET_FUNCTIONS_TO_OCMATH
/**$
*/
OCMATH_API int ocmath_x_from_y(UINT lSize, const double *px, const double *py, const double dY, double *pX);
/**$
*/
OCMATH_API int ocmath_y_form_x(UINT lSize, const double *px, const double *py, const double dX, double *pY, bool bSorted=true, bool bUniform=true);
/// End MOVE_DATASET_FUNCTIONS_TO_OCMATH

/// Cloud 05/21/2007 REPLACE_DATA_MATCHING_CONDITION_WITH_SPECIFIED_NUM
// Comment last updated by Cloud on 06/03/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_replace_data_in_vector_(global_function)
*/
OCMATH_API int ocmath_replace_data_in_vector(UINT lSize, double *pv, const double dThreshold, const double dRepVal, UINT wBitwiseOption = MATREPL_TEST_EQUAL);
/// End REPLACE_DATA_MATCHING_CONDITION_WITH_SPECIFIED_NUM

///Justin 2007-07-04  ADD_INTEGRAL_FUNCTION_APPLIED_ON_ANALYTIC_FUCNTION
#define INFINITY 1.0e60
typedef double (*EVALUATFUNC)(double x, LPVOID pPara); 
typedef	double (*INTEGFUNC)(double, double, EVALUATFUNC, LPVOID, int);

// Comment last updated by Jack on 06/11/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_function_integral_(global_function)
*/
OCMATH_API double ocmath_function_integral(double a, double b, EVALUATFUNC func, LPVOID pPara, double precision = 10e-8); 
///End ADD_INTEGRAL_FUNCTION_APPLIED_ON_ANALYTIC_FUCNTION

//Jack 12/06/2008 ADD_INTEGRAL_FUNCTION_ON_NEW_ROMBERG
/**$
*/       
OCMATH_API double ocmath_function_normal_integral(double a, double b, EVALUATFUNC func, LPVOID pPara, double precision = 10e-8); //=10e-8
OCMATH_API double ocmath_function_integral_on_new_romberg(double a, double b, EVALUATFUNC func, LPVOID pPara, double precision = 10e-8); //=10e-8
OCMATH_API double ocmath_function_normal_integral_on_gaussian_quadrature(double a, double b, EVALUATFUNC func, LPVOID pPara, double epsabs = 10e-8); //=10e-8
//End ADD_INTEGRAL_FUNCTION_ON_NEW_ROMBERG


/// Cloud 07/10/2007 IMPORT_FIND_INFLECTION_POINT_FROM_OLD_PFM
/**$
*/
OCMATH_API double ocmath_iterate_for_finding_inflection(double x0, double low, double high, UINT lSize, const double* vx, const double* vy, double* py=NULL, double* pdydx1=NULL, double* pdydx2=NULL, double* pdydx3=NULL);

// Comment last updated by Cloud on 06/03/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_inflection_point_(global_function)
*/
OCMATH_API int ocmath_find_inflection_point(UINT lSize, const double* px, const double* py, double xc, double w, double* pLeft, double* pRight, double* pBottomWidth);
/// End IMPORT_FIND_INFLECTION_POINT_FROM_OLD_PFM

///Arvin 07/31/07 QUIKE_METHOD_OF_PEAK_MOMENTS_AND_INTEGRAL_EVALUATION
/**$
*/
OCMATH_API int ocmath_generate_peak_data(UINT* nSize, double* pX, UINT nSrcSize, const double* pSrcX, const double* pSrcY, double dPeakLeft, double dPeakRight, double dPeakPerc = 0.8, double dLeftPerc = 0.1, double dRightPerc = 0.1);
// Comment last updated by Cloud on 06/03/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_calc_peak_moments_(global_function)
*/
OCMATH_API int ocmath_calc_peak_moments(UINT nSize, const double* pX, const double* pY, double* pMoment, int nMomentType = OCMATH_PEAK_CENTRAL_MOMENT, uint nMomentOrder = 2);
///end QUIKE_METHOD_OF_PEAK_MOMENTS_AND_INTEGRAL_EVALUATION

/**$
*/
OCMATH_API int ocmath_calc_peak_moments_ex(UINT nSize, const double* pX, const double* pY, double* pMoment, int nMomentType = OCMATH_PEAK_CENTRAL_MOMENT, uint nMomentOrder = 2);

/// Cloud 10/17/2007 QA80-10492 1D_RESAMPLING
/**$
*/
OCMATH_API int ocmath_combine_vectors(double* px1, UINT nSize1, double* px2, UINT nSize2, double* pDest, double x1=__NANUM, double x2=__NANUM, double dThreshold=-1);
/// End QA80-10492 1D_RESAMPLING

/// Cloud 12/07/2007 QA80-10788 FIND_BASELINE_PARTION
/**$
*/
//OCMATH_API int ocmath_find_baseline_partion(UINT nSize, double* px, double* py, int lmin, double smax, int* basestart, int* baseend);
/// End FIND_BASELINE_PARTION

/// Cloud 12/10/2007 QA80-10788 MOVE_FROM_CURVE_UTILS
typedef struct tagLRresults
{
	uint	i1;
	uint	i2;
	double	a;
	double	b;
	double	aErr;
	double	bErr;
	double	Rvalue;			// R Value
	double	AdjRSq;			// Adjusted residuel sum of squares
} LRresults;
// Comment last updated by Cloud on 06/04/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_fit_linear_multi_regions_(global_function)
*/
OCMATH_API int ocmath_fit_linear_multi_regions(UINT nSize, const double* px, const double* py, UINT nSegs, const int* pBegs, const int* pEnds, LRresults* pResults);

// Comment last updated by Cloud on 06/04/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_base_regions_(global_function)
*/
OCMATH_API int ocmath_find_base_regions(UINT nSize, const double* px, const double* py, int nMinBasePts, UINT nMaxRegions, int* pBegs, int* pEnds, double dTol = 1.0, double dMaxSearchSize = 0.4, int nRange0=0);
/// End MOVE_FROM_CURVE_UTILS

/// Cloud 12/24/2007 QA80-10864 CUT_DATA_INTO_PARTS_BY_HEIGHT
// Comment last updated by Cloud on 06/04/2008
/**$ >Spectroscopy>Peak and Baseline
	Remarks:
		Split the curve to segments with standard deviation range less than threshold

	Example1:
		void ocmath_cut_to_segments_by_height_ex1()
		{
			vector vx = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
			vector vy = {8.15988E-4,
						0.01832,
						0.16901,
						0.64118,
						1,
						0.64118,
						0.16901,
						0.01832,
						8.15988E-4,
						1.49453E-5}
			vector<int> vLength(9);
			vector vAve(9);
			ocmath_cut_to_segments_by_height(10, vx, vy, 0.05, 9, vLength, vAve);
		}
	Parameters:
		nSize = [input] size of the curve data
		px = [input] pointer to x coordinates of the curve
		py = [input] pointer to y coordinates of the curve
		dThreshold = [input] max standard deviation to split the curve
		nSegs = [input] specify the size of buffer to store the lengths of segments
		pLength = [output] buffer to store the lengths of segments
		pAve = [output] buffer to store the averages of segments, if no need for average, set it as NULL

	Return:
		Return segments number.
*/
OCMATH_API int ocmath_cut_to_segments_by_height(UINT nSize, const double* px, const double* py, double dThreshold, int nSegs, int* pLength, double* pAve=NULL);
/// End CUT_DATA_INTO_PARTS_BY_HEIGHT

/// Cloud 01/11/2008 WRAP_FOR_OCMATHSP
/**$
*/
OCMATH_API bool ocmath_generate_data_for_non_monotonic(UINT nSize, const double* pSrcX, const double* pSrcY, double* pDesX, double* pDesY, unsigned int* pInd, bool bInt=false);
OCMATH_API int ocmath_adjust_data_of_peaks(int* pPeakInd, double* pXPeaks, double* pYPeaks, int nPeaksNum, bool bSort, bool bInterp, const unsigned int* pSortInd, int nSize, const double* px, const double* py);
 ///Jack 11/14/2008  INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD 
//OCMATH_API int ocmath_find_peak_by_derivative_centralized(UINT nSize, const double* px, const double* py, const double* pdy, int& nPeakNum, double* pxPeaks, double* pyPeaks, int* pnPeakIndices, int direct, DWORD dwCtrl, BOOL b1stDriv, double* pMissing);
OCMATH_API int ocmath_find_peak_by_derivative_centralized(UINT nSize, const double* px, const double* py, const double* pdy, int& nPeakNum, double* pxPeaks, double* pyPeaks, int* pnPeakIndices, int direct, DWORD dwCtrl, int DerivativeFilterMehthod, double* pMissing);
///End INCORPORATE_SG_DERIV_AS_OPTION_IN_FIND_PEAK_BY_DERIVATIVE_METHOD 
/// End WRAP_FOR_OCMATHSP

///Arvin 01/25/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS_OF_POLYNOMIAL_FIT
// Comment last updated by Cloud on 06/04/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_calc_conf_and_pred_bands_for_polynomial_(global_function)
*/
OCMATH_API int ocmath_calc_conf_and_pred_bands_for_polynomial(const double* pX, const double* pY, int nSize, const double* pdCovMat, const LROptions* psLROptions, int nOrder, double dBoundPerc, double dChiSq, double dtValue, double* pdLower, double* pdUpper, BOOL bConf = TRUE);
///end CALC_CONFIDENCE_AND_PREDICTION_BANDS_OF_POLYNOMIAL_FIT

///Arvin 02/26/08 OVERLOAD_FIND_PEAK_MARKERS_FUNCTION_SUPPORTING_INPUT_PEAK_CENTERS as Sandy said
//#define  CENTRALIZE_FIND_PEAK_MARKER
//Category last updated by Cloud on 05/16/2008
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_find_markers_of_peak_centers_by_height_and_width_(global_function)
*/
OCMATH_API int ocmath_find_markers_of_peak_centers_by_height_and_width(UINT lSize, const double* px, const double* py, int nPeakNum, 
																const double* pPeakX, int nMarkersNum, int* pMarkersIndices,  
																double dMarkerHeight, double dMaxWidth, double dMinWidth);
///end 	 OVERLOAD_FIND_PEAK_MARKERS_FUNCTION_SUPPORTING_INPUT_PEAK_CENTERS

///Jack 28/4/2008 ADD_REDUCE_2D_MATRIX_DATA
// Comment last updated by Cloud on 06/04/2008
/**$ >Mathematics>Matrix Analysis
	Remarks:
		Shrink a matrix to less rows and/or less columns

	Example1:
		void ocmath_reduce_2D_data_ex1()
		{
			vector vx = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
			vector vy = {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};
			matrix mz = {1, 2, 3, 4,
						 5, 6, 7, 8,
						 12, 11, 10, 9,
						 16, 15, 14, 13};

			vector vxs(4);
			vector vys(4);
			matrix mzs(2, 2);
			ocmath_reduce_2D_data(16, vx, vy, mz, 4, 4, vxs, vys, mzs, 2, 2);
			for (int ii=0; ii<2; ii++)
			{
				for (int jj=0; jj<2; jj++)
					printf ("%lf\t", mzs[ii][jj]);
				printf ("\n");
			}
		}

	Parameters:
		nSize = [input] the number of the matrix elements, should be equal to nRows*nCols
		px = [input] pointer to x coordinates of the matrix
		py = [input] pointer to y coordinates of the matrix
		pz = [input] pointer to z coordinates of the matrix
		nRows = [input] rows of the matrix
		nCols = [input] columns of the matrix
		pxReduced = [output] pointer to buffer to store the x coordinates of the reduced matrix
		pyReduced = [output] pointer to buffer to store the y coordinates of the reduced matrix
		pzReduced = [output] pointer to buffer to store the z coordinates of the reduced matrix
		nColShrinkFactor = [input] shrink multiples in columns
		nRowShrinkFactor = [input] shrink multiples in rows

	Return:
		Return matrix size after shrink.
*/
OCMATH_API int ocmath_reduce_2D_data(int nSize, const double* px, const double* py, const double * pz, int nRows, int nCols, double * pxReduced, double * pyReduced, double * pzReduced, int nColShrinkFactor, int nRowShrinkFactor);
/// End ADD_REDUCE_2D_MATRIX_DATA

/// Jack  ADD_LOGISTICS_REGRESSION
OCMATH_API int logistics_regression_by_newton_raphson_method(int n, int p, const double * pDesignMatrixX, const double * pWeightVec, const double * pResponseYVec, int pp, double * pParaBeta, double * pCovMatrix,double dTol, double maxIterNum);
/// End ADD_LOGISTICS_REGRESSION

/// Jack 01/20/04 QA80-12405 REDUCE_DATA_XF
OCMATH_API int ocmath_group_xy_by_x_new(int nPts, double* pX, double* pY, int nPtCntrl, double* pXCntrl, int* pGrpEnd);

enum
{
	FULL_CLOSED = 0,
	SEMI_LOWER_CLOSED,
	SEMI_UPPER_CLOSED,
	FULL_OPEN,
};
OCMATH_API int 	ocmath_get_lower_upper_bounds_index(int nSize, const double * vData, double dLowerBound, double dUpperBound, int * pLowerBoundIndex, int * pUpperBoundIndex, double dInclusivePrecisonEPS=1.0e-8, bool bInclusiveOrExclusiveEPS = true, int intervalOpenOrCloseMethod = FULL_CLOSED);
OCMATH_API int 	ocmath_get_median_in_vector(int nSize, double * vData, double * pMedian);
///End REDUCE_DATA_XF

///	Fisher 2008/10/28 QA80-12458 ADDITIONAL_OUTPUT_FOR_SINGAL_PROCESSING_TOOL
OCMATH_API	int	ocmath_mathematical_expectation(UINT nSize, const double *pDataX, const double *pDataY, double *pExpected );
OCMATH_API	int	ocmath_basic_stats_distribution(UINT nSize, const double *pDataX, const double *pDataY, double *pxPeak = NULL, double *pyPeak = NULL, int *iPeak = NULL, double *pMean = NULL, double *pMedian = NULL, double *pSD = NULL, int nDir = POSITIVE_DIRECTION );
OCMATH_API	int	ocmath_percentiles_distribution(UINT nSize, const double *pDataX, const double *pDataY, const double *pPercents, const int nPercentSize, double *pPercentiles = NULL, int *pPercentilesXIndex = NULL);
///	End ADDITIONAL_OUTPUT_FOR_SINGAL_PROCESSING_TOOL

/// Fisher 23/3/09	QA80-3224  SUPPORT_LINEAR_FIT_WITH_ERROR_BAR
OCMATH_API int ocmath_linear_fit_xyerror_york(const double* px, UINT nSizex,
										const double* py, UINT nSizey,
										const double* pwtx, UINT nSizewtx,
										 const double* pwty, UINT nSizewty,
										 double *dIntercept = NULL, double *dSlope = NULL, double *daErr = NULL, double *dbErr = NULL, const int nIters = 500);


OCMATH_API int ocmath_linear_fit_xyerror_fv(const double* px, const double* py, const double* psx,
										const double* psy, int nSize, const double dtol = 0.0001, const int ich = 500,
										double *pda = NULL, double *pdb = NULL, double *pdv = NULL, double *pdea = NULL, double *pdeb = NULL,
										double *pdev = NULL, double *pds = NULL);

OCMATH_API int ocmath_linear_fit_xyerror_ripley(const double* px, const double* py, const double* psx,
										const double* psy, int nSize, double *dIntercept = NULL, double *dSlope = NULL, 
										double *da_Err = NULL, double *db_Err = NULL);
/// End  SUPPORT_LINEAR_FIT_WITH_ERROR_BAR


///Sandy 2008-11-14 MOVE_FROM_FFTW_FOR_SPREAD_USEAGE
/**$
	Remarks:
	Check the intervals of the sequence are even or not and compute the interval if even.

	Parameters:
	iSize = [input]	the number of data values in the sequence.
	vX	= [input]	sequence to be checked.
	dInterval = [output] the time interval of the sequence.

	Return:	
	returns 0 for evenly spaced frequencies and error codes
	Error codes:
	OE_INVALID_SIZE: the size of the sequency is less than 2
	OE_NULL_POINTER: the data pointer is NULL.
	OE_INVALID_INTERVAL: invalid interval -- the interval is less than 1e-20
	UNEVENLY_SPACE: unevenly spaced values.
		  
*/
OCMATH_API int ocmath_check_interval(int iSize, double *vX, double* dInterval);

/// Fisher 2008-11-14 QA80-12546 ADD_BACK_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL
OCMATH_API int ocmath_savitsky_golay_derivative(double *px, double *py, double *pSmooth, UINT nSize, int nLeftpts, int nRightpts = -1, UINT nPolydeg = 2, UINT nDervOrder = 1, bool bSmoothPeakPoint = false);
/// End ADD_BACK_SMOOTH_OPTION_IN_DIFFERENTIATE_TOOL

///Jack 12/04/2008	ADD_DATA_INTEGRATE_WITH_BOUNDS
// assume it is sorted in an ascending order
// also check monotonic inside
// the default precision eps used inside to locating bounds and their index is 0.0
/**$
	dLowerBound [input] lower bounds for integration
	dUpperBound [input] upper bounds for integration
	nSize [input] input source data size
	pXData =	[input] pointer to X vector data 
	pYData =	[input] pointer to Y vector data 
	pInteg =	[output] result of integration. 
	pBaseLine = [input] integrate baseline 
	areaType = [input] MATHEMATICAL_AREA, direct cumulative vector from the integration; ABSOLUTE_AREA, integrate absolute area 
	pnDataPtsIntegrated = [output] the pratical number of data points integrated including intepolated points number (if there are)
	pIntegral = [output] optional cumulative vector from the integration, must be allocated with with at least (nDataSize+2) points 
	pBoundedSubX = [output]	the pratical x data points integrated including intepolated points (if there are), must be allocated with with at least (nDataSize+2) points 
	pBoundedInterpBaseY	= [output] the pratical baseline y data points used in integration including intepolated points (if there are), must be allocated with with at least (nDataSize+2) points 
	OPTIONS = [input] DWORDS to indicate need sort, or extrapolate for bounds outside input data range.  If no need both use OCMATH_NONE_OPTION bit
	if need	sort set OCMATH_INTEGRATE_WITH_BOUNDS_SORT bit, if need extrapolate set	 OCMATH_INTEGRATE_WITH_BOUNDS_EXTRAPOLATE bit, default set two bits
*/
OCMATH_API int ocmath_integrate_with_bounds(double dLowerBound, double dUpperBound, 
											int nSize,
											const double* pXData,	//[in]
											const double* pYData, //[in]																			
											IntegrationResult* pInteg,//[out]
											const double* pBaseLine = NULL, //[in]
											int areaType = MATHEMATICAL_AREA, //[in]
											int * pnDataPtsIntegrated=NULL,	 //[out]
											double* pIntegral = NULL,
											double* pBoundedSubX = NULL,
											double* pBoundedInterpBaseY = NULL,
///Jack	12/26/2008 CHANGE_BOOL_CONTROL_INTO_DWORD_OPTIONS_CTRL
//											bool bSortAscending = true,
//											bool bExtrapolate = true
											DWORD OPTIONS = OCMATH_INTEGRATE_WITH_BOUNDS_SORT | OCMATH_INTEGRATE_WITH_BOUNDS_EXTRAPOLATE,
											int nMethodSearchHalfWidth = SEARCH_FROM_BOTH_ENDS
///End CHANGE_BOOL_CONTROL_INTO_DWORD_OPTIONS_CTRL
											);
///End	ADD_DATA_INTEGRATE_WITH_BOUNDS

/// Jack 12/30/2008 ADD_LEVEL_CROSSING
OCMATH_API int ocmath_get_level_crossing(int nSize, const double *px, const double *py, double level, int* numZeros, double *pxValueofCrossing);
/// End ADD_LEVEL_CROSSING

enum{
	REDUCE_XY_STATS_MEAN,
	REDUCE_XY_STATS_MIN,
	REDUCE_XY_STATS_MAX,
	REDUCE_XY_STATS_MEDIAN,
	REDUCE_XY_STATS_FIRST,		///Kyle 01/15/2009 BRING_BACK_FIRST_SAMPLING_METHOD
	///Jack	 05/01/2008 ADD_FIRST_AND_RANDOM_SAMPLING_METHOD
	///Jack 01/05/2008 CHANGE_FIRST_TO_MIDDLE_SAMPLING_METHOD
	//REDUCE_XY_STATS_FIRST,
	REDUCE_XY_STATS_MIDDLE,
	///ENd CHANGE_FIRST_TO_MIDDLE_SAMPLING_METHOD
	REDUCE_XY_STATS_RANDOM,
	///End ADD_FIRST_AND_RANDOM_SAMPLING_METHOD
	REDUCE_XY_STATS_LAST,
	REDUCE_XY_STATS_SUM,
	REDUCE_XY_STATS_SD,

};

enum{
	REDUCE_XY_YMEANXBINC,
	REDUCE_XY_YMEDIANXBINC,
	REDUCE_XY_YINT_MISSING,
	REDUCE_XY_YINT_LINEARINTERP,
};
///Jack 01/06/2009	ADD_RANDOM_GENERATOR_SEED_SETTING_OPTION
//OCMATH_API int reduce_xy_get_sampling_data(const double *pX, const double *pData, int nSize, const int yinterpmethod, double *pMergedY, double *pMergedX, int nNumBins, double *pBins, int nBinsSize, const int lastinterwithxen, int iOption);
OCMATH_API int reduce_xy_get_sampling_data(const double *pX, const double *pData, int nSize, const int yinterpmethod, double *pMergedY, double *pMergedX, int nNumBins, double *pBins, int nBinsSize, const int lastinterwithxen, int iOption, int iSeedNegValue);
/// End ADD_RANDOM_GENERATOR_SEED_SETTING_OPTION

///Jack	01/05/2009 ADD_UNIFORM_RANDOM_NUMBER_GENERATOR
// for test only can directly use LABUTIL_rnd or ran1
OCMATH_API double ocmath_uniform_random_number(int iSeed);
///ENd ADD_UNIFORM_RANDOM_NUMBER_GENERATOR

/// Fisher 1/7/09 QA80-12727 AVECURVES_RESULTS_NOT_GOOD_WHEN_CURVES_HAVE_MISSING_VALUES
OCMATH_API int ocmath_ave_multiple_curves_remove_missing_value(UINT nSize, const OneCurveData* pCurves);
/// End AVECURVES_RESULTS_NOT_GOOD_WHEN_CURVES_HAVE_MISSING_VALUES

/// Jack 01/07/2008 SKIP_POINTS_IN_VECTOR
enum
{
	KEEP_FIRST_PT=0,
	AVER_X_AVER_Y,
	AVER_X_RANDOM_Y,
};

///Jack 1/12/2009 ADD_OPTION_WHETHER_CONSIDER_LAST_SAMPLING_SIZE_DATA_POINTS
//OCMATH_API int ocmath_skip_points_in_every_sampling_size(double * pX, double * pY, int nSize, double * pSkippedX, double * pSkippedY, int nSkipEveryNumPoints, int nStartSkipIndex=0, int KeepDataPtMethod=0, int iSeedNegValue=0);
OCMATH_API int ocmath_skip_points_in_every_sampling_size(double * pX, double * pY, int nSize, double * pSkippedX, double * pSkippedY, int nSkipEveryNumPoints, int nStartSkipIndex=0, int KeepDataPtMethod=0, int iSeedNegValue=0, bool bConsiderLastUnModPtsOrNot = true);
///ENd ADD_OPTION_WHETHER_CONSIDER_LAST_SAMPLING_SIZE_DATA_POINTS
/// End SKIP_POINTS_IN_VECTOR

///Jack 1/09/2009 ADD_VARIATION_AND_INTERPOLATE_OPTION
OCMATH_API int ocmath_create_equal_spaced_vec(double * pEqualSpaceData, int nSize, double dFirstValue, double dinc);
///End ADD_VARIATION_AND_INTERPOLATE_OPTION


enum {GPX_GAUSS, GPX_LORENTZ};
//x0 = peak center
//w = peak width
//nFuncForm = enum {GPX_GAUSS, GPX_LORENTZ}
OCMATH_API int ocmath_generate_peak_x_array(double* pData, uint nPts, double x1, double x2, double x0, double w, int nFuncForm);

//OCMATH_API	int ocmath_reducexy_by_x_inc(const double *px, const double *py, const UINT nSize, const double inc, double *pxd, double *pyd, double *pxstart=NULL, double *pxend=NULL);

//OCMATH_API	int ocmath_reducexy_by_groups(const double *px, const double *py, const UINT nSize, const UINT nGroups, double *pxd, double *pyd, double *pxstart=NULL, double *pxend=NULL);

/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_reducexy_n_groups_(global_function)
*/
OCMATH_API	int ocmath_reducexy_n_groups(const double *px, const double *pData, const UINT nSize, const int iOption, double *pMerged, int nBins);

/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_reducexy_n_points_(global_function)
*/
OCMATH_API	int ocmath_reducexy_n_points(const double *pData, double *pDataMerged, const UINT nSize, const UINT nPoints, int iOption);

/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocmath_reducexy_fixing_increbin_(global_function)
*/
OCMATH_API	int ocmath_reducexy_fixing_increbin(const double *px, const double *pData, const UINT nSize, const int iOption, double *pMerged, double dInc);

OCMATH_API	int	ocmath_2d_subtract_background_from_data(int nSizeX, int nSizeY, const double *px, const double *py, const double *pz, int nSizeBX, int nSizeBY, const double *pxb, const double *pyb, const double *pzb, double *pzd);

/// Fisher 07/22/09 AREA_OF_3D_SURFACE
OCMATH_API	int	ocmath_3d_surface_area_grid(const double *pxGrid, const double *pyGrid, const double *pzMat, const UINT nRows, const UINT nCols, double *pArea, const double *pxBoundry = NULL, const double *pyBoundry = NULL, const int nSizeBoundary = 0);
OCMATH_API	int	ocmath_3d_surface_area_mesh(const double *px, const double *py, const double *pz, const UINT nSize, double *pArea);
/// End AREA_OF_3D_SURFACE

/// Fisher 2009/08/26 TERNARY_CONTOUR_PLOT
OCMATH_API	int	ocmath_get_ternary_data_from_xy(int nSize, double *px, double *py, double *pz);
/// ------

/// Fisher 2010/03/03 qa80-15161 AREA_INSIDE_TERNARY_CONTOUR
OCMATH_API	int	ocmath_get_xy_from_ternary_data(int nSize, double *px, double *py, double *pz);
/// ------

OCMATH_API int ocmath_check_infinity(double* pData, int nSize, int* pResult, int nResultSize);

OCMATH_API int ocmath_array_find_indices(double* pData, int nSize, double* pVal, int nNumVal, int *pnIndices);
OCMATH_API int ocmath_binary_search(double* pData, int nSize, double dVal, int *pnIndex);
OCMATH_API int ocmath_find_nearest_index(double* pData, int nSize, double dVal, int *pnNearestLeft = NULL, int *pnNearestRight = NULL, int *pnNearest = NULL);

///Kyle 05/21/2010 OGR-98 IMAGE_PROFILE_SPEED_IMPROVMENT
enum {
	FINDVAL_NO_ROUND_NEAREST_INDEX = 0x0001,
};
OCMATH_API int ocmath_find_nearest_values(double* pValues, int nSizeData, const double* pData, int nSizeIndex, const double* pIndices, DWORD dwCtrl = 0);
///End IMAGE_PROFILE_SPEED_IMPROVMENT

///------ Folger 09/27/2010 ORG-1159 MOVE_match_peaks_centers_by_index_TO_VC_AS_OCMATH_FUNCTION
OCMATH_API int	ocmath_match_peaks_centers_by_index(const double* pvX, const double* pvY, int nSize, const int* pvnPeakIndices, double* pvPeakX, double* pvPeakY, int nSizePeaks);
///------ End MOVE_match_peaks_centers_by_index_TO_VC_AS_OCMATH_FUNCTION

#ifdef __AFX_H__
	}
#endif	//__AFX_H__

#endif //_OC_MATH_H
