900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 对称矩形C语言 c语言编程求任意对称正定矩阵的逆。

对称矩形C语言 c语言编程求任意对称正定矩阵的逆。

时间:2020-05-24 07:37:28

相关推荐

对称矩形C语言 c语言编程求任意对称正定矩阵的逆。

满意答案

玖林国际999

推荐于 .03.21

采纳率:58%等级:13

已帮助:6009人

#ifndef __MATRIX_DOT_H__

#define __MATRIX_DOT_H__

template

void Swap(T& a, T& b)

{

T temp;

temp = a;

a = b;

b = temp;

}

class CMatrix

{

static double ZERO;//极小值

public:

CMatrix(int row = 3, int col = 3); //

CMatrix(const CMatrix& right); //拷贝构造函数

~CMatrix();

void Show(const char* pre = NULL)const; //输出矩阵

void Free();

int Resize(int row, int col); //重新定义矩阵大小

int GetRow()const{ return m_iRow; } //返回矩阵行数

int GetCol()const{ return m_iCol; } //返回矩阵列数

int RowSwap(int x, int y); //行交换,成功返回1,否则0

int ColSwap(int x, int y); //列交换

static void SetZero(double z); //设定ZERO的值,所有CMatrix实例精度都将改变

const CMatrix Transpose()const; //返回转置矩阵

const CMatrix Adjoint()const; //伴随矩阵

const CMatrix Residue(int row, int col)const;//求对应元素的余子式

const CMatrix Contrary()const;//逆矩阵

const CMatrix Gauss_Jordan(double* pDet = NULL)const;//逆矩阵(高斯-约旦法),pDet为行列式,

//此法精度较低,但效率较高

double Residue_a(int row, int col)const;//求对应元素的代数余子式

double Determinant()const; //返回方阵的行列式

double Det_Recursion()const; //返回方阵的行列式(递归)

int IsZero()const; //判断元素是否全为0(零矩阵)

int IsPhalanx()const; //判断是否为方阵

int IsReverse()const; //判断矩阵是否可逆

int IsNonfunnyPhalanx()const; //判断是否非奇异方阵

double* operator[](int i)const; //操作单个元素

CMatrix& operator=(const CMatrix& right);

CMatrix& operator=(const double* pRight);

CMatrix& operator=(const double** ppRight);

const CMatrix& operator+()const; //一元操作符

const CMatrix operator-()const; //一元操作符

const CMatrix operator+(const CMatrix& right)const;

const CMatrix operator-(const CMatrix& right)const;

const CMatrix operator*(const CMatrix& right)const;

const CMatrix operator*(const double& right)const;

const CMatrix operator/(const double& right)const;

CMatrix& operator+=(const CMatrix& right);

CMatrix& operator-=(const CMatrix& right);

CMatrix& operator*=(const CMatrix& right);

CMatrix& operator*=(const double& right);

CMatrix& operator/=(const double& right);

int operator==(const CMatrix& right)const;

int operator!=(const CMatrix& right)const;

private:

int m_iRow; //行数

int m_iCol; //列数

double** m_ppData; //数据

};

#endif //__MATRIX_DOT_H__

//matrix.cpp

//

#include

#include

#include

#include

#include

#include "matrix.h"

double CMatrix::ZERO = 1e-10;

CMatrix::CMatrix(int row/*=3*/, int col/*=3*/)

{

m_ppData = NULL;

Resize(row, col);

}

//拷贝构造函数

CMatrix::CMatrix(const CMatrix& right)

{

m_ppData = NULL;//一定要加这句初始化(一个对象不会同时调用构造函数和拷贝构造函数)

Resize(right.GetRow(), right.GetCol());

for(int i = 0; i < right.GetRow(); i++)

{

for(int j = 0; j < right.GetCol(); j++)

m_ppData[i][j] = right[i][j];

}

}

CMatrix::~CMatrix()

{

Free();

}

void CMatrix::Free()

{

if(m_ppData != NULL){

for(int i = 0; i < m_iRow; i++)

{

if(m_ppData[i] != NULL)

delete[] m_ppData[i];

m_ppData[i] = NULL;

}

m_ppData = NULL;

}

}

