/*------------------------------------------------------------------------------*
 * File Name: Data.h															*
 * Creation: CPY 7/14/2001														*
 * Purpose: Origin C header file for Origin basic Data types					*
 * Copyright (c) OriginLab Corp.	2002 - 2007									*
 * All Rights Reserved															*
 * Modifications:
 *  LAS, 1/31/03 commented out NLSFCntrl related items; 
 *               using NLSF = LabTalk.NLSF can be used instead
 *
 *------------------------------------------------------------------------------*/

#ifndef _DATA_H
#define _DATA_H

#include <common.h>

#ifndef _STRING_H
#include <string.h>		// Most likely will need strings
#endif // _STRING_H

#include <OC_types.h>	// Structures used in Origin internal functions

#ifndef _WKSHEET_H
#include <Wksheet.h>
#endif // _WKSHEET_H

#include <vector.h>
#include <MatrixData.h>
#include <curve.h>
/////////////////////////////////////////////////////////
// The following functions are implemented in internal.c.
/////////////////////////////////////////////////////////

/** >Statistics
		Get the maximum value of a data set.
	Example:
		// Assumes Data1_A exists and contains data
		Dataset dsA("Data1_A");
		double dMax = max(dsA);
		printf("Maximum value of Data1_A is %g", dMax);
	Parameters:
		 ds=Input Origin C Dataset object
	Return:
		Returns the maximum value of a data set.
	SeeAlso:
		min
*/
double	max(Dataset &ds); // Get the maximum value of a data set.

/** >Statistics
		Get the minimum value of a data set.
	Example:
		// Assumes Data1_A exists and contains data
		Dataset dsA("Data1_A");
		double dMin = min(dsA);
		printf("Minimum value of Data1_A is %g", dMin);
	Parameters:
		 ds=Input Origin C Dataset object
	Return:
		Returns the minimum value of a data set.
	SeeAlso:
		max
*/
double	min(Dataset &ds); // Get the minimum value of a data set.

/** >Analysis
		Get the value of X at the minimum Y value of a curve.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double dXatYmin = xatymin(crv); 
		printf("Value of X at minimum Y is %g", dXatYmin);
	Parameters:
		 crv=Input Origin C Curve object
	Return:
		Returns the value of X at the minimum Y value of a curve.
	SeeAlso:
		xatymax, yatxmin, yatxmax, xaty50
*/
double	xatymin(Curve &crv); // Get the value of X at the minimum Y value of a curve.

/** >Analysis
		Get the value of X at the maximum Y value of a curve.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double dXatYmax = xatymax(crv); 
		printf("Value of X at maximum Y is %g", dXatYmax);
	Parameters:
		 crv=Input Origin C Curve object
	Return:
		Returns the value of X at the maximum Y value of a curve.
	SeeAlso:
		xatymin, yatxmin, yatxmax, xaty50
*/
double	xatymax(Curve &crv); // Get the value of X at the maximum Y value of a curve.

/** >Analysis
		Get the value of Y at the maximum X value of a curve.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double dYatXmax = yatxmax(crv); 
		printf("Value of Y at maximum X is %g", dYatXmax);
	Parameters:
		 crv=Input Origin C Curve object
	Return:
		Returns the value of Y at the maximum X value of a curve.
	SeeAlso:
		xatymin, yatxmin, xatymax, xaty50
*/
double	yatxmax(Curve &crv); // Get the value of Y at the maximum X value of a curve.

/** >Analysis
		Get the 25th percentile of a data set.
	Example:
		// Assumes Data1_A exists and contains data
		Dataset dsA("Data1_A");
		double dP25 = y25(dsA);
		printf("25th Percentile of Data1_A is %g", dP25);
	Parameters:
		 ds=Input Origin C Dataset object
	Return:
		Returns the 25th percentile of a data set.
	SeeAlso:
		y50, y75
*/
double	y25(Dataset &ds); // Get the 25th percentile of a data set.

/** >Analysis
		Get the 50th percentile of a data set.
	Example:
		// Assumes Data1_A exists and contains data
		Dataset dsA("Data1_A");
		double dP50 = y50(dsA);
		printf("50th Percentile of Data1_A is %g", dP50);
	Parameters:
		 ds=Input Origin C Dataset object
	Return:
		Returns the 50th percentile of a data set.
	SeeAlso:
		y25, y75
*/
double	y50(Dataset &ds); // Get the 50th percentile of a data set.

/** >Analysis
		Get the 75th percentile of a data set.
	Example:
		// Assumes Data1_A exists and contains data
		Dataset dsA("Data1_A");
		double dP75 = y75(dsA);
		printf("75th Percentile of Data1_A is %g", dP75);
	Parameters:
		 ds=Input Origin C Dataset object
	Return:
		Returns the 75th percentile of a data set.
	SeeAlso:
		y25, y50
*/
double	y75(Dataset &ds); // Get the 75th percentile of a data set.

