矩阵运算概要
2017-02-17 23:20
211 查看
提到矩阵,相信大家都不陌生,作为最基本的数学概念之一,我们 知道常用的矩阵运算包括:矩阵加减乘、行列式、转置矩阵、逆矩阵、特征向量(特征值)。
具体概念不做过多讲讲,直接上代码(相信代码是最好的讲述方式)。
• 求解线性方程组
线性方程组 是我们经常会遇到的一个问题,常用的 解线性方程组常用的方法有两个:
1. 高斯消元法;
2. 利用行列式,即Crammer法则 求解。
这里我们只讲 克莱姆法则,该方法的前提条件是:
1. 线性方程组 AX=b 方程的个数与未知量的个数相同,即系数矩阵A是一个方阵;
2. 系数矩阵A的行列式 |A| ≠ 0。则方程组有唯一解: xi = Di/D
D=|A|
Di 是 D 中第 i 列换成 b 得到的行列式。
下面给出Crammer法则 的代码:
具体概念不做过多讲讲,直接上代码(相信代码是最好的讲述方式)。
/* 矩阵定义 - 4*4齐次矩阵 用于openGL linolzhang, 2010.2.10 */ #ifndef MATRIX4_H #define MATRIX4_H #include "Tuple4.h" #include "BaseOperation.h" template <typename T> class Matrix4 { public: T m[16]; // 一维数组,与openGL矩阵一致 - 按列优先 // [ m0, m4, m8, m12 ] // [ m1, m5, m9, m13 ] // [ m2, m6, m10,m14 ] // [ m3, m4, m11,m15 ] public: Matrix4() // 默认构造函数,设置单位矩阵 { setIdentity(); } Matrix4( T m0, T m1, T m2, T m3, T m4, T m5, T m6, T m7, T m8, T m9, T m10, T m11, T m12, T m13, T m14, T m15 ) // 构造函数,指定值 { m[ 0] = m0; m[ 1] = m1; m[ 2] = m2; m[ 3] = m3; m[ 4] = m4; m[ 5] = m5; m[ 6] = m6; m[ 7] = m7; m[ 8] = m8; m[ 9] = m9; m[10] = m10; m[11] = m11; m[12] = m12; m[13] = m13; m[14] = m14; m[15] = m15; } Matrix4(const T* elements) // 构造函数,指针指定 { memcpy(m, elements, sizeof(T)*16); } Matrix4(const Matrix4 &mat) // 拷贝构造函数 { memcpy(m,mat.m, sizeof(T)*16); } const Matrix4 &operator = (const Matrix4 &mat) // 赋值操作符 { memcpy(m,mat.m, sizeof(T)*16); return *this; } // -------------------------------------------------------- // 构造函数 - 由其它转换 Matrix4(const Tuple3<T> &rAxis, float rAngle) // 由 旋转轴向量,旋转角 得到 { float sinAngle = fastSin(rAngle), cosAngle = fastCos(rAngle), oneMinusCosAngle = 1.0f - cosAngle; m[ 0] = (rAxis.x)*(rAxis.x) + cosAngle*(1-(rAxis.x)*(rAxis.x)); m[ 4] = (rAxis.x)*(rAxis.y)*(oneMinusCosAngle) - sinAngle*rAxis.z; m[ 8] = (rAxis.x)*(rAxis.z)*(oneMinusCosAngle) + sinAngle*rAxis.y; m[ 1] = (rAxis.x)*(rAxis.y)*(oneMinusCosAngle) + sinAngle*rAxis.z; m[ 5] = (rAxis.y)*(rAxis.y) + cosAngle*(1-(rAxis.y)*(rAxis.y)); m[ 9] = (rAxis.y)*(rAxis.z)*(oneMinusCosAngle) - sinAngle*rAxis.x; m[ 2] = (rAxis.x)*(rAxis.z)*(oneMinusCosAngle) - sinAngle*rAxis.y; m[ 6] = (rAxis.y)*(rAxis.z)*(oneMinusCosAngle) + sinAngle*rAxis.x; m[10] = (rAxis.z)*(rAxis.z) + cosAngle*(1-(rAxis.z)*(rAxis.z)); m[3] = m[7] = m[11] = 0; m[12] = m[13] = m[14] = 0; m[15] = 1; } // -------------------------------------------------------- // 重载 +=, -=, *=矩阵, *=常量 void operator +=(const Matrix4 &mat) { for(int i = 0; i < 16; i++) m[i] += mat.m[i]; } void operator -=(const Matrix4 &mat) { for(int i = 0; i < 16; i++) m[i] -= mat.m[i]; } void operator *= (const Matrix4 &mat) { setElements( m[0]*mat.m[ 0]+m[4]*mat.m[ 1]+m[ 8]*mat.m[ 2]+ m[12]*mat.m[ 3], m[1]*mat.m[ 0]+m[5]*mat.m[ 1]+m[ 9]*mat.m[ 2]+ m[13]*mat.m[ 3], m[2]*mat.m[ 0]+m[6]*mat.m[ 1]+m[10]*mat.m[ 2]+ m[14]*mat.m[ 3], m[3]*mat.m[ 0]+m[7]*mat.m[ 1]+m[11]*mat.m[ 2]+ m[15]*mat.m[ 3], m[0]*mat.m[ 4]+m[4]*mat.m[ 5]+m[ 8]*mat.m[ 6]+ m[12]*mat.m[ 7], m[1]*mat.m[ 4]+m[5]*mat.m[ 5]+m[ 9]*mat.m[ 6]+ m[13]*mat.m[ 7], m[2]*mat.m[ 4]+m[6]*mat.m[ 5]+m[10]*mat.m[ 6]+ m[14]*mat.m[ 7], m[3]*mat.m[ 4]+m[7]*mat.m[ 5]+m[11]*mat.m[ 6]+ m[15]*mat.m[ 7], m[0]*mat.m[ 8]+m[4]*mat.m[ 9]+m[ 8]*mat.m[10]+ m[12]*mat.m[11], m[1]*mat.m[ 8]+m[5]*mat.m[ 9]+m[ 9]*mat.m[10]+ m[13]*mat.m[11], m[2]*mat.m[ 8]+m[6]*mat.m[ 9]+m[10]*mat.m[10]+ m[14]*mat.m[11], m[3]*mat.m[ 8]+m[7]*mat.m[ 9]+m[11]*mat.m[10]+ m[15]*mat.m[11], m[0]*mat.m[12]+m[4]*mat.m[13]+m[ 8]*mat.m[14]+ m[12]*mat.m[15], m[1]*mat.m[12]+m[5]*mat.m[13]+m[ 9]*mat.m[14]+ m[13]*mat.m[15], m[2]*mat.m[12]+m[6]*mat.m[13]+m[10]*mat.m[14]+ m[14]*mat.m[15], m[3]*mat.m[12]+m[7]*mat.m[13]+m[11]*mat.m[14]+ m[15]*mat.m[15] ); } void operator *= (T scale) // 乘常量 { for(int i=0; i<16; i++) m[i] *= scale; } // ---------------------------------- // ==, != bool operator == (const Matrix4 &mat) { return memcmp(m, mat.m, sizeof(T)*16) == 0; } bool operator != (const Matrix4 &mat) { return memcmp(m, mat.m, sizeof(T)*16) != 0; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // -------------------------------------------------------- // 矩阵求解 const T getDeterminant() // 得到行列式的值(行列式 !=0 可逆) { T det; det = m[0] * m[5] * m[10]; det += m[4] * m[9] * m[2]; det += m[8] * m[1] * m[6]; det -= m[8] * m[5] * m[2]; det -= m[4] * m[1] * m[10]; det -= m[0] * m[9] * m[6]; return det; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // -------------------------------------------------------- // 矩阵变换 void setElements(const T* elements) // 重新设置矩阵元素 { memcpy(m, elements, sizeof(T)*16); } void setElements( T m0, T m1, T m2, T m3, T m4, T m5, T m6, T m7, T m8, T m9, T m10, T m11, T m12, T m13, T m14, T m15 ) // 重新设置矩阵元素 { m[ 0] = m0; m[ 1] = m1; m[ 2] = m2; m[ 3] = m3; m[ 4] = m4; m[ 5] = m5; m[ 6] = m6; m[ 7] = m7; m[ 8] = m8; m[ 9] = m9; m[10] = m10; m[11] = m11; m[12] = m12; m[13] = m13; m[14] = m14; m[15] = m15; } void setElements(const Matrix4 &matrix) // 重新设置矩阵元素 { setElements(matrix.m); } // ---------------------------------- void setZero() // 设置为0矩阵 { for(int i = 0; i < 16; i++) m[i] = 0; } void setIdentity() // 设置为单位矩阵 { m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0; m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0; m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0; m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; } // ---------------------------------- void setTranspose() // 矩阵转置 { T temp = 0; temp = m[4]; m[4] = m[1]; m[1] = temp; temp = m[8]; m[8] = m[2]; m[2] = temp; temp = m[12]; m[12] = m[3]; m[3] = temp; temp = m[9]; m[9] = m[6]; m[6] = temp; temp = m[13]; m[13] = m[7]; m[7] = temp; temp = m[14]; m[14] = m[11]; m[11] = temp; } void setNegate() // 矩阵取反 { for(int i = 0; i < 16; i++) m[i] =-m[i]; } // -------------------------------------------------------- bool setInverse() // 求逆矩阵 { int i, j, k, swap; T temp[16], t; memcpy(temp, m, 16*sizeof(T)); // 当前矩阵拷贝到暂存temp setIdentity(); for (i = 0; i < 4; i++) { swap = i; for (j = i + 1; j < 4; j++) { if (fabs(temp[j*4 + i]) > fabs(temp[i*4 + i])) { swap = j; } } if (swap != i) { for (k = 0; k < 4; k++) { t = temp[i*4 + k]; temp[i*4 + k] = temp[swap*4 + k]; temp[swap*4 + k] = t; t = m[i*4 + k]; m[i*4 + k] = m[swap*4 + k]; m[swap*4 + k] = t; } } if(!temp[i*4 + i]) return false; t = temp[i*4 + i]; for (k = 0; k < 4; k++) { temp[i*4 + k] /= t; m[i*4 + k] = m[i*4 + k] / t; } for (j = 0; j < 4; j++) { if (j != i) { t = temp[j*4 + i]; for (k = 0; k < 4; k++) { temp[j*4 + k] -= temp[i*4 + k] * t; m[j*4 + k] = m[j*4 + k] - m[i*4 + k] * t; } } } } return true; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // -------------------------------------------------------- // 矩阵转化,由其它表达方式转换得到 void setTranslate(const Tuple3<T> &t) // 设置为平移矩阵 - 由三元组指定平移量 { setIdentity(); m[12] = t.x; m[13] = t.y; m[14] = t.z; } void setTranslate(T x,T y,T z) // 设置为平移矩阵 - 由x,y,z指定平移量 { setIdentity(); m[12] = x; m[13] = y; m[14] = z; } void setRotationX(float xAngle) // 设置为旋转矩阵 - 指定绕 X 旋转角度 - 欧拉角 { setIdentity(); m[ 5] = fastCos(xAngle); m[ 6] = fastSin(xAngle); m[ 9] = -m[6]; m[10] = m[5]; } void setRotationY(float yAngle) // 设置为旋转矩阵 - 指定绕 Y 旋转角度 - 欧拉角 { setIdentity(); m[ 0] = fastCos(yAngle); m[ 2] = fastSin(yAngle); m[ 8] = -m[2]; m[10] = m[0]; } void setRotationZ(float zAngle) // 设置为旋转矩阵 - 指定绕 Z 旋转角度 - 欧拉角 { setIdentity(); m[0] = fastCos(zAngle); m[1] = fastSin(zAngle); m[4] = -m[1]; m[5] = m[0]; } void setRotationXYZ(float x,float y,float z) // 设置为旋转矩阵 - 分别指定绕 X,Y,Z 旋转角度 - 欧拉角 { float cosX = fastCos(x), sinX = fastSin(x), cosY = fastCos(y), sinY = fastSin(y), cosZ = fastCos(z), sinZ = fastSin(z); setElements( cosY * cosZ + sinX * sinY * sinZ, -cosX * sinZ, sinX * cosY * sinZ - sinY * cosZ, 0, cosY * sinZ - sinX * sinY * cosZ, cosX * cosZ, -sinY * sinZ - sinX * cosY * cosZ, 0, cosX * sinY, sinX, cosX * cosY, 0, 0, 0, 0, 1 ); } void setRotateAxis(const Tuple3<T> &axis, float angle) // 设置为旋转矩阵 - 由旋转轴向量,旋转角指定 { float sinAngle = fastSin(angle), cosAngle = fastCos(angle), oneMinusCosAngle = 1.0f - cosAngle; m[ 0] = (axis.x)*(axis.x) + cosAngle*(1-(axis.x)*(axis.x)); m[ 4] = (axis.x)*(axis.y)*(oneMinusCosAngle) - sinAngle*axis.z; m[ 8] = (axis.x)*(axis.z)*(oneMinusCosAngle) + sinAngle*axis.y; m[ 1] = (axis.x)*(axis.y)*(oneMinusCosAngle) + sinAngle*axis.z; m[ 5] = (axis.y)*(axis.y) + cosAngle*(1-(axis.y)*(axis.y)); m[ 9] = (axis.y)*(axis.z)*(oneMinusCosAngle) - sinAngle*axis.x; m[ 2] = (axis.x)*(axis.z)*(oneMinusCosAngle) - sinAngle*axis.y; m[ 6] = (axis.y)*(axis.z)*(oneMinusCosAngle) + sinAngle*axis.x; m[10] = (axis.z)*(axis.z) + cosAngle*(1-(axis.z)*(axis.z)); m[3] = m[7] = m[11] = 0; m[12] = m[13] = m[14] = 0; m[15] = 1; } void setScale(T x,T y,T z) // 设置为缩放矩阵,由 x,y,z 指定缩放量 { setIdentity(); m[ 0] = x; m[ 5] = y; m[10] = z; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // -------------------------------------------------------- // 定义矩阵运算 - 左乘 void multByMatrix(const Matrix4<T> &mat) { setElements( mat.m[0]*m[ 0] + mat.m[4]*m[ 1] + mat.m[ 8]*m[ 2] + mat.m[12]*m[ 3], mat.m[1]*m[ 0] + mat.m[5]*m[ 1] + mat.m[ 9]*m[ 2] + mat.m[13]*m[ 3], mat.m[2]*m[ 0] + mat.m[6]*m[ 1] + mat.m[10]*m[ 2] + mat.m[14]*m[ 3], mat.m[3]*m[ 0] + mat.m[7]*m[ 1] + mat.m[11]*m[ 2] + mat.m[15]*m[ 3], mat.m[0]*m[ 4] + mat.m[4]*m[ 5] + mat.m[ 8]*m[ 6] + mat.m[12]*m[ 7], mat.m[1]*m[ 4] + mat.m[5]*m[ 5] + mat.m[ 9]*m[ 6] + mat.m[13]*m[ 7], mat.m[2]*m[ 4] + mat.m[6]*m[ 5] + mat.m[10]*m[ 6] + mat.m[14]*m[ 7], mat.m[3]*m[ 4] + mat.m[7]*m[ 5] + mat.m[11]*m[ 6] + mat.m[15]*m[ 7], mat.m[0]*m[ 8] + mat.m[4]*m[ 9] + mat.m[ 8]*m[10] + mat.m[12]*m[11], mat.m[1]*m[ 8] + mat.m[5]*m[ 9] + mat.m[ 9]*m[10] + mat.m[13]*m[11], mat.m[2]*m[ 8] + mat.m[6]*m[ 9] + mat.m[10]*m[10] + mat.m[14]*m[11], mat.m[3]*m[ 8] + mat.m[7]*m[ 9] + mat.m[11]*m[10] + mat.m[15]*m[11], mat.m[0]*m[12] + mat.m[4]*m[13] + mat.m[ 8]*m[14] + mat.m[12]*m[15], mat.m[1]*m[12] + mat.m[5]*m[13] + mat.m[ 9]*m[14] + mat.m[13]*m[15], mat.m[2]*m[12] + mat.m[6]*m[13] + mat.m[10]*m[14] + mat.m[14]*m[15], mat.m[3]*m[12] + mat.m[7]*m[13] + mat.m[11]*m[14] + mat.m[15]*m[15] ); } }; //////////////////////////////////////////////////////////////////////////////////////////////////////// // -------------------------------------------------------- // 外部函数 - 矩阵运算 +, -, * ( Matrix4 vs Matrix4) template<typename T> inline const Matrix4<T> operator + (const Matrix4<T> &mat1,const Matrix4<T> &mat2) { return Matrix4<T>( mat1.m[ 0] + mat2.m[ 0], mat1.m[ 1] + mat2.m[ 1], mat1.m[ 2] + mat2.m[ 2], mat1.m[ 3] + mat2.m[ 3], mat1.m[ 4] + mat2.m[ 4], mat1.m[ 5] + mat2.m[ 5], mat1.m[ 6] + mat2.m[ 6], mat1.m[ 7] + mat2.m[ 7], mat1.m[ 8] + mat2.m[ 8], mat1.m[ 9] + mat2.m[ 9], mat1.m[10] + mat2.m[10], mat1.m[11] + mat2.m[11], mat1.m[12] + mat2.m[12], mat1.m[13] + mat2.m[13], mat1.m[14] + mat2.m[14], mat1.m[15] + mat2.m[15] ); } template<typename T> inline const Matrix4<T> operator - (const Matrix4<T> &mat1,const Matrix4<T> &mat2) { return Matrix4<T>( mat1.m[ 0] - mat2.m[ 0], mat1.m[ 1] - mat2.m[ 1], mat1.m[ 2] - mat2.m[ 2], mat1.m[ 3] - mat2.m[ 3], mat1.m[ 4] - mat2.m[ 4], mat1.m[ 5] - mat2.m[ 5], mat1.m[ 6] - mat2.m[ 6], mat1.m[ 7] - mat2.m[ 7], mat1.m[ 8] - mat2.m[ 8], mat1.m[ 9] - mat2.m[ 9], mat1.m[10] - mat2.m[10], mat1.m[11] - mat2.m[11], mat1.m[12] - mat2.m[12], mat1.m[13] - mat2.m[13], mat1.m[14] - mat2.m[14], mat1.m[15] - mat2.m[15]); } template<typename T> inline const Matrix4<T> operator * (const Matrix4<T> &mat1,const Matrix4<T> &mat2) { return Matrix4<T>( mat1.m[0]*mat2.m[ 0] + mat1.m[4]*mat2.m[ 1] + mat1.m[ 8]*mat2.m[ 2] + mat1.m[12]*mat2.m[ 3], mat1.m[1]*mat2.m[ 0] + mat1.m[5]*mat2.m[ 1] + mat1.m[ 9]*mat2.m[ 2] + mat1.m[13]*mat2.m[ 3], mat1.m[2]*mat2.m[ 0] + mat1.m[6]*mat2.m[ 1] + mat1.m[10]*mat2.m[ 2] + mat1.m[14]*mat2.m[ 3], mat1.m[3]*mat2.m[ 0] + mat1.m[7]*mat2.m[ 1] + mat1.m[11]*mat2.m[ 2] + mat1.m[15]*mat2.m[ 3], mat1.m[0]*mat2.m[ 4] + mat1.m[4]*mat2.m[ 5] + mat1.m[ 8]*mat2.m[ 6] + mat1.m[12]*mat2.m[ 7], mat1.m[1]*mat2.m[ 4] + mat1.m[5]*mat2.m[ 5] + mat1.m[ 9]*mat2.m[ 6] + mat1.m[13]*mat2.m[ 7], mat1.m[2]*mat2.m[ 4] + mat1.m[6]*mat2.m[ 5] + mat1.m[10]*mat2.m[ 6] + mat1.m[14]*mat2.m[ 7], mat1.m[3]*mat2.m[ 4] + mat1.m[7]*mat2.m[ 5] + mat1.m[11]*mat2.m[ 6] + mat1.m[15]*mat2.m[ 7], mat1.m[0]*mat2.m[ 8] + mat1.m[4]*mat2.m[ 9] + mat1.m[ 8]*mat2.m[10] + mat1.m[12]*mat2.m[11], mat1.m[1]*mat2.m[ 8] + mat1.m[5]*mat2.m[ 9] + mat1.m[ 9]*mat2.m[10] + mat1.m[13]*mat2.m[11], mat1.m[2]*mat2.m[ 8] + mat1.m[6]*mat2.m[ 9] + mat1.m[10]*mat2.m[10] + mat1.m[14]*mat2.m[11], mat1.m[3]*mat2.m[ 8] + mat1.m[7]*mat2.m[ 9] + mat1.m[11]*mat2.m[10] + mat1.m[15]*mat2.m[11], mat1.m[0]*mat2.m[12] + mat1.m[4]*mat2.m[13] + mat1.m[ 8]*mat2.m[14] + mat1.m[12]*mat2.m[15], mat1.m[1]*mat2.m[12] + mat1.m[5]*mat2.m[13] + mat1.m[ 9]*mat2.m[14] + mat1.m[13]*mat2.m[15], mat1.m[2]*mat2.m[12] + mat1.m[6]*mat2.m[13] + mat1.m[10]*mat2.m[14] + mat1.m[14]*mat2.m[15], mat1.m[3]*mat2.m[12] + mat1.m[7]*mat2.m[13] + mat1.m[11]*mat2.m[14] + mat1.m[15]*mat2.m[15] ); } // -------------------------------------------------------- // 外部函数 - 矩阵运算( Matrix4 vs Others) template<typename T> inline const Tuple3<T> operator * (const Tuple3<T> &t,const Matrix4<T> &mat) { return Tuple3<T>( mat.m[ 0]*t.x + mat.m[ 4]*t.y + mat.m[ 8]*t.z + mat.m[12], mat.m[ 1]*t.x + mat.m[ 5]*t.y + mat.m[ 9]*t.z + mat.m[13], mat.m[ 2]*t.x + mat.m[ 6]*t.y + mat.m[10]*t.z + mat.m[14] ); } template<typename T> inline const Tuple3<T> operator * (const Matrix4<T> &mat,const Tuple3<T> &t) { return Tuple3<T>( mat.m[ 0]*t.x + mat.m[ 4]*t.y + mat.m[ 8]*t.z + mat.m[12], mat.m[ 1]*t.x + mat.m[ 5]*t.y + mat.m[ 9]*t.z + mat.m[13], mat.m[ 2]*t.x + mat.m[ 6]*t.y + mat.m[10]*t.z + mat.m[14] ); } template<typename T> inline const Tuple4<T> operator * (const Matrix4<T> &mat, const Tuple4<T> &t) { return Tuple4<T>( mat.m[ 0]*t.x + mat.m[ 4]*t.y + mat.m[ 8]*t.z + mat.m[12]*t.w, mat.m[ 1]*t.x + mat.m[ 5]*t.y + mat.m[ 9]*t.z + mat.m[13]*t.w, mat.m[ 2]*t.x + mat.m[ 6]*t.y + mat.m[10]*t.z + mat.m[14]*t.w, mat.m[ 3]*t.x + mat.m[ 7]*t.y + mat.m[11]*t.z + mat.m[15]*t.w ); } template<typename T> inline const Tuple4<T> operator * (const Tuple4<T> &t,const Matrix4<T> &mat) { return Tuple4<T>( mat.m[ 0]*t.x + mat.m[ 4]*t.y + mat.m[ 8]*t.z + mat.m[12]*t.w, mat.m[ 1]*t.x + mat.m[ 5]*t.y + mat.m[ 9]*t.z + mat.m[13]*t.w, mat.m[ 2]*t.x + mat.m[ 6]*t.y + mat.m[10]*t.z + mat.m[14]*t.w, mat.m[ 3]*t.x + mat.m[ 7]*t.y + mat.m[11]*t.z + mat.m[15]*t.w ); } // ------------------------------------- typedef Matrix4<int> Matrix4i; typedef Matrix4<float> Matrix4f; typedef Matrix4<double> Matrix4d; #endif
• 求解线性方程组
线性方程组 是我们经常会遇到的一个问题,常用的 解线性方程组常用的方法有两个:
1. 高斯消元法;
2. 利用行列式,即Crammer法则 求解。
这里我们只讲 克莱姆法则,该方法的前提条件是:
1. 线性方程组 AX=b 方程的个数与未知量的个数相同,即系数矩阵A是一个方阵;
2. 系数矩阵A的行列式 |A| ≠ 0。则方程组有唯一解: xi = Di/D
D=|A|
Di 是 D 中第 i 列换成 b 得到的行列式。
下面给出Crammer法则 的代码:
// 利用克莱姆法则求方程解 // a11 a12 a13 x1 b1 // a21 a22 a23 * x2 = b2 // a31 a32 a33 x3 b3 // 或者写成矩阵形式为Ax=b,其中A为n*n方阵,x为n个变量构成列向量,b为n个常数项构成列向量。 bool CramerSolver(double a11,double a12,double a13,double a21,double a22,double a23,double a31,double a32,double a33,double b1,double b2,double b3,double& x1,double& x2,double& x3) { // 首先计算行列式的值 double D = Determinant( a11, a12, a13, a21, a22, a23, a31, a32, a33 ); if(0==D) return false; // 当它的系数矩阵可逆,或者说对应的行列式|A|不等于0的时候,它有唯一解xi=|Ai|/|A|,其中Ai〔i = 1,2,……,n〕是矩阵A中第i列的a 1i,a 2i,……a ni (即第i列)依次换成b1,b2,……bn所得的矩阵。 //D1=|b1 a12 a13| // |b2 a22 a23| // |b3 a32 a33| double D1 = Determinant( b1, a12, a13, b2, a22, a23, b3, a32, a33 ); double D2 = Determinant( a11, b1, a13, a21, b2, a23, a31, b3, a33 ); double D3 = Determinant( a11, a12, b1, a21, a22, b2, a31, a32, b3 ); x1 = D1/D; x2 = D2/D; x3 = D3/D; return true; }
相关文章推荐
- Duanxx的Design abroad: C++矩阵运算库Eigen 概要
- 矩阵乘法运算图解
- 卷积运算转换为矩阵乘法
- matlab 矩阵基础运算
- 使用 CUBLAS 库给矩阵运算提速
- C++矩阵库Eigen的仿Matlab矩阵运算
- 数学之美 系列十八 - 矩阵运算和文本处理中的分类问题
- hdu 1588 矩阵运算的应用
- matlab矩阵运算
- 稀疏矩阵运算
- OpenCV矩阵运算
- C#中高效矩阵运算编程
- 矩阵运算模板
- C++实现矩阵运算
- opencv矩阵运算
- 图像处理 估计退化函数之运动模糊和矩阵matlab运算的一些实验情况
- opencv学习笔记(2)----矩阵运算
- 矩阵的加、减、乘、除、求逆运算的实现
- 第9周—项目3(2)两个稀疏矩阵相加的运算