33 #ifndef REMORA_MATRIX_PROXY_HPP 34 #define REMORA_MATRIX_PROXY_HPP 36 #include "detail/expression_optimizers.hpp" 37 #include <type_traits> 56 template<
class M,
class Device>
57 temporary_proxy<typename detail::matrix_transpose_optimizer<M>::type>
58 trans(matrix_expression<M, Device> & m){
59 return detail::matrix_transpose_optimizer<M>::create(m());
61 template<
class M,
class Device>
62 typename detail::matrix_transpose_optimizer<typename const_expression<M>::type >::type
63 trans(matrix_expression<M, Device>
const& m){
64 typedef typename const_expression<M>::type closure_type;
65 return detail::matrix_transpose_optimizer<closure_type>::create(m());
69 temporary_proxy<typename detail::matrix_transpose_optimizer<M>::type>
70 trans(temporary_proxy<M> m){
71 return trans(static_cast<M&>(m));
87 template<
class M,
class Device>
88 temporary_proxy<typename detail::matrix_row_optimizer<M>::type>
89 row(matrix_expression<M, Device>& expression,
typename M::size_type i){
90 return detail::matrix_row_optimizer<M>::create(expression(), i);
92 template<
class M,
class Device>
93 typename detail::matrix_row_optimizer<typename const_expression<M>::type>::type
94 row(matrix_expression<M, Device>
const& expression,
typename M::size_type i){
95 return detail::matrix_row_optimizer<typename const_expression<M>::type>::create(expression(), i);
99 temporary_proxy<typename detail::matrix_row_optimizer<M>::type>
100 row(temporary_proxy<M> expression,
typename M::size_type i){
101 return row(static_cast<M&>(expression), i);
113 template<
class M,
class Device>
114 auto column(matrix_expression<M, Device>& expression,
typename M::size_type j) -> decltype(row(trans(expression),j)){
115 return row(trans(expression),j);
117 template<
class M,
class Device>
118 auto column(matrix_expression<M, Device>
const& expression,
typename M::size_type j) -> decltype(row(trans(expression),j)){
119 return row(trans(expression),j);
122 template<
class M,
class Device>
123 auto column(temporary_proxy<M> expression,
typename M::size_type j) -> decltype(row(trans(expression),j)){
124 return row(trans(static_cast<M&>(expression)),j);
140 template<
class M,
class Device>
141 matrix_vector_range<typename const_expression<M>::type > diag(matrix_expression<M, Device>
const& mat){
142 REMORA_SIZE_CHECK(mat().size1() == mat().size2());
143 matrix_vector_range<typename const_expression<M>::type > diagonal(mat(),0,mat().size1(),0,mat().size1());
147 template<
class M,
class Device>
148 temporary_proxy< matrix_vector_range<M> > diag(matrix_expression<M, Device>& mat){
149 REMORA_SIZE_CHECK(mat().size1() == mat().size2());
150 matrix_vector_range<M> diagonal(mat(),0,mat().size1(),0,mat().size1());
155 temporary_proxy< matrix_vector_range<M> > diag(temporary_proxy<M> mat){
156 return diag(static_cast<M&>(mat));
175 template<
class M,
class Device>
176 temporary_proxy< typename detail::matrix_range_optimizer<M>::type > subrange(
177 matrix_expression<M, Device>& expression,
178 std::size_t start1, std::size_t stop1,
179 std::size_t start2, std::size_t stop2
181 REMORA_RANGE_CHECK(start1 <= stop1);
182 REMORA_RANGE_CHECK(start2 <= stop2);
183 REMORA_SIZE_CHECK(stop1 <= expression().size1());
184 REMORA_SIZE_CHECK(stop2 <= expression().size2());
185 return detail::matrix_range_optimizer<M>::create(expression(), start1, stop1, start2, stop2);
187 template<
class M,
class Device>
188 typename detail::matrix_range_optimizer<typename const_expression<M>::type>::type subrange(
189 matrix_expression<M, Device>
const& expression,
190 std::size_t start1, std::size_t stop1,
191 std::size_t start2, std::size_t stop2
193 REMORA_RANGE_CHECK(start1 <= stop1);
194 REMORA_RANGE_CHECK(start2 <= stop2);
195 REMORA_SIZE_CHECK(stop1 <= expression().size1());
196 REMORA_SIZE_CHECK(stop2 <= expression().size2());
197 return detail::matrix_range_optimizer<typename const_expression<M>::type>::create(expression(), start1, stop1, start2, stop2);
200 template<
class M,
class Device>
202 temporary_proxy<M> expression,
203 std::size_t start1, std::size_t stop1,
204 std::size_t start2, std::size_t stop2
205 ) -> decltype(subrange(static_cast<M&>(expression),start1,stop1,start2,stop2)){
206 return subrange(static_cast<M&>(expression),start1,stop1,start2,stop2);
209 template<
class M,
class Device>
211 matrix_expression<M, Device>& expression,
212 std::size_t start, std::size_t stop
213 ) -> decltype(subrange(expression, start, stop, 0,expression().size2())){
214 REMORA_RANGE_CHECK(start <= stop);
215 REMORA_SIZE_CHECK(stop <= expression().size1());
216 return subrange(expression, start, stop, 0,expression().size2());
219 template<
class M,
class Device>
221 matrix_expression<M, Device>
const& expression,
222 std::size_t start, std::size_t stop
223 ) -> decltype(subrange(expression, start, stop, 0,expression().size2())){
224 REMORA_RANGE_CHECK(start <= stop);
225 REMORA_SIZE_CHECK(stop <= expression().size1());
226 return subrange(expression, start, stop, 0,expression().size2());
231 temporary_proxy<M> expression,
232 std::size_t start, std::size_t stop
233 ) -> decltype( rows(static_cast<M&>(expression),start,stop)){
234 return rows(static_cast<M&>(expression),start,stop);
237 template<
class M,
class Device>
239 matrix_expression<M, Device>& expression,
240 typename M::size_type start,
typename M::size_type stop
241 ) -> decltype(subrange(expression, 0,expression().size1(), start, stop)){
242 REMORA_RANGE_CHECK(start <= stop);
243 REMORA_SIZE_CHECK(stop <= expression().size2());
244 return subrange(expression, 0,expression().size1(), start, stop);
247 template<
class M,
class Device>
249 matrix_expression<M, Device>
const& expression,
250 typename M::size_type start,
typename M::size_type stop
251 ) -> decltype(subrange(expression, 0,expression().size1(), start, stop)){
252 REMORA_RANGE_CHECK(start <= stop);
253 REMORA_SIZE_CHECK(stop <= expression().size2());
254 return subrange(expression, 0,expression().size1(), start, stop);
259 temporary_proxy<M> expression,
260 std::size_t start, std::size_t stop
261 ) -> decltype(columns(static_cast<M&>(expression),start,stop)){
262 return columns(static_cast<M&>(expression),start,stop);
271 temporary_proxy< dense_matrix_adaptor<T> > adapt_matrix(std::size_t size1, std::size_t size2, T* data){
272 return dense_matrix_adaptor<T>(data,size1, size2);
276 template <
class T, std::
size_t M, std::
size_t N>
277 temporary_proxy<dense_matrix_adaptor<T> > adapt_matrix(T (&array)[M][N]){
278 return dense_matrix_adaptor<T>(&(array[0][0]),M,N);
282 template <
class V,
class Tag>
283 typename std::enable_if<
284 std::is_same<typename V::storage_type::storage_tag,continuous_dense_tag>::value,
285 temporary_proxy< dense_matrix_adaptor<
286 typename std::remove_reference<typename V::reference>::type,row_major, Tag
290 vector_expression<V, Tag>& v,
291 std::size_t size1, std::size_t size2
293 REMORA_SIZE_CHECK(size1 * size2 == v().size());
294 typedef typename std::remove_reference<typename V::reference>::type ElementType;
295 return dense_matrix_adaptor<ElementType, row_major, Tag>(v, size1, size2);
299 template <
class V,
class Tag>
300 typename std::enable_if<
301 std::is_same<typename V::storage_type::storage_tag,continuous_dense_tag>::value,
302 temporary_proxy< dense_matrix_adaptor<typename V::value_type const,row_major, Tag> >
305 vector_expression<V, Tag>
const& v,
306 std::size_t size1, std::size_t size2
308 REMORA_SIZE_CHECK(size1 * size2 == v().size());
309 return dense_matrix_adaptor<typename V::value_type const, row_major, Tag>(v, size1, size2);
313 auto to_matrix(temporary_proxy<E> e, std::size_t size1, std::size_t size2)->decltype(to_matrix(static_cast<E&>(e),size1, size2)){
314 return to_matrix(static_cast<E&>(e), size1, size2);
321 template<
class E,
class Device>
322 typename std::enable_if<
323 std::is_same<typename E::evaluation_category::tag,dense_tag>::value,
324 temporary_proxy< linearized_matrix<typename const_expression<E>::type> >
326 to_vector(matrix_expression<E, Device>
const& e){
327 return linearized_matrix<typename const_expression<E>::type>(e());
330 template<
class E,
class Device>
331 typename std::enable_if<
332 std::is_same<typename E::evaluation_category::tag,dense_tag>::value,
333 temporary_proxy< linearized_matrix<E> >
335 to_vector(matrix_expression<E,Device>& e){
336 return linearized_matrix<E>(e());
340 auto to_vector(temporary_proxy<E> e)->decltype(to_vector(static_cast<E&>(e))){
341 return to_vector(static_cast<E&>(e));