Post date: Dec 22, 2016 6:34:47 AM
Read that OpenCV LU does not give access to the LU matrices. So came up with my own which I will include in its entirety here.
LUdecomp::LUdecomp(cv::Mat a)
{
_A = cv::Mat(a);
_L = cv::Mat::zeros(a.rows, a.cols, a.type());
_U = cv::Mat::zeros(a.rows, a.cols, a.type());
}
LUdecomp::~LUdecomp()
{
_A.release();
_L.release();
_U.release();
}
void LUdecomp::decomp()
{
if ((!_A.rows > 0) || (!_A.cols > 0))
return;
if (_A.rows != _A.cols)
return;
// test for determinant == 0
for (int i = 1; i < _A.cols; i++)
{
cv::Rect r = cv::Rect(0, 0, i, i);
cv::Mat _sA = _A(r);
double det = determinant(_sA);
if (det == 0)
return;
}
// now decomp proper
cv::Mat cU = _A.clone();
cv::Mat cL = cv::Mat::zeros(_A.rows, _A.cols, _A.type());
for (int i = 0; i < cU.rows - 1; i++) // cols
{
for (int j = i; j < cU.cols - 1; j++) // rows
{
cv::Mat* pivot = GetRow(&cU, i);
cv::Mat* zerow = GetRow(&cU, j + 1);
double mult = zerow->at<float>(0, i) / pivot->at<float>(0, i);
cv::Mat rowmult = pivot->mul(mult);
cv::Mat res;
cv::subtract(*zerow, rowmult, res);
SetRow(&cU, &res, j + 1);
cL.at<float>(j + 1, i) = static_cast<float>(mult);
}
}
for (int i = 0; i < cL.cols; i++)
{
for (int j = 0; j < cL.rows; j++)
{
if (i == j)
cL.at<float>(j, i) = 1.0f;
}
}
cU.copyTo(_U);
cL.copyTo(_L);
cU.release();
cL.release();
}
cv::Mat* GetRow(cv::Mat* mat, int rownum)
{
if ((rownum < 0) || (rownum > mat->cols))
return NULL;
cv::Rect r(0, rownum, mat->cols, 1);
cv::Mat* sm = new cv::Mat((*mat)(r));
return sm;
}
void SetRow(cv::Mat* mat, cv::Mat* mrow, int rownum)
{
if (mrow->rows != 1)
return;
if (mat->cols != mrow->cols)
return;
if ((rownum < 0) || (rownum > mat->cols))
return;
cv::Rect r(0, rownum, mrow->cols, 1);
cv::Mat sm = (*mat)(r);
mrow->copyTo(sm);
}
So what you need to so is with a square matrix as argument, construct LUdecomp class.
Then call .decomp() method.
L will be available in ._L and U in _U.
n.b. This is a implementation of the decomposition at its most basic form. I did not incorporate any other algorithms or checks.