/** >Analysis
		Get the value of X at the 50th percentile Y value of a curve.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double dXatY50 = xaty50(crv); 
		printf("Value of X at 50th Percentile of Y is %g", dXatY50);
	Parameters:
		 crv=Input Origin C Curve object
	Return:
		Returns the value of X at the 50th percentile Y value of a curve.
	SeeAlso:
		xatymin, xatymax, yatxmin, yatxmax
*/
double	xaty50(Curve &crv); // Get the value of X at the 50th percentile Y value of a curve.

/** >Analysis
		Get the peak width of a curve at half the maximum Y value.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double dWx = fwhm(crv);
		printf("Peak width at half maximum Y is %g", dWx);
	Parameters:
		 crv=Input Origin C Curve object
		 dYoffset=Y offset subtracted from curve
	Return:
		Returns the peak width of a curve at half the maximum Y value.
	SeeAlso:
		area
*/
double	fwhm(Curve &crv, double dYoffset = 0); // Get the peak width of a curve at half the maximum Y value.

/** >Analysis
		Get the area under a curve.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double dA = area(crv);
		printf("Area under curve is %g",dA);
	Parameters:
		 crv=Input Origin C Curve object
		 dYoffset=Y offset subtracted from curve
	Return:
		Returns the area under a curve.
	SeeAlso:
		fwhm
*/
double	area(Curve &crv, double dYoffset = 0); // Get the area under a curve.

/** >Analysis
		Sort a curve in ascending order of X.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		BOOL bErr = sort(crv);
	Parameters:
		 crv=Input Origin C Curve object
	Return:
		Returns TRUE on success and FALSE on failure.
	SeeAlso:
		vectorbase::Sort
*/
BOOL	sort(Curve &crv); // Sort a curve in ascending order of X.

/** >Analysis
		Smooth a curve using Adjacent Averaging, FFT, or Savitzky-Golay.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		BOOL bErr = smooth(crv);
	Parameters:
		crv=Input Origin C Curve object
		imethod=Input method: Adjacent Averaging (default 0), FFT (1), or Savitzky-Golay (2)
		ileftpts=Input left points (default is 3)
		irightpts=Input right points (default is 3, Savitzky-Golay only)
		ipolydeg=Input degree of polynomial (default is 2, Savitzky-Golay only) 
	Return:
		Returns TRUE on success and FALSE on failure.
*/
BOOL	smooth(Curve &crv, int imethod=0, int ileftpts = 3, int irightpts = 3, int ipolydeg = 2); // Smooth a curve using Adjacent Averaging, FFT, or Savitzky-Golay.

/** >Analysis
		Fit a polynomial equation to a curve or curve segment and return the parameter coefficients. If specified,
		only the Nth segment of M equal curve segments is fit.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double coeff[3];
		fitpoly(crv, 2, &coeff, 1, 3); // Fit 2nd degree polynomial to first of 3 equal curve segments
	Parameters:
		crv=Input curve to fit
		ipolyorder=Input degree of polynomial equation
		coeff=Output array containing parameter coefficients
		inumer=Input Nth segment of M equal curve segments (default 0 fits entire range as one segment) 
		idenom=Input number M of equal curve segments (default 0 fits entire range as one segment)   
	Return:
		Returns TRUE on success and FALSE on failure.
	SeeAlso:
		fitpoly_range, initNLSF, fitNLSF 
*/
BOOL	fitpoly(Curve &crv, int ipolyorder, double *coeff, int inumer = 0, int idenom = 0); // Fit a polynomial equation to a curve or curve segment.

/** >Analysis
		Initialize the Origin C NLSF control structure.
	Sample Data:
		2	10.54362
		4	8.85013
		6	7.51005
		8	6.23363
		10	5.31886
		12	5.04538
		14	5.47292
		16	5.6315
		18	5.09736
		20	4.94923
		22	5.10317
		24	5.02472
	Example:
		// Assumes Sample Data are in Data1_A and Data1_B
		NLSFCntrl control;                       // Declare NLSF control
		initNLSF(control);                       // Initialize NLSF control
		lstrcpy(control.szYdataName, "Data1_B"); // Set Y data to fit
		lstrcpy(control.szFuncName, "ExpDec1");  // Set fit function
		fitNLSF(control);                        // Use NLSF control to fit data
		LT_execute("layer -a");                  // Rescale graph to show all points
	Parameters:
		control=Input NLSF control structure (see system header file OC_types.h for elements and initial values)   
	Return:
		Returns TRUE on success and FALSE on failure.
	SeeAlso:
		fitNLSF, fitpoly, fitpoly_range
*/
//BOOL	initNLSF(NLSFCntrl &control); // Initialize the Origin C NLSF control structure.

/** >Analysis
		Use the Origin C NLSF control structure to fit a data set.
	Sample Data:
		2	10.54362
		4	8.85013
		6	7.51005
		8	6.23363
		10	5.31886
		12	5.04538
		14	5.47292
		16	5.6315
		18	5.09736
		20	4.94923
		22	5.10317
		24	5.02472
	Example:
		// Assumes Sample Data are in Data1_A and Data1_B
		NLSFCntrl control;                       // Declare NLSF control
		initNLSF(control);                       // Initialize NLSF control
		lstrcpy(control.szYdataName, "Data1_B"); // Set Y data to fit
		lstrcpy(control.szFuncName, "ExpDec1");  // Set fit function
		fitNLSF(control);                        // Use NLSF control to fit data
		LT_execute("layer -a");                  // Rescale graph to show all points
	Parameters:
		control=Input NLSF control structure (see system header file OC_types.h for elements and initial values)   
	Return:
		Returns TRUE on success and FALSE on failure.
	SeeAlso:
		initNLSF, fitpoly, fitpoly_range
*/
//BOOL	fitNLSF(NLSFCntrl &control); // Use the Origin C NLSF control structure to fit a data set.

/** >Analysis
		Fit a data set having to pass only a small set of parameters.
	Sample Data:
		2	10.54362
		4	8.85013
		6	7.51005
		8	6.23363
		10	5.31886
		12	5.04538
		14	5.47292
		16	5.6315
		18	5.09736
		20	4.94923
		22	5.10317
		24	5.02472
	Example:
		// Assumes Sample Data are in Data1_A and Data1_B
		string strYData = "Data1_B";
		string strFitFunc = "ExpDec1";
		fitNLSF(strYData,strFitFunc);
		LT_execute("layer -a");                  // Rescale graph to show all points
	Parameters:
		strYData=Input name of Y data set to fit
		strFitFunc=Input name of NLSF fitting function
		iwType=Input weighting type or method: no weighting (default 0), instrumental or weight by error bars (1),
			statistical (2), and arbitrary or weight by data set (3)  
		strWtData=Input name of weighting data set when iwType is 3
	Return:
		Returns the Chi-Square value. 
	SeeAlso:
		fitpoly, fitpoly_range, initNLSF
*/
//double	fitNLSF(string strYData, string strFitFunc, int iwType=0, string strWtData=''); // Fit a data set having to pass only a small set of parameters.

/** >Analysis
		Get the value of Y at a horizontal asymptote. If the asymptote has two branches then Y is defined as
		Y = (yatxmax+yatxmin)/2 and if the asymptote has a single branch then Y is defined as either yatxmax
		or yatxmin depending on where the slope of the curve is closest to zero.
	Sample Data:
		-20	-3.04762
		-14	-3.06667
		-8	-3.11111
		-2	-3.33333
		-1	-3.5
		0	-4
		1	--
		2	-2
		3	-2.5
		4	-2.66667
		10	-2.88889
		16	-2.93333
		22	-2.95238
	Example:
		// Assumes Data1_A and Data1_B exist and contain the Sample Data
		Curve crv("Data1_A","Data1_B");
		double dYatHA = yatasymt(crv);
		printf("The value of Y at the Horizontal Asymptote is %g",dYatHA); 
	Parameters:
		crv=Input curve whose asymptote is found
	Return:
		Returns the value of Y at a horizontal asymptote.
	SeeAlso:
		xatasymt, yatxmax, yatxmin
*/
double	yatasymt(Curve &crv); // Get the value of Y at a horizontal asymptote.

/** >Analysis
		Get the value of X at a vertical asymptote. If the asymptote has two branches then X is defined as
		X = (xatymax+xatymin)/2 and if the asymptote has a single branch then X is defined as either xatymax
		or xatymin depending on where the reciprocal of the slope of the curve is closest to zero.
	Sample Data:
		-20	-3.04762
		-14	-3.06667
		-8	-3.11111
		-2	-3.33333
		-1	-3.5
		0	-4
		1	--
		2	-2
		3	-2.5
		4	-2.66667
		10	-2.88889
		16	-2.93333
		22	-2.95238
	Example:
		// Assumes Data1_A and Data1_B exist and contain the Sample Data
		Curve crv("Data1_A","Data1_B");
		double dXatVA = xatasymt(crv);
		printf("The value of X at the Vertical Asymptote is %g",dXatVA);
	Parameters:
		crv=Input curve whose asymptote is found
	Return:
		Returns the value of X at a vertical asymptote.
	SeeAlso:
		yatasymt, xatymax, xatymin
*/
double	xatasymt(Curve &crv); // Get the value of X at a vertical asymptote.

/** >Analysis
		Fit a polynomial equation to a range of a curve and return the parameter coefficients.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double coeff[3];
		fitpoly_range(crv, 0, crv.GetUpperBound(), 2, &coeff); // Fit 2nd degree polynomial to entire curve
	Parameters:
		crv=Input curve to fit
		ibeg=Input beginning index to fit
		iend=Input ending index to fit
		ipolyorder=Input degree of polynomial equation
		coeff=Output array containing parameter coefficients
	Return:
		Returns TRUE on success and FALSE on failure.
	SeeAlso:
		fitpoly, initNLSF, fitNLSF 
*/
BOOL	fitpoly_range(Curve &crv, int ibeg, int iend, int ipolyorder, double *coeff); // Fit a polynomial equation to a range of a curve.

