1 // -*- C++ -*- 2 /** @file */ 3 #pragma once 4 5 6 #include <memory> 7 #include <cstring> 8 #include <algorithm> 9 #include <iostream> 10 #include "common.hpp" 11 #include "arch.hpp" 12 #include <type_traits> 13 #include "number.hpp" 14 #include "forward.hpp" 15 #include "fusion.hpp" 16 #include "unroll.hpp" 17 #include "algorithms.hpp" 18 #include "vec.hpp" 19 #include "matrix_impl.hpp" 20 21 namespace arm_cmsis_dsp { 22 23 /** \addtogroup Matrix 24 * @{ 25 */ 26 27 /** @brief Matrix 28 * @tparam T Type of the scalar 29 * @tparam S Stride 30 */ 31 template<typename T,int S=1> 32 struct MatrixView 33 { 34 /** @brief Number of rows 35 * @return Number of rows 36 */ rowsarm_cmsis_dsp::MatrixView37 vector_length_t rows() const {return(nb_rows_);} 38 39 /** @brief Number of columns 40 * @return Number of columns 41 */ columnsarm_cmsis_dsp::MatrixView42 vector_length_t columns() const {return(nb_cols_);} 43 44 /** @brief Number of stride 45 * @return Number of stride 46 */ stridearm_cmsis_dsp::MatrixView47 constexpr uint32_t stride() const {return(S);} 48 49 /** @brief Create matrix view on a buffer (buffer not owned by the view) 50 * @param v buffer 51 * @param rows number of rows 52 * @param cols number of columns 53 */ MatrixViewarm_cmsis_dsp::MatrixView54 explicit MatrixView(T* v, 55 const vector_length_t rows, 56 const vector_length_t cols): 57 v_(v),nb_rows_(rows),nb_cols_(cols){}; 58 59 /** @brief Create matrix view on vector (vector not owned by the view) 60 * @param v vector 61 * @param rows number of rows 62 * @param cols number of columns 63 */ MatrixViewarm_cmsis_dsp::MatrixView64 explicit MatrixView(const Vector_Base<T> &v, 65 const vector_length_t rows, 66 const vector_length_t cols): 67 v_(v.ptr()),nb_rows_(rows),nb_cols_(cols){}; 68 ~MatrixViewarm_cmsis_dsp::MatrixView69 virtual ~MatrixView() {}; 70 MatrixViewarm_cmsis_dsp::MatrixView71 MatrixView(const MatrixView& other): 72 v_(other.v_), 73 nb_rows_(other.nb_rows_),nb_cols_(other.nb_cols_){}; 74 MatrixViewarm_cmsis_dsp::MatrixView75 MatrixView(MatrixView&& other) : 76 v_(other.v_), 77 nb_rows_(other.nb_rows_),nb_cols_(other.nb_cols_){}; 78 79 80 MatrixView& operator=(const MatrixView& other) = delete; 81 MatrixView& operator=(MatrixView&& other) = delete; 82 83 /** @brief Access matrix view element at given position 84 * @param r Row index 85 * @param c Column index 86 * @return reference to element 87 * 88 */ operator ()arm_cmsis_dsp::MatrixView89 T& operator()(const index_t r,const index_t c) 90 { 91 return(v_[r*stride()+c]); 92 } 93 94 /** @brief Access matrix view element at given position 95 * @param r Row index 96 * @param c Column index 97 * @return reference to element 98 * 99 */ operator ()arm_cmsis_dsp::MatrixView100 T const operator()(const index_t r,const index_t c) const 101 { 102 return(v_[r*stride()+c]); 103 } 104 105 106 /** @brief Assign matrix from expression 107 * @tparam Derived Datatype representing the abstract syntax tree of the expression 108 * @param other Expression 109 * @return the matrix 110 * 111 */ 112 template<typename Derived> operator =arm_cmsis_dsp::MatrixView113 MatrixView& operator=(const _Expr<Derived>&other) 114 { 115 eval2D(*this,other.derived(),rows(),columns(),CURRENT_ARCH); 116 return(*this); 117 } 118 119 /** @brief Assign matrix view from constant 120 * @param val The constant 121 * @return the matrix 122 * 123 */ operator =arm_cmsis_dsp::MatrixView124 MatrixView& operator=(const T val) 125 { 126 _Fill2D(*this,val,rows(),columns(),CURRENT_ARCH); 127 128 return(*this); 129 } 130 131 132 /** @brief Add matrix from expression 133 * @tparam Derived Datatype representing the abstract syntax tree of the expression 134 * @param other Expression 135 * @return the matrix 136 * 137 */ 138 template<typename Derived> operator +=arm_cmsis_dsp::MatrixView139 MatrixView& operator +=(const _Expr<Derived>& other) 140 { 141 eval2D(*this,*this + other.derived(),rows(),columns(),CURRENT_ARCH); 142 return(*this); 143 }; 144 145 /** @brief Add matrix from matrix view 146 * @param other Other matrix 147 * @return the matrix 148 * 149 */ operator +=arm_cmsis_dsp::MatrixView150 MatrixView& operator +=(const MatrixView& other) 151 { 152 eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH); 153 return(*this); 154 }; 155 156 157 /** @brief Add constant to matrix view 158 * @param other The constant 159 * @return the matrix 160 * 161 */ operator +=arm_cmsis_dsp::MatrixView162 MatrixView& operator +=(const T other) 163 { 164 eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH); 165 return(*this); 166 }; 167 168 /** @brief Subtract matrix from expression 169 * @tparam Derived Datatype representing the abstract syntax tree of the expression 170 * @param other expression 171 * @return the matrix 172 * 173 */ 174 template<typename Derived> operator -=arm_cmsis_dsp::MatrixView175 MatrixView& operator -=(const _Expr<Derived>& other) 176 { 177 eval2D(*this,*this - other.derived(),rows(),columns(),CURRENT_ARCH); 178 return(*this); 179 }; 180 181 /** @brief Subtract matrix view 182 * @param other Other matrix view 183 * @return the matrix 184 * 185 */ operator -=arm_cmsis_dsp::MatrixView186 MatrixView& operator -=(const MatrixView& other) 187 { 188 eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH); 189 return(*this); 190 }; 191 192 /** @brief Subtract constant 193 * @param other Other matrix 194 * @return the matrix 195 * 196 */ operator -=arm_cmsis_dsp::MatrixView197 MatrixView& operator -=(const T other) 198 { 199 eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH); 200 return(*this); 201 }; 202 203 /** @brief Elementwise multiply matrix view with expression 204 * @tparam Derived Datatype representing the abstract syntax tree of the expression 205 * @param other expression 206 * @return the matrix 207 * 208 */ 209 template<typename Derived> operator *=arm_cmsis_dsp::MatrixView210 MatrixView& operator *=(const _Expr<Derived>& other) 211 { 212 eval2D(*this,*this * other.derived(),rows(),columns(),CURRENT_ARCH); 213 return(*this); 214 }; 215 216 /** @brief Elementwise multiply matrix view with matrix view 217 * @param other Other matrix 218 * @return the matrix 219 * 220 */ operator *=arm_cmsis_dsp::MatrixView221 MatrixView& operator *=(const MatrixView& other) 222 { 223 eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH); 224 return(*this); 225 }; 226 227 /** @brief Elementwise multiply matrix view constant 228 * @param other constant 229 * @return the matrix 230 * 231 */ operator *=arm_cmsis_dsp::MatrixView232 MatrixView& operator *=(const T other) 233 { 234 eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH); 235 return(*this); 236 }; 237 238 /** 239 * @brief Display the matrix content for debug purpose 240 * @param stream Output stream 241 * @param other The matrix to display 242 * @return the stream 243 * 244 */ operator <<(std::ostream & stream,const MatrixView & other)245 friend std::ostream& operator<< (std::ostream& stream, const MatrixView& other) { 246 for(index_t row=0;row<other.rows();row++) 247 { 248 for(index_t col=0;col<other.columns();col++) 249 { 250 stream << other(row,col)<< " , "; 251 } 252 stream << "\r\n"; 253 } 254 stream << "\r\n"; 255 return(stream); 256 } 257 258 /** @brief Create a row view with stride 1 259 * @param i row index 260 * @param start Start index in row 261 * @return row view vector 262 * 263 */ rowarm_cmsis_dsp::MatrixView264 VectorView<T,1> row(const index_t i,const index_t start=0) 265 { 266 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+columns())); 267 } 268 269 /** @brief Create a row view with stride 1 270 * @param i row index 271 * @param start Start index in row 272 * @param stop Stop index in row 273 * @return row view vector 274 * 275 */ rowarm_cmsis_dsp::MatrixView276 VectorView<T,1> row(const index_t i,const index_t start,const index_t stop) 277 { 278 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+stop)); 279 } 280 281 /** @brief Create a constant row view with stride 1 282 * @param i row index 283 * @param start Start index in row 284 * @return row view vector 285 * 286 */ rowarm_cmsis_dsp::MatrixView287 const VectorView<T,1> row(const index_t i,const index_t start=0) const 288 { 289 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+columns())); 290 } 291 292 /** @brief Create a constant row view with stride 1 293 * @param i row index 294 * @param start Start index in row 295 * @param stop Stop index in row 296 * @return row view vector 297 * 298 */ rowarm_cmsis_dsp::MatrixView299 const VectorView<T,1> row(const index_t i,const index_t start,const index_t stop) const 300 { 301 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+stop)); 302 } 303 304 /** @brief Create a column view vector 305 * @tparam CS column stride 306 * @param i column index 307 * @param start Start index in column 308 * @return column view vector 309 * 310 */ 311 template<int CS=1> colarm_cmsis_dsp::MatrixView312 VectorView<T,CS*S> col(const index_t i,const index_t start=0) 313 { 314 return(VectorView<T,CS*S>(v_,i+stride()*start,i+stride()*rows())); 315 } 316 317 /** @brief Create a column view vector 318 * @tparam CS column stride 319 * @param i column index 320 * @param start Start index in column 321 * @param stop Stop index in column 322 * @return column view vector 323 * 324 */ 325 template<int CS=1> colarm_cmsis_dsp::MatrixView326 VectorView<T,CS*S> col(const index_t i,const index_t start,const index_t stop) 327 { 328 return(VectorView<T,CS*S>(v_,i+stride()*start,i+stride()*stop)); 329 } 330 331 /** @brief Create a constant column view vector 332 * @tparam CS column stride 333 * @param i column index 334 * @param start Start index in column 335 * @return column view vector 336 * 337 */ 338 template<int CS=1> colarm_cmsis_dsp::MatrixView339 const VectorView<T,CS*S> col(const index_t i,const index_t start=0) const 340 { 341 return(VectorView<T,CS*S>(v_,i+stride()*start,i+stride()*rows())); 342 } 343 344 /** @brief Create a constant column view vector 345 * @tparam CS column stride 346 * @param i column index 347 * @param start Start index in column 348 * @param stop Stop index in column 349 * @return column view vector 350 * 351 */ 352 template<int CS=1> colarm_cmsis_dsp::MatrixView353 const VectorView<T,CS*S> col(const index_t i,const index_t start,const index_t stop) const 354 { 355 return(VectorView<T,CS*S>(v_,i+stride()*start,i+stride()*stop)); 356 } 357 358 #if defined(HAS_VECTOR) 359 //! Type of vectors for a vector architecture and for scalar datatype P 360 using VectorType = typename vector_traits<T>::vector; 361 362 /** 363 * @brief %Vector store at a given row,column position 364 * 365 * @param row row index 366 * @param col column index 367 * @param val %Vector value 368 * 369 * On an architecture supporting vectors, if the scalar datatype T 370 * has a corresponding vector datatype, this function stores a vector 371 * value at row,column in this matrix. 372 */ matrix_storearm_cmsis_dsp::MatrixView373 void matrix_store(const index_t row, 374 const index_t col, 375 const VectorType val) const 376 { 377 inner::vstore1<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]),val); 378 } 379 380 #if defined(HAS_PREDICATED_LOOP) 381 /** 382 * @brief %Vector store at a given row,column position with predicated tail 383 * 384 * @param row row index 385 * @param col column index 386 * @param remaining Number of remaining samples in the loop 387 * @param val Vector value to write at index i with tail predication 388 * 389 * On an architecture supporting vectors and predicated loops, if the 390 * scalar datatype T has a corresponding vector datatype, this 391 * function stores a vector value at row,column index in this matrix datatype 392 * with predication 393 */ matrix_store_tailarm_cmsis_dsp::MatrixView394 void matrix_store_tail(const index_t row, 395 const index_t col, 396 const vector_length_t remaining, 397 const VectorType val) const 398 { 399 inner::vstore1_z<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]),val,remaining,inner::vctpq<T>::mk(remaining)); 400 } 401 402 /** 403 * @brief %Vector operation at a given row,column position with predicated tail 404 * 405 * @param row row index 406 * @param col column index 407 * @param remaining Number of remaining samples in the loop 408 * @return the vector result of the operation 409 * 410 * On an architecture supporting vectors and predicated loops, if the 411 * scalar datatype T has a corresponding vector datatype, this 412 * function compute an operation at row,column index in this matrix datatype 413 * with predication 414 */ matrix_op_tailarm_cmsis_dsp::MatrixView415 VectorType const matrix_op_tail(const index_t row, 416 const index_t col, 417 const vector_length_t remaining) const 418 { 419 return(inner::vload1_z<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]),remaining,inner::vctpq<T>::mk(remaining))); 420 } 421 #endif 422 423 /** 424 * @brief %Vector operation at a given row,column position 425 * 426 * @param row row index 427 * @param col column index 428 * @return the vector result of the operation 429 * 430 * On an architecture supporting vectors and predicated loops, if the 431 * scalar datatype T has a corresponding vector datatype, this 432 * function compute an operation at row,column index in this matrix datatype 433 */ matrix_oparm_cmsis_dsp::MatrixView434 VectorType const matrix_op(const index_t row, 435 const index_t col) const 436 { 437 return(inner::vload1<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]))); 438 } 439 #endif 440 441 /** @brief Fill diagonal of a matrix with a vector 442 * @tparam VA Vector datatype 443 * @param a Vector for initializing the diagonal 444 * 445 */ 446 template<typename VA, 447 typename std::enable_if<IsVector<VA>::value && 448 SameElementType<VA,T>::value,bool>::type = true> fill_diagonalarm_cmsis_dsp::MatrixView449 void fill_diagonal(const VA& a) 450 { 451 _fill_diagonal(*this,a,this->length()); 452 } 453 454 /** @brief Create the transposed matrix 455 * @return a matrix 456 * 457 */ transposearm_cmsis_dsp::MatrixView458 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> transpose() const 459 { 460 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(columns(),rows()); 461 transposeTo(res,*this); 462 return(res); 463 } 464 465 /** @brief Create a matrix of same type 466 * @return a matrix 467 * 468 */ createarm_cmsis_dsp::MatrixView469 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> create() const 470 { 471 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(rows(),columns()); 472 return(res); 473 } 474 475 /** 476 * @brief Pointer to storage buffer 477 * @return Pointer to storage 478 */ ptrarm_cmsis_dsp::MatrixView479 T* ptr() const {return(v_);} 480 481 /** 482 * @brief Constant pointer to storage buffer 483 * @return Pointer to storage 484 */ const_ptrarm_cmsis_dsp::MatrixView485 const T* const_ptr() const {return(v_);} 486 487 protected: 488 T* const v_; 489 const vector_length_t nb_rows_; 490 const vector_length_t nb_cols_; 491 }; 492 493 /* 494 495 When the stride is not known at build time AND different 496 from the nb_cols_ 497 498 */ 499 500 /** @brief Dynamic Matrix View 501 * @tparam T Type of the scalar 502 * 503 * This template is used for dynamic matrix (stride not known 504 * at build time) and when we do not know if stride == number of 505 * columns. 506 * When stride is different from number of columns, the matrix cannot 507 * be seen as a vector. 508 */ 509 template<typename T> 510 struct MatrixView<T,DYNAMIC> 511 { 512 /** @brief Number of rows 513 * @return Number of rows 514 */ rowsarm_cmsis_dsp::MatrixView515 vector_length_t rows() const {return(nb_rows_);} 516 517 /** @brief Number of columns 518 * @return Number of columns 519 */ columnsarm_cmsis_dsp::MatrixView520 vector_length_t columns() const {return(nb_cols_);} 521 522 /** @brief Number of stride 523 * @return Number of stride 524 */ stridearm_cmsis_dsp::MatrixView525 uint32_t stride() const {return(stride_);} 526 527 /** @brief Create matrix view on a buffer (buffer not owned by the view) 528 * @param v buffer 529 * @param rows number of rows 530 * @param cols number of columns 531 * @param stride stride 532 */ MatrixViewarm_cmsis_dsp::MatrixView533 explicit MatrixView(T* v, 534 const vector_length_t rows, 535 const vector_length_t cols, 536 const uint32_t stride): 537 v_(v),nb_rows_(rows),nb_cols_(cols),stride_(stride){}; 538 539 /** @brief Create matrix view on vector (vector not owned by the view) 540 * @param v vector 541 * @param rows number of rows 542 * @param cols number of columns 543 * @param stride stride 544 */ MatrixViewarm_cmsis_dsp::MatrixView545 explicit MatrixView(const Vector_Base<T> &v, 546 const vector_length_t rows, 547 const vector_length_t cols, 548 const uint32_t stride): 549 v_(v.ptr()),nb_rows_(rows),nb_cols_(cols),stride_(stride){}; 550 ~MatrixViewarm_cmsis_dsp::MatrixView551 virtual ~MatrixView() {}; 552 MatrixViewarm_cmsis_dsp::MatrixView553 MatrixView(const MatrixView& other): 554 v_(other.v_), 555 nb_rows_(other.nb_rows_),nb_cols_(other.nb_cols_),stride_(other.stride_){}; 556 MatrixViewarm_cmsis_dsp::MatrixView557 MatrixView(MatrixView&& other) : 558 v_(other.v_), 559 nb_rows_(other.nb_rows_),nb_cols_(other.nb_cols_),stride_(other.stride_){}; 560 561 562 MatrixView& operator=(const MatrixView& other) = delete; 563 MatrixView& operator=(MatrixView&& other) = delete; 564 565 /** @brief Access matrix view element at given position 566 * @param r Row index 567 * @param c Column index 568 * @return reference to element 569 * 570 */ operator ()arm_cmsis_dsp::MatrixView571 T& operator()(const index_t r,const index_t c) 572 { 573 return(v_[r*stride()+c]); 574 } 575 576 /** @brief Access matrix view element at given position 577 * @param r Row index 578 * @param c Column index 579 * @return reference to element 580 * 581 */ operator ()arm_cmsis_dsp::MatrixView582 T const operator()(const index_t r,const index_t c) const 583 { 584 return(v_[r*stride()+c]); 585 } 586 587 588 /** @brief Assign matrix view from expression 589 * @tparam Derived Datatype representing the abstract syntax tree of the expression 590 * @param other Expression 591 * @return the matrix 592 * 593 */ 594 template<typename Derived> operator =arm_cmsis_dsp::MatrixView595 MatrixView& operator=(const _Expr<Derived>&other) 596 { 597 eval2D(*this,other.derived(),rows(),columns(),CURRENT_ARCH); 598 return(*this); 599 } 600 601 /** @brief Assign matrix view from constant 602 * @param val The constant 603 * @return the matrix 604 * 605 */ operator =arm_cmsis_dsp::MatrixView606 MatrixView& operator=(const T val) 607 { 608 _Fill2D(*this,val,rows(),columns(),CURRENT_ARCH); 609 610 return(*this); 611 } 612 613 614 /** @brief Add matrix from expression 615 * @tparam Derived Datatype representing the abstract syntax tree of the expression 616 * @param other Expression 617 * @return the matrix 618 * 619 */ 620 template<typename Derived> operator +=arm_cmsis_dsp::MatrixView621 MatrixView& operator +=(const _Expr<Derived>& other) 622 { 623 eval2D(*this,*this + other.derived(),rows(),columns(),CURRENT_ARCH); 624 return(*this); 625 }; 626 627 /** @brief Add matrix from matrix view 628 * @param other Other matrix 629 * @return the matrix 630 * 631 */ operator +=arm_cmsis_dsp::MatrixView632 MatrixView& operator +=(const MatrixView& other) 633 { 634 eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH); 635 return(*this); 636 }; 637 638 /** @brief Add constant to matrix view 639 * @param other The constant 640 * @return the matrix 641 * 642 */ operator +=arm_cmsis_dsp::MatrixView643 MatrixView& operator +=(const T other) 644 { 645 eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH); 646 return(*this); 647 }; 648 649 /** @brief Subtract matrix from expression 650 * @tparam Derived Datatype representing the abstract syntax tree of the expression 651 * @param other expression 652 * @return the matrix 653 * 654 */ 655 template<typename Derived> operator -=arm_cmsis_dsp::MatrixView656 MatrixView& operator -=(const _Expr<Derived>& other) 657 { 658 eval2D(*this,*this - other.derived(),rows(),columns(),CURRENT_ARCH); 659 return(*this); 660 }; 661 662 /** @brief Subtract matrix view 663 * @param other Other matrix view 664 * @return the matrix 665 * 666 */ operator -=arm_cmsis_dsp::MatrixView667 MatrixView& operator -=(const MatrixView& other) 668 { 669 eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH); 670 return(*this); 671 }; 672 673 /** @brief Subtract constant 674 * @param other Other matrix 675 * @return the matrix 676 * 677 */ operator -=arm_cmsis_dsp::MatrixView678 MatrixView& operator -=(const T other) 679 { 680 eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH); 681 return(*this); 682 }; 683 684 /** @brief Elementwise multiply matrix view with expression 685 * @tparam Derived Datatype representing the abstract syntax tree of the expression 686 * @param other expression 687 * @return the matrix 688 * 689 */ 690 template<typename Derived> operator *=arm_cmsis_dsp::MatrixView691 MatrixView& operator *=(const _Expr<Derived>& other) 692 { 693 eval2D(*this,*this * other.derived(),rows(),columns(),CURRENT_ARCH); 694 return(*this); 695 }; 696 697 /** @brief Elementwise multiply matrix view with matrix view 698 * @param other Other matrix 699 * @return the matrix 700 * 701 */ operator *=arm_cmsis_dsp::MatrixView702 MatrixView& operator *=(const MatrixView& other) 703 { 704 eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH); 705 return(*this); 706 }; 707 708 /** @brief Elementwise multiply matrix view constant 709 * @param other constant 710 * @return the matrix 711 * 712 */ operator *=arm_cmsis_dsp::MatrixView713 MatrixView& operator *=(const T other) 714 { 715 eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH); 716 return(*this); 717 }; 718 719 /** 720 * @brief Display the matrix content for debug purpose 721 * @param stream Output stream 722 * @param other The matrix to display 723 * @return the stream 724 * 725 */ operator <<(std::ostream & stream,const MatrixView & other)726 friend std::ostream& operator<< (std::ostream& stream, const MatrixView& other) { 727 for(index_t row=0;row<other.rows();row++) 728 { 729 for(index_t col=0;col<other.columns();col++) 730 { 731 stream << other(row,col)<< " , "; 732 } 733 stream << "\r\n"; 734 } 735 stream << "\r\n"; 736 return(stream); 737 } 738 739 /** @brief Create a row view with stride 1 740 * @param i row index 741 * @param start Start index in row 742 * @return row view vector 743 * 744 */ rowarm_cmsis_dsp::MatrixView745 VectorView<T,1> row(const index_t i,const index_t start=0) 746 { 747 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+columns())); 748 } 749 750 /** @brief Create a row view with stride 1 751 * @param i row index 752 * @param start Start index in row 753 * @param stop Stop index in row 754 * @return row view vector 755 * 756 */ rowarm_cmsis_dsp::MatrixView757 VectorView<T,1> row(const index_t i,const index_t start,const index_t stop) 758 { 759 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+stop)); 760 } 761 762 /** @brief Create a constant row view with stride 1 763 * @param i row index 764 * @param start Start index in row 765 * @return row view vector 766 * 767 */ rowarm_cmsis_dsp::MatrixView768 const VectorView<T,1> row(const index_t i,const index_t start=0) const 769 { 770 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+columns())); 771 } 772 773 /** @brief Create a constant row view with stride 1 774 * @param i row index 775 * @param start Start index in row 776 * @param stop Stop index in row 777 * @return row view vector 778 * 779 */ rowarm_cmsis_dsp::MatrixView780 const VectorView<T,1> row(const index_t i,const index_t start,const index_t stop) const 781 { 782 return(VectorView<T,1>(v_,i*stride()+start,i*stride()+stop)); 783 } 784 785 786 /** @brief Create a column view vector 787 * @tparam CS column stride 788 * @param i column index 789 * @param start Start index in column 790 * @return column view vector 791 * 792 */ 793 template<int CS=1> colarm_cmsis_dsp::MatrixView794 VectorView<T,DYNAMIC> col(const index_t i,const index_t start=0) 795 { 796 return(VectorView<T,DYNAMIC>(v_,i+stride()*start,i+stride()*rows(),stride()*CS)); 797 } 798 799 800 /** @brief Create a column view vector 801 * @tparam CS column stride 802 * @param i column index 803 * @param start Start index in column 804 * @param stop Stop index in column 805 * @return column view vector 806 * 807 */ 808 template<int CS=1> colarm_cmsis_dsp::MatrixView809 VectorView<T,DYNAMIC> col(const index_t i,const index_t start,const index_t stop) 810 { 811 return(VectorView<T,DYNAMIC>(v_,i+stride()*start,i+stride()*stop,stride()*CS)); 812 } 813 814 /** @brief Create a constant column view vector 815 * @tparam CS column stride 816 * @param i column index 817 * @param start Start index in column 818 * @return column view vector 819 * 820 */ 821 template<int CS=1> colarm_cmsis_dsp::MatrixView822 const VectorView<T,DYNAMIC> col(const index_t i,const index_t start=0) const 823 { 824 return(VectorView<T,DYNAMIC>(v_,i+stride()*start,i+stride()*rows(),stride()*CS)); 825 } 826 827 /** @brief Create a constant column view vector 828 * @tparam CS column stride 829 * @param i column index 830 * @param start Start index in column 831 * @param stop Stop index in column 832 * @return column view vector 833 * 834 */ 835 template<int CS=1> colarm_cmsis_dsp::MatrixView836 const VectorView<T,DYNAMIC> col(const index_t i,const index_t start,const index_t stop) const 837 { 838 return(VectorView<T,DYNAMIC>(v_,i+stride()*start,i+stride()*stop,stride()*CS)); 839 } 840 841 #if defined(HAS_VECTOR) 842 //! Type of vectors for a vector architecture and for scalar datatype P 843 using VectorType = typename vector_traits<T>::vector; 844 845 846 /** 847 * @brief %Vector store at a given row,column position 848 * 849 * @param row row index 850 * @param col column index 851 * @param val %Vector value 852 * 853 * On an architecture supporting vectors, if the scalar datatype T 854 * has a corresponding vector datatype, this function stores a vector 855 * value at row,column in this matrix. 856 */ matrix_storearm_cmsis_dsp::MatrixView857 void matrix_store(const index_t row, 858 const index_t col, 859 const VectorType val) const 860 { 861 inner::vstore1<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]),val); 862 } 863 864 #if defined(HAS_PREDICATED_LOOP) 865 /** 866 * @brief %Vector store at a given row,column position with predicated tail 867 * 868 * @param row row index 869 * @param col column index 870 * @param remaining Number of remaining samples in the loop 871 * @param val Vector value to write at index i with tail predication 872 * 873 * On an architecture supporting vectors and predicated loops, if the 874 * scalar datatype T has a corresponding vector datatype, this 875 * function stores a vector value at row,column index in this matrix datatype 876 * with predication 877 */ matrix_store_tailarm_cmsis_dsp::MatrixView878 void matrix_store_tail(const index_t row, 879 const index_t col, 880 const vector_length_t remaining, 881 const VectorType val) const 882 { 883 inner::vstore1_z<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]),val,remaining,inner::vctpq<T>::mk(remaining)); 884 } 885 886 /** 887 * @brief %Vector operation at a given row,column position with predicated tail 888 * 889 * @param row row index 890 * @param col column index 891 * @param remaining Number of remaining samples in the loop 892 * @return the vector result of the operation 893 * 894 * On an architecture supporting vectors and predicated loops, if the 895 * scalar datatype T has a corresponding vector datatype, this 896 * function compute an operation at row,column index in this matrix datatype 897 * with predication 898 */ matrix_op_tailarm_cmsis_dsp::MatrixView899 VectorType const matrix_op_tail(const index_t row, 900 const index_t col, 901 const vector_length_t remaining) const 902 { 903 return(inner::vload1_z<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]),remaining,inner::vctpq<T>::mk(remaining))); 904 } 905 #endif 906 907 /** 908 * @brief %Vector operation at a given row,column position 909 * 910 * @param row row index 911 * @param col column index 912 * @return the vector result of the operation 913 * 914 * On an architecture supporting vectors and predicated loops, if the 915 * scalar datatype T has a corresponding vector datatype, this 916 * function compute an operation at row,column index in this matrix datatype 917 */ matrix_oparm_cmsis_dsp::MatrixView918 VectorType const matrix_op(const index_t row, 919 const index_t col) const 920 { 921 return(inner::vload1<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]))); 922 } 923 #endif 924 925 /** @brief Fill diagonal of a matrix with a vector 926 * @tparam VA Vector datatype 927 * @param a Vector for initializing the diagonal 928 * 929 */ 930 template<typename VA, 931 typename std::enable_if<IsVector<VA>::value && 932 SameElementType<VA,T>::value,bool>::type = true> fill_diagonalarm_cmsis_dsp::MatrixView933 void fill_diagonal(const VA& a) 934 { 935 _fill_diagonal(*this,a,this->length()); 936 } 937 938 /** @brief Create the transposed matrix 939 * @return a matrix 940 * 941 */ transposearm_cmsis_dsp::MatrixView942 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> transpose() const 943 { 944 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(columns(),rows()); 945 transposeTo(res,*this); 946 return(res); 947 } 948 949 /** @brief Create a matrix of same type 950 * @return a matrix 951 * 952 */ createarm_cmsis_dsp::MatrixView953 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> create() const 954 { 955 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(rows(),columns()); 956 return(res); 957 } 958 959 /** 960 * @brief Pointer to storage buffer 961 * @return Pointer to storage 962 */ ptrarm_cmsis_dsp::MatrixView963 T* ptr() const {return(v_);} 964 965 /** 966 * @brief Constant pointer to storage buffer 967 * @return Pointer to storage 968 */ const_ptrarm_cmsis_dsp::MatrixView969 const T* const_ptr() const {return(v_);} 970 971 972 protected: 973 T* const v_; 974 const vector_length_t nb_rows_; 975 const vector_length_t nb_cols_; 976 const uint32_t stride_; 977 }; 978 979 /* 980 981 982 Dynamic but with stride == nb_cols_ 983 984 */ 985 986 /** @brief Dynamic Matrix View 987 * @tparam T Type of the scalar 988 * 989 * This template is used for dynamic matrix (stride not known 990 * at build time) and when we do know that stride == number of 991 * columns. 992 * When stride is equal to the number of columns, the matrix can 993 * be seen as a vector and it enables to use the vector eval loop 994 * in the operator fusion mechanism. 995 * 996 * Those matrix views are created by expression when a reference to 997 * a matrix is used in the expression tree (to avoid copying the matrix). 998 * In this case, we do know that the matrix view is the full matrix and thus 999 * stride == number of columns 1000 */ 1001 template<typename T> 1002 struct MatrixView<T,CONSTRAINED_DYNAMIC>:VectorView<T,1> 1003 { 1004 /** @brief Number of rows 1005 * @return Number of rows 1006 */ rowsarm_cmsis_dsp::MatrixView1007 vector_length_t rows() const {return(nb_rows_);} 1008 1009 /** @brief Number of columns 1010 * @return Number of columns 1011 */ columnsarm_cmsis_dsp::MatrixView1012 vector_length_t columns() const {return(nb_cols_);} 1013 1014 /** @brief Number of stride 1015 * @return Number of stride 1016 */ stridearm_cmsis_dsp::MatrixView1017 uint32_t stride() const {return(nb_cols_);} 1018 1019 /** @brief Create matrix view on a buffer (buffer not owned by the view) 1020 * @param v buffer 1021 * @param rows number of rows 1022 * @param cols number of columns 1023 */ MatrixViewarm_cmsis_dsp::MatrixView1024 explicit MatrixView(T* v, 1025 const vector_length_t rows, 1026 const vector_length_t cols): 1027 VectorView<T,1>(v,0,rows*cols), 1028 nb_rows_(rows),nb_cols_(cols){}; 1029 1030 /** @brief Create matrix view on vector (vector not owned by the view) 1031 * @param v vector 1032 * @param rows number of rows 1033 * @param cols number of columns 1034 */ MatrixViewarm_cmsis_dsp::MatrixView1035 explicit MatrixView(const Vector_Base<T> &v, 1036 const vector_length_t rows, 1037 const vector_length_t cols): 1038 VectorView<T,1>(v.ptr(),0,rows*cols), 1039 nb_rows_(rows),nb_cols_(cols){}; 1040 ~MatrixViewarm_cmsis_dsp::MatrixView1041 virtual ~MatrixView() {}; 1042 MatrixViewarm_cmsis_dsp::MatrixView1043 MatrixView(const MatrixView& other): 1044 VectorView<T,1>(other), 1045 nb_rows_(other.nb_rows_),nb_cols_(other.nb_cols_){}; 1046 MatrixViewarm_cmsis_dsp::MatrixView1047 MatrixView(MatrixView&& other) : 1048 VectorView<T,1>(std::forward<MatrixView>(other)), 1049 nb_rows_(other.nb_rows_),nb_cols_(other.nb_cols_){}; 1050 1051 1052 MatrixView& operator=(const MatrixView& other) = delete; 1053 MatrixView& operator=(MatrixView&& other) = delete; 1054 1055 /** @brief Access matrix view element at given position 1056 * @param r Row index 1057 * @param c Column index 1058 * @return reference to element 1059 * 1060 */ operator ()arm_cmsis_dsp::MatrixView1061 T& operator()(const index_t r,const index_t c) 1062 { 1063 return(&(*this)[r*stride()+c]); 1064 } 1065 1066 /** @brief Access matrix view element at given position 1067 * @param r Row index 1068 * @param c Column index 1069 * @return reference to element 1070 * 1071 */ operator ()arm_cmsis_dsp::MatrixView1072 T const operator()(const index_t r,const index_t c) const 1073 { 1074 return((*this)[r*stride()+c]); 1075 } 1076 1077 /** @brief Assign matrix view from expression 1078 * @tparam Derived Datatype representing the abstract syntax tree of the expression 1079 * @param other Expression 1080 * @return the matrix 1081 * 1082 */ 1083 template<typename Derived> operator =arm_cmsis_dsp::MatrixView1084 MatrixView& operator=(const _Expr<Derived>&other) 1085 { 1086 eval2D(*this,other.derived(),rows(),columns(),CURRENT_ARCH); 1087 return(*this); 1088 } 1089 1090 /** @brief Assign matrix view from constant 1091 * @param val The constant 1092 * @return the matrix 1093 * 1094 */ operator =arm_cmsis_dsp::MatrixView1095 MatrixView& operator=(const T val) 1096 { 1097 _Fill2D(*this,val,rows(),columns(),CURRENT_ARCH); 1098 1099 return(*this); 1100 } 1101 1102 1103 /** @brief Add matrix from expression 1104 * @tparam Derived Datatype representing the abstract syntax tree of the expression 1105 * @param other Expression 1106 * @return the matrix 1107 * 1108 */ 1109 template<typename Derived> operator +=arm_cmsis_dsp::MatrixView1110 MatrixView& operator +=(const _Expr<Derived>& other) 1111 { 1112 eval2D(*this,*this + other.derived(),rows(),columns(),CURRENT_ARCH); 1113 return(*this); 1114 }; 1115 1116 /** @brief Add matrix from matrix view 1117 * @param other Other matrix 1118 * @return the matrix 1119 * 1120 */ operator +=arm_cmsis_dsp::MatrixView1121 MatrixView& operator +=(const MatrixView& other) 1122 { 1123 eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH); 1124 return(*this); 1125 }; 1126 1127 /** @brief Add constant to matrix view 1128 * @param other The constant 1129 * @return the matrix 1130 * 1131 */ operator +=arm_cmsis_dsp::MatrixView1132 MatrixView& operator +=(const T other) 1133 { 1134 eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH); 1135 return(*this); 1136 }; 1137 1138 /** @brief Subtract matrix from expression 1139 * @tparam Derived Datatype representing the abstract syntax tree of the expression 1140 * @param other expression 1141 * @return the matrix 1142 * 1143 */ 1144 template<typename Derived> operator -=arm_cmsis_dsp::MatrixView1145 MatrixView& operator -=(const _Expr<Derived>& other) 1146 { 1147 eval2D(*this,*this - other.derived(),rows(),columns(),CURRENT_ARCH); 1148 return(*this); 1149 }; 1150 1151 /** @brief Subtract matrix view 1152 * @param other Other matrix view 1153 * @return the matrix 1154 * 1155 */ operator -=arm_cmsis_dsp::MatrixView1156 MatrixView& operator -=(const MatrixView& other) 1157 { 1158 eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH); 1159 return(*this); 1160 }; 1161 1162 /** @brief Subtract constant 1163 * @param other Other matrix 1164 * @return the matrix 1165 * 1166 */ operator -=arm_cmsis_dsp::MatrixView1167 MatrixView& operator -=(const T other) 1168 { 1169 eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH); 1170 return(*this); 1171 }; 1172 1173 /** @brief Elementwise multiply matrix view with expression 1174 * @tparam Derived Datatype representing the abstract syntax tree of the expression 1175 * @param other expression 1176 * @return the matrix 1177 * 1178 */ 1179 template<typename Derived> operator *=arm_cmsis_dsp::MatrixView1180 MatrixView& operator *=(const _Expr<Derived>& other) 1181 { 1182 eval2D(*this,*this * other.derived(),rows(),columns(),CURRENT_ARCH); 1183 return(*this); 1184 }; 1185 1186 /** @brief Elementwise multiply matrix view with matrix view 1187 * @param other Other matrix 1188 * @return the matrix 1189 * 1190 */ operator *=arm_cmsis_dsp::MatrixView1191 MatrixView& operator *=(const MatrixView& other) 1192 { 1193 eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH); 1194 return(*this); 1195 }; 1196 1197 /** @brief Elementwise multiply matrix view constant 1198 * @param other constant 1199 * @return the matrix 1200 * 1201 */ operator *=arm_cmsis_dsp::MatrixView1202 MatrixView& operator *=(const T other) 1203 { 1204 eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH); 1205 return(*this); 1206 }; 1207 1208 /** 1209 * @brief Display the matrix content for debug purpose 1210 * @param stream Output stream 1211 * @param other The matrix to display 1212 * @return the stream 1213 * 1214 */ operator <<(std::ostream & stream,const MatrixView & other)1215 friend std::ostream& operator<< (std::ostream& stream, const MatrixView& other) { 1216 for(index_t row=0;row<other.rows();row++) 1217 { 1218 for(index_t col=0;col<other.columns();col++) 1219 { 1220 stream << other(row,col)<< " , "; 1221 } 1222 stream << "\r\n"; 1223 } 1224 stream << "\r\n"; 1225 return(stream); 1226 } 1227 1228 /** @brief Create a row view with stride 1 1229 * @param i row index 1230 * @param start Start index in row 1231 * @return row view vector 1232 * 1233 */ rowarm_cmsis_dsp::MatrixView1234 VectorView<T,1> row(const index_t i,const index_t start=0) 1235 { 1236 return(VectorView<T,1>(this->ptr(),i*stride()+start,i*stride()+columns())); 1237 } 1238 1239 /** @brief Create a row view with stride 1 1240 * @param i row index 1241 * @param start Start index in row 1242 * @param stop Stop index in row 1243 * @return row view vector 1244 * 1245 */ rowarm_cmsis_dsp::MatrixView1246 VectorView<T,1> row(const index_t i,const index_t start,const index_t stop) 1247 { 1248 return(VectorView<T,1>(this->ptr(),i*stride()+start,i*stride()+stop)); 1249 } 1250 1251 /** @brief Create a constant row view with stride 1 1252 * @param i row index 1253 * @param start Start index in row 1254 * @return row view vector 1255 * 1256 */ rowarm_cmsis_dsp::MatrixView1257 const VectorView<T,1> row(const index_t i,const index_t start=0) const 1258 { 1259 return(VectorView<T,1>(this->ptr(),i*stride()+start,i*stride()+columns())); 1260 } 1261 1262 /** @brief Create a constant row view with stride 1 1263 * @param i row index 1264 * @param start Start index in row 1265 * @param stop Stop index in row 1266 * @return row view vector 1267 * 1268 */ rowarm_cmsis_dsp::MatrixView1269 const VectorView<T,1> row(const index_t i,const index_t start,const index_t stop) const 1270 { 1271 return(VectorView<T,1>(this->ptr(),i*stride()+start,i*stride()+stop)); 1272 } 1273 1274 /** @brief Create a column view vector 1275 * @tparam CS column stride 1276 * @param i column index 1277 * @param start Start index in column 1278 * @return column view vector 1279 * 1280 */ 1281 template<int CS=1> colarm_cmsis_dsp::MatrixView1282 VectorView<T,DYNAMIC> col(const index_t i,const index_t start=0) 1283 { 1284 return(VectorView<T,DYNAMIC>(this->ptr(),i+stride()*start,i+stride()*rows(),stride()*CS)); 1285 } 1286 1287 /** @brief Create a column view vector 1288 * @tparam CS column stride 1289 * @param i column index 1290 * @param start Start index in column 1291 * @param stop Stop index in column 1292 * @return column view vector 1293 * 1294 */ 1295 template<int CS=1> colarm_cmsis_dsp::MatrixView1296 VectorView<T,DYNAMIC> col(const index_t i,const index_t start,const index_t stop) 1297 { 1298 return(VectorView<T,DYNAMIC>(this->ptr(),i+stride()*start,i+stride()*stop,stride()*CS)); 1299 } 1300 1301 /** @brief Create a constant column view vector 1302 * @tparam CS column stride 1303 * @param i column index 1304 * @param start Start index in column 1305 * @return column view vector 1306 * 1307 */ 1308 template<int CS=1> colarm_cmsis_dsp::MatrixView1309 const VectorView<T,DYNAMIC> col(const index_t i,const index_t start=0) const 1310 { 1311 return(VectorView<T,DYNAMIC>(this->ptr(),i+stride()*start,i+stride()*rows(),stride()*CS)); 1312 } 1313 1314 /** @brief Create a constant column view vector 1315 * @tparam CS column stride 1316 * @param i column index 1317 * @param start Start index in column 1318 * @param stop Stop index in column 1319 * @return column view vector 1320 * 1321 */ 1322 template<int CS=1> colarm_cmsis_dsp::MatrixView1323 const VectorView<T,DYNAMIC> col(const index_t i,const index_t start,const index_t stop) const 1324 { 1325 return(VectorView<T,DYNAMIC>(this->ptr(),i+stride()*start,i+stride()*stop,stride()*CS)); 1326 } 1327 1328 #if defined(HAS_VECTOR) 1329 //! Type of vectors for a vector architecture and for scalar datatype P 1330 using VectorType = typename vector_traits<T>::vector; 1331 1332 /** 1333 * @brief %Vector store at a given row,column position 1334 * 1335 * @param row row index 1336 * @param col column index 1337 * @param val %Vector value 1338 * 1339 * On an architecture supporting vectors, if the scalar datatype T 1340 * has a corresponding vector datatype, this function stores a vector 1341 * value at row,column in this matrix. 1342 */ matrix_storearm_cmsis_dsp::MatrixView1343 void matrix_store(const index_t row, 1344 const index_t col, 1345 const VectorType val) const 1346 { 1347 inner::vstore1<1>((typename std::remove_cv<T>::type*)(ptr(row*stride() + col)),val); 1348 } 1349 1350 #if defined(HAS_PREDICATED_LOOP) 1351 /** 1352 * @brief %Vector store at a given row,column position with predicated tail 1353 * 1354 * @param row row index 1355 * @param col column index 1356 * @param remaining Number of remaining samples in the loop 1357 * @param val Vector value to write at index i with tail predication 1358 * 1359 * On an architecture supporting vectors and predicated loops, if the 1360 * scalar datatype T has a corresponding vector datatype, this 1361 * function stores a vector value at row,column index in this matrix datatype 1362 * with predication 1363 */ matrix_store_tailarm_cmsis_dsp::MatrixView1364 void matrix_store_tail(const index_t row, 1365 const index_t col, 1366 const vector_length_t remaining, 1367 const VectorType val) const 1368 { 1369 inner::vstore1_z<1>((typename std::remove_cv<T>::type*)(ptr(row*stride() + col)),val,remaining,inner::vctpq<T>::mk(remaining)); 1370 } 1371 1372 /** 1373 * @brief %Vector operation at a given row,column position with predicated tail 1374 * 1375 * @param row row index 1376 * @param col column index 1377 * @param remaining Number of remaining samples in the loop 1378 * @return the vector result of the operation 1379 * 1380 * On an architecture supporting vectors and predicated loops, if the 1381 * scalar datatype T has a corresponding vector datatype, this 1382 * function compute an operation at row,column index in this matrix datatype 1383 * with predication 1384 */ matrix_op_tailarm_cmsis_dsp::MatrixView1385 VectorType const matrix_op_tail(const index_t row, 1386 const index_t col, 1387 const vector_length_t remaining) const 1388 { 1389 return(inner::vload1_z<1>((typename std::remove_cv<T>::type*)(VectorView<T,1>::ptr(row*stride() + col)),remaining,inner::vctpq<T>::mk(remaining))); 1390 } 1391 #endif 1392 1393 /** 1394 * @brief %Vector operation at a given row,column position 1395 * 1396 * @param row row index 1397 * @param col column index 1398 * @return the vector result of the operation 1399 * 1400 * On an architecture supporting vectors and predicated loops, if the 1401 * scalar datatype T has a corresponding vector datatype, this 1402 * function compute an operation at row,column index in this matrix datatype 1403 */ matrix_oparm_cmsis_dsp::MatrixView1404 VectorType const matrix_op(const index_t row, 1405 const index_t col) const 1406 { 1407 return(inner::vload1<1>((typename std::remove_cv<T>::type*)(VectorView<T,1>::ptr(row*stride() + col)))); 1408 } 1409 #endif 1410 1411 /** @brief Fill diagonal of a matrix with a vector 1412 * @tparam VA Vector datatype 1413 * @param a Vector for initializing the diagonal 1414 * 1415 */ 1416 template<typename VA, 1417 typename std::enable_if<IsVector<VA>::value && 1418 SameElementType<VA,T>::value,bool>::type = true> fill_diagonalarm_cmsis_dsp::MatrixView1419 void fill_diagonal(const VA& a) 1420 { 1421 _fill_diagonal(*this,a,this->length()); 1422 } 1423 1424 /** @brief Create the transposed matrix 1425 * @return a matrix 1426 * 1427 */ transposearm_cmsis_dsp::MatrixView1428 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> transpose() const 1429 { 1430 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(columns(),rows()); 1431 transposeTo(res,*this); 1432 return(res); 1433 } 1434 1435 /** @brief Create a matrix of same type 1436 * @return a matrix 1437 * 1438 */ createarm_cmsis_dsp::MatrixView1439 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> create() const 1440 { 1441 Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(rows(),columns()); 1442 return(res); 1443 } 1444 1445 1446 protected: 1447 const vector_length_t nb_rows_; 1448 const vector_length_t nb_cols_; 1449 }; 1450 1451 /*! @} */ 1452 1453 }