Commit fafb5fe4 authored by Christophe Favergeon's avatar Christophe Favergeon
Browse files

Improved vector and matrix documentation on C++ extension

parent 3ec7f427
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -773,7 +773,7 @@ SHOW_FILES = YES
# Folder Tree View (if specified).
# The default value is: YES.

SHOW_NAMESPACES        = YES
SHOW_NAMESPACES        = NO

# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
@@ -2430,7 +2430,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

PREDEFINED             = ARM_MATH_NEON=1 ARM_FLOAT16_SUPPORTED=1 __STATIC_FORCEINLINE= __ALIGNED(x)=
PREDEFINED             = HAS_VECTOR HAS_PREDICATED_LOOP ARM_MATH_NEON=1 ARM_FLOAT16_SUPPORTED=1 __STATIC_FORCEINLINE= __ALIGNED(x)=

# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
+66 −22
Original line number Diff line number Diff line
@@ -2,13 +2,11 @@
/** @file */ 
#pragma once 

/** \addtogroup DSPPP C++ extension
/** \defgroup DSPPP C++ extension
 *  C++ template extension to CMSIS-DSP. It is not yet part of
 *  the pack but the headers can be found on the 
 *  [CMSIS-DSP github](https://github.com/ARM-software/CMSIS-DSP/dsppp/Include)
 *  The principles are described in this @ref dsppp_main "page"
 *  @{
 *  @}
 */


@@ -22,7 +20,7 @@ namespace arm_cmsis_dsp {

/** \addtogroup ALGO Architecture independent algorithms
 *  \ingroup DSPPP
 *  @{
 *  Algorithms written in an architecture independent way
 */

/*
@@ -32,9 +30,12 @@ Matrix transpose
*/


/**
 * Transpose a matrix.

 /** @ingroup ALGO
  *  @brief Transpose a matrix.
  *
  * @tparam MA Any matrix type
  * @tparam MB Any matrix type
  * @param dst Destination matrix.
  * @param src Source matrix.
  *
@@ -52,6 +53,7 @@ inline void transposeTo(MA &dst,
}



/*

Init a diagonal matrix (0 outside of diagonal)
@@ -110,7 +112,17 @@ inline void _identity(Matrix<P,R,R,A> &v,
}



/**
 * @ingroup ALGO
 * @brief Matrix x Vector product.
 *
 * @tparam M Any matrix type
 * @tparam V Any vector type
 * @param m matrix.
 * @param v vector.
 * @return The matrix x vector product
 *
 */
template<typename M,
         typename V,
         typename std::enable_if<CompatibleStaticMatVecProduct<M,V>::value,bool>::type = true>
@@ -141,6 +153,17 @@ inline void dot(RES && res,const M&m,const V&v)
   _dot_m_v(res,m,v,CURRENT_ARCH);
}


 /** @ingroup ALGO
  *  @brief Matrix x Matrix product.
  *
  * @tparam MA Any matrix type
  * @tparam MB Any matrix type
  * @param ma Matrix.
  * @param mb Matrix.
  * @return ma x mb matrix product
  *
  */
template<typename MA,
         typename MB,
         typename std::enable_if<CompatibleStaticMatMatProduct<MA,MB>::value &&
@@ -197,12 +220,20 @@ inline typename OutputMatrix<MA,MB>::type dot(const MA&ma,const MB&mb)
   return(res);
}

/*


Get res matrix as argument to avoid memory allocation when
assigning the result to a different type of Matrix (like a Matrix view).

 /** @ingroup ALGO
  *  @brief Matrix x Matrix product
  *
  * @tparam MA Any matrix type
  * @tparam MB Any matrix type
  * @tparam RES Any matrix type
  * @param res Output matrix. Result of ma x mb is written to this argument
  * @param ma Matrix.
  * @param mb Matrix.
  * 
  * Used in dynamic mode (dimension of matrix not know at build time)
  * to avoid a memory allocation if the result matrix is already available
  * (Enable to reuse the same matrix storage for the result in some algorithms)
  *
  */
template<typename MA,
         typename MB,
@@ -246,7 +277,14 @@ inline typename OutputMatrix<MA,MB>::type dot(const MA&ma,const MB&mb,const TMP
}



 /** @ingroup ALGO
  *  @brief Create identity matrix
  *
  * @tparam P Datatype of matrix elements
  * @param l Dimension of matrix (l x l)
  * @return Identity matrix. It is a dynamic matrix (size not know at build time)
  * 
  */
