mirror of
https://github.com/Relintai/MLPP.git
synced 2025-02-10 16:10:06 +01:00
Added 2nd partial derivative test. Detects saddles, mins and maxes.
This commit is contained in:
parent
5764f20ed2
commit
66883a3f5d
@ -704,6 +704,34 @@ namespace MLPP{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LinAlg::negativeDefiniteChecker(std::vector<std::vector<double>> A){
|
||||||
|
auto [eigenvectors, eigenvals] = eig(A);
|
||||||
|
std::vector<double> eigenvals_vec;
|
||||||
|
for(int i = 0; i < eigenvals.size(); i++){
|
||||||
|
eigenvals_vec.push_back(eigenvals[i][i]);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < eigenvals_vec.size(); i++){
|
||||||
|
if(eigenvals_vec[i] >= 0){ // Simply check to ensure all eigenvalues are negative.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinAlg::zeroEigenvalue(std::vector<std::vector<double>> A){
|
||||||
|
auto [eigenvectors, eigenvals] = eig(A);
|
||||||
|
std::vector<double> eigenvals_vec;
|
||||||
|
for(int i = 0; i < eigenvals.size(); i++){
|
||||||
|
eigenvals_vec.push_back(eigenvals[i][i]);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < eigenvals_vec.size(); i++){
|
||||||
|
if(eigenvals_vec[i] == 0){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void LinAlg::printMatrix(std::vector<std::vector<double>> A){
|
void LinAlg::printMatrix(std::vector<std::vector<double>> A){
|
||||||
for(int i = 0; i < A.size(); i++){
|
for(int i = 0; i < A.size(); i++){
|
||||||
for(int j = 0; j < A[i].size(); j++){
|
for(int j = 0; j < A[i].size(); j++){
|
||||||
|
@ -106,6 +106,10 @@ namespace MLPP{
|
|||||||
|
|
||||||
bool positiveDefiniteChecker(std::vector<std::vector<double>> A);
|
bool positiveDefiniteChecker(std::vector<std::vector<double>> A);
|
||||||
|
|
||||||
|
bool negativeDefiniteChecker(std::vector<std::vector<double>> A);
|
||||||
|
|
||||||
|
bool zeroEigenvalue(std::vector<std::vector<double>> A);
|
||||||
|
|
||||||
void printMatrix(std::vector<std::vector<double>> A);
|
void printMatrix(std::vector<std::vector<double>> A);
|
||||||
|
|
||||||
// VECTOR FUNCTIONS
|
// VECTOR FUNCTIONS
|
||||||
|
@ -260,4 +260,43 @@ namespace MLPP{
|
|||||||
}
|
}
|
||||||
return laplacian;
|
return laplacian;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string NumericalAnalysis::secondPartialDerivativeTest(double(*function)(std::vector<double>), std::vector<double> x){
|
||||||
|
LinAlg alg;
|
||||||
|
std::vector<std::vector<double>> hessianMatrix = hessian(function, x);
|
||||||
|
/*
|
||||||
|
The reason we do this is because the 2nd partial derivative test is less conclusive for functions of variables greater than
|
||||||
|
2, and the calculations specific to the bivariate case are less computationally intensive.
|
||||||
|
*/
|
||||||
|
if(x.size() == 2){
|
||||||
|
double det = alg.det(hessianMatrix, hessianMatrix.size());
|
||||||
|
double secondDerivative = numDiff_2(function, x, 0, 0);
|
||||||
|
if(secondDerivative > 0 && det > 0){
|
||||||
|
return "min";
|
||||||
|
}
|
||||||
|
else if(secondDerivative < 0 && det > 0){
|
||||||
|
return "max";
|
||||||
|
}
|
||||||
|
else if(det < 0){
|
||||||
|
return "saddle";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return "test was inconclusive";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(alg.positiveDefiniteChecker(hessianMatrix)){
|
||||||
|
return "min";
|
||||||
|
}
|
||||||
|
else if(alg.negativeDefiniteChecker(hessianMatrix)){
|
||||||
|
return "max";
|
||||||
|
}
|
||||||
|
else if(!alg.zeroEigenvalue(hessianMatrix)){
|
||||||
|
return "saddle";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return "test was inconclusive";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -48,6 +48,8 @@ namespace MLPP{
|
|||||||
|
|
||||||
double laplacian(double(*function)(std::vector<double>), std::vector<double> x); // laplacian
|
double laplacian(double(*function)(std::vector<double>), std::vector<double> x); // laplacian
|
||||||
|
|
||||||
|
std::string secondPartialDerivativeTest(double(*function)(std::vector<double>), std::vector<double> x);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user