Benutzerdefinierte Anpassungsfunktion mit Hilfe der GNU Scientific Library
Dieser Artikel stellt dar, wie die GSL-Funktion als Anpassungsfunktion
verwendet wird.
Origin-Version mind. erforderlich: 8.0 SR6
1. Wir passen die Beispieldaten nach dem folgenden Modell an:
0,1 bis 0,10517 0,2 bis 0,2214 0,3 bis 0,34986 0,4 bis 0,49182 0,5 bis 0,64872 0,6 bis 0,82212 0,7 bis 1,01375 0,8 bis 1,22554 0,9 bis 1,4596 1 bis 1,71828 1,1 bis 2,00417 1,2 bis 2,32012 1,3 bis 2,6693 1,4 bis 3,0552 1,5 bis 3,48169 1,6 bis 3,95303 1,7 bis 4,47395 1,8 bis 5,04965 1,9 bis 5,68589 2 bis 6,38906 2,1 bis 7,16617 2,2 bis 8,02501 2,3 bis 8,97418 2,4 bis 10,02318 2,5 bis 11,18249 2,6 bis 12,46374 2,7 bis 13,87973 2,8 bis 15,44465 2,9 bis 17,17415 3 bis 19,08554 3,1 bis 21,19795 3,2 bis 23,53253
2. Fügen Sie die Datei ocgsl.h in (Anwenderdateiordner) ein und
stellen Sie sicher, dass die gsl-DLLs vor dem nächsten Schritt in denselben
Speicherort kopiert werden. Siehe Aufrufen der GNU Scientific Library.
ocgsl.h
#pragma dll(libgsl, header) // this is OC special pragma, // header keyword is to indicate libgsl.dll is in same location as this file #define GSL_EXPORT // for OC, this is not needed, so make it empty // you can directly search and copy gsl function prototypes here typedef double (* FUNC)(double x, void * params); struct gsl_function_struct { FUNC function; void * params; }; typedef struct gsl_function_struct gsl_function; typedef struct {size_t limit; size_t size; size_t nrmax; size_t i; size_t maximum_level; double *alist; double *blist; double *rlist; double *elist; size_t *order; size_t *level; } gsl_integration_workspace; GSL_EXPORT gsl_integration_workspace *gsl_integration_workspace_alloc (;const size_t n); GSL_EXPORT void gsl_integration_workspace_free (gsl_integration_workspace * w); GSL_EXPORT int gsl_integration_qag (const gsl_function * f, double a, double b, double epsabs, double epsrel, size_t limit, int key, gsl_integration_workspace * workspace, double *result, double *abserr);
3. Drücken Sie F9, um den Dialog Fitfunktionen verwalten zu öffnen
und dann eine neue Funktion hinzuzufügen:
4. Drücken Sie auf die Schaltfläche auf der rechten Seite des Felds Funktion, um den Code Builder zu öffnen und die folgenden Codes zu kompilieren: _nlfgsl_integration_qag.fit
#include "..\ocgsl.h" static double f_callback(double x, void * params) { double alpha = *(double *)params; return exp(alpha*x); } void _nlsfgsl_integration_qag( // Fit Parameter(s): double y0, double a, double beta, // Independent Variable(s): double x, // Dependent Variable(s): double& y) { // Beginning of editable part double result, err, expected = -4,0; // Allocates a workspace suffcient to hold 1000 double precision intervals, // their integration results and error estimates gsl_integration_workspace *ww = gsl_integration_workspace_alloc(1000); gsl_function F; F.function = f_callback; F.params = β // integral interval (0, x), within the desired absolute // error 0 and relative error 1e-7 gsl_integration_qag(&F, 0, x, 0, 1e-7, 1000, 0, ww, &result, &err); // frees the memory associated with the workspace w gsl_integration_workspace_free (ww); y = y0 + a*result; // End of editable part }
Außerdem gibt es die folgende ausführlichere, aber ebenfalls effiziente
Version der Anpassungsfunktion:
//---------------------------------------------------------- // #include <ONLSF.h> #include "..\ocgsl.h"static double f_callback(double x, void * params) { double alpha = *(double *)params; return exp(alpha*x); } void _nlsfgsl_integration_qag( // Fit Parameter(s): double y0, double a, double beta, // Independent Variable(s): double x, // Dependent Variable(s): double& y) { // Beginning of editable part NLFitContext *pCtxt = Project.GetNLFitContext(); if ( pCtxt ) { static vector vInteg; NLSFCURRINFO stCurrInfo; pCtxt->GetFitCurrInfo(;&stCurrInfo); int nCurrentIndex = stCurrInfo.nCurrDataIndex; BOOL bIsNewParamValues = pCtxt->IsNewParamValues(); if ( bIsNewParamValues ) { vector vx; pCtxt->GetIndepData(&vx); int nSize = vx.GetSize(); vInteg.SetSize(nSize); // Allocates a workspace suffcient to hold 1000 double precision intervals, // their integration results and error estimates gsl_integration_workspace *ww = gsl_integration_workspace_alloc(1000); gsl_function F; F.function = f_callback; F.params = β double result, err, expected = -4,0; for(int ii=0; ii<nSize; ++ii) { // integral interval (0, vx[ii]), within the desired absolute // error 0 and relative error 1e-7 gsl_integration_qag(&F, 0, vx[ii], 0, 1e-7, 1000, 0, ww, &result, &err); vInteg[ii] = result; } // frees the memory associated with the workspace w gsl_integration_workspace_free (ww); } y = y0 + a*vInteg[nCurrentIndex]; x; } // End of editable part }
5. Fügen Sie die folgenden Initialisierungscodes hinzu:
Parameter Init
//Code to be executed to initialize parameters sort( x_y_curve ); double coeff[2]; fitpoly( x_y_curve, 1, coeff);a = coeff[0]; y0 = coeff[1]; beta=1,0
6. Anpassung mit Hilfe der benutzerdefinierten Funktion gsl_integration_qag, hier sind die Ergebnisse:
y0 = -1,06363E-6
a = 1
beta=1