Calling a C Function Within Maple 6
© 2000 Waterloo Maple Inc.
The External Code
First, we define a C procedure to multiply two matrices A and B, which stores the result into the matrix C.
Arithmetic is done modulo the prime integer p, which should be less than
void multiply( int *A, int *B, int *C, int I, int J, int K, int p ) { int i, j, k; int t; for( i = 0; i < I; i++ ) for( k = 0; k < K; k++ ) { t = 0; for( j = 0; j < J; j++ ) {
t += A[i*J+j] * B[j*K+k];
t %= p; if (t<0) t += p;
}
C[i*K+k] = t; } }
This code needs to be compiled and turned into a shared library. Under Windows, we need to produce a DLL with this code. Let's call this DLL "MulMat.dll"
The Maple Wrapper
Next, we define a Maple wrapper, which we will use to call into the external DLL
> multiplyMatrixModp := define_external( 'multiply', a::ARRAY(1..i,1..j,integer[4]), b::ARRAY(1..j,1..k,integer[4]), c::REF(ARRAY(1..i,1..k,integer[4]),RETURN_ONLY), i::integer[4], j::integer[4], k::integer[4], p::integer[4], LIB="MulMat.dll"):
Calling the External Function
We will now use the external code that we have developed, compiled and turned into a DLL. We want to multiply two 100x100 matrices with entries from the integers modulo 17.
> p := 17;
> A := Matrix(100,100,(i,j)->i+j mod p,datatype=integer[4],order=C_order):
> B := Matrix(100,100,(i,j)->i*j mod p,datatype=integer[4],order=C_order):
> multiplyMatrixModp(A,B,C,100,100,100,p):
The last command converted the input arguments to a format that can be passed to C code directly, called the external C function 'multiply' from the DLL 'MulMat.dll' and returned the result in the variable C. Because the internal datastructure used for matrices (using C_order) is very close to what C uses, the conversion overhead was minimal.