1 // Copyright (C) 2006  Davis E. King (davis@dlib.net)
2 // License: Boost Software License   See LICENSE.txt for the full license.
3 #undef DLIB_MATRIx_EXP_ABSTRACT_
4 #ifdef DLIB_MATRIx_EXP_ABSTRACT_
5 
6 #include "matrix_fwd.h"
7 
8 namespace dlib
9 {
10 
11 // ----------------------------------------------------------------------------------------
12 
13     template <
14         typename EXP
15         >
16     class matrix_exp
17     {
18         /*!
19             REQUIREMENTS ON EXP
20                 - must be an object that inherits publicly from matrix_exp (this class).
21 
22             WHAT THIS OBJECT REPRESENTS
23                 This object represents an expression that evaluates to a matrix
24                 of nr() rows and nc() columns.
25 
26                 The reason for having an object that represents an expression is that it
27                 allows us to use the "expression templates" technique to eliminate the
28                 temporary matrix objects that would normally be returned from expressions
29                 such as M = A+B+C+D;  Normally each invocation of the + operator would
30                 construct and return a temporary matrix object but using this technique we
31                 can avoid creating all of these temporary objects and receive a large
32                 speed boost.
33 
34                 Note that every time you invoke operator() on this object it recomputes
35                 its result which may not be what you want to do.  For example, if you
36                 are going to be accessing the same element over and over it might
37                 be faster to assign the matrix_exp to a temporary matrix and then
38                 use that temporary.
39 
40 
41                 const_ret_type typedef (defined below)
42                     The purpose of the const_ret_type typedef is to allow matrix expressions
43                     to return their elements by reference when appropriate.  So const_ret_type
44                     should be one of the following types:
45                         - const type
46                         - const type&
47         !*/
48 
49     public:
50         typedef typename EXP::type type;
51         typedef type value_type; // Redefined for compatibility with the STL
52         typedef typename EXP::const_ret_type const_ret_type;
53         typedef typename EXP::mem_manager_type mem_manager_type;
54         typedef typename EXP::layout_type layout_type;
55         const static long cost = EXP::cost;
56         const static long NR = EXP::NR;
57         const static long NC = EXP::NC;
58         typedef matrix<type,NR,NC, mem_manager_type,layout_type> matrix_type;
59         typedef EXP exp_type;
60         typedef matrix_exp_iterator<EXP> iterator;
61         typedef matrix_exp_iterator<EXP> const_iterator;
62 
63         const_ret_type operator() (
64             long r,
65             long c
66         ) const;
67         /*!
68             requires
69                 - 0 <= r < nr()
70                 - 0 <= c < nc()
71             ensures
72                 - returns ref()(r,c)
73                   (i.e. returns the value at the given row and column that would be in
74                   the matrix represented by this matrix expression)
75         !*/
76 
77         const_ret_type operator() (
78             long i
79         ) const;
80         /*!
81             requires
82                 - nc() == 1 || nr() == 1 (i.e. this must be a column or row vector)
83                 - if (nc() == 1) then
84                     - 0 <= i < nr()
85                 - else
86                     - 0 <= i < nc()
87             ensures
88                 - if (nc() == 1) then
89                     - returns (*this)(i,0)
90                 - else
91                     - returns (*this)(0,i)
92         !*/
93 
94         operator const type (
95         ) const;
96         /*!
97             requires
98                 - nr() == 1
99                 - nc() == 1
100             ensures
101                 - returns (*this)(0,0)
102         !*/
103 
104         long nr (
105         ) const;
106         /*!
107             ensures
108                 - returns the number of rows in this matrix expression.
109         !*/
110 
111         long nc (
112         ) const;
113         /*!
114             ensures
115                 - returns the number of columns in this matrix expression.
116         !*/
117 
118         long size (
119         ) const;
120         /*!
121             ensures
122                 - returns nr()*nc()
123         !*/
124 
125         template <typename U>
126         bool aliases (
127             const matrix_exp<U>& item
128         ) const;
129         /*!
130             ensures
131                 - if (A change to the state of item could cause a change to the state of *this
132                       matrix_exp object.  ) then
133                     - returns true
134                     - This happens when this matrix_exp contains item in some way.
135                 - else
136                     - returns false
137         !*/
138 
139         template <typename U>
140         bool destructively_aliases (
141             const matrix_exp<U>& item
142         ) const;
143         /*!
144             ensures
145                 - if (aliases(item)) then
146                     - if (nr() != item.nr() || nc() != item.nc()
147                         - returns true
148                           (i.e. if this expression has different dimensions than item then
149                           we have destructive aliasing)
150 
151                     - returns true if the following assignment would evaluate incorrectly:
152                       for (long r = 0; r < nr(); ++r)
153                         for (long c = 0; c < nc(); ++c)
154                           item(r,c) = (*this)(r,c)
155                     - That is, if this matrix expression aliases item in such a way that a modification
156                       to element item(r,c) causes a change in the value of something other than
157                       (*this)(r,c) then this function returns true.
158 
159                     - returns false if none of the above conditions say we should return true
160                 - else
161                     - returns false
162         !*/
163 
164         inline const exp_type& ref (
165         ) const;
166         /*!
167             ensures
168                 - returns a reference to the expression contained in *this.
169                   (i.e. returns *static_cast<const exp_type*>(this) )
170         !*/
171 
172         const_iterator begin(
173         ) const;
174         /*!
175             ensures
176                 - returns a forward access iterator pointing to the first element in this
177                   matrix expression.
178                 - Since matrix_exp objects represent immutable views of a matrix, the
179                   returned iterator does not allow the user to modify the matrix
180                   expression's elements.
181                 - The iterator will iterate over the elements of the matrix in row major
182                   order.
183         !*/
184 
185         const_iterator end(
186         ) const;
187         /*!
188             ensures
189                 - returns a forward access iterator pointing to one past the end of the
190                   last element in this matrix expression.
191         !*/
192 
193     protected:
194 
195         // Only derived classes of matrix_exp may call the matrix_exp constructors.
196         matrix_exp(const matrix_exp&);
197         matrix_exp();
198 
199     private:
200         // no one may ever use the assignment operator on a matrix_exp
201         matrix_exp& operator= (const matrix_exp&);
202     };
203 
204 // ----------------------------------------------------------------------------------------
205 
206 }
207 
208 #endif // DLIB_MATRIx_EXP_ABSTRACT_
209 
210 
211