Beispiel #1
0
void Matrix4D::Invert()
{
    Matrix4D inverse;
    inverse.Identity();

    if ( Math::fabs( m[0][0] ) < Math::fabs( m[1][0] ) ) Swap_Rows( 0, 1 );

    Scalar one_over = 1.0f / m[0][0]; 
    Scalar scale_factor = m[1][0];

    // generate row echelon form
    for ( int j = 0; j < dimension; j++ )
    {
        m[0][j]			*= one_over;
        inverse.m[0][j] *= one_over;
        m[1][j]			-= m[0][j] * scale_factor;
        inverse.m[1][j] -= inverse.m[0][j] * scale_factor;
    }
    // back substitution
    one_over = 1.0f / m[1][1];
    scale_factor = m[0][1];
    for ( int j = dimension-1; j >= 0; j-- )
    {
        m[1][j]			*= one_over;
        inverse.m[1][j] *= one_over;
        m[0][j]			-= m[1][j] * scale_factor;
        inverse.m[0][j]	-= inverse.m[1][j] * scale_factor;
    }
    *this = inverse;
}
Beispiel #2
0
// Perform Gaussian elimination with back substituion, given vector b,
// find vector X such that Ax = b
XVECTOR	XSQUARE_MATRIX::Solve_GEb(const XVECTOR &i_vB)
{
	XVECTOR	vX;
	XVECTOR	vBlcl = i_vB;
	if (m_lpdValues && i_vB.m_lpdValues && i_vB.m_uiN == m_uiN)
	{
		double * lpdValues_Store = new double [m_uiN * m_uiN];
		// store original matrix
		memcpy(lpdValues_Store,m_lpdValues,
					sizeof(double) * m_uiN * m_uiN);
		vX.Set_Size(m_uiN);

		unsigned int uiRef_Idx = 0;
		double	dMax = 0.0;
		unsigned int uiRow, uiRowInner, uiCol;
		for (uiRow = 0; uiRow < m_uiN; uiRow++)
		{
			// find max valued row
			uiRef_Idx = uiRow;
			for (uiRowInner = uiRow; uiRowInner < m_uiN; uiRowInner++)
			{
				if (m_lpdValues[uiRowInner * m_uiN + uiRow] > dMax)
				{
					uiRef_Idx = uiRowInner;
					dMax = m_lpdValues[uiRowInner * m_uiN + uiRow];
				}
			}
			Swap_Rows(uiRow,uiRef_Idx);
			vBlcl.Swap_Rows(uiRow,uiRef_Idx);
			// Perform Gaussian elimination for this column
			for (uiRowInner = uiRow + 1; uiRowInner < m_uiN; uiRowInner++)
			{
				double	dInner_Scalar = 
							-m_lpdValues[uiRowInner * m_uiN + uiRow] / 
									m_lpdValues[uiRow * m_uiN + uiRow];
				for (uiCol = uiRow; uiCol < m_uiN; uiCol++)
				{
					m_lpdValues[uiRowInner * m_uiN + uiCol] += 
						m_lpdValues[uiRow * m_uiN + uiCol] * 
						dInner_Scalar;
				}
				vBlcl.m_lpdValues[uiRowInner] += 
						vBlcl.m_lpdValues[uiRow] * dInner_Scalar;
			}
		}
		// Perform backsubstituion step
		vX = Back_Substituion(m_lpdValues,vBlcl);
		// restore original matrix
		memcpy(m_lpdValues,lpdValues_Store,
					sizeof(double) * m_uiN * m_uiN);
		delete [] lpdValues_Store;
	}
	return vX;
}
Beispiel #3
0
// perform Guass-Jordanian elimination:  The matrix will become
// it's inverse
void	XSQUARE_MATRIX::Inverse_GJ(void)
{
	if (m_lpdValues)
	{
		XSQUARE_MATRIX	cI(m_uiN);
		cI.Identity();
		// allocate work space
		double	dScalar;

		// Using row reduction, reduce the source matrix to the identity, 
		// and the identity will become A^{-1}
		for (unsigned int uiRow = 0; uiRow < m_uiN; uiRow++)
		{
			if (m_lpdValues[uiRow * m_uiN + uiRow] == 0.0)
			{
				for (unsigned int uiRowInner = uiRow + 1; 
						uiRowInner < m_uiN; 
						uiRowInner++)
				{
					if (m_lpdValues[uiRowInner * m_uiN + uiRow] != 0.0)
					{
						Swap_Rows(uiRow,uiRowInner);
						cI.Swap_Rows(uiRow,uiRowInner);
					}
				}
			}
			dScalar = 1.0 / m_lpdValues[uiRow * m_uiN + uiRow];
			Scale_Row(uiRow,dScalar);
			cI.Scale_Row(uiRow,dScalar);

			for (unsigned int uiRowInner = 0; 
					uiRowInner < m_uiN; 
					uiRowInner++)
			{
				double	dRow_Scalar = 
							-m_lpdValues[uiRowInner * m_uiN + uiRow];
				if (uiRowInner != uiRow)
				{
					cI.Add_Rows(uiRowInner,uiRow,dRow_Scalar,false);
					Add_Rows(uiRowInner,uiRow,dRow_Scalar,true);
				}
			}
		}
		// copy result into current matrix
		*this = cI;
	}
}