📄 internal.c
字号:
/*------------------------------------------------------------------------------*
* File Name: Internal.c *
* Creation: CPY 3/5/2001 *
* Purpose: Support for using Origin C from inside Origin *
* This is used primarily in places like NLSF, Set Matrix Values and *
* function plotting and etc. *
* Copyright (c) OriginLab Corp.2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 *
* All Rights Reserved *
* *
* Modification Log: *
* Bill Liang,1/16/02
* Bill Liang,1/17/02
* CPY v7.0365 QA70-2583 LABTALK_AND_OC_ABS_CONSISTENT
* LAS 1/31/03 commented out the NLSFCntrl
* using NLSF = LabTalk.NLSF can be used instead
* CPY 7/7/03 changed to include only origin.h to take advantage of PCH
*------------------------------------------------------------------------------*/
#include <origin.h> // main Origin C header that is precompiled and already include most headers
// add your additional include files here
// ***************************
// functions that accept scalars and return a scalar
// ***************************
//------- CPY v7.0365 QA70-2583 LABTALK_AND_OC_ABS_CONSISTENT
// we need to provide this function such that the labtalk verison of abs
// will work the same as in Origin C. The C library function abs(n) would
// still be called if you are passing in an integer argument.
double abs(double x)
{
return fabs(x);
}
//-------
// returns max of two doubles
double max(double da, double db)
{
return (da > db ? da : db);
}
// returns min of two doubles
double min(double da, double db)
{
return (da < db ? da : db);
}
// returns max of two floats
float max(float fa, float fb)
{
return (fa > fb ? fa : fb);
}
// returns min of two floats
float min(float fa, float fb)
{
return (fa < fb ? fa : fb);
}
// returns max of two ints
int max(int ia, int ib)
{
return (ia > ib ? ia : ib);
}
// returns min of two ints
int min(int ia, int ib)
{
return (ia < ib ? ia : ib);
}
// returns max of two uints
uint max(uint na, uint nb)
{
return (na > nb ? na : nb);
}
// returns min of two uints
uint min(uint na, uint nb)
{
return (na < nb ? na : nb);
}
// returns max of two shorts
short max(short na, short nb)
{
return (na > nb ? na : nb);
}
// returns min of two shorts
short min(short na, short nb)
{
return (na < nb ? na : nb);
}
// returns max of two ushorts
ushort max(ushort wa, ushort wb)
{
return (wa > wb ? wa : wb);
}
// returns min of two ushorts
ushort min(ushort wa, ushort wb)
{
return (wa < wb ? wa : wb);
}
// ***************************
// functions that accept a dataset and return values from its properties
// ***************************
// returns min value of dataset
double min(Dataset &aa)
{
BasicStats stat;
stat.min = -1;
Data_sum(&aa, &stat);
return stat.min;
}
// returns max value of dataset
double max(Dataset &aa)
{
BasicStats stat;
stat.max = -1;
Data_sum(&aa, &stat);
return stat.max;
}
// returns 25th percentile value of dataset
double y25(Dataset &aa)
{
double perc, result;
BOOL interp = false;
perc=25;
Data_percentiles(&aa, &perc, &result, 1,interp);
return result;
}
// returns 50th percentile value of dataset
double y50(Dataset &aa)
{
double perc, result;
BOOL interp = false;
perc=50;
Data_percentiles(&aa, &perc, &result, 1,interp);
return result;
}
// returns 75th percentile value of dataset
double y75(Dataset &aa)
{
double perc, result;
BOOL interp = false;
perc=75;
Data_percentiles(&aa, &perc, &result, 1,interp);
return result;
}
// ***************************
// functions that accept a curve and return values from its properties
// ***************************
// this function is used only for the two functions below, so must be set to static
// so that it is invisible outside this file
static int minmax(Dataset &aa, BOOL bGetMin=TRUE)
{
BasicStats stat;
stat.iMin =0;
stat.iMax =0;
Data_sum(&aa, &stat);
return bGetMin? stat.iMin:stat.iMax;
}
// returns x value corresponding to minimum in y value
double xatymin(Curve &cc)
{
return Curve_x(&cc, minmax(cc));
}
// returns x value corresponding to minimum in y value
double xatymax(Curve &cc)
{
return Curve_x(&cc, minmax(cc,FALSE));
}
double yatxmax(Curve &cc)
{
if (cc.HasX())
{
Dataset xdata();
cc.AttachX(xdata);
double xmax = max(xdata);
return Curve_yfromX(&cc, xmax);
}
else
{
// GetUpperIndex returns the index immediately after the last point
int n = cc.GetUpperBound();
return cc[n-1];
}
}
double yatxmin(Curve &cc)
{
if (cc.HasX())
{
Dataset xdata();
cc.AttachX(xdata);
double xmin = min(xdata);
return Curve_yfromX(&cc, xmin);
}
else
{
return cc[0];
}
}
//returns x value correpsonding to mid y value
double xaty50(Curve &cc)
{
double ymiddle = (max(cc) + min(cc))/2.0;
return Curve_xfromY(&cc, ymiddle);
}
//returns x width of dataset corresponding to half the max value in y
//double fwhm(Curve &cc, double yoffset = 0)
double fwhm(Curve &cc, double yoffset)
{
Curve ccLocal(cc);
ccLocal -= yoffset;
IntegrationResult result;
BOOL ipass = Curve_integrate(&ccLocal, &result);
return result.dxPeak;
}
//returns area under the curve
//double area(Curve &cc, double yoffset = 0)
double area(Curve &cc, double yoffset)
{
Curve ccLocal(cc);
ccLocal -= yoffset;
IntegrationResult result;
BOOL ipass = Curve_integrate(&ccLocal, &result);
return result.Area;
}
// sorts the curve
BOOL sort(Curve &cc)
{
cc.TrimLeft(TRUE);
cc.Sort();// missing values are sorted to the end
cc.TrimRight();
return true;
}
// smooth the curve
//BOOL smooth(Curve &cc, int method=0, int leftpts = 3, int rightpts = 3, int polydeg = 2)
BOOL smooth(Curve &cc, int method, int leftpts , int rightpts, int polydeg)
{
string ydataname;
cc.GetName(ydataname);
if(method == 0) // perform adjacent averaging
{
_LT_Obj
{
curve.reset();
curve.data$ = ydataname;
curve.result$ = ydataname;
curve.smoothPts = leftpts;
curve.adjave();
}
return true;
}
else if (method == 1) // perform fft filtering
{
_LT_Obj
{
curve.reset();
curve.data$ = ydataname;
curve.result$ = ydataname;
curve.smoothPts = leftpts;
curve.FFTSmooth();
}
return true;
}
else // perform Savitzky-Golay filtering
{
_LT_Obj
{
curve.reset();
curve.data$ = ydataname;
curve.result$ = ydataname;
curve.smoothLeftPts = leftpts;
curve.smoothRightPts = rightpts;
curve.smoothPts = leftpts + rightpts + 1;
curve.polyDeg = polydeg;
curve.SGSmooth();
}
return true;
}
}
//-------- Bill Liang,1/16/02
// return the asymtoptic y value as follow:
// double-branch: (yatxmax+yatxmin)/2
// single-branch: yatxmax or yatxmin with the smaller slope
double yatasymt(Curve &cc)
{
Dataset xd;
cc.AttachX(xd);
if(fabs(xatymax(cc)-xatymin(cc))<(max(xd)-min(xd))*2.0/3)
{ // double-branch
return (yatxmin(cc)+yatxmax(cc))/2.0;
}
else
{ // single-branch
double dy1=Curve_yfromX(&cc,0.9*min(xd)+0.1*max(xd))-yatxmin(cc);
double dy2=yatxmax(cc)-Curve_yfromX(&cc,0.1*min(xd)+0.9*max(xd));
if(fabs(dy1)<fabs(dy2))
return yatxmin(cc);
else
return yatxmax(cc);
}
}
// return the asymtoptic x value as follow:
// double-branch: (xatymax+xatymin)/2
// single-branch: xatymax or xatymin with the smaller 1/slope
//************** Bill Liang,1/17/02
double xatasymt(Curve &cc)
{
Dataset xd;
cc.AttachX(xd);
if(fabs(yatxmax(cc)-yatxmin(cc))<(max(cc)-min(cc))*2.0/3)
{ // double-branch
if(fabs(xatymax(cc)-xatymin(cc))>(max(xd)-min(xd))*1.0/3)
{ // y-symemtric double-branch
if(fabs(min(cc)-yatasymt(cc))<fabs(max(cc)-yatasymt(cc)))
return xatymax(cc);
else
return xatymin(cc);
}
else
return (xatymin(cc)+xatymax(cc))/2.0;
}
else
{ // single-branch
double dy1=Curve_yfromX(&cc,0.9*min(xd)+0.1*max(xd))-yatxmin(cc);
double dy2=yatxmax(cc)-Curve_yfromX(&cc,0.1*min(xd)+0.9*max(xd));
if(fabs(dy1)<fabs(dy2))
return xatymax(cc);
else
return xatymin(cc);
}
}
//************** Bill Liang,1/17/02
// fit polynomial to curve on data points indexed from ibeg to iend
BOOL fitpoly_range(Curve &cc,int ibeg,int iend,int ipolyorder,double *coeff)
{
int ilower=cc.GetLowerBound();
int iupper=cc.GetUpperBound();
if(ibeg<ilower || iend>iupper || ibeg>=iend)
return false;
cc.SetLowerIndex(ibeg);
cc.SetUpperIndex(iend);
fitpoly(cc,ipolyorder,coeff);
// restore original indics
cc.SetLowerIndex(ilower);
cc.SetUpperIndex(iupper);
return true;
}
//----------------- end Bill Liang,1/16/02
// fit polynomial to curve and return coefficients
BOOL fitpoly(Curve &cc, int ipolyorder, double *coeff, int inumer, int idenom)
{
string strYdata;
cc.GetName(strYdata);
int ilower, iupper, ilen, iseg, ibeg, iend;
if ( (idenom != 0) )
{
if (inumer > idenom) return false;
ilower = cc.GetLowerBound();
iupper = cc.GetUpperBound();
ilen = iupper - ilower;
if (ilen <= idenom) return false;
iseg = ilen / idenom;
ibeg = iseg * (inumer - 1);
iend = ibeg + iseg;
cc.SetLowerIndex(ibeg);
cc.SetUpperIndex(iend);
}
_LT_Obj
{
stat.reset();
stat.apparent=0;
stat.pr.order = ipolyorder;
stat.data$ = strYdata;
stat.pr();
coeff[0] = stat.pr.a;
}
for( int i = 1; i <= ipolyorder; i++ )
{
string str;
str.Format("stat.pr.b%d", i);
LT_get_var(str, &coeff[i]);
}
if ( (idenom != 0) )
{
cc.SetLowerIndex(ilower);
cc.SetUpperIndex(iupper);
}
return true;
}
// the following is no longer needed and users should use
// using NLSF = LabTalk.NLSF; // Point to the NLSF object
// perform initialization of NLSF and set all control strucutre variables to sensible values
//BOOL initNLSF(NLSFCntrl &control)
//{
// _LT_Obj
// {
// nlsf.init();
// lstrcpy(control.szYdataName, nlsf.y$);
// lstrcpy(control.szFuncName, nlsf.func$);
// lstrcpy(control.szWtDataName, nlsf.w$);
// control.Tolerance = nlsf.tolerance;
// control.Confidence = nlsf.conf;
// control.Prediction = nlsf.pred;
// control.imaxIter = nlsf.maxIter;
// control.idataBegin = nlsf.dataBegin;
// control.idataEnd = nlsf.dataEnd;
// control.idataStep = nlsf.dataStep;
// control.iwType = nlsf.wType;
//
// for(int ii=0; ii <200; ii++)
// {
// control.Par[ii] = 0;
// control.Err[ii] = 0;
// control.Dep[ii] = 0;
// control.ConfIntv[ii] = 0;
// }
//
// control.openGraph = true;
// control.createCurve = true;
// control.confBands = false;
// control.predBands = false;
// control.createWks = false;
// control.pasteToPlot = true;
// control.pasteToResults = true; //control.sameXasData = true;
//
//
// }
// return true;
//}
//
// perform NLSF fitting using the NLSFControl structure
//BOOL fitNLSF(NLSFCntrl &control)
//{
// _LT_Obj
// {
// nlsf.msgPrompt = 0; // suppress error messages!
// nlsf.func$ = control.szFuncName; // set fitting function
// nlsf.fitdata$ = control.szYdataName; // set dependent variable
//
//
// Dataset dWeight(control.szWtDataName); // create dWeight dataset variable
//
// if( (control.iwType > 0) && (control.iwType < 5) )
// {
// nlsf.wType = control.iwType; // set weight method
// if( (dWeight.IsValid()) && (nlsf.wType != 0 && nlsf.wType !=2) )
// {
// nlsf.w$ = control.szWtDataName; // set weighting dataset
// }
// }
//
//
// nlsf.execute("parainit"); // initialize parameters
//
// if (control.imaxIter > 0) nlsf.iterateEX(control.imaxIter);
// else nlsf.iterateEX(100); // iterate
//
// if(control.openGraph)
// {
// if(control.confBands)
// {
// nlsf.createCurves("C"); // create confidence bands
// }
// if(control.predBands)
// {
// nlsf.createCurves("P"); // create prediction bands
// }
// if(control.pasteToPlot)
// {
// nlsf.pasteParams("Plot"); // create fit label on graph
// }
// if(control.createCurve)
// {
// nlsf.end(12); // create fit curve on graph
// }
// }
// if(control.pasteToResults)
// {
// nlsf.pasteParams("Results"); // create results in Results Log
// }
// if(control.createWks)
// {
// nlsf.paramWKS("Parameters"); // create Parameters worksheet
// }
//
// // assign nlsf object properties to NLSFCntrl structure
// control.ChisqDoF = nlsf.chiSqr;
// control.SSR = nlsf.ssr;
// control.Correlation = nlsf.cor;
// control.COD = nlsf.cod;
// control.MuFinal = nlsf.muMin;
// control.Mu = nlsf.mu;
// control.DerivStep = nlsf.derivStep;
// control.Tolerance = nlsf.tolerance;
// control.Confidence = nlsf.conf;
// control.Prediction = nlsf.pred;
// control.inPara = nlsf.nPara;
// control.inParaVary = nlsf.nParaVary;
// control.imaxIter = nlsf.maxIter;
// control.idataBegin = nlsf.dataBegin;
// control.idataEnd = nlsf.dataEnd;
// control.idataStep = nlsf.dataStep;
// control.inPoints = nlsf.nPoints;
// /*
// control.ixBegin = nlsf.xBegin;
// control.ixEnd = nlsf.xEnd;
// control.ixPoints = nlsf.xPoints;
// */
// control.iDOF = nlsf.dof;
// control.inConstr = nlsf.nConstr;
// control.inConstrEff = nlsf.nConstrEff;
// control.iwType = nlsf.wType;
//
// // set values of results from fit
// for(int ii = 1; ii <= nlsf.nPara; ii++)
// {
// control.Par[ii-1] = nlsf.p$(ii);
// control.Err[ii-1] = nlsf.e$(ii);
// control.Dep[ii-1] = nlsf.d$(ii);
// control.ConfIntv[ii-1] = nlsf.c$(ii);
// }
// }
// return true;
//}
// overloaded fitNLSF function to allow for quick fitting with weighting
//double fitNLSF(string strYData, string strFitFunc, int iwType, string strWtData)
//{
// NLSFCntrl control; // instantiate structure variable
// initNLSF(control); // initialize fit
//
// lstrcpy(control.szYdataName, strYData); // initialize dependent variable
// lstrcpy(control.szFuncName, strFitFunc); // initialize fitting function
//
// control.iwType = iwType; // initialize weight type
// lstrcpy(control.szWtDataName, strWtData); // initialize weighting dataset name
//
// fitNLSF(control); // fit
// return control.ChisqDoF;
//
//}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -