Reworked more methods.

This commit is contained in:
Relintai 2023-12-29 10:43:16 +01:00
parent 719556e9bc
commit abaf8ad1f2
3 changed files with 70 additions and 75 deletions

View File

@ -932,34 +932,44 @@ MLPPLinAlg::QRDResult MLPPLinAlg::qrd(const Ref<MLPPMatrix> &A) {
return res; return res;
} }
/* MLPPLinAlg::CholeskyResult MLPPLinAlg::cholesky(const Ref<MLPPMatrix> &A) {
MLPPLinAlg::CholeskyResult MLPPLinAlg::cholesky(std::vector<std::vector<real_t>> A) { Size2i a_size = A->size();
std::vector<std::vector<real_t>> L = zeromat(A.size(), A[0].size());
for (uint32_t j = 0; j < L.size(); j++) { // Matrices entered must be square. No problem here. CholeskyResult res;
for (uint32_t i = j; i < L.size(); i++) {
ERR_FAIL_COND_V(a_size.x != a_size.y, res);
Ref<MLPPMatrix> L = zeromatnm(a_size.y, a_size.x);
for (int j = 0; j < a_size.y; ++j) { // Matrices entered must be square. No problem here.
for (int i = j; i < a_size.y; ++i) {
if (i == j) { if (i == j) {
real_t sum = 0; real_t sum = 0;
for (uint32_t k = 0; k < j; k++) {
sum += L[i][k] * L[i][k]; for (int k = 0; k < j; k++) {
real_t lik = L->element_get(i, k);
sum += lik * lik;
} }
L[i][j] = Math::sqrt(A[i][j] - sum);
L->element_set(i, j, Math::sqrt(A->element_get(i, j) - sum));
} else { // That is, i!=j } else { // That is, i!=j
real_t sum = 0; real_t sum = 0;
for (uint32_t k = 0; k < j; k++) {
sum += L[i][k] * L[j][k]; for (int k = 0; k < j; k++) {
sum += L->element_get(i, k) * L->element_get(j, k);
} }
L[i][j] = (A[i][j] - sum) / L[j][j];
L->element_set(i, j, (A->element_get(i, j) - sum) / L->element_get(j, j));
} }
} }
} }
CholeskyResult res;
res.L = L; res.L = L;
res.Lt = transpose(L); // Indeed, L.T is our upper triangular matrix. res.Lt = L->transposen(); // Indeed, L.T is our upper triangular matrix.
return res; return res;
} }
*/
/* /*
real_t MLPPLinAlg::sum_elements(std::vector<std::vector<real_t>> A) { real_t MLPPLinAlg::sum_elements(std::vector<std::vector<real_t>> A) {
@ -990,62 +1000,54 @@ Ref<MLPPVector> MLPPLinAlg::flattenvvnv(const Ref<MLPPMatrix> &A) {
return res; return res;
} }
/* Ref<MLPPVector> MLPPLinAlg::solve(const Ref<MLPPMatrix> &A, const Ref<MLPPVector> &b) {
std::vector<real_t> MLPPLinAlg::solve(std::vector<std::vector<real_t>> A, std::vector<real_t> b) { return A->inverse()->mult_vec(b);
return mat_vec_mult(inverse(A), b);
} }
bool MLPPLinAlg::positiveDefiniteChecker(std::vector<std::vector<real_t>> A) { bool MLPPLinAlg::positive_definite_checker(const Ref<MLPPMatrix> &A) {
auto eig_result = eig(A); EigenResult eig_result = eigen(A);
auto eigenvectors = std::get<0>(eig_result);
auto eigenvals = std::get<1>(eig_result);
std::vector<real_t> eigenvals_vec; Ref<MLPPMatrix> eigenvals = eig_result.eigen_values;
for (uint32_t i = 0; i < eigenvals.size(); i++) { Size2i eigenvals_size = eigenvals->size();
eigenvals_vec.push_back(eigenvals[i][i]);
} for (int i = 0; i < eigenvals_size.y; ++i) {
for (uint32_t i = 0; i < eigenvals_vec.size(); i++) { if (eigenvals->element_get(i, i) <= 0) { // Simply check to ensure all eigenvalues are positive.
if (eigenvals_vec[i] <= 0) { // Simply check to ensure all eigenvalues are positive.
return false; return false;
} }
} }
return true; return true;
} }
bool MLPPLinAlg::negativeDefiniteChecker(std::vector<std::vector<real_t>> A) { bool MLPPLinAlg::negative_definite_checker(const Ref<MLPPMatrix> &A) {
auto eig_result = eig(A); EigenResult eig_result = eigen(A);
auto eigenvectors = std::get<0>(eig_result);
auto eigenvals = std::get<1>(eig_result);
std::vector<real_t> eigenvals_vec; Ref<MLPPMatrix> eigenvals = eig_result.eigen_values;
for (uint32_t i = 0; i < eigenvals.size(); i++) { Size2i eigenvals_size = eigenvals->size();
eigenvals_vec.push_back(eigenvals[i][i]);
} for (int i = 0; i < eigenvals_size.y; ++i) {
for (uint32_t i = 0; i < eigenvals_vec.size(); i++) { if (eigenvals->element_get(i, i) >= 0) { // Simply check to ensure all eigenvalues are negative.
if (eigenvals_vec[i] >= 0) { // Simply check to ensure all eigenvalues are negative.
return false; return false;
} }
} }
return true; return true;
} }
bool MLPPLinAlg::zeroEigenvalue(std::vector<std::vector<real_t>> A) { bool MLPPLinAlg::zero_eigenvalue(const Ref<MLPPMatrix> &A) {
auto eig_result = eig(A); EigenResult eig_result = eigen(A);
auto eigenvectors = std::get<0>(eig_result);
auto eigenvals = std::get<1>(eig_result);
std::vector<real_t> eigenvals_vec; Ref<MLPPMatrix> eigenvals = eig_result.eigen_values;
for (uint32_t i = 0; i < eigenvals.size(); i++) { Size2i eigenvals_size = eigenvals->size();
eigenvals_vec.push_back(eigenvals[i][i]);
} for (int i = 0; i < eigenvals_size.y; ++i) {
for (uint32_t i = 0; i < eigenvals_vec.size(); i++) { if (eigenvals->element_get(i, i) == 0) { // TODO should it use is_equal_approx?
if (eigenvals_vec[i] == 0) { return false;
return true;
} }
} }
return false;
return true;
} }
*/
Ref<MLPPVector> MLPPLinAlg::flattenmnv(const Vector<Ref<MLPPVector>> &A) { Ref<MLPPVector> MLPPLinAlg::flattenmnv(const Vector<Ref<MLPPVector>> &A) {
Ref<MLPPVector> a; Ref<MLPPVector> a;

View File

@ -121,28 +121,22 @@ public:
QRDResult qrd(const Ref<MLPPMatrix> &A); QRDResult qrd(const Ref<MLPPMatrix> &A);
/*
struct CholeskyResult { struct CholeskyResult {
std::vector<std::vector<real_t>> L; Ref<MLPPMatrix> L;
std::vector<std::vector<real_t>> Lt; Ref<MLPPMatrix> Lt;
}; };
CholeskyResult cholesky(std::vector<std::vector<real_t>> A); CholeskyResult cholesky(const Ref<MLPPMatrix> &A);
*/
//real_t sum_elements(std::vector<std::vector<real_t>> A); //real_t sum_elements(std::vector<std::vector<real_t>> A);
Ref<MLPPVector> flattenvvnv(const Ref<MLPPMatrix> &A); Ref<MLPPVector> flattenvvnv(const Ref<MLPPMatrix> &A);
Ref<MLPPVector> solve(const Ref<MLPPMatrix> &A, const Ref<MLPPVector> &b);
/* bool positive_definite_checker(const Ref<MLPPMatrix> &A);
std::vector<real_t> solve(std::vector<std::vector<real_t>> A, std::vector<real_t> b); bool negative_definite_checker(const Ref<MLPPMatrix> &A);
bool positiveDefiniteChecker(std::vector<std::vector<real_t>> A); bool zero_eigenvalue(const Ref<MLPPMatrix> &A);
bool negativeDefiniteChecker(std::vector<std::vector<real_t>> A);
bool zeroEigenvalue(std::vector<std::vector<real_t>> A);
*/
// VECTOR FUNCTIONS // VECTOR FUNCTIONS

View File

@ -1157,7 +1157,7 @@ void MLPPTests::test_new_math_functions() {
PLOG_MSG(alg.gram_schmidt_process(P)->to_string()); PLOG_MSG(alg.gram_schmidt_process(P)->to_string());
MLPPLinAlg::QRDResult qrd_result = alg.qrd(P); // It works! MLPPLinAlg::QRDResult qrd_result = alg.qrd(P); // It works!
//[MLPPMatrix: //[MLPPMatrix:
// [ 0.857143 -0.394286 -0.331429 ] // [ 0.857143 -0.394286 -0.331429 ]
// [ 0.428571 0.902857 0.034286 ] // [ 0.428571 0.902857 0.034286 ]
@ -1172,27 +1172,26 @@ void MLPPTests::test_new_math_functions() {
PLOG_MSG(qrd_result.R->to_string()); PLOG_MSG(qrd_result.R->to_string());
} }
void MLPPTests::test_positive_definiteness_checker() { void MLPPTests::test_positive_definiteness_checker() {
/*
//MLPPStat stat;
MLPPLinAlg alg; MLPPLinAlg alg;
//MLPPActivation avn;
//MLPPCost cost;
//MLPPData data;
//MLPPConvolutions conv;
// Checking positive-definiteness checker. For Cholesky Decomp. // Checking positive-definiteness checker. For Cholesky Decomp.
std::vector<std::vector<real_t>> A = { std::vector<std::vector<real_t>> A_arr = {
{ 1, -1, -1, -1 }, { 1, -1, -1, -1 },
{ -1, 2, 2, 2 }, { -1, 2, 2, 2 },
{ -1, 2, 3, 1 }, { -1, 2, 3, 1 },
{ -1, 2, 1, 4 } { -1, 2, 1, 4 }
}; };
std::cout << std::boolalpha << alg.positiveDefiniteChecker(A) << std::endl; Ref<MLPPMatrix> A(memnew(MLPPMatrix(A_arr)));
PLOG_MSG("positive_definite_checker Example:");
PLOG_MSG(String::bool_str(alg.positive_definite_checker(A)));
PLOG_MSG("Cholesky Example:");
MLPPLinAlg::CholeskyResult chres = alg.cholesky(A); // works. MLPPLinAlg::CholeskyResult chres = alg.cholesky(A); // works.
alg.printMatrix(chres.L);
alg.printMatrix(chres.Lt); PLOG_MSG(chres.L->to_string());
*/ PLOG_MSG(chres.Lt->to_string());
} }
// real_t f(real_t x){ // real_t f(real_t x){