/* File: Fitdemo.c Copyright 1993 Microcal Software Inc Revised 25 August 1994 for version 3.5 */ #include /* The following entry function * related to Windows */ #ifndef _WIN32 int FAR PASCAL LibMain(hModule, wDataSeg, cbHeapSize, lpszCmdLine) HANDLE hModule; WORD wDataSeg; WORD cbHeapSize; LPSTR lpszCmdLine; { return 1;/* Nothing is done, but it is necessary */ } // ANU v4.134 9/30/96 32_BIT_COMPATIBLE #else //_WIN32 BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) { // The return value is only used for DLL_PROCESS_ATTACH; all other // conditions are ignored. return TRUE; // successful DLL_PROCESS_ATTACH } #endif ///end 32_BIT_COMPATIBLE /* Your DLL code starts here */ #include /* This is needed for FitFunc2 * which uses pow and exp */ #include "..\..\include\orgdll.h" /* this file includes callback function * information that is used in FitFunc2 to perform a convolution */ ///Function names have to be upper case so that origin can //recognize the functions. int FAR PASCAL FITFUNC1(HWND hWnd, double FAR * lpValue, short nParam, double FAR *lpParam,LPCALLBK lpfn); int FAR PASCAL FITFUNC2(HWND hWnd, double FAR * lpValue, short nParam, double FAR *lpParam,LPCALLBK lpfn); int FAR PASCAL FITFUNC1( HWND hWnd, /* Origin's main window */ double FAR * lpValue,/* input (x) ,output (y)*/ short nParam, /* number of parameters */ double FAR * lpParam,/* parameter array */ LPCALLBK lpfn) /* call back function for additional info */ { /* In this demo, the function is a simple linear * f(x) = A + B * x + C * x * x; * nParam should be 3 */ double x = *lpValue; /* lpValue point to a temperary location * that contains the X value on input */ double y; if(nParam == 0) return(0); /* this is an init message, we don't * do anything here but we must exit * before trying to evaluate the function */ #define A lpParam[0] #define B lpParam[1] #define C lpParam[2] y = A + B * x + C*x*x; *lpValue = y; /* result of the function is stored back to lpValue */ return(0); /* You must return zero if there is no error * otherwise you can return any number other than * zero to signal an error */ } /* the following is a more complicated example that involves * using the call back function to access the worksheet * for additional data to perform a convolution */ int FAR PASCAL FITFUNC2( HWND hWnd, /* Origin's main window */ double FAR * lpValue, /* input (x) ,output (y)*/ short nParam, /* number of parameters */ double FAR * lpParam, /* parameter array */ LPCALLBK lpfn) /* call back function for additional info */ { /* In this example we have four parameters: H, K, M, C. The basic function form is f(i) = M X[i]^H /(K^H + x[i]^H) We convolute f(i) with an exponential decay for j = 0 to i y(i) += f(j) * exp((j - i) / C) */ #define PARAM_H lpParam[0] #define PARAM_K lpParam[1] #define PARAM_M lpParam[2] #define PARAM_C lpParam[3] long i, j, N[4]; double /*value,*/ f_value, y_value, x_value; char szTemp[80]; DWORD dwID; DATAELEMENT stDataElement; if( nParam == 0 ) return(0); /* this is an init message, we don't * do anything here but we must exit * before trying to evaluate the function */ /* first we need to find the data range in the worksheet */ /* Execute a simple script command to place the name of the current fitting dataset into the %A variable. Next, copy the name from %A to our local buffer. When we have the name we can get the dataset's id. */ lpfn(hWnd, WCB_EXECUTE, "%A=NLSF.FITDATA$", 0L); // Execute script command. lpfn(hWnd, WCB_GET_STRING, (LPSTR)szTemp, 0); // Copy %A string. dwID = lpfn(hWnd, WCB_DATA_GET_ID, (LPSTR)szTemp, (LPSTR)N); // Get dataset's id and range. if( dwID == 0 ) // Zero indicates dataset was not found. return 1; // Return 1 to indicate an error. /* this is C, not LabTalk, so row number starts * from zero, so typically N[0] == 0 */ /* next, we need to find the current row number that * we need to return the function value */ i = (long)lpValue[1]; /* as provided when the DLL function is called, * [0] is the x value and [1] is the row number * which is in C convention to start from zero */ y_value = 0; for( j = N[0]; j < i; j++ ) { /* to evaluate f_value, we need * the x_value at row j */ stDataElement.index = j; if( lpfn(hWnd, WCB_DATA_GET_VALUE, dwID, &stDataElement) ) return 1; x_value = stDataElement.value; f_value = PARAM_M * pow(x_value, PARAM_H) / (pow(PARAM_K, PARAM_H) + pow(x_value, PARAM_H)); y_value += f_value * exp((j - i) / PARAM_C); } /* you may need to add error checking and parameter * checking in the code above and return 1 whenever * anything goes wrong */ *lpValue = y_value; /* result of the function is stored back to lpValue */ return(0); }