MuPAD - Dynamic Modules [1]Integration of Magnum in MuPADAndreas Sorgatz (andi@uni-paderborn.de) - 07. Nov. 1996 | ![]() |
About The Dynamic Module magnum
Magnum is integrated into MuPAD 1.3 with the dynamic module
magnum [2]. So far, the following Magnum algorithms are accessible
in MuPAD:
This module was tested on the following plattforms (further ports are planned).
A Demonstration Of The Factorization
Figure 1 demonstrates the speed of Magnum and the efficiency of dynamic
MuPAD modules. After loading the magnum, a random polynomial
is created and factorized by a Magnum function. The cpu time (ms) was
measured under Linux 2.0 on a 90Mhz Pentium with 48Mb RAM.
Fig. 1: Using magnum in MuPAD |
>> module(magnum): >> P:= randpoly( [x], IntMod(65437), Degree=200, Terms=100 ): >> magnum::irreducible(P); FALSE >> time( magnum::factor(P) ); 31160 >> magnum::doc(): MODULE magnum - Factorization package for univariate polynomials over Fp [...] |
The Online Help Pages
The following help pages are placed in a file magnum.mdh in the
same directory as the module itself. They can be read during a MuPAD
session via the function magnum::doc() - after the module
magnum was loaded.
Fig. 2: The Online Help Pages |
MODULE magnum - Factorization package for univariate polynomials over Fp INTRODUCTION This module contains very fast algorithms for the factorization of univariate polynomials over residue class rings Fp, with p is prime and less than 2^16. It interfaces the package Magnum, written by Wolfgang Roth (roth@math.uni-mannheim.de). The file 'magnum.tar.gz' (C++ code of Magnum) is originally available via anonymous ftp at: ftp://obelix.statistik.uni-mannheim.de/public/magnum The MuPAD source of this interface and a tested version of Magnum is available in the contributions directory of any official MuPAD mirror site. The MuPAD home site is: ftp://math-www.uni-paderborn.de/MuPAD/ For further technical information refer to the script 'magnum.sh' in the MuPAD contributions directory and to the documentation in- cluded in the Magnum package. INTERFACE doc, factor, gcd, id, irreducible, issqrfree, sqrfree NAME magnum::doc - Online documentation SYNOPSIS magnum::doc() magnum::doc( func ) ARGUMENTS func - String, function name without the prefix "magnum::" DESCRIPTION Displays a brief description of the module Magnum, respectively the function magnum::'func'. EXAMPLE: >> magnum::doc("factor"); [...] SEE ALSO module::help NAME magnum::factor - Factorizes an univariate polynomial over IntMod(p) SYNOPSIS magnum::factor( poly ) ARGUMENTS poly - An univariate polynomial over IntMod(p) DESCRIPTION The function factorizes 'poly' over a residue class ring IntMod(p) with p is prime and p is less than 2^16. factor returns FAIL if the input is invalid. factor returns the list [u, f1, e1, ..., fn, en] with poly = u * f1^e1 *...* fn^en, where fi is a irreducible factor and 'u' is the content of 'poly'. All fi are pairwise different and primitive. EXAMPLE >> magnum::factor( poly(x^11+x+1,IntMod(6449)) ); 2 3 [1, poly(3211 x + 157 x + x + 150, [x], IntMod(6449)), 1, 2 poly(- 1177 x + x + 1815, [x], IntMod(6449)), 1, 2 poly(- 1372 x + x + 2487, [x], IntMod(6449)), 1, 2 poly(x + x + 1, [x], IntMod(6449)), 1, poly(x + 337, [x], IntMod(6449)), 1, poly(x + 2054, [x], IntMod(6449)), 1] SEE ALSO magnum::irreducible, magnum::issqrfree, magnum::sqrfree, factor NAME magnum::gcd - greatest common divisor of polynomials over IntMod(p) SYNOPSIS magnum::gcd( [poly] ... ) ARGUMENTS poly - An univariate polynomial over IntMod(p) DESCRIPTION gcd calculates the greatest common divisor of any number of polyno- mials over a residue class ring IntMod(p), with p is prime and p is less than 2^16. gcd returns FAIL if the input is invalid. EXAMPLE >> P:= poly(x^60*(-19) + x^384*(-202) + x^388*(-209), IntMod(503)): Q:= poly(x^20*146 + x^138*52 + x^425*172, IntMod(503)): magnum::gcd(P,Q); 20 poly(x , [x], IntMod(503)) SEE ALSO magnum::irreducible, gcd NAME magnum::id - the identical function for polynomials over IntMod(p) SYNOPSIS magnum::id( poly ) ARGUMENTS poly - An univariate polynomial over IntMod(p) DESCRIPTION id converts a polynomial over a residue class ring IntMod(p),with p is prime and p is less than 2^16, into a Magnum polynomial and then back into a MuPAD polynomial. This functions can be used to check the conversion routines.This is usefull when the magnum source code was exchanged and a new dynamic MuPAD module was compiled In contrast to other magnum module functions, id returns detailed error messages when its input is invalid. EXAMPLE >> P:= poly(x^20*146 + x^138*52 + x^425*172, IntMod(503)): magnum::id(P); 20 138 425 poly(146 x + 52 x + 172 x , [x], IntMod(503)) SEE ALSO id NAME magnum::irreducible - tests if a polynomial over IntMod(p) is irreducible SYNOPSIS magnum::irreducible( poly ) ARGUMENTS poly - An univariate polynomial over IntMod(p) DESCRIPTION Tests if a polynomial over a residue class ring IntMod(p), with p is prime and p is less than 2^16, is irreducible. The function re- turns TRUE, respectively FALSE, or FAIL if the input was invalid. EXAMPLE >> P:= poly(x^20*146 + x^138*52 + x^425*172, IntMod(503)): magnum::irreducible(P); FALSE SEE ALSO magnum::issqefree, magnum::sqrfree, magnum::factor NAME magnum::issqrfree - tests if a polynomial over IntMod(p) is square free SYNOPSIS magnum::issqrfree( poly ) ARGUMENTS poly - An univariate polynomial over IntMod(p) DESCRIPTION Tests if the a polynomial over a residue class ring IntMod(p), with p is prime and p is less than 2^16, is square free.The function re- turns TRUE, respectively FALSE, or FAIL if the input was invalid. EXAMPLE >> P:= poly(x^20*146 + x^138*52 + x^425*172, IntMod(503)): magnum::issqrfree(P); FALSE SEE ALSO magnum::irreducible, magnum::sqrfree, magnum::factor NAME magnum::sqrfree - square-free factorization of polynomials over IntMod(p) SYNOPSIS magnum::sqrfree( poly ) ARGUMENTS poly - An univariate polynomial over IntMod(p) DESCRIPTION sqrfree calculates the square-free factorization of a polynomial 'poly' over a residue class ring IntMod(p) with p is prime and p is less than 2^16. sqrfree returns FAIL if the input is invalid. sqrfree returns the list [u, f1, e1, ..., fn, en] with poly = u * f1^e1 * ...* fn^en, where the fi are the square-free factors of a and 'u' is the content of 'poly'. The fi are primitive and pairwise relatively prime. EXAMPLE >> P:= poly(x^20*146 + x^138*52 + x^425*172, IntMod(503)): magnum::sqrfree(P); [172, poly(x, [x], IntMod(503)), 20 118 405 poly(12 x + x - 5, [x], IntMod(503)), 1] SEE ALSO magnum::issqrfree, magnum::factor |
The Source Code Of The Magnum Module Interface
The source code of the module interface only contains about 300 lines of C++ code - including comments. Figure 3 shows the complete source code.
Fig. 3: The Complete Source Code Of magnum |
/******************************************************************************/ /* MODUL : magnum.C - Module Interface for Magnum (refer to the README) */ /* MuPAD : Release 1.2.9a, 1.3 */ /* AUTHOR : Paul Zimmermann (Paul.Zimmermann@loria.fr) */ /* Andreas Sorgatz (andi@uni-paderborn.de) */ /* CREATED: 26/09/96 */ /* CHANGED: 07/11/96 */ /* */ /* This is a MuPAD interface to the package Magnum. It is written in C++ and */ /* must be compiled into a dynamic MuPAD module by using the module generator */ /* mmg. For further information refer to the script 'magnum.sh'. */ /* */ /* Wolfgang Roth's (roth@math.uni-mannheim.de) package 'magnum' provides fast */ /* factorization algorithms for polynomials over fields Fp with p is prime. */ /* His package 'magnum.tar.gz' is originally available via anonymous ftp at */ /* */ /* ftp://obelix.statistik.uni-mannheim.de/public/magnum */ /* */ /******************************************************************************/ MMG( info = "Module: Factorization of univariate polynomials over fields Fp" ) // Magnum header files ///////////////////////////////////////////////////////// // #include "magnum/Prime.H" #include "magnum/FpPolynom.H" #include "magnum/FpPolynom_Set.H" // Conversion routines for polynomials - Magnum <--> MuPAD ///////////////////// // /******************************************************************************/ /* NAME: Convert */ /******************************************************************************/ #define CONVERT(arg,magPoly,mupUndets,mupField,prime,expo,mode) \ \ /* Check if 'arg' is a valid polynomial, convert it into its MuPAD list */ \ /* representation and collect information for the further conversion. */ \ \ MTcell mupList, mupUndets, mupField; \ long prime, expo; \ \ if( !mupPolyCheck(arg,mupList,mupUndets,mupField,prime,expo,mode) ) \ MFreturn( MFcopy(MVfail) ); \ \ /* Create a Magnum polynomial with the collected information */ \ \ FpPolynom magPoly( (Prime) prime ); \ \ mupPoly2mag( mupList, prime, magPoly ); \ MFfree( mupList ); /******************************************************************************/ /* NAME: mupPolyCheck */ /******************************************************************************/ static int mupPolyCheck ( MTcell mupPoly, // IN MTcell &mupList, // OUT MTcell &mupUndets, // OUT MTcell &mupField, // OUT long &prime, // OUT long &expo, // OUT int ExitOnError=0 // IN ) { int error = 0; // Check if 'mupPoly' is an univariate polynomial over the finite field Fp // with p is prime and less than 2^16. Other polynomials cannot be handled // by Magnum. // if( !MFisPolynom(mupPoly) ) { if( ExitOnError ) MFerror( "Polynomial expected" ); return( 0 ); } mupUndets = MFop( mupPoly, 1 ); if( MFnops(mupUndets) != 1 ) { if( ExitOnError ) MFerror( "Polynomial must be univariate" ); return( 0 ); } mupField = MFop( mupPoly, 2 ); if( !MFisExpr(mupField,"IntMod") || MFnops(mupField) != 2 ) { if( ExitOnError ) MFerror( "Polynomial must be of type 'IntMod(p)'" ); return( 0 ); } MTcell mprime = MFop(mupField,1); if( MFlt(mprime,MVzero) || MFgt(mprime,MFlong(65535)) ) { if( ExitOnError ) MFerror( "IntMod(p), p out of range" ); return( 0 ); } prime = MFlong( MFop(mupField,1) ); expo = 1; MTcell result = MFcall( "isprime", 1, MFlong(prime) ); if( !MFisTrue(result) ) { MFfree( result ); if( ExitOnError ) MFerror( "IntMod(p), p must be prime" ); return( 0 ); } MFfree( result ); // Convert the MuPAD polynomial into its list representation, which is much // easier to analyse during the further conversion into a Magnum polynomial. // mupList = MFcall( "poly2list", 1, MFcopy(mupPoly) ); return( 1 ); } /******************************************************************************/ /* NAME: mupPoly2mag */ /******************************************************************************/ static int mupPoly2mag ( MTcell mupList, // IN long prime, // IN FpPolynom &magPoly // OUT ) { // Convert the list representation of a MuPAD polynomial into a Magnum // polynomial. Use 'prime' for this. // MTcell monom; long coeff, expo, length = MFnops(mupList); for( int pos = 0; pos < length ; pos++ ) { monom = MFgetList( &mupList, pos ); coeff = MFlong( MFgetList(&monom,0) ); if( coeff < 0 ) coeff += prime; expo = MFlong( MFgetList(&monom,1) ); magPoly += FpPolynom( magPoly.descriptor, (Fp)coeff, expo ); } return( 1 ); } /******************************************************************************/ /* NAME: magPoly2mup */ /******************************************************************************/ static MTcell magPoly2mup ( const FpPolynom &magPoly, // IN MTcell &mupUndets, // IN MTcell &mupField // IN ) { MTcell mupList, mupPoly, monom; long pos = 0; // First create a list representation of the MuPAD polynomial. Then // convert is into a native polynomial by using 'poly'. // mupList = MFnewList( magPoly.length() ); for( FpPolynom_Iterator x_iter(magPoly); x_iter(); ++x_iter ) { monom = MFnewList( 2 ); MFsetList( &monom, 0, MFlong((long)x_iter()->factor) ); MFsetList( &monom, 1, MFlong((long)x_iter()->power) ); MFsetList( &mupList, pos++, monom ); } return( MFcall("poly", 3, mupList, MFcopy(mupUndets), MFcopy(mupField)) ); } /******************************************************************************/ /* NAME: magPolyListLen */ /******************************************************************************/ static long magPolyListLen ( const FpPolynom_List &magPolyList ) { long n = 0; // How many polynomials are in this list ? // for( FpPolynom_List_Iterator l_iter(magPolyList); l_iter(); ++l_iter ) { n += l_iter()->set().size(); } return( n ); } /******************************************************************************/ /* NAME: magPolyList2mup */ /******************************************************************************/ static MTcell magPolyList2mup ( const FpPolynom_List &magPolyList, // IN MTcell &mupUndets, // IN MTcell &mupField // IN ) { FpPolynom_List_Iterator l_iter( magPolyList ); MTcell mupList, mupPoly; long pos = 1; // Create a MuPAD list with the first element is the integer factor. // mupList = MFnewList( magPolyListLen(magPolyList)*2+1 ); MFsetList( &mupList, 0, MFlong((long) magPolyList.factor) ); // Insert pairs (poly,exponent) into the factor list. // if( l_iter() ) do { FpPolynom_Set_Iterator s_iter( l_iter()->set() ); if( s_iter() ) do { mupPoly = magPoly2mup( s_iter()->polynom(), mupUndets, mupField ); MFsetList( &mupList, pos++, mupPoly ); MFsetList( &mupList, pos++, MFlong((long)l_iter()->power) ); } while( (++s_iter)() ); } while( (++l_iter)() ); MFsig ( mupList ); return( mupList ); } // MuPAD interface functions - these are visible in MuPAD ////////////////////// // /******************************************************************************/ /* NAME: magnum::id - identity, check conversion routines */ /******************************************************************************/ MFUNC( id, MCnop ) { MFnargsCheck(1); CONVERT( MFarg(1), magPoly, mupUndets, mupField, prime, expo, 1 ); MFreturn( magPoly2mup( magPoly, mupUndets, mupField ) ); } MFEND /******************************************************************************/ /* NAME: magnum::factor - factorizes a polynomial and returns a factor list */ /******************************************************************************/ MFUNC( factor, MCnop ) { MFnargsCheck(1); CONVERT( MFarg(1), magPoly, mupUndets, mupField, prime, expo, 0 ); FpPolynom_List magPolyList; factorize( magPolyList, magPoly ); MFreturn( magPolyList2mup( magPolyList, mupUndets, mupField ) ); } MFEND /******************************************************************************/ /* NAME: magnum::gcd - returns the greatest common divisor of polynomials */ /******************************************************************************/ MFUNC( gcd, MCnop ) { if( MVnargs == 0 ) MFreturn( MFcopy(MVzero) ); if( MVnargs == 1 ) MFreturn( MFcopy(MFarg(1)) ); CONVERT( MFarg(1), magPoly, mupUndets, mupField, prime, expo, 0 ); for( long i = 2; i <= MVnargs; i++ ) { CONVERT( MFarg(i), magPoly2, mupUndets2, mupField2, prime2, expo2, 0 ); if( prime != prime2 || !MFequal(mupUndets,mupUndets2) ) { MFreturn( MFcopy(MVfail) ); } if( magPoly == magPoly2 ) continue; magPoly = gcd( magPoly, magPoly2 ); } MFreturn( magPoly2mup( magPoly, mupUndets, mupField ) ); } MFEND /******************************************************************************/ /* NAME: magnum::irreducible - check if a polynomial is irreducible */ /******************************************************************************/ MFUNC( irreducible, MCnop ) { MFnargsCheck(1); CONVERT( MFarg(1), magPoly, mupUndets, mupField, prime, expo, 0 ); if( magPoly.is_irreducible() ) { MFreturn( MFcopy(MVtrue ) ); } else { MFreturn( MFcopy(MVfalse) ); } } MFEND /******************************************************************************/ /* NAME: magnum::issqrfree - check if a polynomial is squarefree */ /******************************************************************************/ MFUNC( issqrfree, MCnop ) { MFnargsCheck(1); CONVERT( MFarg(1), magPoly, mupUndets, mupField, prime, expo, 0 ); if( magPoly.is_squarefree() ) { MFreturn( MFcopy(MVtrue ) ); } else { MFreturn( MFcopy(MVfalse) ); } } MFEND /******************************************************************************/ /* NAME: magnum::sqrfree - returns a list of squarefree factors of a poly. */ /******************************************************************************/ MFUNC( sqrfree, MCnop ) { MFnargsCheck(1); CONVERT( MFarg(1), magPoly, mupUndets, mupField, prime, expo, 0 ); FpPolynom_List magPolyList; squarefree( magPolyList, magPoly ); MFreturn( magPolyList2mup( magPolyList, mupUndets, mupField ) ); } MFEND |
How To Create The Executable Module
In the following example it is suppused that the Magnum library
libmagnum.a has already been build and that all Magnum
header files have to be available.
The module interface source code has been stored in the file
magnum.C. With this, the MuPAD
module generator is called to create the dynamic module (refer
to figure 4). The result is the binary file magnum.mdm,
which is placed in the current directory and can be used by MuPAD
instantly.
Fig. 4: Creating The Dynamic Module magnum |
andi> mmg -v -I$MAGINC -L$MAGLIB -lmagnum -lm magnum.C MMG -- MuPAD-Module-Generator -- V-1.3.0 Oct.96 Mesg.: Scanning source file ... Mesg.: 6 function(s) and 1 option(s) found in 313 lines Mesg.: Creating extended module code ... Mesg.: Compiling extended module code ... g++ -fpic -c MMGmagnum.C -o magnum.o -DPARI_C_PLUSPLUS -DLONG_IS_32BIT -DPOINTER_IS_32BIT -I. -Iinclude -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 Mesg.: Linking dynamic module ... g++ -G -o magnum.mdm magnum.o -L. -Llibrary -lmagnum -lm -L/wiwianka/user/andi/MuPAD/SOURCE/DEV/i386/lib Mesg.: Ok |
Appendix
Binary modules as well as the module source code and a shell script for
the automatic creation 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] A first integration of the factorization function of Magnum in MuPAD 1.2.9a was done by Paul Zimmermann: http://www.loria.fr/~zimmerma/mupad/magnum.html. [3] Spiel (fast) ohne Grenzen, A. Sorgatz, Linux Magazin, Ausgabe 01/97. [4] Using the NAGC Library in MuPAD [5] How to create MuPAD scanners with (f)lex
|