/** >Analysis
		Get the value of Y at the minimum X value of a curve.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data
		Curve crv("Data1_A","Data1_B");
		double dYatXmin = yatxmin(crv);
		printf("Value of Y at minimum X is %g", dYatXmin);
	Parameters:
		 crv=Input Origin C Curve object
	Return:
		Returns the value of Y at the minimum X value of a curve.
	SeeAlso:
		xatymin, xatymax, yatxmax, xaty50
*/
double	yatxmin(Curve &crv); // Get the value of Y at the minimum X value of a curve.

//////////////////////////////////////////////////////////////////////////////
// The following are internal Origin functions related to Datasets and Curves
//////////////////////////////////////////////////////////////////////////////

#pragma dll(@OK)	// Assoicate all functions below to Origin OK dll

/** >Statistics
		Compute basic summary (descriptive) statistics on an Origin data set.
	Example:
		int iSize;
		Dataset dsDataIn("Data1_B");
		iSize=dsDataIn.GetSize();
		Dataset dsSumOfDataIn("Data1_C");
		dsSumOfDataIn.SetSize(iSize);
		BasicStats bsStat;
		Data_sum( &dsDataIn, &bsStat, &dsSumOfDataIn );
		printf( "Min = %f\nMax = %f\nMean = %f\nSD = %f\nTotal = %f\nSSDM = %f\nN = %d\nMissing = %d\niMax = %d\niMin = %d",
		bsStat.min, bsStat.max, bsStat.mean, bsStat.sd, bsStat.total, bsStat.ssdm,
		bsStat.N, bsStat.Missing, bsStat.iMax, bsStat.iMin );
	Parameters:
		pdsData=Pointer to input dataset
		pbsStat=Pointer to returned BasicStats structure (see OC_types.h)
		pdsSumData=Pointer to returned dataset containing cumulative sum
	Return:
		Returns TRUE, a BasicStats structure (see OC_types.h), and if specified, a data set containing
		a cumulative sum of the input data set on success and returns FALSE on failure.
*/
BOOL	Data_sum(Dataset* pdsData, BasicStats* pbsStat, Dataset* pdsSumData=NULL); // Dataset basic summary (descriptive) statistics.

/** >Statistics
		Calculate percentiles at given percent values for the given dataset.
	Example:
		// Assumes Data1_A exists in Origin and contains data
		Dataset dsA( "Data1_A" );
		double dPercent = 50, dPercentile;
		Data_percentiles( &dsA, &dPercent, &dPercentile, 1 );
		printf( "The 50th percentile is %g\n", dPercentile );
		
		double ardPercents[3] = { 5, 25, 95 };
		double ardPercentiles[3];
		Data_percentiles( &dsA, ardPercents, ardPercentiles, 3, TRUE );
		for(int ii = 0; ii < 3; ii++ )
			printf( "The %gth percentile is %g\n", ardPercents[ii], ardPercentiles[ii] );	
	Parameters:
		pdsData=Input Dataset for which percentiles are computed
		ardPercents=Input array of percents at which percentiles are computed
		ardPercentiles=Output array of percentiles
		nValues=Input number of percentile values to compute
		bInterpolate=Input flag indicating whether or not to average (interpolate) when needed such as when computing
			the 50th percentile for an even number of data values
	Return: 
		Returns TRUE on success and FALSE on failure.
*/
BOOL	Data_percentiles(Dataset* pdsData, const double ardPercents[], double ardPercentiles[], int nValues, BOOL bInterpolate=FALSE); // Calculate percentiles at given percent values for the given dataset.

/** >Analysis
		Function to sort a data set inplace.
	Examples:
		int iSize;
		Dataset dsRawDATA("Data1_A");
		iSize=dsRawDATA.GetSize();
		Dataset dsSortedDATA(dsRawDATA);	// Create temporary copy of raw data
		Data_sort(&dsSortedDATA);			// Sort temporary dataset

		vector<double> vSortedDATA;			// Create dynamic structure to hold sorted data
		vSortedDATA.SetSize(iSize);			// Dynamically set size of vector
		vSortedDATA=dsSortedDATA;			// Assign sorted datset to vector
		dsRawDATA.Detach();
		dsSortedDATA.Detach();
	Parameters:
		pdsData=Pointer to dataset
		bDescending=If TRUE sort in descending order otherwise sort in ascending order (default)
		bMissingAsMin=If TRUE evaluate Origin missing values as smallest value otherwise as largest value (default)		
	Returns:
		If successful returns TRUE and a sorted dataset otherwise returns FALSE.
*/
BOOL	Data_sort(Dataset* pdsData, BOOL bDescending = FALSE, BOOL bMissingAsMin = FALSE); // Function to sort a data set inplace.

