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@