28#ifndef REMORA_KERNELS_DEFAULT_MATRIX_ASSIGN_HPP
29#define REMORA_KERNELS_DEFAULT_MATRIX_ASSIGN_HPP
31#include "../vector_assign.hpp"
32#include "../../proxy_expressions.hpp"
33#include "../../detail/traits.hpp"
37namespace remora{
namespace bindings{
40template<
class F,
class M>
42 matrix_expression<M, cpu_tag>& m,
46 for(std::size_t i = 0; i != m().size1(); ++i){
48 kernels::apply(rowM,f);
52template<
class F,
class M>
54 matrix_expression<M, cpu_tag>& m,
58 for(std::size_t j = 0; j != m().size2(); ++j){
59 auto columnM = column(m,j);
60 kernels::apply(columnM,f);
64template<
class F,
class M,
class Orientation,
class Triangular>
66 matrix_expression<M, cpu_tag>& m,
68 triangular<Orientation,Triangular>
70 matrix_apply(m,f,Orientation());
79template<
class F,
class M,
class Orientation>
81 matrix_expression<M, cpu_tag>& m,
82 typename M::value_type t,
86 matrix_apply(m, [=](
typename M::value_type x){
return f(x,t);},Orientation());
99template<
class M,
class E,
class TagE>
101 matrix_expression<M, cpu_tag>& m,
102 matrix_expression<E, cpu_tag>
const& e,
103 row_major, row_major,dense_tag, TagE
105 for(std::size_t i = 0; i != m().size1(); ++i){
106 auto rowM = row(m,i);
107 kernels::assign(rowM,row(e,i));
112template<
class M,
class E>
114 matrix_expression<M, cpu_tag>& m,
115 matrix_expression<E, cpu_tag>
const& e,
116 row_major, row_major,sparse_tag, sparse_tag
119 for(std::size_t i = 0; i != m().size1(); ++i){
120 auto m_pos = m().major_begin(i);
121 auto end = e().major_end(i);
122 for(
auto it = e().major_begin(i); it != end; ++it){
123 m_pos = m().set_element(m_pos,it.index(),*it);
131template<
class M,
class E>
133 matrix_expression<M, cpu_tag>& m,
134 matrix_expression<E, cpu_tag>
const& e,
135 row_major, column_major,dense_tag, dense_tag
138 std::size_t
const blockSize = 8;
139 typename M::value_type blockStorage[blockSize][blockSize];
141 typedef typename M::size_type size_type;
142 size_type size1 = m().size1();
143 size_type size2 = m().size2();
144 for (size_type iblock = 0; iblock < size1; iblock += blockSize){
145 for (size_type jblock = 0; jblock < size2; jblock += blockSize){
146 std::size_t blockSizei = std::min(blockSize,size1-iblock);
147 std::size_t blockSizej = std::min(blockSize,size2-jblock);
150 for (size_type j = 0; j < blockSizej; ++j){
151 for (size_type i = 0; i < blockSizei; ++i){
152 blockStorage[i][j] = e()(iblock+i,jblock+j);
157 for (size_type i = 0; i < blockSizei; ++i){
158 for (size_type j = 0; j < blockSizej; ++j){
159 m()(iblock+i,jblock+j) = blockStorage[i][j];
167template<
class M,
class E>
169 matrix_expression<M, cpu_tag>& m,
170 matrix_expression<E, cpu_tag>
const& e,
171 row_major, column_major,dense_tag, sparse_tag
173 for(std::size_t j = 0; j != m().size2(); ++j){
174 auto columnM = column(m,j);
175 kernels::assign(columnM,column(e,j));
180template<
class M,
class E>
182 matrix_expression<M, cpu_tag>& m,
183 matrix_expression<E, cpu_tag>
const& e,
184 row_major, column_major,sparse_tag,sparse_tag
190 typedef typename M::value_type value_type;
191 typedef typename M::size_type size_type;
192 typedef row_major::sparse_element<value_type> Element;
193 std::vector<Element> elements;
195 size_type size2 = m().size2();
196 for(size_type j = 0; j != size2; ++j){
197 auto pos_e = e().major_begin(j);
198 auto end_e = e().major_end(j);
199 for(; pos_e != end_e; ++pos_e){
201 element.i = pos_e.index();
203 element.value = *pos_e;
204 elements.push_back(element);
207 std::sort(elements.begin(),elements.end());
210 size_type num_elems = size_type(elements.size());
211 for(size_type current = 0; current != num_elems;){
213 size_type row = elements[current].i;
214 size_type row_end = current;
215 while(row_end != num_elems && elements[row_end].i == row)
217 m().major_reserve(row,row_end - current);
220 auto row_pos = m().major_begin(row);
221 for(; current != row_end; ++current){
222 row_pos = m().set_element(row_pos,elements[current].j,elements[current].value);
228template<
class M,
class E,
bool Upper,
bool Unit>
230 matrix_expression<M, cpu_tag>& m,
231 matrix_expression<E, cpu_tag>
const& e,
232 triangular<row_major,triangular_tag<Upper, false> >, triangular<row_major,triangular_tag<Upper, Unit> >,
233 packed_tag, packed_tag
235 for(std::size_t i = 0; i != m().size1(); ++i){
236 auto mpos = m().major_begin(i);
237 auto epos = e().major_begin(i);
238 auto eend = e().major_end(i);
243 REMORA_SIZE_CHECK(mpos.index() == epos.index());
244 for(; epos != eend; ++epos,++mpos){
255template<
class M,
class E,
class Triangular>
257 matrix_expression<M, cpu_tag>& m,
258 matrix_expression<E, cpu_tag>
const& e,
259 triangular<row_major,Triangular>, triangular<column_major,Triangular>,
260 packed_tag, packed_tag
262 for(std::size_t i = 0; i != m().size1(); ++i){
263 auto mpos = m().major_begin(i);
264 auto mend = m().major_end(i);
265 for(; mpos!=mend; ++mpos){
266 *mpos = e()(i,mpos.index());
276template<
class F,
class M,
class E,
class TagE>
277void matrix_assign_functor(
278 matrix_expression<M, cpu_tag>& m,
279 matrix_expression<E, cpu_tag>
const& e,
281 row_major, row_major, dense_tag, TagE
283 for(std::size_t i = 0; i != m().size1(); ++i){
284 auto rowM = row(m,i);
285 kernels::assign(rowM,row(e,i),f);
288template<
class F,
class M,
class E>
289void matrix_assign_functor(
290 matrix_expression<M, cpu_tag>& m,
291 matrix_expression<E, cpu_tag>
const& e,
293 row_major, row_major, sparse_tag, sparse_tag
295 typedef typename M::value_type value_type;
296 value_type zero = value_type();
297 typedef row_major::sparse_element<value_type> Element;
298 std::vector<Element> elements;
300 for(std::size_t i = 0; i != major_size(m); ++i){
304 auto m_pos = m().major_begin(i);
305 auto m_end = m().major_end(i);
306 auto e_pos = e().major_begin(i);
307 auto e_end = e().major_end(i);
309 while(m_pos != m_end && e_pos != e_end){
310 if(m_pos.index() < e_pos.index()){
311 elements.push_back({i,m_pos.index(), f(*m_pos, zero)});
313 }
else if( m_pos.index() == e_pos.index()){
314 elements.push_back({i,m_pos.index(), f(*m_pos ,*e_pos)});
319 elements.push_back({i,e_pos.index(), f(zero,*e_pos)});
323 for(;m_pos != m_end;++m_pos){
324 elements.push_back({i,m_pos.index(), f(*m_pos, zero)});
326 for(;e_pos != e_end; ++e_pos){
327 elements.push_back({i,e_pos.index(), f(zero, *e_pos)});
331 m().clear_range(m().major_begin(i),m().major_end(i));
332 m().major_reserve(i,elements.size());
333 m_pos = m().major_begin(i);
334 for(
auto elem: elements){
335 m_pos = m().set_element(m_pos, elem.j, elem.value);
344template<
class F,
class M,
class E>
345void matrix_assign_functor(
346 matrix_expression<M, cpu_tag>& m,
347 matrix_expression<E, cpu_tag>
const& e,
349 row_major, column_major,dense_tag, dense_tag
352 std::size_t
const blockSize = 16;
353 typename M::value_type blockStorage[blockSize][blockSize];
355 typedef typename M::size_type size_type;
356 size_type size1 = m().size1();
357 size_type size2 = m().size2();
358 for (size_type iblock = 0; iblock < size1; iblock += blockSize){
359 for (size_type jblock = 0; jblock < size2; jblock += blockSize){
360 std::size_t blockSizei = std::min(blockSize,size1-iblock);
361 std::size_t blockSizej = std::min(blockSize,size2-jblock);
364 for (size_type j = 0; j < blockSizej; ++j){
365 for (size_type i = 0; i < blockSizei; ++i){
366 blockStorage[i][j] = e()(iblock+i,jblock+j);
371 for (size_type i = 0; i < blockSizei; ++i){
372 for (size_type j = 0; j < blockSizej; ++j){
373 m()(iblock+i,jblock+j) = f(m()(iblock+i,jblock+j), blockStorage[i][j]);
381template<
class F,
class M,
class E>
382void matrix_assign_functor(
383 matrix_expression<M, cpu_tag>& m,
384 matrix_expression<E, cpu_tag>
const& e,
386 row_major, column_major,dense_tag, sparse_tag
388 for(std::size_t j = 0; j != m().size2(); ++j){
389 auto columnM = column(m,j);
390 kernels::assign(columnM,column(e,j),f);
395template<
class F,
class M,
class E>
396void matrix_assign_functor(
397 matrix_expression<M, cpu_tag>& m,
398 matrix_expression<E, cpu_tag>
const& e,
400 row_major, column_major,sparse_tag t,sparse_tag
402 typename matrix_temporary<M>::type eTrans = e;
403 matrix_assign_functor(m,eTrans,f,row_major(),row_major(),t,t);
408template<
class F,
class M,
class E,
class Triangular,
class Tag1,
class Tag2>
409void matrix_assign_functor(
410 matrix_expression<M, cpu_tag>& m,
411 matrix_expression<E, cpu_tag>
const& e,
413 triangular<row_major,Triangular>, triangular<row_major,Triangular>,
419 for(std::size_t i = 0; i != m().size1(); ++i){
420 auto mpos = m().major_begin(i);
421 auto epos = e().major_begin(i);
422 auto mend = m().major_end(i);
423 REMORA_SIZE_CHECK(mpos.index() == epos.index());
424 for(; mpos!=mend; ++mpos,++epos){
425 *mpos = f(*mpos,*epos);
431template<
class F,
class M,
class E,
class Triangular,
class Tag1,
class Tag2>
432void matrix_assign_functor(
433 matrix_expression<M, cpu_tag>& m,
434 matrix_expression<E, cpu_tag>
const& e,
436 triangular<row_major,Triangular>, triangular<column_major,Triangular>,
441 for(std::size_t i = 0; i != m().size1(); ++i){
442 auto mpos = m().major_begin(i);
443 auto mend = m().major_end(i);
444 for(; mpos!=mend; ++mpos){
445 *mpos = f(*mpos,e()(i,mpos.index()));