// Copyright (C) 2006 Davis E. King (davis@dlib.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 <complex>
#include "../pixel.h"
#include "../geometry.h"
#inclue <vector>
namespace dlib
{
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// Simple matrix utilities
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
const matrix_exp diag (
const matrix_exp& m
);
/*!
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.
!*/
template <typename EXP>
struct diag_exp
{
/*!
WHAT THIS OBJECT REPRESENTS
This struct allows you to determine the type of matrix expression
object returned from the diag() function. An example makes its
use clear:
template <typename EXP>
void do_something( const matrix_exp<EXP>& mat)
{
// d is a matrix expression that aliases mat.
typename diag_exp<EXP>::type d = diag(mat);
// Print the diagonal of mat. So we see that by using
// diag_exp we can save the object returned by diag() in
// a local variable.
cout << d << endl;
// Note that you can only save the return value of diag() to
// a local variable if the argument to diag() has a lifetime
// beyond the diag() expression. The example shown above is
// OK but the following would result in undefined behavior:
typename diag_exp<EXP>::type bad = diag(mat + mat);
}
!*/
typedef type_of_expression_returned_by_diag type;
};
// ----------------------------------------------------------------------------------------
const matrix_exp diagm (
const matrix_exp& m
);
/*!
requires
- is_vector(m) == true
(i.e. m is a row or column matrix)
ensures
- returns a square matrix M such that:
- diag(M) == m
- non diagonal elements of M are 0
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp trans (
const matrix_exp& m
);
/*!
ensures
- returns the transpose of the matrix m
!*/
// ----------------------------------------------------------------------------------------
const matrix_type::type dot (
const matrix_exp& m1,
const matrix_exp& m2
);
/*!
requires
- is_vector(m1) == true
- is_vector(m2) == true
- m1.size() == m2.size()
ensures
- returns the dot product between m1 and m2. That is, this function
computes and returns the sum, for all i, of m1(i)*m2(i).
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp lowerm (
const matrix_exp& m
);
/*!
ensures
- returns a matrix M such that:
- M::type == the same type that was in m
- M has the same dimensions as m
- M is the lower triangular part of m. That is:
- if (r >= c) then
- M(r,c) == m(r,c)
- else
- M(r,c) == 0
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp lowerm (
const matrix_exp& m,
const matrix_exp::type scalar_value
);
/*!
ensures
- returns a matrix M such that:
- M::type == the same type that was in m
- M has the same dimensions as m
- M is the lower triangular part of m except that the diagonal has
been set to scalar_value. That is:
- if (r > c) then
- M(r,c) == m(r,c)
- else if (r == c) then
- M(r,c) == scalar_value
- else
- M(r,c) == 0
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp upperm (
const matrix_exp& m
);
/*!
ensures
- returns a matrix M such that:
- M::type == the same type that was in m
- M has the same dimensions as m
- M is the upper triangular part of m. That is:
- if (r <= c) then
- M(r,c) == m(r,c)
- else
- M(r,c) == 0
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp upperm (
const matrix_exp& m,
const matrix_exp::type scalar_value
);
/*!
ensures
- returns a matrix M such that:
- M::type == the same type that was in m
- M has the same dimensions as m
- M is the upper triangular part of m except that the diagonal has
been set to scalar_value. That is:
- if (r < c) then
- M(r,c) == m(r,c)
- else if (r == c) then
- M(r,c) == scalar_value
- else
- M(r,c) == 0
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp make_symmetric (
const matrix_exp& m
);
/*!
requires
- m.nr() == m.nc()
(i.e. m must be a square matrix)
ensures
- returns a matrix M such that:
- M::type == the same type that was in m
- M has the same dimensions as m
- M is a symmetric matrix, that is, M == trans(M) and
it is constructed from the lower triangular part of m. Specifically,
we have:
- lowerm(M) == lowerm(m)
- upperm(M) == trans(lowerm(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 <
typename T,
long NR,
long NC
>
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
>
const matrix_exp ones_matrix (
long nr,
long nc
);
/*!
requires
- nr > 0 && nc > 0
ensures
- returns uniform_matrix<T>(nr, nc, 1)
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
const matrix_exp zeros_matrix (
long nr,
long nc
);
/*!
requires
- nr > 0 && nc > 0
ensures
- returns uniform_matrix<T>(nr, nc, 0)
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
const matrix_exp identity_matrix (
long N
);
/*!
requires
- N > 0
ensures
- returns an N by N identity matrix with elements of type T.
!*/
// ----------------------------------------------------------------------------------------
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.
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp linspace (
double start,
double end,
long num
);
/*!
requires
- num >= 0
ensures
- returns a matrix M such that:
- M::type == double
- is_row_vector(M) == true
- M.size() == num
- M == a row vector with num linearly spaced values beginning with start
and stopping with end.
- M(num-1) == end
- if (num > 1) then
- M(0) == start
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp logspace (
double start,
double end,
long num
);
/*!
requires
- num >= 0
ensures
- returns a matrix M such that:
- M::type == double
- is_row_vector(M) == true
- M.size() == num
- M == a row vector with num logarithmically spaced values beginning with
10^start and stopping with 10^end.
(i.e. M == pow(10, linspace(start, end, num)))
- M(num-1) == 10^end
!*/
// ----------------------------------------------------------------------------------------
template <
long R,
long C
>
const matrix_exp rotate (
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:
R( (r+R)%m.nr() , (c+C)%m.nc() ) == m(r,c)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp fliplr (
const matrix_exp& m
);
/*!
ensures
- flips the matrix m from left to right and returns the result.
I.e. reverses the order of the columns.
- returns a matrix M such that:
- M::type == the same type that was in m
- M has the same dimensions as m
- for all valid r and c:
M(r,c) == m(r, m.nc()-c-1)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp flipud (
const matrix_exp& m
);
/*!
ensures
- flips the matrix m from up to down and returns the result.
I.e. reverses the order of the rows.
- returns a matrix M such that:
- M::type == the same type that was in m
- M has the same dimensions as m
- for all valid r and c:
M(r,c) == m(m.nr()-r-1, 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 or dlib::matrix
ensures
- if (vector_type is a dlib::matrix) then
- returns a reference to vector
- else
- returns a matrix R such that:
- is_col_vector(R) == true
- R.size() == vector.size()
- 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
or dlib::matrix
ensures
- if (array_type is a dlib::matrix) then
- returns a reference to array
- else
- 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]
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
const matrix_exp pointer_to_matrix (
const T* ptr,
long nr,
long nc
);
/*!
requires
- nr > 0
- nc > 0
- ptr == a pointer to at least nr*nc T objects
ensures
- returns a matrix M such that:
- M.nr() == nr
- m.nc() == nc
- for all valid r and c:
M(r,c) == ptr[r*nc + c]
(i.e. the pointer is interpreted as a matrix laid out in memory
in row major order)
- Note that the returned matrix doesn't take "ownership" of
the pointer and thus will not delete or free it.
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
const matrix_exp pointer_to_column_vector (
const T* ptr,
long nr
);
/*!
requires
- nr > 0
- ptr == a pointer to at least nr T objects
ensures
- returns a matrix M such that:
- M.nr() == nr
- m.nc() == 1
- for all valid i:
M(i) == ptr[i]
- Note that the returned matrix doesn't take "ownership" of
the pointer and thus will not delete or free it.
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp reshape (
const matrix_exp& m,
long rows,
long cols
);
/*!
requires
- m.size() == rows*cols
- rows > 0
- cols > 0
ensures
- returns a matrix M such that:
- M.nr() == rows
- M.nc() == cols
- M.size() == m.size()
- for all valid r and c:
- let IDX = r*cols + c
- M(r,c) == m(IDX/m.nc(), IDX%m.nc())
- i.e. The matrix m is reshaped into a new matrix of rows by cols
dimension. Additionally, the elements of m are laid into M in row major
order.
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp reshape_to_column_vector (
const matrix_exp& m
);
/*!
ensures
- returns a matrix M such that:
- is_col_vector(M) == true
- M.size() == m.size()
- for all valid r and c:
- m(r,c) == M(r*m.nc() + c)
- i.e. The matrix m is reshaped into a column vector. Note that
the elements are pulled out in row major order.
!*/
// ----------------------------------------------------------------------------------------
template <
long R,
long C
>
const matrix_exp removerc (
const matrix_exp& m
);
/*!
requires
- m.nr() > R >= 0
- m.nc() > C >= 0
ensures
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc() - 1
- M == m with its R row and C column removed
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp removerc (
const matrix_exp& m,
long R,
long C
);
/*!
requires
- m.nr() > R >= 0
- m.nc() > C >= 0
ensures
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc() - 1
- M == m with its R row and C column removed
!*/
// ----------------------------------------------------------------------------------------
template <
long R
>
const matrix_exp remove_row (
const matrix_exp& m
);
/*!
requires
- m.nr() > R >= 0
ensures
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc()
- M == m with its R row removed
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp remove_row (
const matrix_exp& m,
long R
);
/*!
requires
- m.nr() > R >= 0
ensures
- returns a matrix M such that:
- M.nr() == m.nr() - 1
- M.nc() == m.nc()
- M == m with its R row removed
!*/
// ----------------------------------------------------------------------------------------
template <
long C
>
const matrix_exp remove_col (
const matrix_exp& m
);
/*!
requires
- m.nc() > C >= 0
ensures
- returns a matrix M such that:
- M.nr() == m.nr()
- M.nc() == m.nc() - 1
- M == m with its C column removed
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp remove_col (
const matrix_exp& m,
long C
);
/*!
requires
- m.nc() > C >= 0
ensures
- returns a matrix M such that:
- M.nr() == m.nr()
- M.nc() == m.nc() - 1
- M == m with its 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<target_type>(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<T,NR,NC,MM>& 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 allows you to easily force a matrix_exp to fully evaluate)
!*/
// ----------------------------------------------------------------------------------------
// if matrix_exp contains non-complex types (e.g. float, double)
bool equal (
const matrix_exp& a,
const matrix_exp& b,
const matrix_exp::type epsilon = 100*std::numeric_limits<matrix_exp::type>::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
!*/
// ----------------------------------------------------------------------------------------
// if matrix_exp contains std::complex types
bool equal (
const matrix_exp& a,
const matrix_exp& b,
const matrix_exp::type::value_type epsilon = 100*std::numeric_limits<matrix_exp::type::value_type>::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(real(a(r,c)-b(r,c))) > epsilon
or abs(imag(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 (one or both
can also be of type std::complex so long as the underlying type
in them is the same)
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 join_rows (
const matrix_exp& a,
const matrix_exp& b
);
/*!
requires
- a.nr() == b.nr()
- a and b both contain the same type of element
ensures
- This function joins two matrices together by concatenating their rows.
- returns a matrix R such that:
- R::type == the same type that was in a and b.
- R.nr() == a.nr() == b.nr()
- R.nc() == a.nc() + b.nc()
- for all valid r and c:
- if (c < a.nc()) then
- R(r,c) == a(r,c)
- else
- R(r,c) == b(r, c-a.nc())
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp join_cols (
const matrix_exp& a,
const matrix_exp& b
);
/*!
requires
- a.nc() == b.nc()
- a and b both contain the same type of element
ensures
- This function joins two matrices together by concatenating their columns.
- returns a matrix R such that:
- R::type == the same type that was in a and b.
- R.nr() == a.nr() + b.nr()
- R.nc() == a.nc() == b.nc()
- for all valid r and c:
- if (r < a.nr()) then
- R(r,c) == a(r,c)
- else
- R(r,c) == b(r-a.nr(), c)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp tensor_product (
const matrix_exp& a,
const matrix_exp& b
);
/*!
requires
- 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.nr() == a.nr() * b.nr()
- R.nc() == a.nc() * b.nc()
- for all valid r and c:
R(r,c) == a(r/b.nr(), c/b.nc()) * b(r%b.nr(), c%b.nc())
- I.e. R is the tensor product of matrix a with matrix b
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp cartesian_product (
const matrix_exp& A,
const matrix_exp& B
);
/*!
requires
- A and B both contain the same type of element
ensures
- Think of A and B as sets of column vectors. Then this function
returns a matrix that contains a set of column vectors that is
the Cartesian product of the sets A and B. That is, the resulting
matrix contains every possible combination of vectors from both A and
B.
- returns a matrix R such that:
- R::type == the same type that was in A and B.
- R.nr() == A.nr() + B.nr()
- R.nc() == A.nc() * B.nc()
- Each column of R is the concatenation of a column vector
from A with a column vector from B.
- for all valid r and c:
- if (r < A.nr()) then
- R(r,c) == A(r, c/B.nc())
- else
- R(r,c) == B(r-A.nr(), c%B.nc())
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp scale_columns (
const matrix_exp& m,
const matrix_exp& v
);
/*!
requires
- is_vector(v) == true
- v.size() == 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.
- Note that this function is identical to the expression m*diagm(v).
That is, the * operator is overloaded for this case and will invoke
scale_columns() automatically as appropriate.
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp scale_rows (
const matrix_exp& m,
const matrix_exp& v
);
/*!
requires
- is_vector(v) == true
- v.size() == m.nr()
- 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(r)
- i.e. R is the result of multiplying each of m's rows by
the corresponding scalar in v.
- Note that this function is identical to the expression diagm(v)*m.
That is, the * operator is overloaded for this case and will invoke
scale_rows() automatically as appropriate.
!*/
// ----------------------------------------------------------------------------------------
template <typename T>
void sort_columns (
matrix<T>& m,
matrix<T>& v
);
/*!
requires
- is_col_vector(v) == true
- v.size() == m.nc()
- m and v both contain the same type of element
ensures
- the dimensions for m and v are not changed
- sorts the columns of m according to the values in v.
i.e.
- #v == the contents of v but in sorted order according to
operator<. So smaller elements come first.
- Let #v(new(i)) == v(i) (i.e. new(i) is the index element i moved to)
- colm(#m,new(i)) == colm(m,i)
!*/
// ----------------------------------------------------------------------------------------
template <typename T>
void rsort_columns (
matrix<T>& m,
matrix<T>& v
);
/*!
requires
- is_col_vector(v) == true
- v.size() == m.nc()
- m and v both contain the same type of element
ensures
- the dimensions for m and v are not changed
- sorts the columns of m according to the values in v.
i.e.
- #v == the contents of v but in sorted order according to
operator>. So larger elements come first.
- Let #v(new(i)) == v(i) (i.e. new(i) is the index element i moved to)
- colm(#m,new(i)) == colm(m,i)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp::type length_squared (
const matrix_exp& m
);
/*!
requires
- is_vector(m) == true
ensures
- returns sum(squared(m))
(i.e. returns the square of the length of the vector m)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp::type length (
const matrix_exp& m
);
/*!
requires
- is_vector(m) == true
ensures
- returns sqrt(sum(squared(m)))
(i.e. returns the length of the vector m)
!*/
// ----------------------------------------------------------------------------------------
bool is_row_vector (
const matrix_exp& m
);
/*!
ensures
- if (m.nr() == 1) then
- return true
- else
- returns false
!*/
bool is_col_vector (
const matrix_exp& m
);
/*!
ensures
- if (m.nc() == 1) then
- return true
- else
- returns false
!*/
bool is_vector (
const matrix_exp& m
);
/*!
ensures
- if (is_row_vector(m) || is_col_vector(m)) then
- return true
- else
- returns false
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// Thresholding relational operators
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator< (
const matrix_exp& m,
const S& s
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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) < s) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator< (
const S& s,
const matrix_exp& m
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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 (s < m(r,c)) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator<= (
const matrix_exp& m,
const S& s
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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) <= s) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator<= (
const S& s,
const matrix_exp& m
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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 (s <= m(r,c)) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator> (
const matrix_exp& m,
const S& s
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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) > s) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator> (
const S& s,
const matrix_exp& m
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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 (s > m(r,c)) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator>= (
const matrix_exp& m,
const S& s
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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) >= s) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator>= (
const S& s,
const matrix_exp& m
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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 (s >= m(r,c)) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator== (
const matrix_exp& m,
const S& s
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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) == s) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator== (
const S& s,
const matrix_exp& m
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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 (s == m(r,c)) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator!= (
const matrix_exp& m,
const S& s
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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) != s) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
template <typename S>
const matrix_exp operator!= (
const S& s,
const matrix_exp& m
);
/*!
requires
- is_built_in_scalar_type<S>::value == true
- is_built_in_scalar_type<matrix_exp::type>::value == true
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 (s != m(r,c)) then
- R(r,c) == 1
- else
- R(r,c) == 0
- i.e. R is a binary matrix of all 1s or 0s.
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// Statistics
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
const matrix_exp::type min (
const matrix_exp& m
);
/*!
requires
- m.size() > 0
ensures
- returns the value of the smallest element of m
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp::type max (
const matrix_exp& m
);
/*!
requires
- m.size() > 0
ensures
- returns the value of the biggest element of m
!*/
// ----------------------------------------------------------------------------------------
void find_min_and_max (
const matrix_exp& m,
matrix_exp::type& min_val,
matrix_exp::type& max_val
);
/*!
requires
- m.size() > 0
ensures
- #min_val == min(m)
- #max_val == max(m)
- This function computes both the min and max in just one pass
over the elements of the matrix m.
!*/
// ----------------------------------------------------------------------------------------
long index_of_max (
const matrix_exp& m
);
/*!
requires
- is_vector(m) == true
- m.size() > 0
ensures
- returns the index of the largest element in m.
(i.e. m(index_of_max(m)) == max(m))
!*/
// ----------------------------------------------------------------------------------------
long index_of_min (
const matrix_exp& m
);
/*!
requires
- is_vector(m) == true
- m.size() > 0
ensures
- returns the index of the smallest element in m.
(i.e. m(index_of_min(m)) == min(m))
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp::type sum (
const matrix_exp& m
);
/*!
ensures
- returns the sum of all elements in m
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp sum_rows (
const matrix_exp& m
);
/*!
requires
- m.size() > 0
ensures
- returns a row matrix that contains the sum of all the rows in m.
- returns a matrix M such that
- M::type == the same type that was in m
- M.nr() == 1
- M.nc() == m.nc()
- for all valid i:
- M(i) == sum(colm(m,i))
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp sum_cols (
const matrix_exp& m
);
/*!
requires
- m.size() > 0
ensures
- returns a column matrix that contains the sum of all the columns in m.
- returns a matrix M such that
- M::type == the same type that was in m
- M.nr() == m.nr()
- M.nc() == 1
- for all valid i:
- M(i) == sum(rowm(m,i))
!*/
// ----------------------------------------------------------------------------------------
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
- is_col_vector(m) == true
- m.size() > 1
- for all valid i, j:
- is_col_vector(m(i)) == true
- m(i).size() > 0
- m(i).size() == m(j).size()
- 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.
!*/
// ----------------------------------------------------------------------------------------
template <typename rand_gen>
const matrix<double> randm(
long nr,
long nc,
rand_gen& rnd
);
/*!
requires
- nr >= 0
- nc >= 0
- rand_gen == an object that implements the rand/rand_float_abstract.h interface
ensures
- generates a random matrix using the given rnd random number generator
- returns a matrix M such that
- M::type == double
- M.nr() == nr
- M.nc() == nc
- for all valid i, j:
- M(i,j) == a random number such that 0 <= M(i,j) < 1
!*/
// ----------------------------------------------------------------------------------------
inline const matrix<double> randm(
long nr,
long nc
);
/*!
requires
- nr >= 0
- nc >= 0
ensures
- generates a random matrix using std::rand()
- returns a matrix M such that
- M::type == double
- M.nr() == nr
- M.nc() == nc
- for all valid i, j:
- M(i,j) == a random number such that 0 <= M(i,j) < 1
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// Pixel and Image Utilities
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename T,
typename P
>
const matrix_exp pixel_to_vector (
const P& pixel
);
/*!
requires
- pixel_traits<P> must be defined
ensures
- returns a matrix M such that:
- M::type == T
- M::NC == 1
- M::NR == pixel_traits<P>::num
- if (pixel_traits<P>::grayscale) then
- M(0) == pixel
- if (pixel_traits<P>::rgb) then
- M(0) == pixel.red
- M(1) == pixel.green
- M(2) == pixel.blue
- if (pixel_traits<P>::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
- vector::NR == pixel_traits<P>::num
- vector::NC == 1
(i.e. you have to use a statically dimensioned vector)
ensures
- if (pixel_traits<P>::grayscale) then
- pixel == M(0)
- if (pixel_traits<P>::rgb) then
- pixel.red == M(0)
- pixel.green == M(1)
- pixel.blue == M(2)
- if (pixel_traits<P>::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)
!*/
// ----------------------------------------------------------------------------------------
const matrix_exp clamp (
const matrix_exp& m,
const matrix_exp::type& lower,
const matrix_exp::type& upper
);
/*!
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_