int CMatrix::Resize(int row, int col)

{

assert(row > 0 && col > 0);

//释放空间

Free();

//申请空间

m_iRow = row;

m_iCol = col;

m_ppData = new double*[m_iRow];

assert(m_ppData != NULL);

for(int i = 0; i < m_iRow; i++)

{

m_ppData[i] = new double[m_iCol];

assert(m_ppData[i] != NULL);

}

//初始化

for(i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

m_ppData[i][j] = 0;

}

return 1;

}

//zero

void CMatrix::SetZero(double z)

{

double zero = fabs(z);

if(zero > 1.0f) return;

ZERO = zero;

}

//show

void CMatrix::Show(const char* pre/*=NULL*/)const

{

int i, j;

#ifdef _WINDOWS

if(m_iRow > 10 || m_iCol > 10)

MessageBox(NULL, "矩阵数据量太大,不能输出", "警告", MB_OK);

char buf[4096];

char temp[256];

strcpy(buf, "");

if(pre != NULL)

{

strcpy(buf, pre);

strcat(buf, "\n");

}

for(i = 0; i < m_iRow; i++)

{

for(j = 0; j < m_iCol; j++)

{

sprintf(temp, "%.3f\t", m_ppData[i][j]);

strcat(buf, temp);

}

strcat(buf, "\n");

}

MessageBox(NULL, buf, "提示信息", MB_OK);

#else

if(pre != NULL)

puts(pre);

for(i = 0; i < m_iRow; i++)

{

for(j = 0; j < m_iCol; j++)

printf("%f\t", m_ppData[i][j]);

printf("\n");

}

#endif //_WINDOWS

}

///计算//

//行交换

int CMatrix::RowSwap(int x, int y)

{

if(x < 0 || x >= m_iRow || y < 0 || y >= m_iRow)

return 0;

if(x == y)

return 1;

for(int i = 0; i < m_iCol; i++)

{

Swap(m_ppData[x][i], m_ppData[y][i]);

}

return 1;

}

//列交换

int CMatrix::ColSwap(int x, int y)

{

if(x < 0 || x >= m_iCol || y < 0 || y >= m_iCol)

return 0;

if(x == y)

return 1;

for(int i = 0; i < m_iRow; i++)

{

Swap(m_ppData[i][x], m_ppData[i][y]);

}

return 1;

}

//转置

const CMatrix CMatrix::Transpose()const

{

CMatrix tr(m_iCol, m_iRow);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

tr[j][i] = m_ppData[i][j];

}

return tr;

}

//计算方阵的行列式(精度不高)

double CMatrix::Determinant()const

{

assert(m_iRow == m_iCol);

CMatrix temp = *this;

int i,j,m,n,s,t,k=1;

double f=1,c,x,sn;

for (i=0,j=0; i

{

if (temp[i][j]==0)

{

for (m = i;m < m_iRow; m++)

{

if(fabs(temp[m][j]) > ZERO)//0

break;

}

if (m == m_iRow)

{

return 0;

}

else

for (n = j; n < m_iRow; n++)

{

c = temp[i][n];

temp[i][n] = temp[m][n];

temp[m][n] = c;

}

k *= (-1);

}

for (s = m_iRow-1; s>i; s--)

{

x = temp[s][j];

for (t = j; t < m_iRow; t++)

temp[s][t] -= temp[i][t] * (x/temp[i][j]);

}

}

for (i = 0; i < m_iRow; i++)

f *= temp[i][i];

sn = k * f;

return sn;

}

//行列式(递归,精度较高)

double CMatrix::Det_Recursion()const

{

assert(m_iRow == m_iCol);

CMatrix temp;

double ans = 0;

if(m_iRow == 1)

{

return m_ppData[0][0];

}

else if(m_iRow == 2)

{

return m_ppData[0][0]*m_ppData[1][1] - m_ppData[1][0]*m_ppData[0][1];

}

else

{

for(int i = 0; i < m_iRow; i++)

{

temp = Residue(i, 0);//this->Residue(i, 0)

ans += temp.Det_Recursion()*m_ppData[i][0]*pow(-1, i);

}

}

return ans;

}

//计算方阵的余子式

const CMatrix CMatrix::Residue(int row, int col)const

{

CMatrix re;

int index = 0;

assert(m_iRow == m_iCol);

assert(m_iRow >= 2);

assert(row < m_iRow && col < m_iCol);

assert(row >= 0 && col >= 0);

double* pData = NULL;

pData = new double[(m_iRow-1)*(m_iCol-1)];

assert(pData != NULL);

re.Resize(m_iRow-1, m_iCol-1);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

if(i != row && j != col)

pData[index++] = m_ppData[i][j];

}

re = pData;

delete[] pData;

pData = NULL;

return re;

}