template<typename P>
Matrix<P,DYNAMIC,DYNAMIC,TMP_ALLOC> mk_identity(const vector_length_t l)
{
@@ -256,6 +294,14 @@ Matrix<P,DYNAMIC,DYNAMIC,TMP_ALLOC> mk_identity(const vector_length_t l)
};


 /** @ingroup ALGO
  *  @brief Create identity matrix
  *
  * @tparam P Datatype of matrix elements
  * @tparam L Matrix dimension (L x L)
  * @return Identity matrix. It is a static matrix : size known at build time.
  * 
  */
template<typename P,int L>
Matrix<P,L,L,TMP_ALLOC> mk_identity()
{
@@ -264,6 +310,4 @@ Matrix<P,L,L,TMP_ALLOC> mk_identity()
       return(res);
};

/*! @} */

}
+93 −4
Original line number Diff line number Diff line
@@ -463,20 +463,42 @@ struct VecRef<Matrix<P,R,C,A>,((R<0) || (C<0))>
 * 
 ****************/

/**
 * @brief  Outer product operator for expressions
 *
 * @tparam LHS Left hand side datatype
 * @tparam RHS Right hand side datatype
 * @tparam DerivedOp Operator for the Outer operation
 * 
 * vector `op` vector (including matrix)
 */
template<typename LHS,typename RHS,typename DerivedOp>
struct _Outer: _Expr<_Outer<LHS,RHS,DerivedOp>>
{
    //! Type of vector elements
    using Scalar = typename traits<LHS>::Scalar;
#if defined(HAS_VECTOR)
    //! Type of vector in the architecture
    using Vector = typename traits<LHS>::Vector;
#endif
    /**
    * @brief      Create an Outer operator
    *
    * @param lhs Left hand side expression
    * @param rhs Right hand side expression
    * @param op operator
    */
    _Outer(const LHS &lhs,
            const RHS &rhs,
            const _BinaryOperator<Scalar,DerivedOp> &op):
            lhs_(lhs),rhs_(rhs),op_(op){
    }

    
    /**
    * @brief      Create an Outer operator from another operator of same type
    *
    * @param other the other operator
    */
    _Outer(const _Outer &other):
    lhs_(other.lhs_),rhs_(other.rhs_),op_(other.op_){
    }
@@ -484,6 +506,11 @@ struct _Outer: _Expr<_Outer<LHS,RHS,DerivedOp>>
    _Outer& operator=(const _Outer& other) = delete;
    _Outer& operator=(_Outer&& other) = delete;

    /**
    * @brief   Move semantic for _Outer operator
    *
    * @param other the other operator
    */
    _Outer(_Outer &&other): 
    lhs_(std::move(other.lhs_)),rhs_(std::move(other.rhs_)),op_(std::move(other.op_))
    {
@@ -491,12 +518,26 @@ struct _Outer: _Expr<_Outer<LHS,RHS,DerivedOp>>

    

    /**
    * @brief   Length of the matrix (seen as vector) resulting from the outer operator
    * @tparam R Right hand side datatype
    * @tparam L Left hand side datatype
    *
    * @return  vector dimension
    */
    template<typename R=RHS, typename L=LHS,
             typename std::enable_if<IsVector<L>::value && IsVector<R>::value,bool>::type = true>
    vector_length_t length() const {
        return(lhs_.length() * rhs_.length());
    }

    /**
    * @brief   Rows of the matrix
    * @tparam R Right hand side datatype
    * @tparam L Left hand side datatype
    *
    * @return  number of rows
    */
    template<typename R=RHS, typename L=LHS,
             typename std::enable_if<IsVector<L>::value,bool>::type = true>
    vector_length_t rows() const {
@@ -504,7 +545,13 @@ struct _Outer: _Expr<_Outer<LHS,RHS,DerivedOp>>
    }



    /**
    * @brief   Columns of the matrix
    * @tparam R Right hand side datatype
    * @tparam L Left hand side datatype
    *
    * @return  number of columns
    */
    template<typename R=RHS, typename L=LHS,
             typename std::enable_if<IsVector<R>::value,bool>::type = true>
    vector_length_t columns() const {
@@ -512,7 +559,15 @@ struct _Outer: _Expr<_Outer<LHS,RHS,DerivedOp>>
    }



    /**
    * @brief   Expression value at given position
    * @tparam R Right hand side datatype
    * @tparam L Left hand side datatype
    * @param r row index
    * @param c column index
    *
    * @return  expression value
    */
    template<typename R=RHS, typename L=LHS,
             typename std::enable_if<IsVector<L>::value && 
                        IsVector<R>::value,bool>::type = true>
@@ -523,13 +578,25 @@ struct _Outer: _Expr<_Outer<LHS,RHS,DerivedOp>>

  
#if defined(HAS_VECTOR)
    /*************
    /*
     * 
     * For matrix
     * 
     */

    /* V + V */

    /**
    * @brief   Expression vector value at given position
    * @tparam R Right hand side datatype
    * @tparam L Left hand side datatype
    * @param r row index
    * @param c column index
    *
    * @return  expression vector value
    *
    * Vector + Vector (matrix interpreted as a Vector)
    */
    template<typename R=RHS, typename L=LHS,
             typename std::enable_if<IsVector<L>::value && 
                        IsVector<R>::value,bool>::type = true>
@@ -538,6 +605,18 @@ struct _Outer: _Expr<_Outer<LHS,RHS,DerivedOp>>
        return(op_(lhs_[r],rhs_.vector_op(c)));
    }

