;include "maplec.h"
|
ALGEB ExtractElems( MKernelVector kv, ALGEB args )
|
{
|
char relation;
|
int n, elems, result_elems, count, i;
|
ALGEB Matrix, result;
|
RTableSettings settings;
|
M_INT bounds[2];
|
/*
|
basic argument checking
|
*/
|
if( MapleNumArgs(kv,args) != 3
|
|| !IsMapleRTable(kv,(ALGEB)args[1])
|
|| !IsMapleInteger32(kv,(ALGEB)args[2])
|
|| !IsMapleString(kv,(ALGEB)args[3]) )
|
{
|
MapleRaiseError(kv,"usage: ExtractElems(Matrix,integer,string)");
|
}
|
/*
|
find more about the Matrix
|
*/
|
Matrix = (ALGEB)args[1];
|
RTableGetSettings(kv,&settings,Matrix);
|
if( settings.data_type != RTABLE_INTEGER32
|
|| settings.storage != RTABLE_RECT
|
|| !IsMapleNULL(kv,settings.index_functions) )
|
{
|
/* not the format we wanted -- make a copy */
|
settings.data_type = RTABLE_INTEGER32;
|
settings.storage = RTABLE_RECT;
|
settings.index_functions = ToMapleNULL(kv);
|
settings.foreign = FALSE;
|
Matrix = RTableCopy(kv,&settings,Matrix);
|
}
|
/*
|
get a pointer to the actual Matrix data
|
*/
|
elems = (int)RTableDataBlock(kv,Matrix);
|
/*
|
translate the other arguments
|
*/
|
n = MapleToInteger32(kv,(ALGEB)args[2]);
|
relation = MapleToString(kv,(ALGEB)args[3]);
|
/*
|
scan over the elements linearly -- we don't need to look at
|
RTableNumDimensions, RTableLowerBound, and RTableUpperBound
|
because we don't care where the elements are, just what they are.
|
*/
|
/*
|
first count the elements that satisfy the relation
|
*/
|
count = 0;
|
switch( relation[0] ) {
|
case '>':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] > n ) count++;
|
break;
|
case '<':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] < n ) count++;
|
break;
|
case '=':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] == n ) count++;
|
break;
|
case '!':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] != n ) count++;
|
break;
|
default:
|
MapleRaiseError1(kv,"invalid relation %1",(ALGEB)args[3]);
|
}
|
/*
|
create a new Array to store the result
|
*/
|
RTableGetDefaults(kv,&settings);
|
settings.data_type = RTABLE_INTEGER32;
|
settings.subtype = RTABLE_ARRAY;
|
settings.num_dimensions = 1;
|
bounds[0] = 1;
|
bounds[1] = count;
|
result = RTableCreate(kv,&settings,NULL,bounds);
|
/*
|
fill in the result
|
*/
|
result_elems = (int)RTableDataBlock(kv,result);
|
count = 0;
|
switch( relation[0] ) {
|
case '>':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] > n ) result_elems[count++] = elems[i];
|
break;
|
case '<':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] < n ) result_elems[count++] = elems[i];
|
break;
|
case '=':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] == n ) result_elems[count++] = elems[i];
|
break;
|
case '!':
|
for( i=0; i<RTableNumElements(kv,Matrix); ++i )
|
if( elems[i] != n ) result_elems[count++] = elems[i];
|
break;
|
}
|
/*
|
display a message
|
*/
|
InitMaplePrintf(kv);
|
MaplePrintf("%d element%s satisfied the relation elem[i] %s %d.\n\n",
|
count, count==1 ? "" : "s",relation,n);
|
/*
|
return the Array we created
|
*/
|
return( result );
|
}
|