//计算方阵的代数余子式

double CMatrix::Residue_a(int row, int col)const

{

return (Residue(row, col)).Det_Recursion()*pow(-1, row+col);

}

//伴随矩阵

const CMatrix CMatrix::Adjoint()const

{

CMatrix ad(m_iRow, m_iCol);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

ad[j][i] = Residue_a(i, j);

}

return ad;

}

//逆矩阵

const CMatrix CMatrix::Contrary()const

{

assert(IsReverse());

CMatrix co(m_iRow, m_iCol);

co = Adjoint();//this

co /= Det_Recursion();//this

return co;

}

//高斯-约旦法求逆矩阵(全选主元), pDet为原方阵的行列式

const CMatrix CMatrix::Gauss_Jordan(double* pDet/*=NULL*/)const

{

assert(IsReverse());

double fDet = 1.0f;

int flag = 1;

int k = 0, i = 0, j = 0;

CMatrix out(m_iRow, m_iCol);//逆

CMatrix m = *this;//原

CMatrix rhs(2, m_iRow);//保存主元素位置,0 i, 1 j;

for(k = 0; k < m_iRow; k++)

{

//第一步:全选主元

double fMax = 0.0f;

for(i = 0; i < m_iRow; i++)

{

for(j = 0; j < m_iCol; j++)

{

const double f = fabs(m[i][j]);

if(f > fMax)

{

fMax = f;

rhs[0][k] = i;

rhs[1][k] = j;

}

}

}

//if(fMax < 0.00001)//元素全为0

//{

// fDet = 0.0f;

// return out;

//}

if((int)rhs[0][k] != k)

{

flag = -flag;

m.RowSwap((int)rhs[0][k], k);

}

if((int)rhs[1][k] != k)

{

flag = -flag;

m.ColSwap((int)rhs[1][k], k);

}

//计算行列值

fDet *= m[k][k];

//计算逆矩阵

//第二步

m[k][k] = 1.0f/m[k][k];

//第三步

for(j = 0; j < m_iCol; j++)

{

if(j != k)

m[k][j] *= m[k][k];

}

//第四步

for(i = 0; i < m_iRow; i++)

{

if(i != k)

{

for(j = 0; j < m_iCol; j++)

{

if(j != k)

m[i][j] = m[i][j] - m[i][k]*m[k][j];

}

}

}

//第五步

for(i = 0; i < m_iRow; i++)

{

if(i != k)

{

m[i][k] *= -m[k][k];

}

}

}//end for(k);

for(k = m_iRow-1; k >= 0; k--)

{

if((int)rhs[1][k] != k)

{

m.RowSwap((int)rhs[1][k], k);

}

if((int)rhs[0][k] != k)

{

m.ColSwap((int)rhs[0][k], k);

}

}

fDet *= flag;

if(pDet != NULL)

*pDet = fDet;

return m;

}

///判断//

//零矩阵

int CMatrix::IsZero()const

{

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

if(fabs(m_ppData[i][j]) > ZERO)

return 0;

}

return 1;

}

//方阵

int CMatrix::IsPhalanx()const

{

return (m_iRow == m_iCol);

}

//非奇异方阵

int CMatrix::IsNonfunnyPhalanx()const

{

return (IsPhalanx() && fabs(Det_Recursion()) > ZERO);

}

//可逆矩阵

