571 lines
19 KiB
C++
571 lines
19 KiB
C++
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#undef DLIB_MATRIx_SUBEXP_ABSTRACT_
|
|
#ifdef DLIB_MATRIx_SUBEXP_ABSTRACT_
|
|
|
|
#include "matrix_abstract.h"
|
|
#include "../geometry/rectangle.h"
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <long start, long inc, long end>
|
|
const matrix_exp range (
|
|
);
|
|
/*!
|
|
requires
|
|
- inc > 0
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R::type == long
|
|
- R.nr() == 1
|
|
- R.nc() == abs(end - start)/inc + 1
|
|
- if (start <= end) then
|
|
- R(i) == start + i*inc
|
|
- else
|
|
- R(i) == start - i*inc
|
|
!*/
|
|
|
|
template <long start, long end>
|
|
const matrix_exp range (
|
|
) { return range<start,1,end>(); }
|
|
|
|
const matrix_exp range (
|
|
long start,
|
|
long inc,
|
|
long end
|
|
);
|
|
/*!
|
|
requires
|
|
- inc > 0
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R::type == long
|
|
- R.nr() == 1
|
|
- R.nc() == abs(end - start)/inc + 1
|
|
- if (start <= end) then
|
|
- R(i) == start + i*inc
|
|
- else
|
|
- R(i) == start - i*inc
|
|
!*/
|
|
|
|
const matrix_exp range (
|
|
long start,
|
|
long end
|
|
) { return range(start,1,end); }
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp subm (
|
|
const matrix_exp& m,
|
|
const matrix_exp& rows,
|
|
const matrix_exp& cols,
|
|
);
|
|
/*!
|
|
requires
|
|
- rows and cols contain integral elements (e.g. int, long)
|
|
- 0 <= min(rows) && max(rows) < m.nr()
|
|
- 0 <= min(cols) && max(cols) < m.nc()
|
|
- rows.nr() == 1 || rows.nc() == 1
|
|
- cols.nr() == 1 || cols.nc() == 1
|
|
(i.e. rows and cols must be vectors)
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R::type == the same type that was in m
|
|
- R.nr() == rows.size()
|
|
- R.nc() == cols.size()
|
|
- for all valid r and c:
|
|
R(r,c) == m(rows(r),cols(c))
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp subm (
|
|
const matrix_exp& m,
|
|
long row,
|
|
long col,
|
|
long nr,
|
|
long nc
|
|
);
|
|
/*!
|
|
requires
|
|
- row >= 0
|
|
- col >= 0
|
|
- nr >= 0
|
|
- nc >= 0
|
|
- row + nr <= m.nr()
|
|
- 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 subm_clipped (
|
|
const matrix_exp& m,
|
|
long row,
|
|
long col,
|
|
long nr,
|
|
long nc
|
|
);
|
|
/*!
|
|
ensures
|
|
- This function is just like subm() except that it will automatically clip the
|
|
indicated sub matrix window so that it does not extend outside m.
|
|
In particular:
|
|
- Let box = rectangle(col,row,col+nc-1,row+nr-1)
|
|
(i.e. the box that contains the indicated sub matrix)
|
|
- Let box_clipped = box.intersect(get_rect(m))
|
|
- Then this function returns a matrix R such that:
|
|
- R.nr() == box_clipped.height()
|
|
- R.nc() == box_clipped.width()
|
|
- for all valid r and c:
|
|
R(r, c) == m(r+box_clipped.top(),c+box_clipped.left())
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp subm_clipped (
|
|
const matrix_exp& m,
|
|
const rectangle& rect
|
|
);
|
|
/*!
|
|
ensures
|
|
- Let box_clipped == rect.intersect(get_rect(m))
|
|
- returns a matrix R such that:
|
|
- R.nr() == box_clipped.height()
|
|
- R.nc() == box_clipped.width()
|
|
- for all valid r and c:
|
|
R(r, c) == m(r+box_clipped.top(), c+box_clipped.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)
|
|
!*/
|
|
|
|
template <typename EXP>
|
|
struct rowm_exp
|
|
{
|
|
/*!
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This struct allows you to determine the type of matrix expression
|
|
object returned from the rowm(m,row) function. An example makes its
|
|
use clear:
|
|
|
|
template <typename EXP>
|
|
void do_something( const matrix_exp<EXP>& mat)
|
|
{
|
|
// r is a matrix expression that aliases mat.
|
|
typename rowm_exp<EXP>::type r = rowm(mat,0);
|
|
|
|
// Print the first row of mat. So we see that by using
|
|
// rowm_exp we can save the object returned by rowm() in
|
|
// a local variable.
|
|
cout << r << endl;
|
|
|
|
// Note that you can only save the return value of rowm() to
|
|
// a local variable if the argument to rowm() has a lifetime
|
|
// beyond the rowm() expression. The example shown above is
|
|
// OK but the following would result in undefined behavior:
|
|
typename rowm_exp<EXP>::type bad = rowm(mat + mat,0);
|
|
}
|
|
!*/
|
|
typedef type_of_expression_returned_by_rowm type;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp rowm (
|
|
const matrix_exp& m,
|
|
long row,
|
|
long length
|
|
);
|
|
/*!
|
|
requires
|
|
- 0 <= row < m.nr()
|
|
- 0 <= length <= m.nc()
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R.nr() == 1
|
|
- R.nc() == length
|
|
- for all valid i:
|
|
R(i) == m(row,i)
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp rowm (
|
|
const matrix_exp& m,
|
|
const matrix_exp& rows
|
|
);
|
|
/*!
|
|
requires
|
|
- rows contains integral elements (e.g. int, long)
|
|
- 0 <= min(rows) && max(rows) < m.nr()
|
|
- rows.nr() == 1 || rows.nc() == 1 || rows.size() == 0
|
|
(i.e. rows must be a vector, or just empty)
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R::type == the same type that was in m
|
|
- R.nr() == rows.size()
|
|
- R.nc() == m.nc()
|
|
- for all valid r and c:
|
|
R(r,c) == m(rows(r),c)
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp colm (
|
|
const matrix_exp& m,
|
|
long col
|
|
);
|
|
/*!
|
|
requires
|
|
- 0 <= col < m.nc()
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R.nr() == m.nr()
|
|
- R.nc() == 1
|
|
- for all valid i:
|
|
R(i) == m(i,col)
|
|
!*/
|
|
|
|
template <typename EXP>
|
|
struct colm_exp
|
|
{
|
|
/*!
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This struct allows you to determine the type of matrix expression
|
|
object returned from the colm(m,col) function. An example makes its
|
|
use clear:
|
|
|
|
template <typename EXP>
|
|
void do_something( const matrix_exp<EXP>& mat)
|
|
{
|
|
// c is a matrix expression that aliases mat.
|
|
typename colm_exp<EXP>::type c = colm(mat,0);
|
|
|
|
// Print the first column of mat. So we see that by using
|
|
// colm_exp we can save the object returned by colm() in
|
|
// a local variable.
|
|
cout << c << endl;
|
|
|
|
// Note that you can only save the return value of colm() to
|
|
// a local variable if the argument to colm() has a lifetime
|
|
// beyond the colm() expression. The example shown above is
|
|
// OK but the following would result in undefined behavior:
|
|
typename colm_exp<EXP>::type bad = colm(mat + mat,0);
|
|
}
|
|
!*/
|
|
typedef type_of_expression_returned_by_colm type;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp colm (
|
|
const matrix_exp& m,
|
|
long col,
|
|
long length
|
|
);
|
|
/*!
|
|
requires
|
|
- 0 <= col < m.nc()
|
|
- 0 <= length <= m.nr()
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R.nr() == length
|
|
- R.nc() == 1
|
|
- for all valid i:
|
|
R(i) == m(i,col)
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
const matrix_exp colm (
|
|
const matrix_exp& m,
|
|
const matrix_exp& cols
|
|
);
|
|
/*!
|
|
requires
|
|
- cols contains integral elements (e.g. int, long)
|
|
- 0 <= min(cols) && max(cols) < m.nc()
|
|
- cols.nr() == 1 || cols.nc() == 1 || cols.size() == 0
|
|
(i.e. cols must be a vector, or just empty)
|
|
ensures
|
|
- returns a matrix R such that:
|
|
- R::type == the same type that was in m
|
|
- R.nr() == m.nr()
|
|
- R.nc() == cols.size()
|
|
- for all valid r and c:
|
|
R(r,c) == m(r,cols(c))
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
template <typename T>
|
|
assignable_matrix_expression set_ptrm (
|
|
T* ptr,
|
|
long nr,
|
|
long nc = 1
|
|
);
|
|
/*!
|
|
requires
|
|
- ptr == a pointer to nr*nc elements of type T
|
|
- nr >= 0
|
|
- nc >= 0
|
|
ensures
|
|
- statements of the following form:
|
|
- set_ptrm(ptr,nr,nc) = some_matrix;
|
|
result in it being the case that:
|
|
- mat(ptr,nr,nc) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_ptrm(ptr,nr,nc) = scalar_value;
|
|
result in it being the case that:
|
|
- mat(ptr,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
assignable_matrix_expression set_subm (
|
|
matrix& m,
|
|
long row,
|
|
long col,
|
|
long nr,
|
|
long nc
|
|
);
|
|
/*!
|
|
requires
|
|
- row >= 0
|
|
- col >= 0
|
|
- nr >= 0
|
|
- nc >= 0
|
|
- row + nr <= m.nr()
|
|
- col + nc <= m.nc()
|
|
ensures
|
|
- statements of the following form:
|
|
- set_subm(m,row,col,nr,nc) = some_matrix;
|
|
result in it being the case that:
|
|
- subm(m,row,col,nr,nc) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_subm(m,row,col,nr,nc) = scalar_value;
|
|
result in it being the case that:
|
|
- subm(m,row,col,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
assignable_matrix_expression set_subm (
|
|
matrix& m,
|
|
const rectangle& rect
|
|
);
|
|
/*!
|
|
requires
|
|
- get_rect(m).contains(rect) == true
|
|
(i.e. rect is a region inside the matrix m)
|
|
ensures
|
|
- statements of the following form:
|
|
- set_subm(m,rect) = some_matrix;
|
|
result in it being the case that:
|
|
- subm(m,rect) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_subm(m,rect) = scalar_value;
|
|
result in it being the case that:
|
|
- subm(m,rect) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
assignable_matrix_expression set_subm (
|
|
matrix& m,
|
|
const matrix_exp& rows,
|
|
const matrix_exp& cols
|
|
);
|
|
/*!
|
|
requires
|
|
- rows and cols contain integral elements (e.g. int, long)
|
|
- 0 <= min(rows) && max(rows) < m.nr()
|
|
- 0 <= min(cols) && max(cols) < m.nc()
|
|
- rows.nr() == 1 || rows.nc() == 1
|
|
- cols.nr() == 1 || cols.nc() == 1
|
|
(i.e. rows and cols must be vectors)
|
|
ensures
|
|
- statements of the following form:
|
|
- set_subm(m,rows,cols) = some_matrix;
|
|
result in it being the case that:
|
|
- subm(m,rows,cols) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_subm(m,rows,cols) = scalar_value;
|
|
result in it being the case that:
|
|
- subm(m,rows,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
assignable_matrix_expression set_rowm (
|
|
matrix& m,
|
|
long row
|
|
);
|
|
/*!
|
|
requires
|
|
- 0 <= row < m.nr()
|
|
ensures
|
|
- statements of the following form:
|
|
- set_rowm(m,row) = some_matrix;
|
|
result in it being the case that:
|
|
- rowm(m,row) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_rowm(m,row) = scalar_value;
|
|
result in it being the case that:
|
|
- rowm(m,row) == uniform_matrix<matrix::type>(1,nc,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
assignable_matrix_expression set_rowm (
|
|
matrix& m,
|
|
const matrix_exp& rows
|
|
);
|
|
/*!
|
|
requires
|
|
- rows contains integral elements (e.g. int, long)
|
|
- 0 <= min(rows) && max(rows) < m.nr()
|
|
- rows.nr() == 1 || rows.nc() == 1
|
|
(i.e. rows must be a vector)
|
|
ensures
|
|
- statements of the following form:
|
|
- set_rowm(m,rows) = some_matrix;
|
|
result in it being the case that:
|
|
- rowm(m,rows) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_rowm(m,rows) = scalar_value;
|
|
result in it being the case that:
|
|
- rowm(m,rows) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
assignable_matrix_expression set_colm (
|
|
matrix& m,
|
|
long col
|
|
);
|
|
/*!
|
|
requires
|
|
- 0 <= col < m.nr()
|
|
ensures
|
|
- statements of the following form:
|
|
- set_colm(m,col) = some_matrix;
|
|
result in it being the case that:
|
|
- colm(m,col) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_colm(m,col) = scalar_value;
|
|
result in it being the case that:
|
|
- colm(m,col) == uniform_matrix<matrix::type>(nr,1,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
assignable_matrix_expression set_colm (
|
|
matrix& m,
|
|
const matrix_exp& cols
|
|
);
|
|
/*!
|
|
requires
|
|
- cols contains integral elements (e.g. int, long)
|
|
- 0 <= min(cols) && max(cols) < m.nc()
|
|
- cols.nr() == 1 || cols.nc() == 1
|
|
(i.e. cols must be a vector)
|
|
ensures
|
|
- statements of the following form:
|
|
- set_colm(m,cols) = some_matrix;
|
|
result in it being the case that:
|
|
- colm(m,cols) == some_matrix.
|
|
|
|
- statements of the following form:
|
|
- set_colm(m,cols) = scalar_value;
|
|
result in it being the case that:
|
|
- colm(m,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
|
|
|
|
- In addition to the normal assignment statements using the = symbol, you may
|
|
also use the usual += and -= versions of the assignment operator. In these
|
|
cases, they have their usual effect.
|
|
!*/
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
#endif // DLIB_MATRIx_SUBEXP_ABSTRACT_
|
|
|