point

 

 Remember me

Register  |   Lost password?

 

 

MoneyScience Financial Training: Introduction to QuantLib Development with Luigi Ballabio - September 22-24, London, UK - Further Information
GPUs, Monte Carlo Simulation and Kooderive with Professor Mark Joshi - October 29-31, London, UK - Further Information


How To: Call Brent's Root-Finding Algorithm From C#

Tue, 03 Apr 2012 13:12:54 GMT

As a Senior Technical Consultant for NAG, I answer many customer questions covering many topics. I thought I’d write up one such question I recently received from a NAG C Library user, as the answer may be useful to others.

Q: In looking through the C# associated info, I found many examples of InteropService calls from C# to the C Library (CLW3209DA_nag.dll). Have any examples been posted for the "c05" functions, e.g. nag_zero_cont_func_brent_bsrch(c05agc)?

A: I'm glad you asked! By the time you reach the end of this post, there will be one. J

In working with the NAG C Library from C#, there are three main factors to which we must attend. The first is how to represent the NAG C Library structure types in C#, and for C# this has largely been taken care of for you in NAGCFunctionsAPI.cs.

The second is translating the C library function signature into a C# declaration.


The third is the C# declaration of any required callback functions and the assignment of delegates.

nag_zero_cont_func_brent_bsrch indeed requires a user-supplied callback function “f”, the function for which we want to find a root, whose C prototype is:

double f(double xx, Nag_Comm *comm);

In the containing namespace I declare the corresponding delegate:

public delegate double NAG_C05AGC_FUN(double xx, ref CommStruct comm);
where CommStruct is defined in NAGCFunctionsAPI.cs.

The C prototype for c05agc itself is
void nag_zero_cont_func_brent_bsrch(double *x, double h, double xtol, double ftol, double (*f)(double xx, Nag_Comm *comm), double *a, double *b, Nag_Comm *comm, NagError *fail);

 

In the relevant class I declare the NAG function thusly:
[DllImport("CLW3209DA_nag")]
        public static extern void c05agc(ref double x, double h, double xtol, double ftol, NAG_C05AGC_FUN f, ref double a, ref double b, ref CommStruct user_comm, ref NagError fail);

A C# example console application program for c05agc, similar to the C/C++ program provided by NAG, then might run something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using NagCFunctionsAPI;

namespace c05agce
{
    public delegate double NAG_C05AGC_FUN(double xx, ref CommStruct comm);
    class Program
    {
        [DllImport("CLW3209DA_nag")]
        public static extern void c05agc(ref double x, double h, double xtol, double ftol, NAG_C05AGC_FUN f, ref double a, ref double b, ref CommStruct user_comm, ref NagError fail);

        static void Main(string[] args)
        {
            NAG_C05AGC_FUN F = new NAG_C05AGC_FUN(f);
            NagError fail = new NagError();
            fail.char_array = new char[512];
            CommStruct user_comm = new CommStruct();
            double a=0;
            double b=0;
            double x = 1.0;
            double h = 0.1;
            double eps = 1e-05;
            double eta = 0.0;

            c05agc( ref x, h, eps, eta, F, ref a, ref b, ref user_comm, ref fail);

            if (fail.code != 0)
            {
                string error_message = new string(fail.char_array);
                Console.WriteLine(error_message);
            }
            else
            {
                Console.WriteLine("Root = {0, 9:f5}", x);
            }
        }

        public static double f(double x, ref CommStruct user_comm)
        {
            return x - Math.Exp(-x);
        }
    }
}

, , , , , , ,