/** >Analysis
		Table lookup with interpolation from two data sets (X and Y) of monotonic data. To find the y
		value at a given row number pass the Y data set but pass NULL for the X data set. To find the y value
		at a given x value pass the Y data set and the X data set. To find the row number of a given y value
		pass a data set containing row numbers as the Y data set and pass the Y data set as the X data set.
		Function Data_list provides table lookup without interpolation.
	SampleData:
		A	B	C
		10	2	1
		20	4	2
		30	6	3
	Example:
		double Xval, Yval, RowNumber;
		// To find Y value at given row number pass desired row number in place of X value and specify
		// NULL for X data set (Data_table will interpolate for fractional row numbers)
		RowNumber=2;
		Dataset dsYData("Data1_B");
		Yval=Data_table(RowNumber,&dsYData,NULL);
		printf("\nData1_B at row number %f = %f",RowNumber,Yval);

		// To find Y value at given X value pass X value and specify X data set (Data_table will interpolate
		// for all X values)
		Xval=25;
		Dataset dsXData("Data1_A");
		Yval=Data_table(Xval, &dsYData, &dsXData);
		printf("\nData1_B at X = %f is %f",Xval,Yval);

		// To find row number of given Y value, pass Y value in place of X value, specify Y data set as X data set, and 
		// pass a data set containing row numbers {1,2,3,4...} for Y data set (Data_table will interpolate to fractional
		// row numbers)
		Yval=4.5;
		Dataset dsRowNums("Data1_C");
		RowNumber=Data_table(Yval, &dsRowNums, &dsYData);
		printf("\nRow Number where Data1_B = %f is %f",Yval,RowNumber);
	Parameters:
		dX=The index value used to perform the lookup 
		pdsYdata=The Y data set
		pdsXdata=The X data set
	Return:
		Returns the interpolated lookup value from two sets of monotonic data.   
	SeeAlso:
		Data_list
*/
double	Data_table(double dX, Dataset* pdsYdata, Dataset* pdsXdata = NULL); // Table lookup with interpolation.

/** >Analysis
		Search for the first occurrence of a given value in a data set.
	Example:
		Dataset dsDataIn("Data1_A");
		dsDataIn.SetSize(4);
		dsDataIn[0]=0.28019;
		dsDataIn[1]=0.93577;
		dsDataIn[2]=0.81075;
		dsDataIn[3]=0.04418;
	
		double tol, v1, v2;
		int nrow;

		v1=0.81075;
		nrow=Data_list(v1, &dsDataIn); // use default precision
		printf("\nnrow = %d",nrow);

		v1=0.82;
		v2=dsDataIn[2];
 		tol=fabs((v2-v1)/(fabs(v1)+fabs(v2)));
 		printf("\ntol = %f",tol);	

 		nrow=Data_list(v1, &dsDataIn, 2); // tol is < 10^-2 so select row 2
		printf("\nnrow = %d",nrow);
		nrow=Data_list(v1, &dsDataIn, 3); // tol is not < 10^-3 so don't select row 2
		printf("\nnrow = %d",nrow);
	Parameters:
		dX=Value to lookup
		pdsData=Dataset to look in for value
		nPrecision=Indicates precision to use when determining if the given x value matches a value in the
			data set. Pass -1 to use Origin's default internal double comparison precision as specified by the @ND
			system variable. Otherwise, pass a positive integer to specify precision (significant digits). When
			either the x or the data set value is non-zero, the following condition indicates whether or not a match
			has been found:	abs((v2-v1)/(abs(v1)+abs(v2))) < 10^(-nPrecision).
	Return:
		Returns the row index of the first occurence of a given value found in a data set. Returns -1 if 
		value is not found.
	SeeAlso:
		Data_table
*/
int		Data_list(double dX, Dataset* pdsData, int nPrecision = 8); // Find first occurrence of value in data set.

/** >Analysis
		Integrate the given Curve relative to the X axis unless a baseline is specified.
	SampleData:
		A	B	C	D (column D is returned by Example)
		2	5	2	--
		4	5	2	6
		6	5	2	12
		8	5	2	18
	Example:
		BOOL bErr;
		Curve crvMyCurve( "Data1_A", "Data1_B" );		// Create Curve object to integrate
		Curve crvMyBaseline( "Data1_A", "Data1_C" );	// Create Curve object of integration baseline
		IntegrationResult irMyResults;					// Origin C structure to store integration results 
		Dataset dsCumIntRes( "Data1_D" );				// Cumulative integration result
		dsCumIntRes.SetSize( crvMyCurve.GetSize() );	// Set size of dsCumIntRes to size of cvMyCurve
		bErr = Curve_integrate( &crvMyCurve, &irMyResults, &crvMyBaseline, &dsCumIntRes, TRUE ); // Perform integration	
		printf( "Area = %f\n", irMyResults.Area );
	Parameters:
		pcrvData=Pointer to Curve to integrate
		pirResult=Pointer to IntegrationResult structure (see OC_types.h)
		pcrvBaseline=Pointer to baseline Curve
		pdsIntegral=Pointer to Dataset holding cumulative integration result
		bPaintShade=TRUE shades area of graph between integrated Curve and X axis (or baseline)
	Return:
		Returns TRUE if integration is successful and FALSE otherwise. Also returns a pointer to an IntegrationResult
		structure (see OC_types.h) and a pointer to dataset holding the cumulative integration result.
*/
BOOL	Curve_integrate(curvebase* pcrvData, IntegrationResult* pirResult, curvebase* pcrvBaseline=NULL, Dataset* pdsIntegral=NULL, BOOL bPaintShade=FALSE); // Integrate the given Curve.

