Finalisation
This commit is contained in:
parent
fcaa08a89a
commit
1d45c1ae31
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue