NAG Technical Report 5/2009

Calling NAG Library Routines from Scilab


Start of report   Skip to Example 1   Skip to Example 3   Skip to Example 4   Skip to Example 5   Reference Page

3.2. Example 2

elliptic

General Elliptic Integral of the Second Kind (s21dac)

Here we show how to write an interface to a NAG C Library function with complex input and return values.

Contents

  1. Function prototype from the NAG C Library Manual
  2. C Interface
  3. Compiling with the builder script
  4. Example of calling the function
  1. Function prototype from the NAG C Library Manual

    According to the C Library Manual, the prototype for function s21dac looks like this:

        #include <nag.h>
        #include <nags.h>
        
        Complex nag_elliptic_integral_f(Complex z, double akp, double a, double b, NagError *fail)
    
    This function takes an input variable of type Complex and returns the evaluation of the general elliptic integral of the second kind from zero up to this input value z.
  2. C Interface

    Here is the source code of our interface written in C nag_intext2.c:

         /* Example 2
            =========
    
            Shows how to implement a simple NAG routine. Using complex types
            and variable left hand side arguments is demonstrated. */
    
         #include "stack-c.h"
         #undef Complex
         #define Complex NagComplex
         #include <nag.h>
         #include <nags.h>
         #define SciComplex doublecomplex
    
         int nag_intext2(char *fname)
         {
         // This is how you could call this function from in Scilab
         // y = nag_elliptic_integral_f_eqn(z,akp,a,b)
         int m1,n1,l1;
         int m2,n2,l2;
         int m3,n3,l3;
         int m4,n4,l4;
         int m5,n5,l5;
         int l6;
    
         double akp, a, b;
         SciComplex z, y;
         NagComplex z_nag, y_nag;
         NagError ifail;
         // define minimum and maximum left and right hand arguments
         int minlhs=1, minrhs=4, maxlhs=2, maxrhs=4;
         Nbvars = 0;
         CheckRhs(minrhs, maxrhs);
         CheckLhs(minlhs,maxlhs);
    
         // Initialise ifail 
         INIT_FAIL(ifail);
    
         // Get the right hand side variables 1 to 4
         GetRhsVar(1, "z", &m1, &n1, &l1);
         GetRhsVar(2, "d", &m2, &n2, &l2);
         GetRhsVar(3, "d", &m3, &n3, &l3);
         GetRhsVar(4, "d", &m4, &n4, &l4);
    
         //   d stands for double, r for float (real), i for integer and 
         //     c for character string and z for complex 
    
         if (m1!=1 || n1!=1)
         {
         sciprint("%s: Dimension should be 1x1 for arg 1\r\n",fname);
         Error(999); return(0);
         }
    
         if (m2!=1 || n2!=1)
         {
         sciprint("%s: Dimension should be 1x1 for arg 2\r\n",fname);
         Error(999); return(0);
         }
    
         if (m3!=1 || n3!=1)
         {
         sciprint("%s: Dimension should be 1x1 for arg 3\r\n",fname);
         Error(999); return(0);
         }
    
         if (m4!=1 || n4!=1)
         {
         sciprint("%s: Dimension should be 1x1 for arg 4\r\n",fname);
         Error(999); return(0);
         }
    
         // Create the 5th and 6th variable for the left hand side output variables
         CreateVar(5, "i", &m1, &n1, &l5);
         CreateVar(6, "z", &m1, &n1, &l6);
    
         // Retrieve the input data from the various stacks. zstk() is for complex, stk()
         // is for double, sstk() is for reals, cstk() is for characters and istk() is
         // for integers.
         z = *zstk(l1);
         akp = *stk(l2);
         a = *stk(l3);
         b = *stk(l4);
    
         // Convert Scilab to NAG complex types 
         z_nag.re = z.r;
         z_nag.im = z.i;
    
         // Run the NAG function s21dac 
         y_nag = nag_elliptic_integral_f(z_nag,akp,a,b,&ifail);
    
         // Convert NAG to Scilab complex types
         y.r = y_nag.re;
         y.i = y_nag.im;
    
         // Put the outputs of the NAG function into the created variables 5 and 6
         *zstk(l6) = y;
         *istk(l5) = ifail.code;
    
         // Point the ouput of the Scilab function to the variables 5 and 6. The order matters 
         // here, as we want 6 to be the first variable out, and 5 to be the second optional 
         // output variable.
         LhsVar(1) = 6;
         LhsVar(2) = 5;
         return(0);
         }
    
    

    Points to note about this code:

  3. Compiling with the Builder Script

    To compile and link this function, you can run the build script nag_builder2.sce which links this interface to the function name fname that will be seen in Scilab. This must be run in the same directory as the interface file, and when run successfully, generates a loader script loader.sce that needs to be executed in order to dynamically link the newly created library into Scilab.

        exec nag_builder2.sce
        exec loader.sce
    
  4. Calling the function

    If the function built and the loader.sce file loaded the function without problem, then we can use the function within Scilab, either on the command-line or in a script. Here we run the example script, nag_example2.sce.

        --> exec nag_example2.sce
        y  = 1.9712598 + 0.5053832i
    

    Tip: If you get any error messages in Scilab check the troubleshooting section.


Start of report   Skip to Example 1   Skip to Example 3   Skip to Example 4   Skip to Example 5   Reference Page