// Copyright (C) 2006 Davis E. King (davisking@users.sourceforge.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_MATRIx_UTILITIES_ABSTRACT_ #ifdef DLIB_MATRIx_UTILITIES_ABSTRACT_ #include "matrix_abstract.h" #include #include "pixel.h" #include "../geometry.h" #inclue namespace dlib { // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // Elementary matrix operations // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- const matrix_exp diag ( const matrix_exp& m ); /*! requires - m is a square matrix ensures - returns a column vector R that contains the elements from the diagonal of m in the order R(0)==m(0,0), R(1)==m(1,1), R(2)==m(2,2) and so on. !*/ // ---------------------------------------------------------------------------------------- const matrix_exp trans ( const matrix_exp& m ); /*! ensures - returns the transpose of the matrix m !*/ // ---------------------------------------------------------------------------------------- template < typename T, long NR, long NC, T val > const matrix_exp uniform_matrix ( ); /*! requires - NR > 0 && NC > 0 ensures - returns an NR by NC matrix with elements of type T and all set to val. !*/ // ---------------------------------------------------------------------------------------- template < long NR, long NC, typename T > const matrix_exp uniform_matrix ( const T& val ); /*! requires - NR > 0 && NC > 0 ensures - returns an NR by NC matrix with elements of type T and all set to val. !*/ // ---------------------------------------------------------------------------------------- template < typename T > const matrix_exp uniform_matrix ( long nr, long nc, const T& val ); /*! requires - nr > 0 && nc > 0 ensures - returns an nr by nc matrix with elements of type T and all set to val. !*/ // ---------------------------------------------------------------------------------------- template < typename T, long N > const matrix_exp identity_matrix ( ); /*! requires - N > 0 ensures - returns an N by N identity matrix with elements of type T. !*/ // ---------------------------------------------------------------------------------------- template < long R, long C > const matrix_exp rotate ( const matrix_exp& m ); /*! requires - R < m.nr() - C < m.nc() ensures - returns a matrix R such that: - R::type == the same type that was in m - R has the same dimensions as m - for all valid r and c: R( (r+R)%m.nr() , (c+C)%m.nc() ) == m(r,c) !*/ // ---------------------------------------------------------------------------------------- template < typename vector_type > const matrix_exp vector_to_matrix ( const vector_type& vector ); /*! requires - vector_type is an implementation of array/array_kernel_abstract.h or std::vector or dlib::std_vector_c ensures - returns a matrix R such that: - R.nr() == vector.size() - R.nc() == 1 - for all valid r: R(r) == vector[r] !*/ // ---------------------------------------------------------------------------------------- template < typename array_type > const matrix_exp array_to_matrix ( const array_type& array ); /*! requires - array_type is an implementation of array2d/array2d_kernel_abstract.h ensures - returns a matrix R such that: - R.nr() == array.nr() - R.nc() == array.nc() - for all valid r and c: R(r, c) == array[r][c] !*/ // ---------------------------------------------------------------------------------------- const rectangle get_rect ( const matrix_exp& m ); /*! ensures - returns rectangle(0, 0, m.nc()-1, m.nr()-1) (i.e. returns a rectangle that has the same dimensions as the matrix m) !*/ // ---------------------------------------------------------------------------------------- const matrix_exp subm ( const matrix_exp& m, long row, long col, long nr, long nc ); /*! requires - row >= 0 - row + nr < m.nr() - col >= 0 - col + nc < m.nc() ensures - returns a matrix R such that: - R.nr() == nr - R.nc() == nc - for all valid r and c: R(r, c) == m(r+row,c+col) !*/ // ---------------------------------------------------------------------------------------- const matrix_exp subm ( const matrix_exp& m, const rectangle& rect ); /*! requires - get_rect(m).contains(rect) == true (i.e. rect is a region inside the matrix m) ensures - returns a matrix R such that: - R.nr() == rect.height() - R.nc() == rect.width() - for all valid r and c: R(r, c) == m(r+rect.top(), c+rect.left()) !*/ // ---------------------------------------------------------------------------------------- const matrix_exp rowm ( const matrix_exp& m, long row ); /*! requires - 0 <= row < m.nr() ensures - returns a matrix R such that: - R.nr() == 1 - R.nc() == m.nc() - for all valid i: R(i) == m(row,i) !*/ // ---------------------------------------------------------------------------------------- const matrix_exp colm ( const matrix_exp& m, long col ); /*! requires - 0 <= col < m.nr() ensures - returns a matrix R such that: - R.nr() == m.nr() - R.nc() == 1 - for all valid i: R(i) == m(i,col) !*/ // ---------------------------------------------------------------------------------------- template < long R, long C > const matrix_exp removerc ( const matrix_exp& m ); /*! requires - m.nr() > 1 - m.nc() > 1 ensures - returns a matrix R such that: - R.nr() == m.nr() - 1 - R.nc() == m.nc() - 1 - R == m with its R row and C column removed !*/ // ---------------------------------------------------------------------------------------- template < typename target_type > const matrix_exp matrix_cast ( const matrix_exp& m ); /*! ensures - returns a matrix R where for all valid r and c: R(r,c) == static_cast(m(r,c)) also, R has the same dimensions as m. !*/ // ---------------------------------------------------------------------------------------- template < typename T, long NR, long NC, typename MM, typename U > void set_all_elements ( matrix& m, U value ); /*! ensures - for all valid r and c: m(r,c) == value !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::matrix_type tmp ( const matrix_exp& m ); /*! ensures - returns a temporary matrix object that is a copy of m. (This is useful because it allows you to easily force a matrix_exp to fully evaluate before giving it to some other function that queries the elements of the matrix more than once each, such as the matrix multiplication operator.) !*/ // ---------------------------------------------------------------------------------------- bool equal ( const matrix_exp& a, const matrix_exp& b, const matrix_exp::type epsilon = 100*std::numeric_limits::epsilon() ); /*! ensures - if (a and b don't have the same dimensions) then - returns false - else if (there exists an r and c such that abs(a(r,c)-b(r,c)) > epsilon) then - returns false - else - returns true !*/ // ---------------------------------------------------------------------------------------- const matrix_exp pointwise_multiply ( const matrix_exp& a, const matrix_exp& b ); /*! requires - a.nr() == b.nr() - a.nc() == b.nc() - a and b both contain the same type of element ensures - returns a matrix R such that: - R::type == the same type that was in a and b. - R has the same dimensions as a and b. - for all valid r and c: R(r,c) == a(r,c) * b(r,c) !*/ const matrix_exp pointwise_multiply ( const matrix_exp& a, const matrix_exp& b, const matrix_exp& c ); /*! performs pointwise_multiply(a,pointwise_multiply(b,c)); !*/ const matrix_exp pointwise_multiply ( const matrix_exp& a, const matrix_exp& b, const matrix_exp& c, const matrix_exp& d ); /*! performs pointwise_multiply(pointwise_multiply(a,b),pointwise_multiply(c,d)); !*/ // ---------------------------------------------------------------------------------------- const matrix_exp scale_columns ( const matrix_exp& m, const matrix_exp& v ); /*! requires - v.nc() == 1 (i.e. v is a column vector) - v.nr() == m.nc() - m and v both contain the same type of element ensures - returns a matrix R such that: - R::type == the same type that was in m and v. - R has the same dimensions as m. - for all valid r and c: R(r,c) == m(r,c) * v(c) - i.e. R is the result of multiplying each of m's columns by the corresponding scalar in v. !*/ // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // Linear algebra functions // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- const matrix_exp::matrix_type inv ( const matrix_exp& m ); /*! requires - m is a square matrix ensures - returns the inverse of m (Note that if m is singular or so close to being singular that there is a lot of numerical error then the returned matrix will be bogus. You can check by seeing if m*inv(m) is an identity matrix) !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::matrix_type pinv ( const matrix_exp& m ); /*! ensures - returns the Moore-Penrose pseudoinverse of m. - The returned matrix has m.nr() columns and m.nc() rows. !*/ // ---------------------------------------------------------------------------------------- void svd ( const matrix_exp& m, matrix& u, matrix& w, matrix& v ); /*! ensures - computes the singular value decomposition of m - m == #u*#w*trans(#v) - trans(#u)*#u == identity matrix - trans(#v)*#v == identity matrix - #u.nr() == m.nr() - #u.nc() == m.nc() - #w.nr() == m.nc() - #w.nc() == m.nc() - #v.nr() == m.nc() - #v.nc() == m.nc() !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::type det ( const matrix_exp& m ); /*! requires - m is a square matrix ensures - returns the determinant of m !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::matrix_type cholesky_decomposition ( const matrix_exp& A ); /*! requires - A is a square matrix ensures - if (A has a Cholesky Decomposition) then - returns the decomposition of A. That is, returns a matrix L such that L*trans(L) == A. L will also be lower triangular. - else - returns a matrix with the same dimensions as A but it will have a bogus value. I.e. it won't be a decomposition. !*/ // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // Statistics // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- const matrix_exp::type min ( const matrix_exp& m ); /*! ensures - returns the value of the smallest element of m !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::type max ( const matrix_exp& m ); /*! ensures - returns the value of the biggest element of m !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::type sum ( const matrix_exp& m ); /*! ensures - returns the sum of all elements in m !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::type prod ( const matrix_exp& m ); /*! ensures - returns the results of multiplying all elements of m together. !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::type mean ( const matrix_exp& m ); /*! ensures - returns the mean of all elements in m. (i.e. returns sum(m)/(m.nr()*m.nc())) !*/ // ---------------------------------------------------------------------------------------- const matrix_exp::type variance ( const matrix_exp& m ); /*! ensures - returns the unbiased sample variance of all elements in m (i.e. 1.0/(m.nr()*m.nc() - 1)*(sum of all pow(m(i,j) - mean(m),2))) !*/ // ---------------------------------------------------------------------------------------- const matrix covariance ( const matrix_exp& m ); /*! requires - matrix_exp::type == a dlib::matrix object - m.nr() > 1 - m.nc() == 1 (i.e. m is a column vector) - for all valid i, j: - m(i).nr() > 0 - m(i).nc() == 1 - m(i).nr() == m(j).nr() - i.e. m contains only column vectors and all the column vectors have the same non-zero length ensures - returns the unbiased sample covariance matrix for the set of samples in m. (i.e. 1.0/(m.nr()-1)*(sum of all (m(i) - mean(m))*trans(m(i) - mean(m)))) - the returned matrix will contain elements of type matrix_exp::type::type. - the returned matrix will have m(0).nr() rows and columns. !*/ // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // Pixel and Image Utilities // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- template < typename T, typename P > const matrix_exp pixel_to_vector ( const P& pixel ); /*! requires - pixel_traits

