summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/matrix/matrix_abstract.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/matrix/matrix_abstract.h')
-rw-r--r--ml/dlib/dlib/matrix/matrix_abstract.h857
1 files changed, 857 insertions, 0 deletions
diff --git a/ml/dlib/dlib/matrix/matrix_abstract.h b/ml/dlib/dlib/matrix/matrix_abstract.h
new file mode 100644
index 000000000..0d05ce981
--- /dev/null
+++ b/ml/dlib/dlib/matrix/matrix_abstract.h
@@ -0,0 +1,857 @@
+// Copyright (C) 2006 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#undef DLIB_MATRIx_ABSTRACT_
+#ifdef DLIB_MATRIx_ABSTRACT_
+
+#include "matrix_exp_abstract.h"
+#include "../serialize.h"
+#include "../algs.h"
+#include "matrix_data_layout_abstract.h"
+
+namespace dlib
+{
+
+// ----------------------------------------------------------------------------------------
+
+ /*
+ Note that these operator prototypes are not correct C++ (the real versions, which
+ you can see in the implementation are really complex and so probably would
+ distract/confuse people if shown here). Think of this as just a list of the
+ operators available to you and what they do.
+ */
+
+ const matrix_exp operator* (
+ const matrix_exp& m1,
+ const matrix_exp& m2
+ );
+ /*!
+ requires
+ - m1.nc() == m2.nr()
+ - m1.size() > 0 && m2.size() > 0
+ (you can't multiply any sort of empty matrices together)
+ - m1 and m2 both contain elements of the same type
+ ensures
+ - returns the result of doing the matrix multiplication m1*m2. The resulting
+ matrix will have m1.nr() rows and m2.nc() columns.
+ !*/
+
+ const matrix_exp operator+ (
+ const matrix_exp& m1,
+ const matrix_exp& m2
+ );
+ /*!
+ requires
+ - m1.nr() == m2.nr()
+ - m1.nc() == m2.nc()
+ - m1 and m2 both contain elements of the same type
+ ensures
+ - returns a matrix R such that for all valid r and c:
+ R(r,c) == m1(r,c) + m2(r,c)
+ (i.e. returns the result of doing a pairwise addition of the matrices m1 and m2.)
+ The resulting matrix will have the same dimensions as the originals.
+ !*/
+
+ const matrix_exp operator- (
+ const matrix_exp& m1,
+ const matrix_exp& m2
+ );
+ /*!
+ requires
+ - m1.nr() == m2.nr()
+ - m1.nc() == m2.nc()
+ - m1 and m2 both contain elements of the same type
+ ensures
+ - returns a matrix R such that for all valid r and c:
+ R(r,c) == m1(r,c) - m2(r,c)
+ (i.e. returns the result of doing a pairwise subtraction of the matrices m1 and m2.)
+ The resulting matrix will have the same dimensions as the originals.
+ !*/
+
+ template <typename T>
+ const matrix_exp operator* (
+ const matrix_exp& m,
+ const T& value
+ );
+ /*!
+ ensures
+ - returns the result of multiplying all the elements of matrix m by the given
+ scalar value. The resulting matrix will have the same dimensions as m.
+ !*/
+
+ template <typename T>
+ const matrix_exp operator* (
+ const T& value,
+ const matrix_exp& m
+ );
+ /*!
+ ensures
+ - returns the result of multiplying all the elements of matrix m by the given
+ scalar value. The resulting matrix will have the same dimensions as m.
+ !*/
+
+ const matrix_exp operator- (
+ const matrix_exp& m
+ );
+ /*!
+ ensures
+ - returns -1*m
+ !*/
+
+ template <typename T>
+ const matrix_exp operator/ (
+ const matrix_exp& m,
+ const T& value
+ );
+ /*!
+ ensures
+ - returns the result of dividing all the elements of matrix m by the given
+ scalar value. The resulting matrix will have the same dimensions as m.
+ !*/
+
+ template <typename T>
+ const matrix_exp operator/ (
+ const T& value,
+ const matrix_exp& m
+ );
+ /*!
+ ensures
+ - returns the result of dividing the given scalar value by all the elements
+ of matrix m. The resulting matrix will have the same dimensions as m.
+ !*/
+
+ template <typename T>
+ const matrix_exp operator+ (
+ const matrix_exp& m,
+ const T& value
+ );
+ /*!
+ ensures
+ - returns the result of adding value to all the elements of matrix m.
+ The resulting matrix will have the same dimensions as m.
+ !*/
+
+ template <typename T>
+ const matrix_exp operator+ (
+ const T& value,
+ const matrix_exp& m
+ );
+ /*!
+ ensures
+ - returns the result of adding value to all the elements of matrix m.
+ The resulting matrix will have the same dimensions as m.
+ !*/
+
+ template <typename T>
+ const matrix_exp operator- (
+ const matrix_exp& m,
+ const T& value
+ );
+ /*!
+ ensures
+ - returns the result of subtracting value from all the elements of matrix m.
+ The resulting matrix will have the same dimensions as m.
+ !*/
+
+ template <typename T>
+ const matrix_exp operator- (
+ const T& value,
+ const matrix_exp& m
+ );
+ /*!
+ ensures
+ - Returns a matrix M such that:
+ - M has the same dimensions as m
+ - M contains the same type of element as m
+ - for all valid r and c:
+ - M(r,c) == value - m(r,c)
+ !*/
+
+ bool operator== (
+ const matrix_exp& m1,
+ const matrix_exp& m2
+ );
+ /*!
+ ensures
+ - if (m1.nr() == m2.nr() && m1.nc() == m2.nc() &&
+ for all valid r and c: m1(r,c) == m2(r,c) ) then
+ - returns true
+ - else
+ - returns false
+ !*/
+
+ bool operator!= (
+ const matrix_exp& m1,
+ const matrix_exp& m2
+ );
+ /*!
+ ensures
+ - returns !(m1 == m2)
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T,
+ long num_rows = 0,
+ long num_cols = 0,
+ typename mem_manager = default_memory_manager,
+ typename layout = row_major_layout
+ >
+ class matrix : public matrix_exp<matrix<T,num_rows,num_cols,mem_manager,layout> >
+ {
+ /*!
+ REQUIREMENTS ON num_rows and num_cols
+ both must be bigger than or equal to 0
+
+ REQUIREMENTS ON mem_manager
+ must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
+ must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
+ must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
+ mem_manager::type can be set to anything.
+
+ REQUIREMENTS ON layout
+ Must be either row_major_layout or column_major_layout
+
+ INITIAL VALUE
+ - if (num_rows > 0) then
+ - nr() == num_rows
+ - else
+ - nr() == 0
+
+ - if (num_cols > 0) then
+ - nc() == num_cols
+ - else
+ - nc() == 0
+
+ WHAT THIS OBJECT REPRESENTS
+ This object represents a matrix of nr() rows and nc() columns. This object
+ is also a matrix_exp. Thus it can be used in all of the above
+ global operators.
+
+ The number of rows and columns of this object are determined by the template
+ arguments num_rows and num_cols. If num_rows or num_cols are 0 then
+ the matrix starts out empty (i.e. nr() == 0 and nc() == 0) and you may change
+ its size via the set_size() member function.
+
+ Setting num_rows or num_cols to something other than 0 causes that dimension
+ to have a fixed size. Setting a fixed size at compile time is useful because
+ any errors related to operating on matrices with incompatible dimensions will
+ be detected at compile time. It also allows the compiler to perform loop
+ unrolling which can result in substantially faster code.
+
+ Also note that the elements of this matrix are laid out in memory by the layout
+ object supplied as a template argument to this class. The row_major_layout
+ sets elements down contiguously in memory and in row major order. Additionally,
+ all memory allocations are performed using the memory manager object supplied as
+ a template argument to this class.
+ !*/
+
+ public:
+ typedef T type;
+ typedef mem_manager mem_manager_type;
+ typedef layout layout_type;
+ const static long NR = num_rows;
+ const static long NC = num_cols;
+ const static long cost = 1;
+ typedef T* iterator;
+ typedef const T* const_iterator;
+
+ matrix (
+ );
+ /*!
+ ensures
+ - #*this is properly initialized
+ - #aliases(*this) == true
+ - #ref().aliases(*this) == true
+ !*/
+
+ explicit matrix (
+ long length
+ );
+ /*!
+ requires
+ - NR == 1 || NC == 1 (i.e. this must be a column or row vector)
+ - length >= 0
+ - if (NR == 1 && NC > 0) then
+ - length == NC
+ - if (NC == 1 && NR > 0) then
+ - length == NR
+ ensures
+ - #*this is properly initialized
+ - #aliases(*this) == true
+ - #ref().aliases(*this) == true
+ - if (NR == 1) then
+ - #nr() == 1
+ - #nc() == length
+ - else
+ - #nr() == length
+ - #nc() == 1
+ !*/
+
+ matrix (
+ long rows,
+ long cols
+ );
+ /*!
+ requires
+ - rows == NR || NR == 0
+ - cols == NC || NC == 0
+ - rows >= 0 && cols >= 0
+ ensures
+ - #*this is properly initialized
+ - #aliases(*this) == true
+ - #ref().aliases(*this) == true
+ - #nr() == rows
+ - #nc() == cols
+ !*/
+
+ template <typename EXP>
+ matrix (
+ const matrix_exp<EXP>& m
+ );
+ /*!
+ requires
+ - matrix_exp<EXP>::type == T
+ (i.e. m contains the same type as *this does)
+ - if (NR != 0) then NR == m.nr()
+ - if (NC != 0) then NC == m.nc()
+ ensures
+ - #*this == m
+ - #aliases(*this) == true
+ - #ref().aliases(*this) == true
+ !*/
+
+ template <typename U, size_t len>
+ explicit matrix (
+ U (&array)[len]
+ );
+ /*!
+ requires
+ - NR != 0 && NC != 0 (i.e. you can only use this constructor on statically sized matrices)
+ - len == nr()*nc() (i.e. the array you give here must be the right size)
+ ensures
+ - for all valid r and c:
+ #(*this)(r,c) == array[r*nc() + c]
+ (i.e. initializes this matrix with the contents of the given array)
+ - #aliases(*this) == true
+ - #ref().aliases(*this) == true
+ !*/
+
+ matrix(
+ const std::initializer_list<T>& l
+ );
+ /*!
+ requires
+ - This matrix is capable of having a size() == l.size(). Therefore, if
+ NR*NC != 0 then l.size() must equal NR*NC. Alternatively, if NR or NC is
+ != 0 then l.size() must be a multiple of the non-zero NR or NC.
+ ensures
+ - #size() == l.size()
+ - The contents of l are enumerated and read into the matrix in row major order.
+ - if (NR != 0) then
+ - #nr() == NR
+ - #nc() == l.size()/NR
+ - if (NC != 0) then
+ - #nr() == l.size()/NC
+ - #nc() == NC
+ - if (NR*NC==0) then
+ - #nr() == l.size()
+ - #nc() == 1
+ - #aliases(*this) == true
+ - #ref().aliases(*this) == true
+ !*/
+
+ T& operator() (
+ long r,
+ long c
+ );
+ /*!
+ requires
+ - 0 <= r < nr()
+ - 0 <= c < nc()
+ ensures
+ - returns a reference to the value at the given row and column in
+ this matrix.
+ !*/
+
+ const T& operator() (
+ long r,
+ long c
+ ) const;
+ /*!
+ requires
+ - 0 <= r < nr()
+ - 0 <= c < nc()
+ ensures
+ - returns a const reference to the value at the given row and column in
+ this matrix.
+ !*/
+
+ T& operator() (
+ long i
+ );
+ /*!
+ requires
+ - nc() == 1 || nr() == 1 (i.e. this must be a column or row vector)
+ - 0 <= i < size()
+ ensures
+ - if (nc() == 1) then
+ - returns a reference to (*this)(i,0)
+ - else
+ - returns a reference to (*this)(0,i)
+ !*/
+
+ const T& operator() (
+ long i
+ ) const;
+ /*!
+ requires
+ - nc() == 1 || nr() == 1 (i.e. this must be a column or row vector)
+ - 0 <= i < size()
+ ensures
+ - if (nc() == 1) then
+ - returns a reference to (*this)(i,0)
+ - else
+ - returns a reference to (*this)(0,i)
+ !*/
+
+ operator const type (
+ ) const;
+ /*!
+ requires
+ - nr() == 1
+ - nc() == 1
+ ensures
+ - returns (*this)(0,0)
+ !*/
+
+ long nr(
+ ) const;
+ /*!
+ ensures
+ - returns the number of rows in this matrix
+ !*/
+
+ long nc(
+ ) const;
+ /*!
+ ensures
+ - returns the number of columns in this matrix
+ !*/
+
+ long size (
+ ) const;
+ /*!
+ ensures
+ - returns nr()*nc()
+ !*/
+
+ void set_size (
+ long rows,
+ long cols
+ );
+ /*!
+ requires
+ - rows == NR || NR == 0
+ - cols == NC || NC == 0
+ - rows >= 0 && cols >= 0
+ ensures
+ - #nr() == rows
+ - #nc() == cols
+ !*/
+
+ void set_size (
+ long length
+ );
+ /*!
+ requires
+ - NR == 1 || NC == 1 (i.e. this must be a column or row vector)
+ - length >= 0
+ - if (NR == 1 && NC > 0) then
+ - length == NC
+ - if (NC == 1 && NR > 0) then
+ - length == NR
+ ensures
+ - if (NR == 1) then
+ - #nr() == 1
+ - #nc() == length
+ - else
+ - #nr() == length
+ - #nc() == 1
+ !*/
+
+ template <typename U, size_t len>
+ matrix& operator= (
+ U (&array)[len]
+ );
+ /*!
+ requires
+ - len == nr()*nc() (i.e. the array you give here must be the right size)
+ ensures
+ - for all valid r and c:
+ #(*this)(r,c) == array[r*nc() + c]
+ (i.e. loads this matrix with the contents of the given array)
+ - returns *this
+ !*/
+
+ matrix& operator=(
+ const std::initializer_list<T>& l
+ );
+ /*!
+ requires
+ - This matrix is capable of having a size() == l.size(). Therefore, if
+ NR*NC != 0 then l.size() must equal NR*NC. Alternatively, if NR or NC is
+ != 0 then l.size() must be a multiple of the non-zero NR or NC.
+ ensures
+ - Assigns the contents of l to *this by performing: matrix(l).swap(*this)
+ - returns *this
+ !*/
+
+ template <typename EXP>
+ matrix& operator= (
+ const matrix_exp<EXP>& m
+ );
+ /*!
+ requires
+ - matrix_exp<EXP>::type == T
+ (i.e. m contains the same type as *this does)
+ - if (NR != 0) then NR == m.nr()
+ - if (NC != 0) then NC == m.nc()
+ ensures
+ - copies the given matrix expression m to *this
+ - returns *this
+ !*/
+
+ template <typename EXP>
+ matrix& operator += (
+ const matrix_exp<EXP>& m
+ );
+ /*!
+ requires
+ - matrix_exp<EXP>::type == T
+ - One of the following is true:
+ - nr() == m.nr() && nc() == m.nc()
+ - size() == 0
+ (i.e. this matrix must have matching dimensions or it must be empty)
+ ensures
+ - if (nr() == m.nr() && nc() == m.nc()) then
+ - #(*this) == *this + m
+ - else
+ - #(*this) == m
+ (i.e. if the dimensions don't match then this function performs a
+ normal assignment)
+ - returns *this
+ !*/
+
+ template <typename EXP>
+ matrix& operator -= (
+ const matrix_exp<EXP>& m
+ );
+ /*!
+ requires
+ - matrix_exp<EXP>::type == T
+ - One of the following is true:
+ - nr() == m.nr() && nc() == m.nc()
+ - size() == 0
+ (i.e. this matrix must have matching dimensions or it must be empty)
+ ensures
+ - if (nr() == m.nr() && nc() == m.nc()) then
+ - #(*this) == *this - m
+ - else
+ - #(*this) == -m
+ - returns *this
+ !*/
+
+ template <typename EXP>
+ matrix& operator *= (
+ const matrix_exp<EXP>& m
+ );
+ /*!
+ requires
+ - matrix_exp<EXP>::type == T
+ (i.e. m must contain the same type of element as *this)
+ - nc() == m.nr()
+ - size() > 0 && m.size() > 0
+ (you can't multiply any sort of empty matrices together)
+ ensures
+ - #(*this) == *this * m
+ - returns *this
+ !*/
+
+ matrix& operator *= (
+ const T& a
+ );
+ /*!
+ ensures
+ - #(*this) == *this * a
+ - returns *this
+ !*/
+
+ matrix& operator /= (
+ const T& a
+ );
+ /*!
+ ensures
+ - #(*this) == *this / a
+ - returns *this
+ !*/
+
+ matrix& operator += (
+ const T& a
+ );
+ /*!
+ ensures
+ - #(*this) == *this + a
+ - returns *this
+ !*/
+
+ matrix& operator -= (
+ const T& a
+ );
+ /*!
+ ensures
+ - #(*this) == *this - a
+ - returns *this
+ !*/
+
+ const literal_assign_helper operator = (
+ const T& val
+ );
+ /*!
+ This function is somewhat different than all the others defined in this file.
+ The purpose of this function is to enable you to easily initialize a matrix object.
+ For example:
+ matrix<double> m(2,3);
+ m = 1,2,3,
+ 4,5,6;
+
+ The above code creates a matrix m with 2 rows and 3 columns and sets it so that
+ it contains the matrix | 1 2 3 |
+ | 4 5 6 |
+
+ You can also use this function to assign to all elements of a matrix. So
+ saying m = 3; would assign all elements of m equal to 3.
+
+ Note that to use this method of assignment it is required that you supply
+ exactly m.size() or 1 values so that the matrix is fully initialized. Supplying
+ fewer or more than that is an error that will cause a dlib::fatal_error to be
+ thrown.
+
+ Note also that using an expression of the form m = scalar; when m.size() == 0
+ is legal but has no effect on m.
+ !*/
+
+ void swap (
+ matrix& item
+ );
+ /*!
+ ensures
+ - swaps *this and item
+ !*/
+
+ iterator begin(
+ );
+ /*!
+ ensures
+ - returns a random access iterator pointing to the first element in this
+ matrix.
+ - The iterator will iterate over the elements of the matrix in row major
+ order if layout is row_major_layout or in column major order if layout is
+ column_major_layout.
+ !*/
+
+ iterator end(
+ );
+ /*!
+ ensures
+ - returns a random access iterator pointing to one past the end of the last
+ element in this matrix.
+ !*/
+
+ const_iterator begin(
+ ) const;
+ /*!
+ ensures
+ - returns a random access iterator pointing to the first element in this
+ matrix.
+ - The iterator will iterate over the elements of the matrix in row major
+ order if layout is row_major_layout or in column major order if layout is
+ column_major_layout.
+ !*/
+
+ const_iterator end(
+ ) const;
+ /*!
+ ensures
+ - returns a random access iterator pointing to one past the end of the last
+ element in this matrix.
+ !*/
+ };
+
+// ----------------------------------------------------------------------------------------
+
+ /*!A matrix_colmajor
+ This is just a typedef of the matrix object that uses column major layout.
+ !*/
+ typedef matrix<double,0,0,default_memory_manager,column_major_layout> matrix_colmajor;
+
+ /*!A fmatrix_colmajor
+ This is just a typedef of the matrix object that uses column major layout.
+ !*/
+ typedef matrix<float,0,0,default_memory_manager,column_major_layout> fmatrix_colmajor;
+
+// ----------------------------------------------------------------------------------------
+template <
+ typename T,
+ long NR,
+ long NC,
+ typename mm,
+ typename l
+ >
+ void swap(
+ matrix<T,NR,NC,mm,l>& a,
+ matrix<T,NR,NC,mm,l>& b
+ ) { a.swap(b); }
+ /*!
+ Provides a global swap function
+ !*/
+
+ template <
+ typename T,
+ long NR,
+ long NC,
+ typename mm,
+ typename l
+ >
+ void serialize (
+ const matrix<T,NR,NC,mm,l>& item,
+ std::ostream& out
+ );
+ /*!
+ Provides serialization support. Note that the serialization formats used by the
+ dlib::matrix and dlib::array2d objects are compatible. That means you can load the
+ serialized data from one into another and it will work properly.
+ !*/
+
+ template <
+ typename T,
+ long NR,
+ long NC,
+ typename mm,
+ typename l
+ >
+ void deserialize (
+ matrix<T,NR,NC,mm,l>& item,
+ std::istream& in
+ );
+ /*!
+ Provides deserialization support
+ !*/
+
+ template <
+ typename EXP
+ >
+ std::ostream& operator<< (
+ std::ostream& out,
+ const matrix_exp<EXP>& m
+ );
+ /*!
+ ensures
+ - writes m to the given out stream in a form suitable for human consumption.
+ - returns out
+ !*/
+
+ template <
+ typename T,
+ long NR,
+ long NC,
+ typename MM,
+ typename L
+ >
+ std::istream& operator>> (
+ std::istream& in,
+ matrix<T,NR,NC,MM,L>& m
+ );
+ /*!
+ ensures
+ - Tries to read a matrix from the given input stream and store it into #m.
+ - The format expected is the text format output by the above operator<<().
+ That is, the format should be a grid of text such as:
+ 2 3 4
+ 5 2 6
+ - The separation between numbers can be any number of whitespace characters or
+ commas.
+ - The matrix data is assumed to end upon the first blank line or end-of-file,
+ whichever comes first. This means you can create an input stream with
+ multiple matrices in it by separating them with empty lines.
+ - returns in.
+ - If there was a formatting error or something which prevents the input data
+ from being parsed into a matrix then #in.fail() == true.
+ !*/
+
+ /*!A csv
+ This object is used to define an io manipulator for matrix expressions. In
+ particular, you can write statements like:
+ cout << csv << yourmatrix;
+ and have it print the matrix with commas separating each element.
+ !*/
+ some_undefined_iomnaip_type csv;
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename EXP>
+ class const_temp_matrix : public matrix_exp<const_temp_matrix<EXP> >, noncopyable
+ {
+ /*!
+ REQUIREMENTS ON EXP
+ - must be an object that inherits publicly from matrix_exp.
+
+ WHAT THIS OBJECT REPRESENTS
+ This object represents a copy of a matrix expression. The twist
+ is that it only actually makes a copy of its input matrix expression
+ if that matrix expression is costly to evaluate. If it has
+ low cost then this object just stores a reference.
+
+ This class is useful in cases where you write a function that
+ takes a matrix_exp object as input and you want to do some
+ intensive computation that looks at each element of that matrix_exp
+ many times. If the input matrix_exp has a high cost then you want
+ to store it into a temporary matrix. But if it has low cost then
+ it is faster if you just use a reference to it. The const_temp_matrix
+ makes doing this easy.
+ !*/
+ public:
+
+ const_temp_matrix (
+ const matrix_exp<EXP>& item
+ );
+ /*!
+ ensures
+ - #*this == item
+ - if (EXP::cost <= 1) then
+ - this const_temp_matrix stores a reference to the item matrix
+ - else
+ - this const_temp_matrix creates a temporary matrix and copies
+ item into it
+ !*/
+
+ const_temp_matrix (
+ const EXP& item
+ );
+ /*!
+ ensures
+ - #*this == item
+ - if (EXP::cost <= 1) then
+ - this const_temp_matrix stores a reference to the item matrix
+ - else
+ - this const_temp_matrix creates a temporary matrix and copies
+ item into it
+ !*/
+ };
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_MATRIx_ABSTRACT_
+