MuPAD - Dynamic Modules [1]Using the NAGC Library in MuPADAndreas Sorgatz (andi@uni-paderborn.de) - 30. Nov. 1996 | ![]() |
About mnag.h
mnag.h is a small header file, which makes it easy to use the NAGC
library in a MuPAD module. It provides conversion routines (MuPAD <->
NAGC) for the basic data types of NAGC and supports a MuPAD-like error
handling. This interface was tested on the following plattforms. Further
ports are planned.
A Demonstration Of The NAGC Interface
NAGdemo1: The Random Number Generator
Figure 1 shows the source code of the dynamic module NAGdemo1, which
performs an interface to the NAGC random number generator (g05cbc,
g05cac).
The function "new" of this module gets a first Integer to
initialize the generator and a second one to specify the number of random
values the function shall return in a list.
Fig. 1: NAGdemo1: The Source Code |
/******************************************************************************/ /* FILE : NAGdemo1.C */ /* CONTENT: The function "new" returns a list of five random values. */ /* AUTHOR : Andreas Sorgatz (andi@uni-paderborn.de) */ /* CREATED: 30/11/96 */ /* CHANGED: 30/11/96 */ /* RELEASE: MuPAD 1.3, NAGC Mark 3 */ /* SYSTEMS: Solaris 2.5 */ /* */ /* This simple NAGdemo1 demonstrates how NAG functions can be used in a MuPAD */ /* dynamic module. For conversions of basic NAG data types (Boolean, Complex, */ /* double and Integer) between NAG <--> MuPAD, the functions MNboolean, ... */ /* can be used. */ /******************************************************************************/ //////////////////////////////////////////////////////////////////////////////// // Module Generator Options: /////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Define include and library path as well as libraries to be linked. ////////// // MMG( coption = "-I/usr/local/MATH/NAGC/include" ) MMG( loption = "-L/usr/local/MATH/NAGC -lnagc -lm /usr/lib/libc.so.1" ); // Tell MuPAD not to take the default linker call, but this one. /////////////// // MMG( linker = "ld -G" ) // Include this information string, which will be printed by 'info()'. ///////// // MMG( info = "Using the NAG-Library in MuPAD, Demo-1, random numbers" ) // Include the MuPAD/NAG interface ///////////////////////////////////////////// // #include "mnag.h" //////////////////////////////////////////////////////////////////////////////// // Include NAG header files according to the functions that are used. NOTE: //// // The 'extern "C" { ... }' statement is used because the NAG Library is //// // an ANSI-C library but not a C++ library! //// //////////////////////////////////////////////////////////////////////////////// // extern "C" { #include <Nag/nagg05.h> } // The module function ///////////////////////////////////////////////////////// // MFUNC( new, MCnop ) // NAGdemo1( init_value, num_of_value ) { Integer i, num; // NAG data type MFnargsCheck(2); // exactly two arguments are expected MFargCheck(1,DOM_INT); // range := 0..MFarg(1) MFargCheck(2,DOM_INT); // number:= MFarg(2) random values num = MNinteger( MFarg(2) ); // converts DOM_INT to Integer g05cbc( MNinteger(MFarg(1)) ); // initializes the random number generator MTcell list = MFnewList(num); // creates a MuPAD list for( i=0; i < num; i++ ) // fills the list with random MuPAD numbers { MFsetList( &list, i, MNdouble(g05cac()) ); } MFsig(list); // calculates the signature of the list MFreturn(list); // returns the MuPAD list } MFEND MFUNC( initmod, MCnop ) // An introduction for the user. { MFprintf( "Usage: NAGdemo1( init_value, num_of_value ); \n" ); MFreturn( MFcopy(MVnull) ); } MFEND |
Figure 2 shows how the dynamic module is created and used in a MuPAD session.
Fig. 2: NAGdemo1: Creation And Usage |
andi> mmg -v NAGdemo1.C MMG -- MuPAD-Module-Generator -- V-1.3.0 Oct.96 Mesg.: Scanning source file ... Mesg.: 2 function(s) and 4 option(s) found in 91 lines Mesg.: Module contains a user defined init function Mesg.: Creating extended module code ... Mesg.: Compiling extended module code ... CC -pic -G -DSOLARIS -c MMGNAGdemo1.C -o NAGdemo1.o -DPARI_C_PLUSPLUS -DLONG_IS_32BIT -DPOINTER_IS_32BIT -I/wiwianka/user/andi/MuPAD/SOURCE/DEV/share/mmg/include/kernel -I/wiwianka/user/andi/MuPAD/SOURCE/DEV/share/mmg/include/pari -I/wiwianka/user/andi/MuPAD/SOURCE/DEV/share/mmg/include/mmt -I/usr/local/MATH/NAGC/include Mesg.: Linking dynamic module ... ld -G -o NAGdemo1.mdm NAGdemo1.o -L/wiwianka/user/andi/MuPAD/SOURCE/DEV/solaris/lib -L/usr/local/MATH/NAGC -lnagc -lm /usr/lib/libc.so.1 Mesg.: Ok |
Fig. 3: NAGdemo2: The Source Code |
/******************************************************************************/ /* FILE : NAGdemo2.C */ /* CONTENT: The function "roots" finds all the roots of a complex polynomial */ /* AUTHOR : Andreas Sorgatz (andi@uni-paderborn.de) */ /* CREATED: 30/11/96 */ /* CHANGED: 30/11/96 */ /* RELEASE: MuPAD 1.3, NAGC Mark 3 */ /* SYSTEMS: Solaris 2.5 */ /******************************************************************************/ //////////////////////////////////////////////////////////////////////////////// // Module Generator Options: /////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Define include and library path as well as libraries to be linked. ////////// // MMG( coption = "-I/usr/local/MATH/NAGC/include" ) MMG( loption = "-L/usr/local/MATH/NAGC -lnagc -lm /usr/lib/libc.so.1" ); // Tell MuPAD not to take the default linker call, but this one. /////////////// // MMG( linker = "ld -G" ) // Include this information string, which will be printed by 'info()'. ///////// // MMG( info = "Using the NAG-Library in MuPAD, Demo-2, roots of a polynomial" ) // Include the MuPAD/NAG interface ///////////////////////////////////////////// // #include "mnag.h" //////////////////////////////////////////////////////////////////////////////// // Include NAG header files according to the functions that are used. NOTE: //// // The 'extern "C" { ... }' statement is used because the NAG Library is //// // an ANSI-C library but not a C++ library! //// //////////////////////////////////////////////////////////////////////////////// extern "C" { #include <Nag/nagc02.h> } // The module function ///////////////////////////////////////////////////////// // MFUNC( new, MCnop ) // NAGdemo2( polynomial ) { MFnargsCheck(1); MFargCheck(1,DOM_POLY); // Check if the polynomial is univariate. // if( MFnops(MFop(MFarg(1),1)) != 1 ) MFerror( "Univariate polynomial expected" ); // Convert the MuPAD polynomial into a dense list representation. // This makes further conversions easier. // MTcell polylist = MFcall( "poly2list", 1, MFcopy(MFarg(1)) ); long polyleng = MFnops( polylist ); if( polylist == 0 ) MFerror( "Polynomial must not be zero" ); // Get the degree of the polynomial. // Integer degree = MNinteger( MFop(MFop(polylist,0),1) ); if( degree == 0 ) { MFfree( polylist ); MFerror( "Degree of the polynomial must greater than zero" ); } // Create a NAG (sparse) complex polynomial. // Complex* poly = (Complex*) MFcmalloc( (degree+1) * sizeof(Complex) ); if( poly == NULL ) { MFfree( polylist ); MFerror( "Not enough memory" ); } MTcell Mmonom, Mcoeff; Integer copos = degree, expo; Complex* coeff = poly; for( long i = 0; i < polyleng; i++ ) { Mmonom = MFop( polylist, i ); Mcoeff = MFcall( "float", 1, MFcopy(MFop(Mmonom,0)) ); expo = MNinteger( MFop(Mmonom,1) ); while( copos > expo ) { copos--; coeff++; coeff->re = 0.0; coeff->im = 0.0; } if( MFisFloat(Mcoeff) ) { coeff->re = MNdouble( Mcoeff ); coeff->im = 0.0; } else if( MFisComplex(Mcoeff) ) { *coeff = MNcomplex( Mcoeff ); } else { MFerror( "Numeric element expected [MNcomplexList]" ); } MFfree( Mcoeff ); } while( --copos >= 0 ) { coeff++; coeff->re = 0.0; coeff->im = 0.0; } MFfree( polylist ); // Find all the complex roots of the given polynomial // Complex* root = (Complex*) MFcmalloc( (degree ) * sizeof(Complex) ); if( root == NULL ) { MFcfree( poly ); MFerror( "Not enough memory" ); } c02afc( degree, poly, TRUE, root, MNfail() ); MFcfree( poly ); // Return the result as a MuPAD list. // MTcell result = MNcomplexList( root, degree ); MFcfree( root ); MFreturn( result ); } MFEND MFUNC( initmod, MCnop ) // An introduction for the user. { MFprintf( "Usage: NAGdemo2( complex_polynomial ); \n" ); MFreturn( MFcopy(MVnull) ); } MFEND |
Figure 4 shows how the dynamic module is created and used in a MuPAD session.
Fig. 4: NAGdemo2: Creation And Usage |
andi> mmg -v NAGdemo2.C MMG -- MuPAD-Module-Generator -- V-1.3.0 Oct.96 Mesg.: Scanning source file ... Mesg.: 2 function(s) and 4 option(s) found in 141 lines Mesg.: Module contains a user defined init function Mesg.: Creating extended module code ... Mesg.: Compiling extended module code ... CC -pic -G -DSOLARIS -c MMGNAGdemo2.C -o NAGdemo2.o -DPARI_C_PLUSPLUS -DLONG_IS_32BIT -DPOINTER_IS_32BIT -I/wiwianka/user/andi/MuPAD/SOURCE/DEV/share/mmg/include/kernel -I/wiwianka/user/andi/MuPAD/SOURCE/DEV/share/mmg/include/pari -I/wiwianka/user/andi/MuPAD/SOURCE/DEV/share/mmg/include/mmt -I/usr/local/MATH/NAGC/include Mesg.: Linking dynamic module ... ld -G -o NAGdemo2.mdm NAGdemo2.o -L/wiwianka/user/andi/MuPAD/SOURCE/DEV/solaris/lib -L/usr/local/MATH/NAGC -lnagc -lm /usr/lib/libc.so.1 Mesg.: Ok |
The Header File mnag.h
This interface still has an experimental state and it is incomplete. Further
functions for conversions of NAG/MuPAD objects like lists, polynomials and
arrays are planned ... when I have a bit more time for this.
Fig. 5: The Header File mnag.h |
/******************************************************************************/ /* FILE : mnag.h */ /* CONTENT: The MuPAD dynamic module interface to the NAG C Library */ /* AUTHOR : Andreas Sorgatz (andi@uni-paderborn.de) */ /* CREATED: 29/11/96 */ /* CHANGED: 30/11/96 */ /* RELEASE: MuPAD 1.3, NAGC Mark 3 */ /* SYSTEMS: Solaris 2.5 */ /* */ /******************************************************************************/ // Undefines some conflicting MuPAD/PARI definements. ////////////////////////// // #undef zero // Internal PARI definement #undef lmax // Internal PARI definement #undef debug // Internal MDM definement // NAG header files: On UNIX systems in general the prefix 'Nag/' must be used. // To suppress this prefix, the option -DNOPREFIX can be used. // extern "C" { #if (defined MACINTOSH) || (defined MSDOS) || (defined NOPREFIX) # include |
Appendix
The header file mnag.h will be available for the MuPAD release
1.3.0. Please refer to the contrib directory of any
official MuPAD ftp site.
Bibliography |
[1] Dynamische Module, A. Sorgatz, MuPAD Reports, Teubner Verlag, Stuttgart, Oktober 1996. http://math-www.uni-paderborn.de/MuPAD/BIB/sorgatz96.html [2] Integration of Magnum in MuPAD [3] How to create MuPAD scanners with (f)lex
|