int CMatrix::IsReverse()const

{

return IsNonfunnyPhalanx();

}

///操作符重载//

// []

double* CMatrix::operator [](int i)const

{

assert(i >= 0 && i < m_iRow);

return m_ppData[i];

}

// =

CMatrix& CMatrix::operator =(const CMatrix& right)

{

if(this == &right) return *this;

if((m_iRow != right.GetRow())

|| (m_iCol != right.GetCol()))// 添加于 -11-09

{

Resize(right.GetRow(), right.GetCol());

}

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

m_ppData[i][j] = right[i][j];

}

return *this;

}

// =

CMatrix& CMatrix::operator =(const double* pRight)

{

assert(pRight != NULL);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

m_ppData[i][j] = pRight[m_iCol*i + j];

}

return *this;

}

// =

CMatrix& CMatrix::operator =(const double** ppRight)

{

assert(ppRight != NULL);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

m_ppData[i][j] = ppRight[i][j];

}

return *this;

}

// 一元操作符+

const CMatrix& CMatrix::operator +()const

{

return *this;

}

// 一元操作符-

const CMatrix CMatrix::operator -()const

{

CMatrix temp(m_iRow, m_iCol);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

temp[i][j] = -m_ppData[i][j];

}

return temp;

}

// +

const CMatrix CMatrix::operator +(const CMatrix& right)const

{

CMatrix temp(m_iRow, m_iCol);

if(m_iRow == right.GetRow()

&& m_iCol == right.GetCol())

{

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

temp[i][j] = m_ppData[i][j] + right[i][j];

}

}

return temp;

}

// -

const CMatrix CMatrix::operator -(const CMatrix& right)const

{

CMatrix m_temp(m_iRow, m_iCol);

if(m_iRow == right.GetRow()

&& m_iCol == right.GetCol())

{

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

m_temp[i][j] = m_ppData[i][j] - right[i][j];

}

}

return m_temp;

}

// *

const CMatrix CMatrix::operator *(const CMatrix& right)const

{

double temp = 0;

CMatrix m_temp(m_iRow, right.GetCol());

if(m_iCol != right.GetRow())

return m_temp;

for(int i = 0; i < m_temp.GetRow(); i++)

{

for(int j = 0; j < m_temp.GetCol(); j++)

{

temp = 0;

for(int k = 0; k < right.GetRow(); k++)

temp += m_ppData[i][k] * right[k][j];

m_temp[i][j] = temp;

}

}

return m_temp;

}

// *

const CMatrix CMatrix::operator *(const double& right)const

{

CMatrix m_temp(m_iRow, m_iCol);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

m_temp[i][j] = m_ppData[i][j] * right;

}

return m_temp;

}

// /

const CMatrix CMatrix::operator /(const double& right)const

{

CMatrix m_temp(m_iRow, m_iCol);

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

m_temp[i][j] = m_ppData[i][j] / right;

}

return m_temp;

}

// +=

CMatrix& CMatrix::operator +=(const CMatrix& right)

{

*this = (*this) + right;

return *this;

}

// -=

CMatrix& CMatrix::operator -=(const CMatrix& right)

{

*this = (*this) - right;

return *this;

}

// *=

CMatrix& CMatrix::operator *=(const CMatrix& right)

{

*this = (*this) * right;

return *this;

}

// *=

CMatrix& CMatrix::operator *=(const double& right)

{

*this = (*this) * right;

return *this;

}

// /=

CMatrix& CMatrix::operator /=(const double& right)

{

*this = (*this) / right;

return *this;

}

// ==

int CMatrix::operator ==(const CMatrix& right)const

{

if(this == &right) return 1;

if((m_iRow != right.GetRow())

|| (m_iCol != right.GetCol()))

{

return 0;

}

for(int i = 0; i < m_iRow; i++)

{

for(int j = 0; j < m_iCol; j++)

if(fabs(m_ppData[i][j] - right[i][j]) > ZERO)//0

return 0;

}

return 1;

}

// !=

int CMatrix::operator !=(const CMatrix& right)const

{

return !(*this == right);

}

00分享举报

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。