Пример #1
0
ALGEB minpoly(MKernelVector kv, ALGEB* args)
  {
    int i;
    ALGEB retlist, blank;
    char err[] = "ERROR!  Associated blackbox object does not exist!";
    int key = MapleToInteger32(kv,args[1]), flag;
    std::map<int,int>::iterator f_i;
    std::map<int,void*>::iterator h_i;

    // Get the data from the hash table
    f_i = typeTable.find(key);
    if( f_i == typeTable.end() )
      MapleRaiseError(kv,err);
    else
      flag = f_i->second;


    h_i = hashTable.find(key);
    if(h_i != hashTable.end() ) { // We've got data
      switch( flag ) {
	// Getting the minimal polynomial is rather complicated, so both instances of this code were
	// wrapped up inside a block, to cut down at the clutter at the top of this function.
	// First declares a vector of the proper type and casts the pointer.  Then computes the minimal
	// polynomial.  It then builds the proper Maple list structure for this application.


         case BlackBoxi: {
	   Vectorl mpreturn;
	    Vectorl::iterator mp_i;
	    TriplesBBi* BB = (TriplesBBi*) h_i->second;
	    LinBox::minpoly( mpreturn, *BB, BB->field() );
	    retlist = MapleListAlloc(kv, mpreturn.size() );
	    for(i = 1, mp_i = mpreturn.begin(); mp_i != mpreturn.end(); ++mp_i, ++i)
	      MapleListAssign(kv, retlist, i, ToMapleInteger(kv, *mp_i));
	 }
	 break;

         case BlackBoxI: {
	   VectorI mpreturn;
	   VectorI::iterator mp_i;
	   TriplesBBI* BB = (TriplesBBI*) h_i->second;
	   LinBox::minpoly( mpreturn, *BB, BB->field() );
	   retlist = MapleListAlloc(kv, mpreturn.size());
	   for(i = 1, mp_i = mpreturn.begin(); mp_i != mpreturn.end(); ++mp_i, ++i)
	     MapleListAssign(kv, retlist, i, LiToM(kv, *mp_i, blank));

	 }
	 break;
      }
    }
    else
      MapleRaiseError(kv,err);

    return retlist;

  }
Пример #2
0
 inline void assign_vector(
     VectorI &v_src,
     VectorI &v_ind,
     VectorI &v_val,
     VectorJ &v_out,
     Accum    accum)
 {
     using namespace detail;
     if (v_val.size() != v_ind.size())
     {
         return;
     }
     assign_vector_helper(v_src, v_ind, v_val.begin(), v_out, accum);
 }
