矩阵的初等变换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaolongwoaini99/article/details/80251331

矩阵初等变换:

1.交换矩阵的两行

2.以数K不等于0乘以矩阵某一行

3.把矩阵某一行的K倍添加到某一行上

下面通过求逆矩阵来分析矩阵初等变换:

利用初等变换求下面矩阵的逆矩阵:

        2    2    1        1    0    0                1    0    0        ?    ?    ?

        4    2    2        0    1    0   》》》   0    1    0        ?    ?    ?

        1    4    1        0    0    1                0    0    1        ?    ?    ?

利用初等变换求逆矩阵的实质就是通过矩阵初等变换的三个规则,从而实现以下转变。

通过初等变换求逆矩阵的实质就是将所需矩阵变换为单位矩阵之后,与其同时变化的初始单位矩阵最后得到的结果便是改矩阵的逆矩阵,下面我们将矩阵求逆简单的划分为两部分,即“化1”,“化0”;

第一步:(0,0)化1——第0行*1/(0,0)

        2    2    1        1    0    0                1    1   1/2    1/2    0    0

        4    2    2        0    1    0   》》》   4    2    2        0      1    0

        1    4    1        0    0    1                1    4    1        0      0    1

化“0”:1、第一行=第0行*-(1,0)+第一行

        1    1   1/2         1/2    0    0                1    1   1/2      1/2    0    0

        4    2    2            0    1       0   》》》   0    -2    0       -2      1    0

        1    4    1            0    0       1                1     4     1        0      0    0

化“0”:2、第二行=第0行*-(2,0)+第二行

        1    1   1/2         1/2    0       0                1    1   1/2         1/2    0    0

        0    -2    0          -2      1       0   》》》   0    -2    0          -2      1    0

        1    4      1           0       0      1                0     3     1/2     -1/2    0    1

第二步:(1,1)化“1”——第一行=第一行*1/(1,1)

        1    1   1/2         1/2    0       0                1    1     1/2         1/2    0      0

        0    -2    0          -2      1       0   》》》   0    1      0            1    -1/2    0        

        0     3     1/2     -1/2    0       1                0     3     1/2       -1/2    0      1

化“0”:(2,1)化“0”——第二行=第一行*(-(2,1))+第二行

        1    1   1/2         1/2    0       0                1    1     1/2         1/2      0        0

        0    1      0         1    -1/2      0  》》》    0    1      0            1      -1/2      0       

        0     3     1/2     -1/2    0       1                0     0     1/2       -7/2    3/2      1

第三步:(2,2)化“1”——第二行=第二行*1/(2,2)

        1    1     1/2         1/2    0         0                1    1     1/2         1/2      0        0

        0    1      0            1    -1/2       0  》》》    0    1      0            1      -1/2      0       

        0     0     1/2       -7/2    3/2     1                0     0      1          -7        3         1

化“0”:(0,1)化“0”——第0行=第一行*(-(0,1))+第0行

        1    1     1/2         1/2    0         0                1    0     1/2         -1/2      1/2     0

        0    1      0            1    -1/2       0  》》》    0    1      0            1      -1/2        0       

        0     0     1           -7/2    3/2     1                0     0      1          -7        3           1

化“0”: (0,2)化“0”——第0行=第二行*(-(0,2))+第0行

        1    0     1/2         -1/2      1/2     0                1    0      0            3      -1          -1

        0    1      0              1       -1/2     0  》》》    0    1      0            1      -1/2        0       

        0     0     1             -7        3         1                0     0     1          -7        3           1


算法实现:

/********************************
*逆矩阵求解
*********************************/