    /**
    * @brief   Expression vector value at given position with tail predication
    * @tparam R Right hand side datatype
    * @tparam L Left hand side datatype
    * @param r row index
    * @param c column index
    * @param remaining remaining number of samples in loop
    *
    * @return  expression vector value
    *
    * Vector + Vector (matrix interpreted as a Vector)
    */
    template<typename R=RHS, typename L=LHS,
             typename std::enable_if<IsVector<L>::value && 
                        IsVector<R>::value,bool>::type = true>
@@ -623,6 +702,16 @@ struct NbCols<_Outer<LHS,RHS,OP>>
};


/**
* @brief   Outer product
* @tparam VA Right hand side datatype
* @tparam VB Left hand side datatype
* @param a Vector a
* @param b Vector b
*
* @return  Outer product of a and b
*
*/
template<typename VA,typename VB,
typename std::enable_if<vector_idx_pair<VA,VB>(),bool>::type = true>
inline auto outer(const VA&a,const VB&b)
+551 −2

File changed.

Preview size limit exceeded, changes collapsed.

+232 −1
Original line number Diff line number Diff line
@@ -24,18 +24,43 @@ namespace arm_cmsis_dsp {
 *  @{
 */

/** @brief Matrix
 *  @tparam T Type of the scalar
 *  @tparam S Stride
 */
template<typename T,int S=1>
struct MatrixView
{
   /** @brief Number of rows
    *  @return Number of rows
    */
   vector_length_t rows() const {return(nb_rows_);}

   /** @brief Number of columns
    *  @return Number of columns
    */
   vector_length_t columns() const {return(nb_cols_);}

    /** @brief Number of stride
    *  @return Number of stride
    */
   constexpr uint32_t stride() const {return(S);}

    /** @brief Create matrix view on a buffer (buffer not owned by the view)
    * @param v buffer
    * @param rows number of rows
    * @param cols number of columns
    */
   explicit MatrixView(T* v,
              const vector_length_t rows,
              const vector_length_t cols):
   v_(v),nb_rows_(rows),nb_cols_(cols){};

    /** @brief Create matrix view on vector (vector not owned by the view)
    * @param v vector
    * @param rows number of rows
    * @param cols number of columns
    */
   explicit MatrixView(const Vector_Base<T> &v,
              const vector_length_t rows,
              const vector_length_t cols):
@@ -55,17 +80,35 @@ struct MatrixView
   MatrixView& operator=(const MatrixView& other) = delete;
   MatrixView& operator=(MatrixView&& other)  = delete;

   /** @brief Access matrix view element at given position
    * @param r Row index
    * @param c Column index
    * @return reference to element
    *
    */
   T& operator()(const index_t r,const index_t c)
   {
     return(v_[r*stride()+c]);
   }

    /** @brief Access matrix view element at given position
    * @param r Row index
    * @param c Column index
    * @return reference to element
    *
    */
   T const operator()(const index_t r,const index_t c) const
   {
     return(v_[r*stride()+c]);
   }


   /** @brief Assign matrix from expression
    * @tparam Derived Datatype representing the abstract syntax tree of the expression
    * @param other Expression
    * @return the matrix
    * 
    */
   template<typename Derived>
   MatrixView& operator=(const _Expr<Derived>&other)
   {
@@ -73,6 +116,11 @@ struct MatrixView
      return(*this);
   }

    /** @brief Assign constant from expression
    * @param val The constant
    * @return the matrix
    * 
    */
   MatrixView& operator=(const T val)
   {
        _Fill2D(*this,val,rows(),columns(),CURRENT_ARCH);
@@ -81,6 +129,12 @@ struct MatrixView
   }


    /** @brief Add matrix from expression
    * @tparam Derived Datatype representing the abstract syntax tree of the expression
    * @param other Expression
    * @return the matrix
    * 
    */
   template<typename Derived>
   MatrixView& operator +=(const _Expr<Derived>& other)
   {
@@ -88,18 +142,35 @@ struct MatrixView
      return(*this);
   };

    /** @brief Add matrix from matrix view
    * @param other Other matrix
    * @return the matrix
    * 
    */
   MatrixView& operator +=(const MatrixView& other)
   {
      eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH);
      return(*this);
   };


    /** @brief Add constant to matrix view
    * @param other The constant
    * @return the matrix
    * 
    */
   MatrixView& operator +=(const T other)
   {
      eval2D(*this,*this + other,rows(),columns(),CURRENT_ARCH);
      return(*this);
   };

    /** @brief Subtract matrix from expression
    * @tparam Derived Datatype representing the abstract syntax tree of the expression
    * @param other expression
    * @return the matrix
    * 
    */
   template<typename Derived>
   MatrixView& operator -=(const _Expr<Derived>& other)
   {
@@ -107,19 +178,34 @@ struct MatrixView
      return(*this);
   };

   
    /** @brief Subtract matrix view
    * @param other Other matrix view
    * @return the matrix
    * 
    */
   MatrixView& operator -=(const MatrixView& other)
   {
      eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH);
      return(*this);
   };

    /** @brief Subtract constant
    * @param other Other matrix
    * @return the matrix
    * 
    */
   MatrixView& operator -=(const T other)
   {
      eval2D(*this,*this - other,rows(),columns(),CURRENT_ARCH);
      return(*this);
   };

    /** @brief Elementwise multiply matrix view with expression
    * @tparam Derived Datatype representing the abstract syntax tree of the expression
    * @param other expression
    * @return the matrix
    * 
    */
   template<typename Derived>
   MatrixView& operator *=(const _Expr<Derived>& other)
   {
@@ -127,18 +213,35 @@ struct MatrixView
      return(*this);
   };

   /** @brief Elementwise multiply matrix view with matrix view
    * @param other Other matrix
    * @return the matrix
    * 
    */
   MatrixView& operator *=(const MatrixView& other)
   {
      eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH);
      return(*this);
   };

   /** @brief Elementwise multiply matrix view constant
    * @param other constant
    * @return the matrix
    * 
    */
   MatrixView& operator *=(const T other)
   {
      eval2D(*this,*this * other,rows(),columns(),CURRENT_ARCH);
      return(*this);
   };

  /**
    * @brief  Display the matrix content for debug purpose
    * @param stream Output stream
    * @param other The matrix to display
    * @return the stream
    * 
    */
  friend std::ostream& operator<< (std::ostream& stream, const MatrixView& other) {
        for(index_t row=0;row<other.rows();row++)
        {
@@ -152,44 +255,100 @@ struct MatrixView
        return(stream);
    }

   /** @brief Create a row view with stride 1
    * @param i row index
    * @param start Start index in row
    * @return row view vector
    *
    */
   VectorView<T,1> row(const index_t i,const index_t start=0)
   {
     return(VectorView<T,1>(v_,i*stride()+start,i*stride()+columns()));
   }

    /** @brief Create a row view with stride 1
    * @param i row index
    * @param start Start index in row
    * @param stop Stop index in row
    * @return row view vector
    *
    */
   VectorView<T,1> row(const index_t i,const index_t start,const index_t stop)
   {
     return(VectorView<T,1>(v_,i*stride()+start,i*stride()+stop));
   }

   /** @brief Create a constant row view with stride 1
    * @param i row index
    * @param start Start index in row
    * @return row view vector
    *
    */
   const VectorView<T,1> row(const index_t i,const index_t start=0) const
   {
     return(VectorView<T,1>(v_,i*stride()+start,i*stride()+columns()));
   }

   /** @brief Create a constant row view with stride 1
    * @param i row index
    * @param start Start index in row
    * @param stop Stop index in row
    * @return row view vector
    *
    */
   const VectorView<T,1> row(const index_t i,const index_t start,const index_t stop) const
   {
     return(VectorView<T,1>(v_,i*stride()+start,i*stride()+stop));
   }

    /** @brief Create a column view vector
    * @tparam CS column stride
    * @param i column index
    * @param start Start index in column
    * @return column view vector
    *
    */
   template<int CS=1>
   VectorView<T,CS*S> col(const index_t i,const index_t start=0)
   {
     return(VectorView<T,CS*S>(v_,i+stride()*start,i+stride()*rows()));
   }

    /** @brief Create a column view vector
    * @tparam CS column stride
    * @param i column index
    * @param start Start index in column
    * @param stop Stop index in column
    * @return column view vector
    *
    */
   template<int CS=1>
   VectorView<T,CS*S> col(const index_t i,const index_t start,const index_t stop)
   {
     return(VectorView<T,CS*S>(v_,i+stride()*start,i+stride()*stop));
   }

   /** @brief Create a constant column view vector
    * @tparam CS column stride
    * @param i column index
    * @param start Start index in column
    * @return column view vector
    *
    */
   template<int CS=1>
   const VectorView<T,CS*S> col(const index_t i,const index_t start=0) const
   {
     return(VectorView<T,CS*S>(v_,i+stride()*start,i+stride()*rows()));
   }

    /** @brief Create a constant column view vector
    * @tparam CS column stride
    * @param i column index
    * @param start Start index in column
    * @param stop Stop index in column
    * @return column view vector
    *
    */
   template<int CS=1>
   const VectorView<T,CS*S> col(const index_t i,const index_t start,const index_t stop) const
   {
@@ -197,7 +356,20 @@ struct MatrixView
   }

   #if defined(HAS_VECTOR)
    //! Type of vectors for a vector architecture and for scalar datatype P
    using VectorType = typename vector_traits<T>::vector;

    /**
    * @brief   %Vector store at a given row,column position
    *
    * @param row row index
    * @param col column index
    * @param val %Vector value
    * 
    * On an architecture supporting vectors, if the scalar datatype T
    * has a corresponding vector datatype, this function stores a vector
    * value at row,column in this matrix.
    */
    void matrix_store(const index_t row,
                      const index_t col,
                      const VectorType val) const
@@ -206,6 +378,19 @@ struct MatrixView
    }

