#include <iostream>
#include <string>
#include <algorithm>
#include <matvec/matvec.h>
struct Chyba
{
template <typename T> Chyba(T t) : text(t) {}
std::string text;
};
double determinant(GNU_gama::Mat<>& A)
{
// matice musi byt ctvercova a nesmi mit nulovy rozmer
const int N = A.rows();
if (N != A.cols() || N == 0) throw Chyba("chybny rozmer matice");
// D registruje zmeny znamenka determinantu
double D = 1;
// hlavni cyklus anuluje prvky pod hlavni diagonalou
for (int k=1; k<N; k++)
{
// vyber pivotniho prvku
double pivot = std::abs(A(k,k));
int index = k;
for (int i=k+1; i<=N; i++)
if (std::abs(A(i,k)) > pivot)
{
pivot = std::abs(A(i,k));
index = i;
}
// nulovy prvek na diagonale znamena, ze matice neni regularni
if (pivot == 0) return 0;
// vymena pivotniho radku znamena zmenu znamenka determinantu
if (index != k)
{
D *= -1;
for (int j=k; j<=N; j++)
std::swap(A(index,j), A(k,j));
}
// vynulovani sloupce pod pivotnim prvkem
for (int i=k+1; i<=N; i++)
{
double p = A(i,k)/A(k,k);
A(i,k) = 0;
for (int j=k+1; j<=N; j++)
A(i,j) -= p*A(k,j);
}
}
// soucin prvku na hlavni diagonale
double S = 1;
for (int k=1; k<=N; k++) S *= A(k,k);
return D*S;
}
int main()
{
try
{
GNU_gama::Mat<> A(4,4); // det(A) je 12
A =
0, 2, 2, 4,
1, 2, 3, 4,
3, 0, 9, 8,
2, 7, 0, 1;
std::cout << "det(A) = " << determinant(A) << "\n";
GNU_gama::Mat<> B(9,9); // det(B) je 1
B =
4917, 5081, 5242, 5397, 5542, 5672, 5781, 5862, 5907,
5081, 5253, 5421, 5582, 5732, 5866, 5978, 6061, 6107,
5242, 5421, 5596, 5763, 5918, 6056, 6171, 6256, 6303,
5397, 5582, 5763, 5936, 6096, 6238, 6356, 6443, 6491,
5542, 5732, 5918, 6096, 6261, 6407, 6528, 6617, 6666,
5672, 5866, 6056, 6238, 6407, 6557, 6681, 6772, 6822,
5781, 5978, 6171, 6356, 6528, 6681, 6808, 6901, 6952,
5862, 6061, 6256, 6443, 6617, 6772, 6901, 6996, 7048,
5907, 6107, 6303, 6491, 6666, 6822, 6952, 7048, 7101;
std::cout << "det(B) = " << determinant(B) << "\n";
}
catch(Chyba& ch)
{
std::cout << "Chyba : " << ch.text << "\n";
}
}