/** >Analysis
		Get X value of Curve at specified index.
	Example:
		double dXatI;
		Curve crvMyCurve( "Data1_A", "Data1_B" );		// Create Curve object
		dXatI = Curve_x( &crvMyCurve, 2 );				// Get X value at 0 based index I=2
		printf( "X at I=2:\t%f\n", dXatI );
	Parameters:
		pcrvData=Pointer to Curve
		nIndex=Zero based index
	Return:
		For given Curve returns value of X at specified value of nIndex.
	SeeAlso:
		Curve_y, Curve_xfromY, Curve_yfromX
*/
double	Curve_x(curvebase* pcrvData, int nIndex); // Get X value of Curve at specified index.

/** >Analysis
		Get Y value of Curve at specified index.
	Example:
		double dYatI;
		Curve crvMyCurve( "Data1_A", "Data1_B" );		// Create Curve object
		dYatI = Curve_y( &crvMyCurve, 2 );				// Get Y value at 0 based index I=2
		printf( "Y at I=2:\t%f\n", dYatI );
	Parameters:
		pcrvData=Pointer to Curve
		nIndex=Zero based index
	Return:
		For given Curve returns value of Y at specified value of nIndex.
	SeeAlso:
		Curve_x, Curve_xfromY, Curve_yfromX 
*/
double	Curve_y(curvebase* pcrvData, int nIndex); // Get Y value of Curve at specified index.

/** >Analysis
		Get interpolated/extrapolated X value of Curve at specified Y value.
	Example:
		double dXfromY;
		Curve crvMyCurve( "Data1_A", "Data1_B" );		// Create Curve object
		dXfromY = Curve_xfromY( &crvMyCurve, 0.25 );	// Get X value at Y=0.25
		printf( "X from Y=0.25:\t%f\n", dXfromY );
	Parameters:
		pcrvData=Pointer to Curve
		dY=Value of Y
	Return:
		For given Curve returns interpolated/extrapolated value of X at specified value of Y.
	SeeAlso:
		Curve_y, Curve_x, Curve_yfromX
*/
double	Curve_xfromY(curvebase* pcrvData, double dY); // Get interpolated/extrapolated X value of Curve at specified Y value.

/** >Analysis
		Get interpolated/extrapolated Y value of Curve at specified X value.
	Example:
		double dYfromX;
		Curve crvMyCurve( "Data1_A", "Data1_B" );		// Create Curve object
		dYfromX = Curve_yfromX( &crvMyCurve, 3.0 );		// Get Y value at X=3.0
		printf( "Y from X=3.0:\t%f\n", dYfromX );
	Parameters:
		pcrvData=Pointer to Curve
		dX=Value of X
	Return:
		For given Curve returns interpolated/extrapolated value of Y at specified value of X.
	SeeAlso:
		Curve_y, Curve_x, Curve_xfromY
*/
double	Curve_yfromX(curvebase* pcrvData, double dX); // Get interpolated/extrapolated Y value of Curve at specified X value.

/** >Analysis
		Create a B Spline curve with optional weighting. The smoothness parameter can either be an arbitrary value
		>= 0 or an enumerated constant. The resulting B Spline curve will copy the source X data set if an empty
		X data set is provided or it will use a specified X data set as long as the range is within the source X range.
	Sample Data:
		57.93992	83.52885
		66.22726	75.17097
		70.83567	87.96739
		72.25362	91.59955
		72.39297	81.93563
		76.73526	89.47048
		77.71110	67.86902
	Example:
		// Assumes Data1_A and Data1_B exist and contain Sample Data
		// Assumes Data2_A and Data2_B exist
		Worksheet wks("Data1");
		Curve crvInput(wks,0,1);
		
		Worksheet wks2("Data2");
		Curve crvResult(wks2,0,1);

		Curve_bspline(&crvInput, &crvResult);
	Parameters:
		pcrvData=Input source curve
		pcrvResults=Output result curve
		dSmoothness=Smoothness factor can be any arbitrary value >= 0 or a predefined constant (BSPLN_AUTO=-3,
			BSPLN_INTERPOLATE and BSPLN_WEIGTHED_LEAST_SQUARE_POLYNOMIAL) enumerated in OC_const.h. The
			enumerated constants are negative numbers to distinguish them from arbitrary smoothness factors.
		pdsWeights=Dataset containing weights for the input curve. If not NULL the number of points in the weight
			data set must equal the number of points in the source curve. The default weighting is 1 for all points.
	Return:
   		Returns zero on successful exit and a non-zero error code on failure.
   		Errors:
	   		-1=System can not allocate enough memeory
			-2=Curve data type error
			-4=The result curve range can not be set 
			5=The smoothness parameter must be equal to or greater than 0
			11=The number of data points is less than 4
			63=The sequence of X in source data is not increasing
			73=Memory allocation failed
			240=The weights are not all positive
			254=The smoothness parameter is too small
   	SeeAlso:
		Curve_derivative
*/
int		Curve_bspline(curvebase* pcrvData, curvebase* pcrvResults, double dSmoothness = BSPLN_AUTO,  Dataset* pdsWeights = NULL); // Create a B Spline curve with optional weighting.

/** >Analysis
	 	Create the n-th Order derivative of a source curve with optional weighting. 
	Remarks:
		The smoothness parameter can either
	 	be an arbitrary value >= 0 or an enumerated constant. The resulting derivative curve will copy the source X data set
	 	if an empty X data set is provided or it will use a specified X data set as long as the range is within the source
	 	X range. 
	 	
	 	Please note that in Origin 7.0, the defualt argument dSmoothness was BSPLN_AUTO, in 7.5 it was changed to BSPLN_OFF.
		
	Example:
		// assumes data already in col(A), col(B)
		Worksheet wks = Project.ActiveLayer();
		Curve crvInput(wks,0,1);
		int nXCol, nYCol;
		Column cx = wks.Columns("DerivX");
		if(!cx)
			nXCol = wks.AddCol("DerivX");
		else
			nXCol = cx.GetIndex();
		
		wks.Columns(nXCol).SetType(OKDATAOBJ_DESIGNATION_X);
		
		Column cy = wks.Columns("DerivY");
		if(!cy)
			nYCol = wks.AddCol("DerivY");
		else
			nYCol = cy.GetIndex();
		
		Curve crvResult(wks,nXCol,nYCol);
		out_int("num of Rows before call = ", crvResult.GetSize());
	
		Curve_derivative(&crvInput, &crvResult);
		
		crvResult.Update(TRUE);// this will update the crvResult object to internal values inside Origin, that has been modified by Curve_derivative
		out_int("num of Rows after call = ", crvResult.GetSize());
		
	Parameters:
		pcrvData=Input source curve
		pcrvResults=Output result curve
		nOrder=The order of the derivative
		dSmoothness=Smoothness factor can be any arbitrary value >= 0 or a predefined constant (BSPLN_AUTO,
			BSPLN_INTERPOLATE and BSPLN_WEIGTHED_LEAST_SQUARE_POLYNOMIAL, BSPLN_OFF) enumerated in OC_const.h. The
			enumerated constants are negative numbers to distinguish them from arbitrary smoothness factors.
		pdsWeights=Dataset containing weights for the input curve. If not NULL the number of points in the weight
			data set must equal the number of points in the source curve. The default weighting is 1 for all points.
		if dSmoothness equals BSPLN_OFF, only the first order derivative will be calculated.
			
	Return:
   		Returns zero on successful exit and a non-zero error code on failure.
   		Errors:
	   		-1=System can not allocate enough memeory
			-2=Curve data type error
			-4=The result curve range can not be set 
			5=The smoothness parameter must be equal to or greater than 0
			11=The number of data points is less than 4
			63=The sequence of X in source data is not increasing
			73=Memory allocation failed
			240=The weights are not all positive
			254=The smoothness parameter is too small
	SeeAlso:
		Curve_bspline		
*/
int		Curve_derivative(curvebase* pcrvData, curvebase* pcrvResults, int nOrder = 1, double dSmoothness = BSPLN_OFF, Dataset* pdsWeights = NULL ); // Create the n-th Order derivative of a source curve with optional weighting.

/** >Analysis
		Get X and Y range of the Curve
	Example:
		double x1, x2;
		Curve cuv( "Data1_A", "Data1_B" );		// Create Curve object
		if(Curve_MinMax(&cuv, &x1, &x2))
			printf("%s X range is from %f to %f\n", cuv.GetName(), x1, x2);
	Parameters:
		pcuvData=Pointer to Curve
		pxMin = pointer to double for X min, NULL if no need to get this value
		pxMax = pointer to double for X max, NULL if no need to get this value
		bScanData = TRUE will scan both XY dataset of the curve for min and max, FALSE will reuse internal cached values. Typically there is no need to scan unless data has changed
		pyMin = pointer to double for Y min, NULL if no need to get this value
		pyMax = pointer to double for Y max, NULL if no need to get this value
	Return:
		True for success
	SeeAlso:
		Data_sum
*/
BOOL	Curve_MinMax(const curvebase* pcuvData, double* pxMin, double* pxMax, BOOL bScanData=FALSE, double* pyMin=NULL, double* pyMax=NULL); 