#if defined(HAS_PREDICATED_LOOP)
    /**
    * @brief   %Vector store at a given row,column position with predicated tail
    *
    * @param row row index
    * @param col column index
    * @param remaining Number of remaining samples in the loop
    * @param val Vector value to write at index i with tail predication
    * 
    * On an architecture supporting vectors and predicated loops, if the 
    * scalar datatype T has a corresponding vector datatype, this 
    * function stores a vector value at row,column index in this matrix datatype
    * with predication
    */
    void matrix_store_tail(const index_t row,
                           const index_t col,
                           const vector_length_t remaining,
@@ -214,6 +399,19 @@ struct MatrixView
        inner::vstore1_z<1>((typename std::remove_cv<T>::type*)(&v_[row*stride() + col]),val,remaining,inner::vctpq<T>::mk(remaining));
    }

     /**
    * @brief   %Vector operation at a given row,column position with predicated tail
    *
    * @param row row index
    * @param col column index
    * @param remaining Number of remaining samples in the loop
    * @return the vector result of the operation
    * 
    * On an architecture supporting vectors and predicated loops, if the 
    * scalar datatype T has a corresponding vector datatype, this 
    * function compute an operation at row,column index in this matrix datatype
    * with predication
    */
    VectorType const matrix_op_tail(const index_t row,
                                const index_t col,
                                const vector_length_t remaining) const
