📄 mat_matrix.cpp
字号:
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CSG_String CSG_Matrix::asString(void)
{
CSG_String s;
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
s.Append(CSG_String::Format(SG_T("%f\t"), m_z[y][x]));
}
s.Append(SG_T("\n"));
}
return( s );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CSG_Matrix::is_Equal(const CSG_Matrix &Matrix) const
{
if( m_nx == Matrix.m_nx && m_ny == Matrix.m_ny )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
if( m_z[y][x] != Matrix.m_z[y][x] )
{
return( false );
}
}
}
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Assign(double Scalar)
{
if( m_nx > 0 && m_ny > 0 )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m_z[y][x] = Scalar;
}
}
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Assign(const CSG_Matrix &Matrix)
{
if( Create(Matrix.m_nx, Matrix.m_ny) )
{
memcpy(m_z[0], Matrix.m_z[0], m_nx * m_ny * sizeof(double));
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Add(double Scalar)
{
if( m_nx > 0 && m_ny > 0 )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m_z[y][x] += Scalar;
}
}
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Add(const CSG_Matrix &Matrix)
{
if( m_nx == Matrix.m_nx && m_ny == Matrix.m_ny )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m_z[y][x] += Matrix.m_z[y][x];
}
}
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Subtract(const CSG_Matrix &Matrix)
{
if( m_nx == Matrix.m_nx && m_ny == Matrix.m_ny )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m_z[y][x] -= Matrix.m_z[y][x];
}
}
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Multiply(double Scalar)
{
if( m_nx > 0 && m_ny > 0 )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m_z[y][x] *= Scalar;
}
}
return( true );
}
return( false );
}
CSG_Vector CSG_Matrix::Multiply(const CSG_Vector &Vector) const
{
CSG_Vector v;
if( m_nx == Vector.Get_N() && v.Create(m_ny) )
{
for(int y=0; y<m_ny; y++)
{
double z = 0.0;
for(int x=0; x<m_nx; x++)
{
z += m_z[y][x] * Vector(x);
}
v[y] = z;
}
}
return( v );
}
CSG_Matrix CSG_Matrix::Multiply(const CSG_Matrix &Matrix) const
{
CSG_Matrix m;
if( m_nx == Matrix.m_ny && m.Create(Matrix.m_nx, m_ny) )
{
for(int y=0; y<m.m_ny; y++)
{
for(int x=0; x<m.m_nx; x++)
{
double z = 0.0;
for(int n=0; n<m_nx; n++)
{
z += m_z[y][n] * Matrix.m_z[n][x];
}
m.m_z[y][x] = z;
}
}
}
return( m );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CSG_Matrix::operator == (const CSG_Matrix &Matrix) const
{
return( is_Equal(Matrix) );
}
//---------------------------------------------------------
CSG_Matrix & CSG_Matrix::operator = (double Scalar)
{
Assign(Scalar);
return( *this );
}
CSG_Matrix & CSG_Matrix::operator = (const CSG_Matrix &Matrix)
{
Assign(Matrix);
return( *this );
}
//---------------------------------------------------------
CSG_Matrix & CSG_Matrix::operator += (double Scalar)
{
Add(Scalar);
return( *this );
}
CSG_Matrix & CSG_Matrix::operator += (const CSG_Matrix &Matrix)
{
Add(Matrix);
return( *this );
}
//---------------------------------------------------------
CSG_Matrix & CSG_Matrix::operator -= (double Scalar)
{
Add(-Scalar);
return( *this );
}
CSG_Matrix & CSG_Matrix::operator -= (const CSG_Matrix &Matrix)
{
Subtract(Matrix);
return( *this );
}
//---------------------------------------------------------
CSG_Matrix & CSG_Matrix::operator *= (double Scalar)
{
Multiply(Scalar);
return( *this );
}
CSG_Matrix & CSG_Matrix::operator *= (const CSG_Matrix &Matrix)
{
Multiply(Matrix);
return( *this );
}
//---------------------------------------------------------
CSG_Matrix CSG_Matrix::operator + (double Scalar) const
{
CSG_Matrix m(*this);
m.Add(Scalar);
return( m );
}
CSG_Matrix CSG_Matrix::operator + (const CSG_Matrix &Matrix) const
{
CSG_Matrix m(*this);
m.Add(Matrix);
return( m );
}
//---------------------------------------------------------
CSG_Matrix CSG_Matrix::operator - (double Scalar) const
{
CSG_Matrix m(*this);
m.Add(-Scalar);
return( m );
}
CSG_Matrix CSG_Matrix::operator - (const CSG_Matrix &Matrix) const
{
CSG_Matrix m(*this);
m.Subtract(Matrix);
return( m );
}
//---------------------------------------------------------
CSG_Matrix CSG_Matrix::operator * (double Scalar) const
{
CSG_Matrix m(*this);
m.Multiply(Scalar);
return( m );
}
CSG_Vector CSG_Matrix::operator * (const CSG_Vector &Vector) const
{
return( Multiply(Vector) );
}
CSG_Matrix CSG_Matrix::operator * (const CSG_Matrix &Matrix) const
{
return( Multiply(Matrix) );
}
CSG_Matrix operator * (double Scalar, const CSG_Matrix &Matrix)
{
return( Matrix * Scalar );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CSG_Matrix::Set_Zero(void)
{
return( Create(m_nx, m_ny) );
}
//---------------------------------------------------------
bool CSG_Matrix::Set_Identity(void)
{
if( m_nx > 0 && m_ny > 0 )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m_z[y][x] = x == y ? 1.0 : 0.0;
}
}
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Set_Transpose(void)
{
CSG_Matrix m;
if( m.Create(*this) && Create(m_ny, m_nx) )
{
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m_z[y][x] = m.m_z[y][x];
}
}
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CSG_Matrix::Set_Inverse(bool bSilent, int nSubSquare)
{
bool bResult = false;
int n = 0;
//-----------------------------------------------------
if( nSubSquare > 0 )
{
if( nSubSquare <= m_nx && nSubSquare <= m_ny )
{
n = nSubSquare;
}
}
else if( is_Square() )
{
n = m_nx;
}
//-----------------------------------------------------
if( n > 0 )
{
CSG_Matrix m(*this);
int *Permutation = (int *)SG_Malloc(n * sizeof(int));
if( SG_Matrix_LU_Decomposition(n, Permutation, m.Get_Data(), bSilent) )
{
CSG_Vector v(n);
for(int j=0; j<n && (bSilent || SG_UI_Process_Set_Progress(j, n)); j++)
{
v.Set_Zero();
v[j] = 1.0;
SG_Matrix_LU_Solve(n, Permutation, m.Get_Data(), v.Get_Data(), true);
for(int i=0; i<n; i++)
{
m_z[i][j] = v[i];
}
}
bResult = true;
}
SG_Free(Permutation);
}
return( bResult );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
double CSG_Matrix::Get_Determinant(void) const
{
double d = 0.0;
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
}
}
return( d );
}
//---------------------------------------------------------
CSG_Matrix CSG_Matrix::Get_Transpose(void) const
{
CSG_Matrix m(m_ny, m_nx);
for(int y=0; y<m_ny; y++)
{
for(int x=0; x<m_nx; x++)
{
m.m_z[x][y] = m_z[y][x];
}
}
return( m );
}
//---------------------------------------------------------
CSG_Matrix CSG_Matrix::Get_Inverse(bool bSilent, int nSubSquare) const
{
CSG_Matrix m(*this);
m.Set_Inverse(bSilent, nSubSquare);
return( m );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool SG_Matrix_Solve(CSG_Matrix &Matrix, CSG_Vector &Vector, bool bSilent)
{
bool bResult = false;
int n = Vector.Get_N();
if( n > 0 && n == Matrix.Get_NX() && n == Matrix.Get_NY() )
{
int *Permutation = (int *)SG_Malloc(n * sizeof(int));
if( SG_Matrix_LU_Decomposition(n, Permutation, Matrix.Get_Data(), bSilent) )
{
SG_Matrix_LU_Solve(n, Permutation, Matrix.Get_Data(), Vector.Get_Data(), bSilent);
bResult = true;
}
SG_Free(Permutation);
}
return( bResult );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool SG_Matrix_LU_Decomposition(int n, int *Permutation, double **Matrix, bool bSilent)
{
int i, j, k, iMax;
double dMax, d, Sum;
CSG_Vector Vector;
Vector.Create(n);
for(i=0, iMax=0; i<n && (bSilent || SG_UI_Process_Set_Progress(i, n)); i++)
{
dMax = 0.0;
for(j=0; j<n; j++)
{
if( (d = fabs(Matrix[i][j])) > dMax )
{
dMax = d;
}
}
if( dMax <= 0.0 ) // singular matrix !!!...
{
return( false );
}
Vector[i] = 1.0 / dMax;
}
for(j=0; j<n && (bSilent || SG_UI_Process_Set_Progress(j, n)); j++)
{
for(i=0; i<j; i++)
{
Sum = Matrix[i][j];
for(k=0; k<i; k++)
{
Sum -= Matrix[i][k] * Matrix[k][j];
}
Matrix[i][j] = Sum;
}
for(i=j, dMax=0.0; i<n; i++)
{
Sum = Matrix[i][j];
for(k=0; k<j; k++)
{
Sum -= Matrix[i][k] * Matrix[k][j];
}
Matrix[i][j] = Sum;
if( (d = Vector[i] * fabs(Sum)) >= dMax )
{
dMax = d;
iMax = i;
}
}
if( j != iMax )
{
for(k=0; k<n; k++)
{
d = Matrix[iMax][k];
Matrix[iMax][k] = Matrix[j ][k];
Matrix[j ][k] = d;
}
Vector[iMax] = Vector[j];
}
Permutation[j] = iMax;
if( Matrix[j][j] == 0.0 )
{
Matrix[j][j] = M_TINY;
}
if( j != n )
{
d = 1.0 / (Matrix[j][j]);
for(i=j+1; i<n; i++)
{
Matrix[i][j] *= d;
}
}
}
return( bSilent || SG_UI_Process_Get_Okay(false) );
}
//---------------------------------------------------------
bool SG_Matrix_LU_Solve(int n, int *Permutation, double **Matrix, double *Vector, bool bSilent)
{
int i, j, k;
double Sum;
for(i=0, k=-1; i<n && (bSilent || SG_UI_Process_Set_Progress(i, n)); i++)
{
Sum = Vector[Permutation[i]];
Vector[Permutation[i]] = Vector[i];
if( k >= 0 )
{
for(j=k; j<=i-1; j++)
{
Sum -= Matrix[i][j] * Vector[j];
}
}
else if( Sum )
{
k = i;
}
Vector[i] = Sum;
}
for(i=n-1; i>=0 && (bSilent || SG_UI_Process_Set_Progress(n-i, n)); i--)
{
Sum = Vector[i];
for(j=i+1; j<n; j++)
{
Sum -= Matrix[i][j] * Vector[j];
}
Vector[i] = Sum / Matrix[i][i];
}
return( true );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -