Finalisation

This commit is contained in:
FyloZ 2024-02-14 18:17:17 -05:00
parent fcaa08a89a
commit 1d45c1ae31
Signed by: william
GPG Key ID: 835378AE9AF4AE97
2 changed files with 158 additions and 51 deletions

View File

@ -306,13 +306,102 @@ namespace gti320 {
} }
} }
template<typename _Scalar, int _Rows, int _Cols>
bool is_identity(const Matrix<_Scalar, _Rows, _Cols> &m) {
for (int i = 0; i < m.rows(); i++) {
if (m(i, i) != 1) {
return false;
}
}
return true;
}
template<typename _Scalar, int _Rows, int _Cols>
bool is_triangle(const Matrix<_Scalar, _Rows, _Cols> &m) {
int n = m.rows();
int lower, upper = 0;
int required_zero = 0;
for (int i = 1; i < n; i++) {
required_zero += i;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i < j && m(i, j) == 0) {
upper++;
}
if (j < i && m(i, j) == 0) {
lower++;
}
if (lower == n || upper == n) {
return true;
}
}
}
return false;
}
// Calcul générique du déterminant
template<typename _Scalar, int _Rows, int _Cols>
double det(const Matrix<_Scalar, _Rows, _Cols> &m) {
assert(m.rows() == m.cols());
// Cherche d'abord pour un algorithme plus simple
if (is_identity(m)) {
return 1;
}
if (is_triangle(m)) {
return det_tri(m);
}
int n = m.rows();
auto l = Matrix<double, _Rows, _Cols>();
auto u = Matrix<double, _Rows, _Cols>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// L
if (i < j) {
l(i, j) = 0;
} else if (j == i) {
l(i, j) = 1;
} else {
l(i, j) = m(i, j) / u(j, j);
for (int k = 0; k < j; k++) {
l(i, j) -= (u(k, j) * l(i, k)) / u(j, j);
}
}
// U
if (j < i) {
u(i, j) = 0;
} else {
u(i, j) = m(i, j);
for (int k = 0; k < i; k++) {
u(i, j) -= l(i, k) * u(k, j);
}
}
}
}
// Det(L) = 1, on peut l'ignorer
return det_tri(u);
}
// Déterminant d'une matrice 1x1
template<typename _Scalar> template<typename _Scalar>
_Scalar det(const Matrix<_Scalar, 1, 1> &m) { double det(const Matrix<_Scalar, 1, 1> &m) {
return m(0, 0); return m(0, 0);
} }
// Déterminant d'une matrice 2x2
template<typename _Scalar> template<typename _Scalar>
_Scalar det(const Matrix<_Scalar, 2, 2> &m) { double det(const Matrix<_Scalar, 2, 2> &m) {
_Scalar a = m(0, 0); _Scalar a = m(0, 0);
_Scalar b = m(0, 1); _Scalar b = m(0, 1);
_Scalar c = m(1, 0); _Scalar c = m(1, 0);
@ -321,40 +410,12 @@ namespace gti320 {
return (a * d) - (b * c); return (a * d) - (b * c);
} }
// Déterminant d'une matrice triangulaire
template<typename _Scalar, int _Rows, int _Cols> template<typename _Scalar, int _Rows, int _Cols>
double det(const Matrix<_Scalar, _Rows, _Cols> &m) { double det_tri(const Matrix<_Scalar, _Rows, _Cols> &m) {
assert(m.rows() == m.cols());
auto l = Matrix<double, _Rows, _Cols>();
auto u = Matrix<double, _Rows, _Cols>();
for (int j = 0; j < m.cols(); j++) {
for (int i = 0; i < m.rows(); i++) {
u(i, j) = m(i, j);
l(i, j) = m(i, j);
for (int k = 0; k < i; k++) {
u(i, j) -= l(i, k) * u(k, j);
}
for (int k = 0; k < j; k++) {
l(i, j) -= l(i, k) * u(k, j);
}
l(i, j) = 1 / u(j, j);
}
}
print_matrix(l);
print_matrix(u);
return det_tri(l) * det_tri(u);
}
template<typename _Scalar, int _Rows, int _Cols>
_Scalar det_tri(const Matrix<_Scalar, _Rows, _Cols> &m) {
int n = std::min(m.rows(), m.cols()); int n = std::min(m.rows(), m.cols());
int det = 1; double det = 1;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
det *= m(i, i); det *= m(i, i);
} }

View File

@ -125,8 +125,6 @@ TEST(TestLabo1, DynamicMatrixTests) {
EXPECT_DOUBLE_EQ(RowMT(2, 3), 0.0); EXPECT_DOUBLE_EQ(RowMT(2, 3), 0.0);
} }
/** /**
* Test pour les vecteurs à taille dynamique * Test pour les vecteurs à taille dynamique
*/ */
@ -557,6 +555,18 @@ TEST(TestLabo1, PerformanceLargeMatrixMatrix) {
EXPECT_TRUE(optimal_t < 0.4 * naive_t); EXPECT_TRUE(optimal_t < 0.4 * naive_t);
} }
template<typename _Scalar, int _Rows, int _Cols>
Matrix<_Scalar, _Rows, _Cols> build_test_matrix() {
Matrix<_Scalar, _Rows, _Cols> m;
int n = m.rows();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
m(i, j) = i * m.rows() + j + 1;
}
}
return m;
}
TEST(TestLabo1, Supplementaires) { TEST(TestLabo1, Supplementaires) {
// === Stockage === // === Stockage ===
// Test 1: Set zero // Test 1: Set zero
@ -670,30 +680,66 @@ TEST(TestLabo1, Supplementaires) {
EXPECT_EQ(V5(i), V4(i)); EXPECT_EQ(V5(i), V4(i));
} }
// === Déterminants === // === Déterminants ====
Matrix<int, 1, 1> MD1x1; auto MD1x1 = build_test_matrix<double, 1, 1>();
MD1x1(0, 0) = 1; auto MD2x2 = build_test_matrix<double, 2, 2>();
auto MD3x3 = build_test_matrix<double, 3, 3>();
Matrix<int, 2, 2> MD2x2;
MD2x2(0, 0) = 1; MD2x2(0, 1) = 2;
MD2x2(1, 0) = 3; MD2x2(1, 1) = 4;
Matrix<int, 3, 3> MD3x3;
MD3x3(0, 0) = 1; MD3x3(0, 1) = 2; MD3x3(0, 2) = 3;
MD3x3(1, 0) = 4; MD3x3(1, 1) = 5; MD3x3(1, 2) = 6;
MD3x3(2, 0) = 7; MD3x3(2, 1) = 9; MD3x3(2, 2) = 0;
// Test 13: 1x1 // Test 13: 1x1
int det1 = det(MD1x1); double det1 = det(MD1x1);
EXPECT_EQ(det1, MD1x1(0, 0)); EXPECT_EQ(det1, MD1x1(0, 0));
// Test 14: 2x2 // Test 14: 2x2
int det2 = det(MD2x2); double det2 = det(MD2x2);
EXPECT_EQ(det2, -2); EXPECT_EQ(det2, -2);
// Test 15: 3x3 // Test 15: 3x3
int det3 = det(MD3x3); MD3x3(2, 1) = 9;
EXPECT_EQ(det3, 33); MD3x3(2, 2) = 0;
double det3 = det(MD3x3);
EXPECT_NEAR(det3, 33, 0.1);
// Test 16: Identité
Matrix<int, 14, 14> MI;
MI.setIdentity();
double detI = det(MI);
EXPECT_EQ(detI, 1);
// Test 17: Triangle
MD3x3(0, 0) = 1;
MD3x3(0, 1) = 0;
MD3x3(0, 2) = 0;
MD3x3(1, 0) = 4;
MD3x3(1, 1) = 5;
MD3x3(1, 2) = 0;
MD3x3(2, 0) = 7;
MD3x3(2, 1) = 9;
MD3x3(2, 2) = 3;
double detT = det(MD3x3);
EXPECT_EQ(detT, 1 * 5 * 3);
// Test 18: Triangle avec 0
MD3x3(1, 1) = 0;
detT = det(MD3x3);
EXPECT_EQ(detT, 0);
// Test 19: Matrix4d setIdentity
Matrix4d M4D;
M4D.setIdentity();
for (int i = 0; i < M4D.rows(); i++) {
EXPECT_EQ(M4D(i, i), 1);
}
// Test 20: build_test_matrix (Si ce test ne fonctionne pas, plusieurs autres tests seront aussi cassés)
auto BM = build_test_matrix<double, 5, 5>();
int n = 1;
for (int i = 0; i < BM.rows(); i++) {
for (int j = 0; j < BM.rows(); j++) {
EXPECT_EQ(BM(i, j), n);
n++;
}
}
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {