Author |
Topic |
|
King007
India
5 Posts |
Posted - 07/07/2017 : 05:23:35 AM
|
Hi, I need codes for Origin C regarding fitting a non linear function which include an integral: Debye Model for Specific Heat:
y=374.13 (x/θ_D )^3 ∫_0^(θ_D/x)▒(x^4 e^x)/(e^x-1)^2 dx
I tried with a given example and it was showing no error during compilation but doesn't show any curve while simulating or fitting. Here is the code which i used. Any help in this regard will be highly appreciated.
#pragma warning(error : 15618) #include <origin.h>
// Add your special include files here. // For example, if you want to fit with functions from the NAG library, // add the header file for the NAG functions here. #include <OC_nag.h>
// Add code here for other Origin C functions that you want to define in this file, // and access in your fitting function. struct user // parameters in the integrand { double Theta; }; // Function supplied by user, return the value of the integrand at a given x. static double NAG_CALL f_callback(double x, Nag_User *comm) { struct user *sp = (struct user *)(comm->p); double Theta; // temp variable to accept the parameters in the Nag_User communication struct Theta = sp->Theta; return x * x * x * x * exp( x ) / ((exp( x ) - 1) * ((exp ( x ) - 1)); }
// You can access C functions defined in other files, if those files are loaded and compiled // in your workspace, and the functions have been prototyped in a header file that you have // included above.
// You can access NLSF object methods and properties directly in your function code.
// You should follow C-language syntax in defining your function. // For instance, if your parameter name is P1, you cannot use p1 in your function code. // When using fractions, remember that integer division such as 1/2 is equal to 0, and not 0.5 // Use 0.5 or 1/2.0 to get the correct value.
// For more information and examples, please refer to the "User-Defined Fitting Function" // section of the Origin Help file.
//---------------------------------------------------------- // void _nlsfNewFunction42( // Fit Parameter(s): double a, double Q, // Independent Variable(s): double x, // Dependent Variable(s): double& y) { // Beginning of editable part // Through the absolute accuracy epsabs, relative accuracy epsrel and max_num_subint you can // control the precision of the integration you need // if epsrel is set negative, the absolute accuracy will be used. // Similarly, you can control only relative accuracy by set the epsabs negative double epsabs = 0.0, epsrel = 0.0001; // The max number of sub-intervals needed to evaluate the function in the integral // The more difficult the integrand the larger max_num_subint should be // For most problems 200 to 500 is adequate and recommended Integer max_num_subint = 200; // Result keeps the approximate integral value returned by the algorithm // abserr is an estimate of the error which should be an upper bound for the |I - result| // where I is the integral value double result, abserr; // The structure of type Nag_QuadProgress, // it contains pointers allocated memory internally with max_num_subint elements Nag_QuadProgress qp; // The NAG error parameter (structure) static NagError fail; // Parameters passed to integrand by Nag_User communication struct Nag_User comm; struct user s; s.Theta = Q; comm.p = (Pointer)&s; // Perform integration // There are 3 kinds of infinite boundary types you can use in Nag infinite integrator // Nag_LowerSemiInfinite, Nag_UpperSemiInfinite, Nag_Infinite d01smc(f_callback, 0, Theta/x, epsabs, epsrel, max_num_subint, &result, &abserr, &qp, &comm, &fail); // you may want to exam the error by printing out error message, just uncomment the following lines // if (fail.code != NE_NOERROR) // printf("%s\n", fail.message); // For the error other than the following three errors which are due to bad input parameters // or allocation failure NE_INT_ARG_LT NE_BAD_PARAM NE_ALLOC_FAIL // You will need to free the memory allocation before calling the integration routine again to avoid memory leakage if (fail.code != NE_INT_ARG_LT && fail.code != NE_BAD_PARAM && fail.code != NE_ALLOC_FAIL) { NAG_FREE(qp.sub_int_beg_pts); NAG_FREE(qp.sub_int_end_pts); NAG_FREE(qp.sub_int_result); NAG_FREE(qp.sub_int_error); } // Calculate the fitted value y = 374.13 * (x / Q) * (x / Q) * (x / Q) * result; // End of editable part } |
|
yuki_wu
896 Posts |
Posted - 07/07/2017 : 06:20:17 AM
|
Hi,
The fitting function and your code are conflicting, and I am totally confused.
1. You defined a parameter Theta in the integrand, but Theta is not included in the integrand in fact:
struct user // parameters in the integrand
{
double Theta;
};
return x * x * x * x * exp( x ) / ((exp( x ) - 1) * ((exp ( x ) - 1)); 2. You defined a fit parameter in your code (double a), but a is not being used in the code and a is neither in your fitting function. What is a?
Perhaps I missed something, but you better go through your code once more.
Regards, Yuki OriginLab
|
|
|
King007
India
5 Posts |
Posted - 07/10/2017 : 01:31:56 AM
|
Thanks "yuki_wu" for such a spontaneous response.
Actually I tried to modify an example program posted on NAG fitting with integral. As I am totally new to programming, I guess that messed up the code. So, I am wondering if you can suggest me on this a bit more or if possible hint me a new code.
Thanks and Regard. |
|
|
King007
India
5 Posts |
Posted - 07/10/2017 : 01:40:13 AM
|
'a' is defined by mistake as I said, while copying it from another program.
The only parameter provided by user is Theta/Q and is used in integrand as an upper limit.
Actually, the function is supposed to fit a given curve provided Theta/Q for every X. |
|
|
yuki_wu
896 Posts |
|
King007
India
5 Posts |
Posted - 07/21/2017 : 08:42:18 AM
|
Hi,
yuki wu..
Thanks for the links to tutorials. They were a real help. I went through the them and tried to modify the code. The code was compiled successfully. However, the code still cannot simulate or fit the given curve provided the value for Q(Theta).
Any suggestions?
Thanks and regard. |
|
|
King007
India
5 Posts |
Posted - 07/21/2017 : 08:44:46 AM
|
Here is the new code:
#pragma warning(error : 15618) #include <origin.h> #define NAG_FREE(X) x04bdc((Pointer *)&(X)) // Add your special include files here. // For example, if you want to fit with functions from the NAG library, // add the header file for the NAG functions here. #include <oc_nag8.h>
// Add code here for other Origin C functions that you want to define in this file, // and access in your fitting function. struct user // parameters in the integrand { double Theta; }; // Function supplied by user, return the value of the integrand at a given x. static double NAG_CALL f_callback(double x, Nag_User *comm) { struct user *sp = (struct user *)(comm->p); double Theta; // temp variable to accept the parameters in the Nag_User communication struct Theta = sp->Theta; return x*x*x*x*exp(x)/(exp(x)-1)*(exp(x)-1); }
// You can access C functions defined in other files, if those files are loaded and compiled // in your workspace, and the functions have been prototyped in a header file that you have // included above.
// You can access NLSF object methods and properties directly in your function code.
// You should follow C-language syntax in defining your function. // For instance, if your parameter name is P1, you cannot use p1 in your function code. // When using fractions, remember that integer division such as 1/2 is equal to 0, and not 0.5 // Use 0.5 or 1/2.0 to get the correct value.
// For more information and examples, please refer to the "User-Defined Fitting Function" // section of the Origin Help file.
//---------------------------------------------------------- // void _nlsfNewFunction42( // Fit Parameter(s): double Q, // Independent Variable(s): double x, // Dependent Variable(s): double& y) { // Beginning of editable part // Through the absolute accuracy epsabs, relative accuracy epsrel and max_num_subint you can // control the precision of the integration you need // if epsrel is set negative, the absolute accuracy will be used. // Similarly, you can control only relative accuracy by set the epsabs negative double epsabs = 0.0, epsrel = 0.0001; // The max number of sub-intervals needed to evaluate the function in the integral // The more difficult the integrand the larger max_num_subint should be // For most problems 200 to 500 is adequate and recommended Integer max_num_subint = 200; // Result keeps the approximate integral value returned by the algorithm // abserr is an estimate of the error which should be an upper bound for the |I - result| // where I is the integral value double result, abserr; // The structure of type Nag_QuadProgress, // it contains pointers allocated memory internally with max_num_subint elements Nag_QuadProgress qp; // The NAG error parameter (structure) static NagError fail; // Parameters passed to integrand by Nag_User communication struct Nag_User comm; struct user s; s.Theta = Q; comm.p = (Pointer)&s; // Perform integration // There are 3 kinds of infinite boundary types you can use in Nag infinite integrator // Nag_LowerSemiInfinite, Nag_UpperSemiInfinite, Nag_Infinite d01smc(f_callback, 0, Q/x, epsabs, epsrel, max_num_subint, &result, &abserr, &qp, &comm, &fail); // you may want to exam the error by printing out error message, just uncomment the following lines // if (fail.code != NE_NOERROR) // printf("%s\n", fail.message); // For the error other than the following three errors which are due to bad input parameters // or allocation failure NE_INT_ARG_LT NE_BAD_PARAM NE_ALLOC_FAIL // You will need to free the memory allocation before calling the integration routine again to avoid memory leakage if (fail.code != NE_INT_ARG_LT && fail.code != NE_BAD_PARAM && fail.code != NE_ALLOC_FAIL) { NAG_FREE(qp.sub_int_beg_pts); NAG_FREE(qp.sub_int_end_pts); NAG_FREE(qp.sub_int_result); NAG_FREE(qp.sub_int_error); } // Calculate the fitted value y = 374.13*(x/Q)*(x/Q)*(x/Q)*result; // End of editable part } |
|
|
|
Topic |
|
|
|