::has_alpha == false ensures - returns a matrix M such that: - M::type == T - M::NC == 1 - M::NR == pixel_traits

::num - if (pixel_traits

::grayscale) then - M(0) == pixel - if (pixel_traits

::rgb) then - M(0) == pixel.red - M(1) == pixel.green - M(2) == pixel.blue - if (pixel_traits

::hsi) then - M(0) == pixel.h - M(1) == pixel.s - M(2) == pixel.i !*/ // ---------------------------------------------------------------------------------------- template < typename P > void vector_to_pixel ( P& pixel, const matrix_exp& vector ); /*! requires - pixel_traits

::has_alpha == false - vector::NR == pixel_traits

::num - vector::NC == 1 (i.e. you have to use a statically dimensioned vector) ensures - if (pixel_traits

::grayscale) then - pixel == M(0) - if (pixel_traits

::rgb) then - pixel.red == M(0) - pixel.green == M(1) - pixel.blue == M(2) - if (pixel_traits

::hsi) then - pixel.h == M(0) - pixel.s == M(1) - pixel.i == M(2) !*/ // ---------------------------------------------------------------------------------------- template < long lower, long upper > const matrix_exp clamp ( const matrix_exp& m ); /*! ensures - returns a matrix R such that: - R::type == the same type that was in m - R has the same dimensions as m - for all valid r and c: - if (m(r,c) > upper) then - R(r,c) == upper - else if (m(r,c) < lower) then - R(r,c) == lower - else - R(r,c) == m(r,c) !*/ // ---------------------------------------------------------------------------------------- } #endif // DLIB_MATRIx_UTILITIES_ABSTRACT_