@@ -222,6 +420,17 @@ struct MatrixView
    }
#endif

     /**
    * @brief   %Vector operation at a given row,column position
    *
    * @param row row index
    * @param col column index
    * @return the vector result of the operation
    * 
    * On an architecture supporting vectors and predicated loops, if the 
    * scalar datatype T has a corresponding vector datatype, this 
    * function compute an operation at row,column index in this matrix datatype
    */
    VectorType const matrix_op(const index_t row,
                           const index_t col) const
    {
@@ -229,6 +438,11 @@ struct MatrixView
    }
#endif

    /** @brief Fill diagonal of a matrix with a vector
    * @tparam VA Vector datatype
    * @param a Vector for initializing the diagonal
    * 
    */
    template<typename VA,
            typename std::enable_if<IsVector<VA>::value && 
            SameElementType<VA,T>::value,bool>::type = true>
@@ -237,6 +451,10 @@ struct MatrixView
       _fill_diagonal(*this,a,this->length());
    }

    /** @brief Create the transposed matrix
    * @return a matrix
    *   
    */
    Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> transpose() const
    {
       Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(columns(),rows());
@@ -244,13 +462,26 @@ struct MatrixView
       return(res);
    }

    /** @brief Create a matrix of same type
    * @return a matrix
    *   
    */
    Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> create() const
    {
       Matrix<T,DYNAMIC,DYNAMIC,TMP_ALLOC> res(rows(),columns());
       return(res);
    }

     /**
    * @brief      Pointer to storage buffer
    * @return Pointer to storage
    */
    T* ptr() const {return(v_);}

     /**
    * @brief      Constant pointer to storage buffer
    * @return Pointer to storage
    */
    const T* const_ptr() const {return(v_);}

protected:
Loading