CMatrix CMatrix::Inverse()const {

if (m_nRow != m_nCol)    //非方阵
{
// TRACE("非方阵无法求逆!");
// throw "非方阵无法求逆!";
return (CMatrix)0;
}
CMatrix tmp(*this);
CMatrix ret(m_nRow),unit(m_nRow);    //单位阵
ret.SetUnit();
unit.SetUnit();
int maxIndex;
double dMul;
for (int i = 0; i<m_nRow; i++)//执行行的次数
{
maxIndex = tmp.Pivot(i);//1.求出行中最大值的列
if (tmp.m_dData[maxIndex][i] == 0)//矩阵中某一行全为0
{
//TRACE("求逆矩阵的为非满秩矩阵,无法求逆!");
//throw "求逆矩阵的为非满秩矩阵,无法求逆!";
//return (CMatrix)-1;
return unit;
}
if (maxIndex != i)    //2.如果三角阵中此列的最大值不在当前行,交换
{
tmp.Exchange(i, maxIndex);
ret.Exchange(i, maxIndex);
}
ret.Multiple(i, 1 / tmp.m_dData[i][i]);
tmp.Multiple(i, 1 / tmp.m_dData[i][i]);//3.在第i行乘以实数 (1 / tmp.m_dData[i][i])

for (int j = i + 1; j< m_nRow; j++)//4.执行当前行-1的次数
{
dMul = -tmp.m_dData[j][i];
tmp.MultipleAdd(j, i, dMul);//将第i行乘以dMul加到第j行上
ret.MultipleAdd(j, i, dMul);
}
}//end for

for (int i = m_nRow - 1; i>0; i--)//执行行-1次
{
for (int j = i - 1; j >= 0; j--)
{
dMul = -tmp.m_dData[j][i];
tmp.MultipleAdd(j, i, dMul);//将第i行乘以dMul加到第j行上
ret.MultipleAdd(j, i, dMul);
}
}//end for     
return ret;

}


/********************************
*获取行中最大值的列
*********************************/
int CMatrix::Pivot(int row) const
{
int index = row;
for (int i = row + 1; i<m_nRow; i++)
{
//if (m_dData[i][row] < 0) m_dData[i][row] = -m_dData[i][row]; 
if (abs((long)m_dData[i][row]) > abs((long)m_dData[index][row]))
index = i;
}
return index;
}


/*****************************************************
*对调ri,rj行
******************************************************/
//对调两行ri<-->rj
CMatrix&  CMatrix::Exchange(int i, int j)
{
if (i<0 || i >= m_nRow)
{
//TRACE("对换行<i>超出矩阵的行范围!");
//throw "对换行<i>超出矩阵的行范围!";
return (CMatrix)0;
}
if (j<0 || j >= m_nRow)
{
//throw "对换行<i>超出矩阵的行范围!";
//TRACE("对换行<i>超出矩阵的行范围!");
return (CMatrix)0;
}
double dTemp = 0;
for (int k = 0; k<m_nCol; k++)
{
dTemp = m_dData[i][k];
m_dData[i][k] = m_dData[j][k];
m_dData[j][k] = dTemp;
}
return *this;

}

/*******************************************************
*第index 行乘以实数mul 
********************************************************/
CMatrix&  CMatrix::Multiple(int index, double mul)
{
if (index <0 || index >= m_nRow)
{
//TRACE("矩阵行乘中指定的行超出矩阵行范围!");
//throw "矩阵行乘中指定的行超出矩阵行范围!";
return (CMatrix)0;
}
for (int i = 0; i<m_nCol; i++)
m_dData[index][i] *= mul;
return *this;

}

/********************************************************
*第src行乘以mul加到第index行
*********************************************************/
CMatrix& CMatrix::MultipleAdd(int index, int src, double mul)
{
if (index <0 || index >= m_nRow)
{
//TRACE("矩阵行乘相加中指定的行<index>超出矩阵行范围!");
//throw "矩阵行乘相加中指定的行<index>超出矩阵行范围!";
return (CMatrix)0;
}
if (src < 0 || src >= m_nRow)
{
// TRACE("矩阵行乘相加中指定的行<src>超出矩阵行范围!");
// throw "矩阵行乘相加中指定的行<src>超出矩阵行范围!";
return (CMatrix)0;
}


for (int j = 0; j<m_nCol; j++)
m_dData[index][j] += m_dData[src][j] * mul;
return *this;
}

猜你喜欢

转载自blog.csdn.net/xiaolongwoaini99/article/details/80251331