Пример #3
0
  ALGEB getVector(MKernelVector kv, ALGEB* args)
  {
    // Get the key, declare variables
    int key = MapleToInteger32(kv,args[1]), flag;
    char err[] = "ERROR!  The associated Vector object does not exist!";
    M_INT index, bound[2];
    RTableData d;
    RTableSettings s;
    ALGEB rtable, blank;
    char MapleStatement[100] = "rtable(1..";


    // Check to see if the object pointed to by key is in the type table.  If not, panic
    std::map<int,int>::iterator f_i = typeTable.find(key);
    if(f_i == typeTable.end() ) {
      MapleRaiseError(kv, err);
    }

    // Otherwise, we have our object
    flag = f_i->second;

    // Get a pointer to the actual data
    std::map<int,void*>::iterator h_i = hashTable.find(key);
    if(h_i != hashTable.end() ) {

      // Diverge over whether we are using maple 7 or 8 ( and 5 & 6)
      // in Maple, arg 3 is a flag indicating which method to use
      switch( MapleToInteger32(kv, args[3])) {

	// In this case, Maple 7 is being used, we have to construct a call using "EvalMapleStatement()"
	// to call the RTable constructor
         case 1:

	   switch(flag) {
	   case SmallV:{
	     // Get the vector
	     Vectorl* V = (Vectorl*) h_i->second;
	     Vectorl::const_iterator V_i;

	     // Create the Maple object
	     sprintf(MapleStatement + strlen(MapleStatement), "%d", V->size() );
	     strcat(MapleStatement, ", subtype=Vector[column], storage=sparse)");
	     rtable = kv->evalMapleStatement(MapleStatement);

	     // populate the Maple vector w/ the entries from V above
	     for(index = 1, V_i = V->begin(); V_i != V->end(); ++V_i, ++index) {
	       d.dag = ToMapleInteger(kv, *V_i); // d is a union, dag is the
	                                         // ALGEB union field
	       RTableAssign(kv, rtable, &index, d);
	     }
	   }
	   break;

	   case LargeV: {
	     // This part works the same way as above
	     VectorI* V = (VectorI*) h_i->second;
	     VectorI::const_iterator V_i;
	     sprintf(MapleStatement + strlen(MapleStatement), "%d", V->size() );
	     strcat(MapleStatement, ",subtype=Vector[column], storage=sparse)");
	     rtable = kv->evalMapleStatement(MapleStatement);

	     // Use maple callback to call the procedure from Maple that translates a gmp integer
	     // into a large maple integer.  Then put this into the Maple vector
	     for(index = 1, V_i = V->begin(); V_i != V->end(); ++V_i, ++index) {

	       /* Okay, here's how this line works.  Basically,
		* in order to set the entries of this RTable to
		* multi-precision integers, I have to first use my own conversion
		* method, LiToM, to convert the integer entry to a ALGEB structure,
		* then do a callback into Maple that calls the ExToM procedure,
		* which converts the results of LiToM into a Maple multi-precision
		* integer. At the moment, this is the best idea I've got as to
		* how to convert a GMP integer into a Maple representation in one shot.
		*/

	       d.dag = EvalMapleProc(kv,args[2],1,LiToM(kv, *V_i, blank));
	       RTableAssign(kv, rtable, &index, d);
	     }
	   }
	   break;

	   default:
	     MapleRaiseError(kv, err);
	     break;
	   }
	   break;

	   // In this case, use the simpler RTableCreate function, rather than building a string
	   // that must be parsed by maple

	   case 2:

	     kv->rtableGetDefaults(&s); // Get default settings - set datatype to Maple,
                               // DAGTAG to anything
	     s.subtype = 2; // Subtype set to column vector
	     s.storage = 4; // Storage set to rectangular
	     s.num_dimensions = 1; // What do you think this means :-)
	     bound[0] = 1; // Set the lower bounds of each dimension to 0

	     switch(flag) {// Switch on data type of vector
	     case SmallV:{ // single word integer entry vector
	       Vectorl* V = (Vectorl*) h_i->second;
	       Vectorl::const_iterator V_i;
	       bound[1] = V->size();
	       rtable = kv->rtableCreate(&s, NULL, bound); // Create the Maple vector

	       for(index = 1, V_i = V->begin(); V_i != V->end(); ++V_i, ++index) {
		 d.dag = ToMapleInteger(kv, *V_i); // d is a union, dag is the
	                                        // ALGEB union field
		 RTableAssign(kv, rtable, &index, d);
	       }
	     }
	     break;

	     case LargeV: { // Same as above for multi-word integer entry vector
	       VectorI* V = (VectorI*) h_i->second;
	       VectorI::const_iterator V_i;
	       bound[1] = V->size();
	       rtable = kv->rtableCreate(&s, NULL, bound);

	       for(index = 1, V_i = V->begin(); V_i != V->end(); ++V_i, ++index) {


		 /* Okay, here's how this line works.  Basically,
		  * in order to set the entries of this RTable to
		  * multi-precision integers, I have to first use my own conversion
		  * method, LiToM, to convert the integer entry to a ALGEB structure,
		  * then do a callback into Maple that calls the ExToM procedure,
		  * which converts the results of LiToM into a Maple multi-precision
		  * integer. At the moment, this is the best idea I've got as to
		  * how to convert a GMP integer into a Maple representation in one shot.
		  */

		 d.dag = EvalMapleProc(kv,args[2],1,LiToM(kv, *V_i, blank));
		 RTableAssign(kv, rtable, &index, d);
	       }
	     }
	     break;

	     default:
	       MapleRaiseError(kv, err);
	       break;
	     }
	     break; // breaks case 2.
	     // This was causing a wicked error :-)


      default:
	MapleRaiseError(kv, err);
	break;

      }
    }
    else {
      MapleRaiseError(kv, err);
    }

    return rtable;
  }
