3x3矩陣教程
1. 簡介
三維矩陣是線性代數中的重要概念,用于表示三維空間中的線性變換。本教程將介紹如何使用C++實現三維矩陣的基本運算和變換。
2. 代碼實現
2.1 頭文件 (matrix3x3.h)
#ifndef MATRIX3X3_H
#define MATRIX3X3_H#include <array>
#include <stdexcept>
#include <iostream>namespace math {
namespace linear_algebra {/*** @brief 三維矩陣類* * 這個類實現了三維矩陣的基本運算,包括:* - 矩陣加減* - 矩陣乘法* - 標量乘法* - 行列式計算* - 矩陣求逆* - 矩陣轉置* - 特征值和特征向量計算* - 矩陣性質檢查(可逆性、對稱性、正交性)* - 特殊矩陣生成(旋轉矩陣、縮放矩陣等)*/
class Matrix3x3 {
public:// 構造函數Matrix3x3(); // 默認構造函數,初始化為單位矩陣Matrix3x3(const std::array<std::array<double, 3>, 3>& data); // 從二維數組初始化// 基本運算Matrix3x3 operator+(const Matrix3x3& other) const; // 矩陣加法Matrix3x3 operator-(const Matrix3x3& other) const; // 矩陣減法Matrix3x3 operator*(const Matrix3x3& other) const; // 矩陣乘法Matrix3x3 operator*(double scalar) const; // 標量乘法Matrix3x3 operator/(double scalar) const; // 標量除法// 矩陣運算double determinant() const; // 計算行列式Matrix3x3 inverse() const; // 計算逆矩陣Matrix3x3 transpose() const; // 計算轉置矩陣std::array<double, 3> eigenvalues() const; // 計算特征值std::array<Matrix3x3, 3> eigenvectors() const; // 計算特征向量// 矩陣性質bool isInvertible() const; // 檢查是否可逆bool isSymmetric() const; // 檢查是否對稱bool isOrthogonal() const; // 檢查是否正交// 特殊矩陣static Matrix3x3 identity(); // 創建單位矩陣static Matrix3x3 rotation(double theta, char axis); // 創建旋轉矩陣static Matrix3x3 scaling(double sx, double sy, double sz); // 創建縮放矩陣// 輸出運算符friend std::ostream& operator<<(std::ostream& os, const Matrix3x3& m);private:std::array<std::array<double, 3>, 3> data; // 3x3矩陣數據
};} // namespace linear_algebra
} // namespace math#endif // MATRIX3X3_H
2.2 實現文件 (matrix3x3.cpp)
#include "matrix3x3.h"
#include <cmath>namespace math {
namespace linear_algebra {// 默認構造函數:初始化為單位矩陣
Matrix3x3::Matrix3x3() {for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {data[i][j] = (i == j) ? 1.0 : 0.0;}}
}// 從二維數組初始化
Matrix3x3::Matrix3x3(const std::array<std::array<double, 3>, 3>& data) : data(data) {}// 矩陣加法實現
Matrix3x3 Matrix3x3::operator+(const Matrix3x3& other) const {Matrix3x3 result;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {result.data[i][j] = data[i][j] + other.data[i][j];}}return result;
}// 矩陣減法實現
Matrix3x3 Matrix3x3::operator-(const Matrix3x3& other) const {Matrix3x3 result;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {result.data[i][j] = data[i][j] - other.data[i][j];}}return result;
}// 矩陣乘法實現
Matrix3x3 Matrix3x3::operator*(const Matrix3x3& other) const {Matrix3x3 result;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {result.data[i][j] = 0.0;for (int k = 0; k < 3; ++k) {result.data[i][j] += data[i][k] * other.data[k][j];}}}return result;
}// 標量乘法實現
Matrix3x3 Matrix3x3::operator*(double scalar) const {Matrix3x3 result;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {result.data[i][j] = data[i][j] * scalar;}}return result;
}// 標量除法實現
Matrix3x3 Matrix3x3::operator/(double scalar) const {if (scalar == 0.0) {throw std::runtime_error("Division by zero");}return *this * (1.0 / scalar);
}// 行列式計算實現
double Matrix3x3::determinant() const {return data[0][0] * (data[1][1] * data[2][2] - data[1][2] * data[2][1]) -data[0][1] * (data[1][0] * data[2][2] - data[1][2] * data[2][0]) +data[0][2] * (data[1][0] * data[2][1] - data[1][1] * data[2][0]);
}// 逆矩陣計算實現
Matrix3x3 Matrix3x3::inverse() const {double det = determinant();if (det == 0.0) {throw std::runtime_error("Matrix is not invertible");}Matrix3x3 result;double invDet = 1.0 / det;// 計算伴隨矩陣result.data[0][0] = (data[1][1] * data[2][2] - data[1][2] * data[2][1]) * invDet;result.data[0][1] = (data[0][2] * data[2][1] - data[0][1] * data[2][2]) * invDet;result.data[0][2] = (data[0][1] * data[1][2] - data[0][2] * data[1][1]) * invDet;result.data[1][0] = (data[1][2] * data[2][0] - data[1][0] * data[2][2]) * invDet;result.data[1][1] = (data[0][0] * data[2][2] - data[0][2] * data[2][0]) * invDet;result.data[1][2] = (data[0][2] * data[1][0] - data[0][0] * data[1][2]) * invDet;result.data[2][0] = (data[1][0] * data[2][1] - data[1][1] * data[2][0]) * invDet;result.data[2][1] = (data[0][1] * data[2][0] - data[0][0] * data[2][1]) * invDet;result.data[2][2] = (data[0][0] * data[1][1] - data[0][1] * data[1][0]) * invDet;return result;
}// 轉置矩陣實現
Matrix3x3 Matrix3x3::transpose() const {Matrix3x3 result;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {result.data[i][j] = data[j][i];}}return result;
}// 特征值計算實現
std::array<double, 3> Matrix3x3::eigenvalues() const {// 計算特征多項式系數double a = 1.0;double b = -(data[0][0] + data[1][1] + data[2][2]);double c = data[0][0] * data[1][1] + data[1][1] * data[2][2] + data[2][2] * data[0][0] -data[0][1] * data[1][0] - data[1][2] * data[2][1] - data[2][0] * data[0][2];double d = -determinant();// 求解三次方程// 這里使用簡化的方法,實際應用中可能需要更復雜的數值方法std::array<double, 3> roots;// ... 求解三次方程的代碼 ...return roots;
}// 特征向量計算實現
std::array<Matrix3x3, 3> Matrix3x3::eigenvectors() const {std::array<double, 3> eigenvals = eigenvalues();std::array<Matrix3x3, 3> eigenvecs;// ... 計算特征向量的代碼 ...return eigenvecs;
}// 可逆性檢查實現
bool Matrix3x3::isInvertible() const {return determinant() != 0.0;
}// 對稱性檢查實現
bool Matrix3x3::isSymmetric() const {for (int i = 0; i < 3; ++i) {for (int j = i + 1; j < 3; ++j) {if (data[i][j] != data[j][i]) {return false;}}}return true;
}// 正交性檢查實現
bool Matrix3x3::isOrthogonal() const {Matrix3x3 product = *this * transpose();Matrix3x3 identity = Matrix3x3::identity();for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (std::abs(product.data[i][j] - identity.data[i][j]) > 1e-10) {return false;}}}return true;
}// 單位矩陣創建實現
Matrix3x3 Matrix3x3::identity() {return Matrix3x3();
}// 旋轉矩陣創建實現
Matrix3x3 Matrix3x3::rotation(double theta, char axis) {Matrix3x3 result;double cos_theta = std::cos(theta);double sin_theta = std::sin(theta);switch (axis) {case 'x':result.data[1][1] = cos_theta;result.data[1][2] = -sin_theta;result.data[2][1] = sin_theta;result.data[2][2] = cos_theta;break;case 'y':result.data[0][0] = cos_theta;result.data[0][2] = sin_theta;result.data[2][0] = -sin_theta;result.data[2][2] = cos_theta;break;case 'z':result.data[0][0] = cos_theta;result.data[0][1] = -sin_theta;result.data[1][0] = sin_theta;result.data[1][1] = cos_theta;break;default:throw std::runtime_error("Invalid rotation axis");}return result;
}// 縮放矩陣創建實現
Matrix3x3 Matrix3x3::scaling(double sx, double sy, double sz) {Matrix3x3 result;result.data[0][0] = sx;result.data[1][1] = sy;result.data[2][2] = sz;return result;
}// 輸出運算符實現
std::ostream& operator<<(std::ostream& os, const Matrix3x3& m) {for (int i = 0; i < 3; ++i) {os << "[ ";for (int j = 0; j < 3; ++j) {os << m.data[i][j] << " ";}os << "]" << std::endl;}return os;
}} // namespace linear_algebra
} // namespace math
3. 使用示例
3.1 基本運算
#include "matrix3x3.h"
#include <iostream>using namespace math::linear_algebra;int main() {// 創建矩陣Matrix3x3 m1({{{1.0, 2.0, 3.0},{4.0, 5.0, 6.0},{7.0, 8.0, 9.0}}});Matrix3x3 m2({{{9.0, 8.0, 7.0},{6.0, 5.0, 4.0},{3.0, 2.0, 1.0}}});// 基本運算Matrix3x3 sum = m1 + m2; // 矩陣加法Matrix3x3 diff = m1 - m2; // 矩陣減法Matrix3x3 prod = m1 * m2; // 矩陣乘法Matrix3x3 scaled = m1 * 2.0; // 標量乘法// 輸出結果std::cout << "m1:\n" << m1 << std::endl;std::cout << "m2:\n" << m2 << std::endl;std::cout << "m1 + m2:\n" << sum << std::endl;std::cout << "m1 - m2:\n" << diff << std::endl;std::cout << "m1 * m2:\n" << prod << std::endl;std::cout << "m1 * 2:\n" << scaled << std::endl;return 0;
}
3.2 矩陣變換
#include "matrix3x3.h"
#include <iostream>
#include <cmath>using namespace math::linear_algebra;int main() {// 創建旋轉矩陣(繞Z軸旋轉45度)Matrix3x3 rotation = Matrix3x3::rotation(M_PI / 4.0, 'z');// 創建縮放矩陣Matrix3x3 scaling = Matrix3x3::scaling(2.0, 3.0, 4.0);// 組合變換Matrix3x3 transform = rotation * scaling;// 輸出結果std::cout << "旋轉矩陣:\n" << rotation << std::endl;std::cout << "縮放矩陣:\n" << scaling << std::endl;std::cout << "組合變換:\n" << transform << std::endl;return 0;
}
4. 編譯和運行
4.1 編譯
使用提供的Makefile進行編譯:
make # 編譯所有目標
make test # 運行測試
make demo # 運行示例
make clean # 清理編譯文件
4.2 運行測試
./matrix3x3_test
4.3 運行示例
./matrix3x3_demo
5. 注意事項
-
數值精度
- 在比較浮點數時使用適當的誤差范圍
- 例如:
std::abs(det) < 1e-10
判斷是否可逆
-
異常處理
- 除以零的情況
- 不可逆矩陣求逆的情況
- 無效的旋轉軸
-
性能考慮
- 矩陣乘法的時間復雜度為O(n3)
- 特征值計算可能需要迭代方法
- 考慮使用SIMD指令優化計算
-
使用建議
- 優先使用成員函數而不是全局函數
- 保持接口的一致性
- 提供清晰的錯誤信息
6. 擴展閱讀
該文章為學習過程中的筆記,目的是防止自己忘記,也為了方便隨時隨地查閱。其中大部分內容收集于互聯網。