Calling a NAG function from an Origin C function is very much like calling any other Origin C function. You must familiarize yourself with the desired NAG function to gain an understanding of what parameters the function requires to be passed as arguments and what parameters the function returns. Once familiar with the function, you must develop code that follows the function's requirements.
The NAG header file containing the function's prototype must be included, required parameters must be correctly declared, sized, and initialized, and the function call must follow the function's prototype as described in header file. The objective of this tutorial is to demonstrate how to call a NAG function from an Origin C function.
Minimum Origin Version Required: Origin 8.1 SR1
This tutorial will show you how to:
The primary resource for understanding NAG functions is NAG library. The library also can be found in Origin C Reference. For example, d01sjc NAG function:
Secondary resource for understanding the Origin C NAG functions is Examples book. From the Origin menu select Help:Programming:OriginC, expand Examples book, expand Analysis book, choose Accessing NAG Functions, there are some examples to show how to call NAG functions in Origin C.
The best way to understand how to write an Origin C function that calls a NAG function is to step through an example function in Debug mode. Follow the steps below to set up Origin and Code Builder to execute such a sample Origin C function in Debug mode.
// Include your own header files here. #include <OC_nag.h> // Start your functions here. //NAG_CALL denotes proper calling convention. You may treat it like a function pointer //and define your own integrand static double NAG_CALL f_callback_ex(double x, Nag_User *comm) { int *use_comm = (int *)comm->p; return (x*sin(x*30.0)/sqrt(1.0-x*x/(PI*PI*4.0))); } void nag_d01sjc_ex() { double a = 0.0; double b = PI * 2.0; // integration interval double epsabs, abserr, epsrel, result; // you may use epsabs and epsrel and this quantity to enhance your desired precision // when not enough precision encountered epsabs = 0.0; epsrel = 0.0001; // The max number of sub-intervals needed to evaluate the function in the integral // The more diffcult the integrand the larger max_num_subint should be // For most problems 200 to 500 is adequate and recommmended int max_num_subint = 200; Nag_QuadProgress qp; NagError fail; Nag_User comm; static int use_comm[1] = {1}; comm.p = (Pointer)&use_comm; //Note:nag_1d_quad_gen (d01ajc) has been replaced by nag_1d_quad_gen_1 (d01sjc) at Mark 25 d01sjc(f_callback_ex, a, b, epsabs, epsrel, max_num_subint,&result, &abserr, &qp, &comm, &fail); // 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); } printf("%10.6f", result); }
#include <OC_nag.h>
This header file containing all the header files of NAG functions, and all type define and error code define. So just include this one function should be enough.
See the declaration of NAG functions from the header file:
To see the declaration of functions from NAG PDF:
How to know what error codes will be got:
typedef double (NAG_CALL * NAG_D01_TS_FUN)(double, Nag_User *comm);User defined function should keep the same return type and argument list as this define. And NAG_CALL denotes proper calling convention and it should be used in your own function.
double NAG_CALL f_callback_ex(double x, Nag_User *comm) { int *use_comm = (int *)comm->p; return (x*sin(x*30.0)/sqrt(1.0-x*x/(PI*PI*4.0))); }