int LinearAffineEq::buildLookupTableAndCheck(mat_GF2 & Ta, bsetElem cst, smap & mapA){
	for(unsigned int i=0; i<size; i++){
		mat_GF2 e = colVector(i);
		mat_GF2 v = Ta * e;
		GF2X res = colVector_GF2X(v, 0);
		bsetElem resE = getLong(res) + cst;

		// check mapping, if it is correct (consistent table data with new computed data)
		if (mapA.count(i)>0){
			if (mapA[i] != resE) {
				if (verbosity){
					cout << "Mapping inconsistent for i=" << i
						<< "; mapA[i] = " << mapA[i]
						<< "; resE = " << resE << endl;
					cout << "colVector: " << endl;
					dumpMatrix(e);
					cout << " Ta*e " << endl;
					dumpMatrix(v);
					cout << "res: " << res << endl;
				}
				return -4;
			}
		} else {
			mapA.insert(smapElem(i, resE));
		}
	}

	return 0;
}
/** @note There will always be a BOUNDS section, even if there are no bounds.
 */
void SPxLP::writeMPS(
   std::ostream&  p_output,          ///< output stream.
   const NameSet* p_rnames,          ///< row names.
   const NameSet* p_cnames,          ///< column names.
   const DIdxSet* p_intvars)         ///< integer variables.
   const
{
   METHOD("writeMPS");

   const char*    indicator;
   char           name [16];
   char           name1[16];
   char           name2[16];
   bool           has_ranges = false;
   int            i;
   int            k;
   
   // --- NAME Section ---
   p_output << "NAME          MPSDATA" << std::endl;

   // --- ROWS Section ---
   p_output << "ROWS" << std::endl;

   for(i = 0; i < nRows(); i++)
   {
      if (lhs(i) == rhs(i))
         indicator = "E";
      else if ((lhs(i) > -infinity) && (rhs(i) < infinity))
      {
         indicator  = "E";
         has_ranges = true;
      }
      else if (lhs(i) > -infinity)
         indicator = "G";
      else if (rhs(i) <  infinity)
         indicator = "L";
      else
         throw SPxInternalCodeException("XMPSWR02 This should never happen.");

      writeRecord(p_output, indicator, getRowName(*this, i, p_rnames, name)); 
   }
   writeRecord(p_output, "N", "MINIMIZE"); 
   
   // --- COLUMNS Section ---
   p_output << "COLUMNS" << std::endl;

   bool has_intvars = (p_intvars != 0) && (p_intvars->size() > 0);

   for(int j = 0; j < (has_intvars ? 2 : 1); j++)
   {
      bool is_intrun = has_intvars && (j == 1);

      if (is_intrun)
         p_output << "    MARK0001  'MARKER'                 'INTORG'" 
                  << std::endl;

      for(i = 0; i < nCols(); i++)
      {
         bool is_intvar = has_intvars && (p_intvars->number(i) >= 0);

         if (  ( is_intrun && !is_intvar)
            || (!is_intrun &&  is_intvar))
             continue;

         const SVector& col = colVector(i);
         int colsize2       = (col.size() / 2) * 2;

         assert(colsize2 % 2 == 0);

         for(k = 0; k < colsize2; k += 2)
            writeRecord(p_output, 0, 
               getColName(*this, i,                p_cnames, name),
               getRowName(*this, col.index(k),     p_rnames, name1),
               col.value(k),
               getRowName(*this, col.index(k + 1), p_rnames, name2),
               col.value(k + 1));

         if (colsize2 != col.size())
            writeRecord(p_output, 0,
               getColName(*this, i,            p_cnames, name),
               getRowName(*this, col.index(k), p_rnames, name1),
               col.value(k));

         if (isNotZero(maxObj(i)))
            writeRecord(p_output, 0, getColName(*this, i, p_cnames, name),
               "MINIMIZE", -maxObj(i));
      }
      if (is_intrun)
         p_output << "    MARK0001  'MARKER'                 'INTEND'"
                  << std::endl;
   }
   // --- RHS Section ---
   p_output << "RHS" << std::endl;

   i = 0;
   while(i < nRows())
   {
      Real rhsval1 = 0.0;
      Real rhsval2 = 0.0;

      for(; i < nRows(); i++)
         if ((rhsval1 = getRHS(lhs(i), rhs(i))) != 0.0)
            break;

      if (i < nRows())
      {
         for(k = i + 1; k < nRows(); k++)
            if ((rhsval2 = getRHS(lhs(k), rhs(k))) != 0.0)
               break;

         if (k < nRows())
            writeRecord(p_output, 0, "RHS", 
               getRowName(*this, i, p_rnames, name1),
               rhsval1, 
               getRowName(*this, k, p_rnames, name2),
               rhsval2);
         else
            writeRecord(p_output, 0, "RHS", 
               getRowName(*this, i, p_rnames, name1),
               rhsval1);

         i = k + 1;
      }
   }

   // --- RANGES Section ---
   if (has_ranges)
   {
      p_output << "RANGES" << std::endl;
         
      for(i = 0; i < nRows(); i++)
         if ((lhs(i) > -infinity) && (rhs(i) < infinity))
            writeRecord(p_output, "", "RANGE", 
               getRowName(*this, i, p_rnames, name1),
               rhs(i) - lhs(i));
   }
   // --- BOUNDS Section ---
   p_output << "BOUNDS" << std::endl;

   for(i = 0; i < nCols(); i++)
   {
      // skip variables that do not appear in the objective function or any constraint
      const SVector& col = colVector(i);
      if (col.size() == 0 && isZero(maxObj(i)))
         continue;
      if (lower(i) == upper(i))
      {
         writeRecord(p_output, "FX", "BOUND", 
            getColName(*this, i, p_cnames, name1),
            lower(i));

         continue;
      }
      if ((lower(i) <= -infinity) && (upper(i) >= infinity))
      {
         writeRecord(p_output, "FR", "BOUND", 
            getColName(*this, i, p_cnames, name1));
         continue;
      }
      if (lower(i) != 0.0)
      {
         if (lower(i) > -infinity)
            writeRecord(p_output, "LO", "BOUND", 
               getColName(*this, i, p_cnames, name1),
               lower(i));
         else
            writeRecord(p_output, "MI", "BOUND", 
               getColName(*this, i, p_cnames, name1));
      }

      if (has_intvars && (p_intvars->number(i) >= 0))
      {
         // Integer variables have default upper bound 1.0, but we should write
         // it nevertheless since CPLEX seems to assume infinity otherwise.
         writeRecord(p_output, "UP", "BOUND", 
            getColName(*this, i, p_cnames, name1),
            upper(i));
      }
      else
      {
         // Continous variables have default upper bound infinity
         if (upper(i) < infinity)
            writeRecord(p_output, "UP", "BOUND", 
               getColName(*this, i, p_cnames, name1),
               upper(i));
      }
   }   
   // --- ENDATA Section ---
   p_output << "ENDATA" << std::endl;   

   // Output warning when writing a maximisation problem
   if(spxSense() == SPxLP::MAXIMIZE)
   {
      MSG_WARNING( spxout << "XMPSWR03 Warning: objective function inverted when writing maximization problem in MPS file format" << std::endl; )
   }