Пример #4
0
  ALGEB getMatrix(MKernelVector kv, ALGEB* args)
  {
    // Get the key
    int key = MapleToInteger32(kv,args[1]), flag;
    char err[] = "ERROR!  The associated BlackBox object does not exist!";
    M_INT index[2], bound[4];
    RTableData d;
    ALGEB rtable, blank;
    RTableSettings s;
    std::vector<size_t> Row, Col;
    std::vector<size_t>::const_iterator r_i, c_i;
    char MapleStatement[100] = "rtable(1..";


    // Get the data type of the blackbox
    std::map<int,int>::iterator f_i = typeTable.find(key);
    if( f_i == typeTable.end() ) // In case the blackbox isn't there
      MapleRaiseError(kv,err);
    flag = f_i->second; // Otherwise, get the blackbox type

    // Check that the data is there
    std::map<int,void*>::iterator h_i = hashTable.find(key);
    if(h_i != hashTable.end() ) {

      // Switch according to mode - regular or "special fix" mode
      switch( MapleToInteger32(kv, args[3])) {

      case 1: // This is the Maple 7 case, "special fix" mode
	      // Use the EvalMapleStatement() to call the rtable constructor in the
	      // Maple environment

	   // Switch according to the type
	   switch(flag) {
	   case BlackBoxi:{ // For single word entry matrices

	     // Extract the necessary data
	     TriplesBBi* BB = (TriplesBBi*) h_i->second;
	     Vectorl Data = BB->getData();
	     Row = BB->getRows();
	     Col = BB->getCols();
	     Vectorl::const_iterator d_i;

	     // Builds the statement that will be used in the Maple 7 callback

	     sprintf(MapleStatement + strlen(MapleStatement), "%d", BB->rowdim() );
	     strcat(MapleStatement, ",1..");

	     sprintf(MapleStatement + strlen(MapleStatement), "%d", BB->coldim() );
	     strcat(MapleStatement, ", subtype=Matrix, storage=sparse);");

	     // Perform the callback
	     rtable = kv->evalMapleStatement(MapleStatement);

	     // Insert each non-zero entry
	     for(d_i = Data.begin(), r_i = Row.begin(), c_i = Col.begin(); r_i != Row.end(); ++d_i, ++c_i, ++r_i) {
	       index[0] = *r_i; index[1] = *c_i;
	       d.dag = ToMapleInteger(kv, *d_i); // d is a union, dag is the
	                                        // ALGEB union field
	       RTableAssign(kv, rtable, index, d);
	     }
	   }
	   break;

	   case BlackBoxI: { // For multi-word size matrix types
	     TriplesBBI* BB = (TriplesBBI*) h_i->second;
	     VectorI Data = BB->getData();
	     VectorI::const_iterator d_i;

	     // Build and execute the Maple callback
	     sprintf(MapleStatement + strlen(MapleStatement), "%d", BB->rowdim() );
	     strcat(MapleStatement, ", 1..");
	     sprintf(MapleStatement + strlen(MapleStatement), "%d", BB->coldim() );
	     strcat(MapleStatement, ", subtype=Matrix, storage=sparse);");
	     rtable = kv->evalMapleStatement(MapleStatement);

	     for(d_i = Data.begin(), r_i = Row.begin(), c_i = Col.begin(); r_i != Row.end(); ++d_i, ++r_i, ++c_i) {
	       index[0] = *r_i; index[1] = *c_i;

	       //    * Okay, here's how this line works.  Basically,
	       //    * in order to set the entries of this RTable to
	       //    * multi-precision integers, I have to first use my own conversion
	       //    * method, LiToM, to convert the integer entry to a ALGEB structure,
	       //    * then do a callback into Maple that calls the ExToM procedure,
	       //    * which converts the results of LiToM into a Maple multi-precision
	       //    * integer. At the moment, this is the best idea I've got as to
	       //    * how to convert a GMP integer into a Maple representation in one shot.
	       //    *

	       d.dag = EvalMapleProc(kv,args[2],1,LiToM(kv, *d_i, blank));
	       RTableAssign(kv, rtable, index, d);
             }
	   }
	   break;

	   // In this case the object is not a BlackBox type
	   default:
	     MapleRaiseError(kv,err);
	     break;
	   }
	break;

      case 2: // Okay, here is the normal case.
	      // Use RTableCreate to create a Maple rtable object

	    kv->rtableGetDefaults(&s);
	    // Get default settings - set datatype to Maple,
	    // DAGTAG to anything

	    s.subtype = RTABLE_MATRIX; // Subtype set to Matrix
	    s.storage = RTABLE_SPARSE; // Storage set to sparse
	    s.num_dimensions = 2; // What do you think this means :-)
	    bound[0] = bound[2] = 1; // Set the lower bounds of each dimension to 0, which for maple is 1

	    switch(flag) { // Switch on data type

	    case BlackBoxi:{ // word size entry Matrix
		TriplesBBi* BB = (TriplesBBi*) h_i->second;
		Vectorl Data = BB->getData();
		Row = BB->getRows();
		Col = BB->getCols();
		Vectorl::const_iterator d_i;

		bound[1] = BB->rowdim();
		bound[3] = BB->coldim();
		rtable = kv->rtableCreate(&s, NULL, bound); // This is the RTableCreate function, it's
		                                            // just the one that works

		// Assign all the non-zero rows
		for( d_i = Data.begin(), r_i = Row.begin(), c_i = Col.begin(); r_i != Row.end(); ++d_i, ++c_i, ++r_i) {
		  index[0] = *r_i; index[1] = *c_i;
		  d.dag = ToMapleInteger(kv, *d_i); // d is a union, dag is the
	                                        // ALGEB union field
		  RTableAssign(kv, rtable, index, d);
		}
	      }
	      break;

	    case BlackBoxI: { // For multi-word entry Matrices
	      TriplesBBI* BB = (TriplesBBI*) h_i->second;
	      VectorI Data = BB->getData();

	      // Setup the Create() call
	      VectorI::const_iterator d_i;
	      Row = BB->getRows();
	      Col = BB->getCols();
	      bound[1] = BB->rowdim();
	      bound[3] = BB->coldim();
	      rtable = kv->rtableCreate(&s, NULL, bound); // Create an empty RTable

	      // Populate the RTable using the callback method described below
	      for(d_i = Data.begin(), r_i = Row.begin(), c_i = Col.begin(); r_i != Row.end(); ++d_i, ++r_i, ++c_i) {
		index[0] = *r_i; index[1] = *c_i;

	    //    * Okay, here's how this line works.  Basically,
	   //    * in order to set the entries of this RTable to
	   //    * multi-precision integers, I have to first use my own conversion
	   //    * method, LiToM, to convert the integer entry to a ALGEB structure,
	   //    * then do a callback into Maple that calls the ExToM procedure,
	   //    * which converts the results of LiToM into a Maple multi-precision
	   //    * integer. At the moment, this is the best idea I've got as to
	   //    * how to convert a GMP integer into a Maple representation in one shot.

	      d.dag = EvalMapleProc(kv,args[2],1,LiToM(kv, *d_i, blank));
	      RTableAssign(kv, rtable, index, d);
	      }
	    }
	  break;
       }
      }
    }
    else
      MapleRaiseError(kv,err);

    return rtable;
  }