/** >Analysis
		Get the value of the specified dependent variable for the specified value of the independent variable. This function
		is used in conjunction with the internal Origin Non-linear Least Squares Fitter (NLSF) object and uses the most recent
		fitting function and parameter values specified through the NLSF interface or through script.
	Sample Data:
		2	10.54362
		4	8.85013
		6	7.51005
		8	6.23363
		10	5.31886
		12	5.04538
		14	5.47292
		16	5.6315
		18	5.09736
		20	4.94923
		22	5.10317
		24	5.02472
	Example:
		// Assumes the Sample Data has been plotted in an Origin graph and has just been fit
		// using the Origin Analysis:Fit Exponential Decay:First Order menu item
		double dDVal,dIVal = 7.22;
		dDVal = nlfFit( dIVal );
		printf("The value of the fit curve at x = %g is y = %g", dIVal, dDVal );
	Parameters:
		dx=Input value of the independent variable
		nDepend=Input dependent variable (0 based offset) 
	Return:
		Returns the value of the specified dependent variable for the given value of the independent variable.
   	SeeAlso:
   		nlfXfromY
*/
double	nlfFit(double dx, int nDepend = 0); // Get the value of the specified dependent variable for the specified value of the independent variable.

/** >Analysis
		Get the value(s) of the independent variable for the specified value of the specified dependent variable. This
		function is used in conjunction with the internal Origin Non-linear Least Squares Fitter (NLSF) object and uses
		the most recent fitting function and parameter values specified through the NLSF interface or through script.
	Sample Data:
		2	10.54362
		4	8.85013
		6	7.51005
		8	6.23363
		10	5.31886
		12	5.04538
		14	5.47292
		16	5.6315
		18	5.09736
		20	4.94923
		22	5.10317
		24	5.02472
	Example:
		// Assumes the Sample Data has been plotted in an Origin graph and has just been fit
		// using the Origin Analysis:Fit Exponential Decay:First Order menu item
		int nMaxX=1; // 1st Order exponentional decay funtion is 1 to 1 so there is only 1 independent value per dependent value
		double dDVal = 8.067, dIVal;
		int iErr;
		iErr = nlfXfromY( dDVal, &dIVal, nMaxX );
		printf("The value of x where y = %g is %g", dDVal, dIVal );
	Parameters:
		dy=Input value of the dependent variable
		parX=Output array for the x values
		nMaxX=Size of array pointed to by parX
		nDepend=Input dependent variable (0 based offset) 
	Return:
		Returns 1 if successful and returns the value(s) of the independent variable for the given value of the
		dependent variable.
   	SeeAlso:
   		nlfFit
*/
int		nlfXfromY(double dy, double* parX, int nMaxX, int nDependent=0); // Get the value(s) of the independent variable for the specified value of the specified dependent variable.

/**	>Analysis
		Copy a range of data from one data set to another. If need be the destination data set will be automatically
		resized.
	Example:
		Worksheet wks = Project.ActiveLayer();
		Dataset ds1(wks,0);
		Dataset ds2(wks,1);
		// Copy from row 3 to row 10 of column 1 into row 20 to 27 of column 2
		Data_copy(&ds2, &ds1, 2, 9, 19);
	Parameters:
		pdsDest=Input pointer to destination data set
		pdsSrc=Input pointer to source data set
		nSrcFrom=Input starting index of the source data set (0 based offset)
		nSrcTo=Input ending index of the source data set (0 based offset, default -1 copies to upper index)
		nDestFrom=Input starting index of the destination data set (0 based offset, default -1 uses nSrcFrom)
		bIgnoreMask=TRUE ignores masking in source data set, FALSE copies masked values as missing values
	Return:
		Returns TRUE if successful and FALSE if:
			1) nSrcFrom < 0 or nSrcFrom > source UpperIndex
			2) nSrcTo  < nSrcFrom or nSrcTo > UpperIndex
			3) nDestFrom < -1 (-1 means to use nSrcFrom)
*/
BOOL	Data_copy(Dataset* pdsDest, Dataset* pdsSrc, int nSrcFrom = 0, int nSrcTo=-1, int nDestFrom=-1, BOOL bIgnoreMask=TRUE); // Copy a range of data from one data set to another. 

#if _OC_VER > 0x0703
/**	>Plotting
		get dataset From and Step values that are used for plotting with Row# as X 
	Example:
		double dFrom, dStep;
		string str = "Data1_b";
		if(GetDatasetXFromStep(str, &dFrom, &dStep))
			printf("%s is a loose dataset, or its worksheet has No X column, so it has From/Step = %g/%g\n", str, dFrom, dStep);

	Parameters:
		lpcszDatasetName = [in] Dataset name
		double =  [out] plotting X from
		lpdbStep =[out] plotting X increment
	Return:
		Returns TRUE if the given dataset is a valid dataset and it is in a worksheet with no X column, or is a loose dataset, so the From/Step values are available, 
*/
BOOL GetDatasetXFromStep(LPCSTR lpcszDatasetName, double* lpdbFrom, double* lpdbStep);
#endif // _OC_VER > 0x0703

#endif //_DATA_H