1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
Matrix& Matrix::rowEchelonForm()
{
if (m_cols <= m_rows)
throw MatrixException(wrongSizeCalc, __FUNCTION__, __LINE__, __FILE__);
// Step 1, remove the lower terms
for (int col = 0; col < m_rows; ++col)
{
// It's a zero, Swap with another row
if ( at(col,col)==0 )
{
for (int row = col+1; row < m_rows; ++row)
if ( at(row,col) )
rowSwap(row,col);
if( ! at(col,col) )
throw MatrixException(unsolvable, __FUNCTION__, __LINE__, __FILE__);
}
// Set the first element to 1
rowGain(col, ((T)1) / at(col,col) );
// Set the rest of the rows to 0
for (int row = col+1; row < m_rows; ++row)
rowGainAndAdd(T(-1) * at(row,col) , col, row);
}
// Step 2, remove the upper terms
for (int col = 1; col < m_rows; ++col)
for (int row = 0; row < col; ++row)
rowGainAndAdd( T(-1) * at(row,col) , col, row);
return *this;
}
void Matrix::rowGain(int row, T gain)
{
if (row >= m_rows)
throw MatrixException(invSet, __FUNCTION__, __LINE__, __FILE__);
for (int i = 0; i < m_cols; ++i)
m_data[row*m_cols + i] *= gain;
}
void Matrix::rowSwap(int row1, int row2)
{
if (row1 >= m_rows || row2 >= m_rows)
throw MatrixException(invSet, __FUNCTION__, __LINE__, __FILE__);
T* row = new T[m_cols];
for (int i = 0; i < m_cols; ++i)
{
row[i] = at(row1, i);
set(row1, i, at(row2, i) );
set(row2, i, row[i]);
}
delete[] row;
}
void Matrix::rowGainAndAdd(T gain, int SourceRow, int DestinationRow)
{
if (SourceRow >= m_rows || DestinationRow >= m_rows)
throw MatrixException(invSet, __FUNCTION__, __LINE__, __FILE__);
for (int i = 0; i < m_cols; ++i)
m_data[DestinationRow*m_cols + i] += gain * m_data[SourceRow*m_cols + i];
}
|