Commit 10b5a517 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

added "small matrix" class Matx<T, m, n>

parent bed63cc7
This diff is collapsed.
......@@ -663,7 +663,7 @@ CvFuncTable;
typedef struct CvBigFuncTable
{
void* fn_2d[CV_DEPTH_MAX*CV_CN_MAX];
void* fn_2d[CV_DEPTH_MAX*4];
}
CvBigFuncTable;
......
......@@ -231,13 +231,39 @@ template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
}
template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec)
template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
rows(0), cols(0), step(0), data(0), refcount(0),
datastart(0), dataend(0)
{
create(n, 1, DataType<_Tp>::type);
memcpy(data, &vec[0], n*sizeof(_Tp));
if( !copyData )
{
rows = n;
cols = 1;
step = sizeof(_Tp);
data = datastart = (uchar*)vec.val;
dataend = datastart + rows*step;
}
else
Mat(n, 1, DataType<_Tp>::type, vec.val).copyTo(*this);
}
template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
rows(0), cols(0), step(0), data(0), refcount(0),
datastart(0), dataend(0)
{
if( !copyData )
{
rows = m;
cols = n;
step = sizeof(_Tp);
data = datastart = (uchar*)M.val;
dataend = datastart + rows*step;
}
else
Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
}
......@@ -619,13 +645,17 @@ template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRan
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
: Mat(m, roi) {}
template<typename _Tp> template<int n> inline Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec)
: Mat(n, 1, DataType<_Tp>::type)
template<typename _Tp> template<int n> inline
Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec, bool copyData)
: Mat(vec, copyData)
{
_Tp* d = (_Tp*)data;
for( int i = 0; i < n; i++ )
d[i] = vec[i];
}
template<typename _Tp> template<int m, int n> inline
Mat_<_Tp>::Mat_(const Matx<_Tp,m,n>& M, bool copyData)
: Mat(M, copyData)
{
}
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<_Tp>& pt)
: Mat(2, 1, DataType<_Tp>::type)
......
......@@ -518,7 +518,7 @@ IplConvKernelFP;
* Matrix type (CvMat) *
\****************************************************************************************/
#define CV_CN_MAX 64
#define CV_CN_MAX 1024
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
......
......@@ -57,7 +57,162 @@
namespace cv
{
/****************************************************************************************\
* LU & Cholesky implementation for small matrices *
\****************************************************************************************/
template<typename _Tp> static inline int LUImpl(_Tp* A, int m, _Tp* b, int n)
{
int i, j, k, p = 1;
for( i = 0; i < m; i++ )
{
k = i;
for( j = i+1; j < m; j++ )
if( std::abs(A[j*m + i]) > std::abs(A[k*m + i]) )
k = j;
if( std::abs(A[k*m + i]) < std::numeric_limits<_Tp>::epsilon() )
return 0;
if( k != i )
{
for( j = i; j < m; j++ )
std::swap(A[i*m + j], A[k*m + j]);
if( b )
for( j = 0; j < n; j++ )
std::swap(b[i*n + j], b[k*n + j]);
p = -p;
}
_Tp d = -1/A[i*m + i];
for( j = i+1; j < m; j++ )
{
_Tp alpha = A[j*m + i]*d;
for( k = i+1; k < m; k++ )
A[j*m + k] += alpha*A[i*m + k];
if( b )
for( k = 0; k < n; k++ )
b[j*n + k] += alpha*b[i*n + k];
}
A[i*m + i] = -d;
}
if( b )
{
for( i = m-1; i >= 0; i-- )
for( j = 0; j < n; j++ )
{
_Tp s = b[i*n + j];
for( k = i+1; k < m; k++ )
s -= A[i*m + k]*b[k*n + j];
b[i*n + j] = s*A[i*m + i];
}
}
return p;
}
int LU(float* A, int m, float* b, int n)
{
return LUImpl(A, m, b, n);
}
int LU(double* A, int m, double* b, int n)
{
return LUImpl(A, m, b, n);
}
template<typename _Tp> static inline bool CholImpl(_Tp* A, int m, _Tp* b, int n)
{
_Tp* L = A;
int i, j, k;
double s;
for( i = 0; i < m; i++ )
{
for( j = 0; j < i; j++ )
{
s = A[i*m + j];
for( k = 0; k < j; k++ )
s -= L[i*m + k]*L[j*m + k];
L[i*m + j] = (_Tp)(s*L[j*m + j]);
}
s = A[i*m + i];
for( k = 0; k < j; k++ )
{
double t = L[i*m + k];
s -= t*t;
}
if( s < std::numeric_limits<_Tp>::epsilon() )
return 0;
L[i*m + i] = (_Tp)(1./std::sqrt(s));
}
if( !b )
return false;
// LLt x = b
// 1: L y = b
// 2. Lt x = y
/*
[ L00 ] y0 b0
[ L10 L11 ] y1 = b1
[ L20 L21 L22 ] y2 b2
[ L30 L31 L32 L33 ] y3 b3
[ L00 L10 L20 L30 ] x0 y0
[ L11 L21 L31 ] x1 = y1
[ L22 L32 ] x2 y2
[ L33 ] x3 y3
*/
for( i = 0; i < m; i++ )
{
for( j = 0; j < n; j++ )
{
s = b[i*n + j];
for( k = 0; k < i; k++ )
s -= L[i*m + k]*b[k*n + j];
b[i*n + j] = (_Tp)(s*L[i*m + i]);
}
}
for( i = m-1; i >= 0; i-- )
{
for( j = 0; j < n; j++ )
{
s = b[i*n + j];
for( k = m-1; k > i; k-- )
s -= L[k*m + i]*b[k*n + j];
b[i*n + j] = (_Tp)(s*L[i*m + i]);
}
}
return true;
}
bool Cholesky(float* A, int m, float* b, int n)
{
return CholImpl(A, m, b, n);
}
bool Cholesky(double* A, int m, double* b, int n)
{
return CholImpl(A, m, b, n);
}
/****************************************************************************************\
* Determinant of the matrix *
\****************************************************************************************/
......
......@@ -2344,7 +2344,7 @@ SparseMat::Hdr::Hdr( int _dims, const int* _sizes, int _type )
dims = _dims;
valueOffset = (int)alignSize(sizeof(SparseMat::Node) +
sizeof(int)*(dims - CV_MAX_DIM), CV_ELEM_SIZE1(_type));
sizeof(int)*std::max(dims - CV_MAX_DIM, 0), CV_ELEM_SIZE1(_type));
nodeSize = alignSize(valueOffset +
CV_ELEM_SIZE(_type), (int)sizeof(size_t));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment