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 }