Exemple #1
0
SparseMatrix & SparseMatrix::operator*=(const SparseMatrix & b)
{
  if (cols != b.rows)
    throw exception();
  if ((terms == MAX_TERMS) || (b.terms == MAX_TERMS))
    throw exception();

  SparseMatrix result;
  SparseMatrix bXpose = b.FastTranspose();
  int curRowIndex = 0;
  int curRowA = smArray[curRowIndex].row;
  int curRowBegin = curRowIndex;
  int sum = 0;
  int lastInResult = -1;

  // set boundary conditions
  smArray[terms].row = rows;
  bXpose.smArray[b.terms].row = b.rows;
  bXpose.smArray[b.terms].col = -1;

  while (curRowIndex < terms) // generate row curRowA of result
  {
    int curColIndex = 0;
    int curColB = bXpose.smArray[curColIndex].row;

    while (curColIndex <= b.terms) // multiply row curRowA of A by column curColB of b
    {
      if (smArray[curRowIndex].row != curRowA // end of row curRowA of A
        || bXpose.smArray[curColIndex].row != curColB) // end of column curColB of b
      {
        if (result.StoreSum(sum, lastInResult, curRowA, curColB))
          throw exception();

        sum = 0; // reset sum
        curRowIndex = curRowBegin;
        while (bXpose.smArray[curColIndex].row == curColB) // go to next column
          ++curColIndex;
        curColB = bXpose.smArray[curColIndex].row;
      }
      else
      {
        int colA = smArray[curRowIndex].col;
        int colB = bXpose.smArray[curColIndex].col;
        if (colA < colB)
          ++curRowIndex;
        else if (colA > colB)
          ++curColIndex;
        else // colA == colB
          sum += smArray[curRowIndex++].value * bXpose.smArray[curColIndex++].value;
      }
    }

    while (smArray[curRowIndex].row == curRowA) // advanced to next row
      ++curRowIndex;
    curRowBegin = curRowIndex;
    curRowA = smArray[curRowIndex].row;
  }

  result.rows = rows; result.cols = b.cols; result.terms = lastInResult + 1;

  return *this = result;
}
SparseMatrix SparseMatrix::Multiply(SparseMatrix b)
//Multiply two sparse matrices @A@ (\(**\fBthis\fR) and @B@ producing @D@.
{
  if (Cols != b.Rows) {
  cout << "Incompatible matrices" << endl;
  return EmptyMatrix();
  }

  if ((Terms == MaxTerms) || (b.Terms == MaxTerms))
  {
      cout << "One additional space in @a@ or @b@ needed" << endl;
      return EmptyMatrix();
  }
  SparseMatrix bXpose = b.FastTranspose();
  SparseMatrix result;
  int currRowIndex = 0, LastD = -1, currRowBegin = 0, currRowA = smArray[0].row;
  // set boundary conditions
  smArray[Terms].row = Rows; bXpose.smArray[b.Terms].row = b.Cols;
  bXpose.smArray[b.Terms].col = -1; int sum = 0;
  while (currRowIndex < Terms) // generate row @currRowA@ of @result@
  {
      int currColB = bXpose.smArray[0].row; int currColIndex = 0;
	while (currColIndex <= b.Terms) // multiply row @currRowA@ of @a@ by column \fIcurrColB\fP of @b@
	{
 //	   cout << "currRowIndex:" << currRowIndex << " currColIndex:" << currColIndex << " currRowA:" << currRowA << " currColB:" << currColB << endl;
	   if(smArray[currRowIndex].row != currRowA) // end of row @currRowA@
	   {
//	      cout << "1: new col" << endl;
	      result.StoreSum(sum, LastD,currRowA,currColB);
	      currRowIndex = currRowBegin;
	      // go to next column
	      while (bXpose.smArray[currColIndex].row == currColB) currColIndex++;
	      currColB = bXpose.smArray[currColIndex].row;
	   }
	   else if (bXpose.smArray[currColIndex].row != currColB) // end of column \fIcurrColB\fP of @b@
	   {
//	      cout << "2: new row" << endl;
	      result.StoreSum(sum,LastD,currRowA,currColB);
	      // set to multiply row @currRowA@ with next column
	      currRowIndex = currRowBegin; currColB = bXpose.smArray[currColIndex].row;
	   }
	   else
	      switch (compare (smArray[currRowIndex].col, bXpose.smArray[currColIndex].col)) {
		 case '<':   // advance to next term in row.
//		     cout << "3a: next term in row" << endl;
		     currRowIndex++; break;
		 case '=':   // add to \fIsum\fP
//		     cout << "3b:  add to sum" << endl;
		     sum += smArray[currRowIndex].value * bXpose.smArray[currColIndex].value;
		     currRowIndex++; currColIndex++; break;
		 case '>': // advance to next term in column \fIc\fP
//		     cout << "3c: next term in col" << endl;
		     currColIndex++;
	      } // end of switch
	} // of \fBwhile\fP (@currColIndex@ <= @b.Terms)@
	while (smArray[currRowIndex].row == currRowA) // advance to next row
	  currRowIndex++;
	currRowBegin = currRowIndex; currRowA = smArray[currRowIndex].row;
  } //end of \fBwhile\fP (@currRowIndex@ < @Terms@)
  result.Rows = Rows; result.Cols = b.Cols; result.Terms =  LastD+1;
  return result;
} // of @Multiply@