CMSIS-DSP: Update to Python wrapper

New functions added.
diff --git a/CMSIS/DSP/PythonWrapper/cmsisdsp.ipynb b/CMSIS/DSP/PythonWrapper/cmsisdsp.ipynb
new file mode 100755
index 0000000..e9dd6c9
--- /dev/null
+++ b/CMSIS/DSP/PythonWrapper/cmsisdsp.ipynb
@@ -0,0 +1,183 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Populating the interactive namespace from numpy and matplotlib\n"
+     ]
+    }
+   ],
+   "source": [
+    "import cmsisdsp as dsp\n",
+    "import numpy as np\n",
+    "from numpy import pi as PI\n",
+    "from pylab import figure, clf, plot, xlabel, ylabel, xlim, ylim, title, grid, axes, show,semilogx, semilogy\n",
+    "%pylab inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def chirp(fmin,fmax,dur,t):\n",
+    "    c=(fmax-fmin)/dur\n",
+    "    return(np.sin(2.0*PI*(c/2*t*t+ fmin * t)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sampling_frequency = 8000 \n",
+    "duration = 4096/sampling_frequency # seconds\n",
+    "time = np.arange(0,duration,1.0 / sampling_frequency)\n",
+    "fmin=10\n",
+    "fmax=500\n",
+    "\n",
+    "c=(fmax-fmin)/duration\n",
+    "signal=chirp(fmin,fmax,duration,time)\n",
+    "nb=len(signal)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[<matplotlib.lines.Line2D at 0x1b3c4c7d0f0>]"
+      ]
+     },
+     "execution_count": 60,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot(signal)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Some useful functions to convert between f32 and q31 format.\n",
+    "def q31sat(x):\n",
+    "     if x > 0x7FFFFFFF:\n",
+    "          return(np.int32(0x7FFFFFFF))\n",
+    "     elif x < -0x80000000:\n",
+    "          return(np.int32(0x80000000))\n",
+    "     else:\n",
+    "          return(np.int32(x))\n",
+    "\n",
+    "q31satV=np.vectorize(q31sat)\n",
+    "\n",
+    "def toQ31(x):\n",
+    "     return(q31satV(np.round(x * (1<<31))))\n",
+    "\n",
+    "def Q31toF32(x):\n",
+    "     return(1.0*x / 2**31)\n",
+    "    \n",
+    "# The return of a RFFT is complex. But cmsidsp is returning a flattened buffer with\n",
+    "# twice the size. This function is doing the convertion to complex numbers.\n",
+    "def asComplex(ar):\n",
+    "    return(ar[0::2] + 1j * ar[1::2])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Initialize the RFFT Q31\n",
+    "rfftq31=dsp.arm_rfft_instance_q31()\n",
+    "status=dsp.arm_rfft_init_q31(rfftq31,nb,0,1)\n",
+    "# Convert the input signal to Q31\n",
+    "signalRQ31=toQ31(signal)\n",
+    "# Compute the RFFT\n",
+    "result = dsp.arm_rfft_q31(rfftq31,signalRQ31)\n",
+    "# Convert the output spectrum to complex float and apply a scaling\n",
+    "result=asComplex(Q31toF32(result)*(1 << 12))\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "mag=10.0 * np.log(np.abs(result))\n",
+    "plot(mag)\n",
+    "title(\"RFFT Q31\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c b/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c
index 47a1c1b..5a3b6d3 100644
--- a/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c
+++ b/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.c
@@ -3,13 +3,13 @@
  * Title:        cmsismodule.c
  * Description:  C code for the CMSIS-DSP Python wrapper
  *
- * $Date:        25. March 2019
- * $Revision:    V0.0.1
+ * $Date:        27 April 2021
+ * $Revision:    VV1.0
  *
  * Target Processor: Cortex-M cores
  * -------------------------------------------------------------------- */
 /*
- * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -186,10 +186,10 @@
     PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_FLOAT, DATA);
 
 #define FLOATARRAY1(OBJ,NB1,DATA)                                          \
-    npy_intp dims[1];                                                  \
-    dims[0]=NB1;                                                       \
-    const int ND=1;                                                    \
-    PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_FLOAT, DATA);
+    npy_intp dims##OBJ[1];                                                  \
+    dims##OBJ[0]=NB1;                                                       \
+    const int ND##OBJ=1;                                                    \
+    PyObject *OBJ=PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_FLOAT, DATA);
 
 #define FLOAT64ARRAY1(OBJ,NB1,DATA)                                          \
     npy_intp dims[1];                                                  \
@@ -221,6 +221,11 @@
     const int ND=1;                                                     \
     PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPY_BYTE, DATA);
 
+#define TYP_ARRAY1(OBJ,NB1,DATA,NPYTYPE)                                          \
+    npy_intp dims[1];                                                   \
+    dims[0]=NB1;                                                        \
+    const int ND=1;                                                     \
+    PyObject *OBJ=PyArray_SimpleNewFromData(ND, dims, NPYTYPE, DATA);
 
 #define MATRIXFROMNUMPY(EXT,TYP,SRCTYPE,NUMPYTYPE)                                   \
 arm_matrix_instance_##EXT *EXT##MatrixFromNumpy(PyObject *o)                   \
@@ -257,6 +262,7 @@
 MATRIXFROMNUMPY(f64,float64_t,double,NPY_DOUBLE);
 MATRIXFROMNUMPY(q31,q31_t,int32_t,NPY_INT32);
 MATRIXFROMNUMPY(q15,q15_t,int16_t,NPY_INT16);
+MATRIXFROMNUMPY(q7,q7_t,int8_t,NPY_BYTE);
 
 #define CREATEMATRIX(EXT,TYP)                                        \
 arm_matrix_instance_##EXT *create##EXT##Matrix(uint32_t r,uint32_t c)\
@@ -274,6 +280,7 @@
 CREATEMATRIX(f64,float64_t);
 CREATEMATRIX(q31,q31_t);
 CREATEMATRIX(q15,q15_t);
+CREATEMATRIX(q7,q7_t);
 
 #define NUMPYVECTORFROMBUFFER(EXT,CTYPE,NUMPYTYPE_FROMC)                     \
 PyObject *NumpyVectorFrom##EXT##Buffer(CTYPE *ptr,int nb)                    \
@@ -310,6 +317,7 @@
 NUMPYARRAYFROMMATRIX(f64,NPY_DOUBLE);
 NUMPYARRAYFROMMATRIX(q31,NPY_INT32);
 NUMPYARRAYFROMMATRIX(q15,NPY_INT16);
+NUMPYARRAYFROMMATRIX(q7,NPY_BYTE);
 
 //#include "specific.h"
 #include "cmsismodule.h"
diff --git a/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.h b/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.h
index d640a41..af8f812 100644
--- a/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.h
+++ b/CMSIS/DSP/PythonWrapper/cmsisdsp_pkg/src/cmsismodule.h
@@ -1,15 +1,15 @@
 /* ----------------------------------------------------------------------
  * Project:      CMSIS DSP Python Wrapper
  * Title:        cmsismodule.h
- * Description:  Automatically generated C code for the CMSIS-DSP Python wrapper
+ * Description:  C code for the CMSIS-DSP Python wrapper
  *
- * $Date:        25. March 2019
- * $Revision:    V0.0.1
+ * $Date:        27 April 2021
+ * $Revision:    V1.0
  *
  * Target Processor: Cortex-M cores
  * -------------------------------------------------------------------- */
 /*
- * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -6485,6 +6485,128 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_mat_cmplx_trans_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  arm_matrix_instance_f32 *pSrc_converted=NULL; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    arm_matrix_instance_f32 *pSrc_converted = f32MatrixFromNumpy(pSrc);
+    pSrc_converted->numCols = pSrc_converted->numCols / 2;
+
+    uint32_t row = pSrc_converted->numCols ;
+    uint32_t column = pSrc_converted->numRows*2 ;
+    arm_matrix_instance_f32 *pDst_converted = createf32Matrix(row,column);
+    /*
+    Dimensions in matrix instance are not correct but they are not used
+    by CMSIS-DSP since the library is not compiled with ARM_MATRIX_CHECK.
+    So only source dimensions are used for the computation.
+
+    The dimensions are correct for createf32Matrix since we need to create
+    a bigger buffer and createf32Matrix only knows real.
+
+    */
+
+    arm_status returnValue = arm_mat_cmplx_trans_f32(pSrc_converted,pDst_converted);
+    PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
+    PyObject* pDstOBJ=NumpyArrayFromf32Matrix(pDst_converted);
+
+    PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pDstOBJ);
+
+    Py_DECREF(theReturnOBJ);
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_mat_cmplx_trans_q31(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  arm_matrix_instance_q31 *pSrc_converted=NULL; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    arm_matrix_instance_q31 *pSrc_converted = q31MatrixFromNumpy(pSrc);
+    pSrc_converted->numCols = pSrc_converted->numCols / 2;
+
+    uint32_t row = pSrc_converted->numCols ;
+    uint32_t column = pSrc_converted->numRows*2 ;
+    arm_matrix_instance_q31 *pDst_converted = createq31Matrix(row,column);
+    /*
+    Dimensions in matrix instance are not correct but they are not used
+    by CMSIS-DSP since the library is not compiled with ARM_MATRIX_CHECK.
+    So only source dimensions are used for the computation.
+
+    The dimensions are correct for createf32Matrix since we need to create
+    a bigger buffer and createf32Matrix only knows real.
+
+    */
+
+    arm_status returnValue = arm_mat_cmplx_trans_q31(pSrc_converted,pDst_converted);
+    PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
+    PyObject* pDstOBJ=NumpyArrayFromq31Matrix(pDst_converted);
+
+    PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pDstOBJ);
+
+    Py_DECREF(theReturnOBJ);
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_mat_cmplx_trans_q15(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  arm_matrix_instance_q15 *pSrc_converted=NULL; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    arm_matrix_instance_q15 *pSrc_converted = q15MatrixFromNumpy(pSrc);
+    pSrc_converted->numCols = pSrc_converted->numCols / 2;
+
+    uint32_t row = pSrc_converted->numCols ;
+    uint32_t column = pSrc_converted->numRows*2 ;
+    arm_matrix_instance_q15 *pDst_converted = createq15Matrix(row,column);
+    /*
+    Dimensions in matrix instance are not correct but they are not used
+    by CMSIS-DSP since the library is not compiled with ARM_MATRIX_CHECK.
+    So only source dimensions are used for the computation.
+
+    The dimensions are correct for createf32Matrix since we need to create
+    a bigger buffer and createf32Matrix only knows real.
+
+    */
+
+    arm_status returnValue = arm_mat_cmplx_trans_q15(pSrc_converted,pDst_converted);
+    PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
+    PyObject* pDstOBJ=NumpyArrayFromq15Matrix(pDst_converted);
+
+    PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pDstOBJ);
+
+    Py_DECREF(theReturnOBJ);
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_mat_cmplx_mult_f32(PyObject *obj, PyObject *args)
@@ -6631,6 +6753,35 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_mat_trans_q7(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  arm_matrix_instance_q7 *pSrc_converted=NULL; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    arm_matrix_instance_q7 *pSrc_converted = q7MatrixFromNumpy(pSrc);
+    uint32_t row = pSrc_converted->numCols ;
+    uint32_t column = pSrc_converted->numRows ;
+    arm_matrix_instance_q7 *pDst_converted = createq7Matrix(row,column);
+
+    arm_status returnValue = arm_mat_trans_q7(pSrc_converted,pDst_converted);
+    PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
+    PyObject* pDstOBJ=NumpyArrayFromq7Matrix(pDst_converted);
+
+    PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pDstOBJ);
+
+    Py_DECREF(theReturnOBJ);
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_mat_trans_q15(PyObject *obj, PyObject *args)
@@ -6693,6 +6844,38 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_mat_vec_mult_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrcA=NULL; // input
+  arm_matrix_instance_f32 *pSrcA_converted=NULL; // input
+  PyObject *pSrcB=NULL; // input
+  float32_t *pSrcB_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
+  {
+
+    arm_matrix_instance_f32 *pSrcA_converted = f32MatrixFromNumpy(pSrcA);
+    GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t);
+    uint32_t row = pSrcA_converted->numRows ;
+    uint32_t column = pSrcA_converted->numCols ;
+    pDst=PyMem_Malloc(sizeof(float32_t)*row);
+
+    arm_mat_vec_mult_f32(pSrcA_converted,pSrcB_converted,pDst);
+    FLOATARRAY1(pDstOBJ,row,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrcA_converted);
+    FREEARGUMENT(pSrcB_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_mat_mult_f32(PyObject *obj, PyObject *args)
@@ -6728,6 +6911,109 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_mat_vec_mult_q15(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrcA=NULL; // input
+  arm_matrix_instance_q15 *pSrcA_converted=NULL; // input
+  PyObject *pSrcB=NULL; // input
+  q15_t *pSrcB_converted=NULL; // input
+  q15_t *pDst=NULL; // output
+
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
+  {
+
+    arm_matrix_instance_q15 *pSrcA_converted = q15MatrixFromNumpy(pSrcA);
+    GETARGUMENT(pSrcB,NPY_INT16,int16_t,q15_t);
+    uint32_t row = pSrcA_converted->numRows ;
+    uint32_t column = pSrcA_converted->numCols ;
+    pDst=PyMem_Malloc(sizeof(q15_t)*row);
+
+    arm_mat_vec_mult_q15(pSrcA_converted,pSrcB_converted,pDst);
+    INT16ARRAY1(pDstOBJ,row,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrcA_converted);
+    FREEARGUMENT(pSrcB_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_mat_vec_mult_q7(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrcA=NULL; // input
+  arm_matrix_instance_q7 *pSrcA_converted=NULL; // input
+  PyObject *pSrcB=NULL; // input
+  q7_t *pSrcB_converted=NULL; // input
+  q7_t *pDst=NULL; // output
+
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
+  {
+
+    arm_matrix_instance_q7 *pSrcA_converted = q7MatrixFromNumpy(pSrcA);
+    GETARGUMENT(pSrcB,NPY_BYTE,int8_t,q7_t);
+    uint32_t row = pSrcA_converted->numRows ;
+    uint32_t column = pSrcA_converted->numCols ;
+    pDst=PyMem_Malloc(sizeof(q7_t)*row);
+
+    arm_mat_vec_mult_q7(pSrcA_converted,pSrcB_converted,pDst);
+    INT8ARRAY1(pDstOBJ,row,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrcA_converted);
+    FREEARGUMENT(pSrcB_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_mat_mult_q7(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrcA=NULL; // input
+  arm_matrix_instance_q7 *pSrcA_converted=NULL; // input
+  PyObject *pSrcB=NULL; // input
+  arm_matrix_instance_q7 *pSrcB_converted=NULL; // input
+  PyObject *pState=NULL; // input
+  q7_t *pState_converted=NULL; // input
+
+  if (PyArg_ParseTuple(args,"OOO",&pSrcA,&pSrcB,&pState))
+  {
+
+    arm_matrix_instance_q7 *pSrcA_converted = q7MatrixFromNumpy(pSrcA);
+    arm_matrix_instance_q7 *pSrcB_converted = q7MatrixFromNumpy(pSrcB);
+    GETARGUMENT(pState,NPY_BYTE,int8_t,q7_t);
+    uint32_t row = pSrcA_converted->numRows ;
+    uint32_t column = pSrcB_converted->numCols ;
+    arm_matrix_instance_q7 *pDst_converted = createq7Matrix(row,column);
+
+    arm_status returnValue = arm_mat_mult_q7(pSrcA_converted,pSrcB_converted,pDst_converted,pState_converted);
+    PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
+    PyObject* pDstOBJ=NumpyArrayFromq7Matrix(pDst_converted);
+
+    PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pDstOBJ);
+
+    Py_DECREF(theReturnOBJ);
+    FREEARGUMENT(pSrcA_converted);
+    FREEARGUMENT(pSrcB_converted);
+    Py_DECREF(pDstOBJ);
+    FREEARGUMENT(pState_converted);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_mat_mult_q15(PyObject *obj, PyObject *args)
@@ -6745,6 +7031,7 @@
 
     arm_matrix_instance_q15 *pSrcA_converted = q15MatrixFromNumpy(pSrcA);
     arm_matrix_instance_q15 *pSrcB_converted = q15MatrixFromNumpy(pSrcB);
+    
     GETARGUMENT(pState,NPY_INT16,int16_t,int16_t);
     uint32_t row = pSrcA_converted->numRows ;
     uint32_t column = pSrcB_converted->numCols ;
@@ -6806,6 +7093,38 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_mat_vec_mult_q31(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrcA=NULL; // input
+  arm_matrix_instance_q31 *pSrcA_converted=NULL; // input
+  PyObject *pSrcB=NULL; // input
+  q31_t *pSrcB_converted=NULL; // input
+  q31_t *pDst=NULL; // output
+
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
+  {
+
+    arm_matrix_instance_q31 *pSrcA_converted = q31MatrixFromNumpy(pSrcA);
+    GETARGUMENT(pSrcB,NPY_INT32,int32_t,q31_t);
+    uint32_t row = pSrcA_converted->numRows ;
+    uint32_t column = pSrcA_converted->numCols ;
+    pDst=PyMem_Malloc(sizeof(q31_t)*row);
+
+    arm_mat_vec_mult_q31(pSrcA_converted,pSrcB_converted,pDst);
+    INT32ARRAY1(pDstOBJ,row,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrcA_converted);
+    FREEARGUMENT(pSrcB_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_mat_mult_q31(PyObject *obj, PyObject *args)
@@ -8623,6 +8942,138 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_levinson_durbin_q31(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pPhi=NULL; // input
+  q31_t *pPhi_converted=NULL; // input
+  q31_t *pA=NULL; // output
+  q31_t err; // output
+  uint32_t nbCoefs; // input
+
+  if (PyArg_ParseTuple(args,"Oi",&pPhi,&nbCoefs))
+  {
+
+    GETARGUMENT(pPhi,NPY_INT32,int32_t,q31_t);
+
+    pA=PyMem_Malloc(sizeof(q31_t)*nbCoefs);
+
+
+    arm_levinson_durbin_q31(pPhi_converted,pA,&err,nbCoefs);
+    
+    INT32ARRAY1(pAOBJ,nbCoefs,pA);
+
+    PyObject *pythonResult = Py_BuildValue("Oi",pAOBJ,err);
+
+    FREEARGUMENT(pPhi_converted);
+    Py_DECREF(pAOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+
+static PyObject *
+cmsis_arm_levinson_durbin_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pPhi=NULL; // input
+  float32_t *pPhi_converted=NULL; // input
+  float32_t *pA=NULL; // output
+  float32_t err; // output
+  uint32_t nbCoefs; // input
+
+  if (PyArg_ParseTuple(args,"Oi",&pPhi,&nbCoefs))
+  {
+
+    GETARGUMENT(pPhi,NPY_DOUBLE,double,float32_t);
+
+    pA=PyMem_Malloc(sizeof(float32_t)*nbCoefs);
+
+
+    arm_levinson_durbin_f32(pPhi_converted,pA,&err,nbCoefs);
+    
+    FLOATARRAY1(pAOBJ,nbCoefs,pA);
+
+    PyObject *pythonResult = Py_BuildValue("Of",pAOBJ,err);
+
+    FREEARGUMENT(pPhi_converted);
+    Py_DECREF(pAOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_quaternion_product_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrcA=NULL; // input
+  float32_t *pSrcA_converted=NULL; // input
+  PyObject *pSrcB=NULL; // input
+  float32_t *pSrcB_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+  uint32_t nbQuaternions; // input
+
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
+  {
+
+    GETARGUMENT(pSrcA,NPY_DOUBLE,double,float32_t);
+    GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t);
+    nbQuaternions = arraySizepSrcA / 4 ;
+
+    pDst=PyMem_Malloc(4*sizeof(float32_t)*nbQuaternions);
+
+
+    arm_quaternion_product_f32(pSrcA_converted,pSrcB_converted,pDst,nbQuaternions);
+ FLOATARRAY1(pDstOBJ,4*nbQuaternions,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrcA_converted);
+    FREEARGUMENT(pSrcB_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_quaternion_product_single_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrcA=NULL; // input
+  float32_t *pSrcA_converted=NULL; // input
+  PyObject *pSrcB=NULL; // input
+  float32_t *pSrcB_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
+  {
+
+    GETARGUMENT(pSrcA,NPY_DOUBLE,double,float32_t);
+    GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t);
+
+    pDst=PyMem_Malloc(4*sizeof(float32_t));
+
+
+    arm_quaternion_product_single_f32(pSrcA_converted,pSrcB_converted,pDst);
+ FLOATARRAY1(pDstOBJ,4,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrcA_converted);
+    FREEARGUMENT(pSrcB_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_add_f32(PyObject *obj, PyObject *args)
@@ -8659,6 +9110,95 @@
   return(NULL);
 }
 
+/*
+
+For the arm_(and|xor|or)_u(32|16|8)
+
+*/
+
+#define U_UN_OP(OP,TYP,EXT,NPYTYPE)                     \
+static PyObject *                                       \
+cmsis_arm_##OP##_##EXT(PyObject *obj, PyObject *args)   \
+{                                                       \
+                                                        \
+  PyObject *pSrcA=NULL;                                 \
+  TYP *pSrcA_converted=NULL;                            \
+  TYP *pDst=NULL;                                       \
+  uint32_t blockSize;                                   \
+                                                        \
+  if (PyArg_ParseTuple(args,"O",&pSrcA))                \
+  {                                                     \
+                                                        \
+    GETARGUMENT(pSrcA,NPYTYPE,TYP,TYP);                 \
+    blockSize = arraySizepSrcA ;                        \
+                                                        \
+    pDst=PyMem_Malloc(sizeof(TYP)*blockSize);           \
+                                                        \
+                                                        \
+    arm_##OP##_##EXT(pSrcA_converted,pDst,blockSize);   \
+ TYP_ARRAY1(pDstOBJ,blockSize,pDst,NPYTYPE);            \
+                                                        \
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);\
+                                                        \
+    FREEARGUMENT(pSrcA_converted);                      \
+    Py_DECREF(pDstOBJ);                                 \
+    return(pythonResult);                               \
+                                                        \
+  }                                                     \
+  return(NULL);                                         \
+}
+
+#define U_BIN_OP(OP,TYP,EXT,NPYTYPE)                                 \
+static PyObject *                                                    \
+cmsis_arm_##OP##_##EXT(PyObject *obj, PyObject *args)                \
+{                                                                    \
+                                                                     \
+  PyObject *pSrcA=NULL;                                              \
+  TYP *pSrcA_converted=NULL;                                         \
+  PyObject *pSrcB=NULL;                                              \
+  TYP *pSrcB_converted=NULL;                                         \
+  TYP *pDst=NULL;                                                    \
+  uint32_t blockSize;                                                \
+                                                                     \
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))                     \
+  {                                                                  \
+                                                                     \
+    GETARGUMENT(pSrcA,NPYTYPE,TYP,TYP);                              \
+    GETARGUMENT(pSrcB,NPYTYPE,TYP,TYP);                              \
+    blockSize = arraySizepSrcA ;                                     \
+                                                                     \
+    pDst=PyMem_Malloc(sizeof(TYP)*blockSize);                        \
+                                                                     \
+                                                                     \
+    arm_##OP##_##EXT(pSrcA_converted,pSrcB_converted,pDst,blockSize);\
+ TYP_ARRAY1(pDstOBJ,blockSize,pDst,NPYTYPE);                         \
+                                                                     \
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);             \
+                                                                     \
+    FREEARGUMENT(pSrcA_converted);                                   \
+    FREEARGUMENT(pSrcB_converted);                                   \
+    Py_DECREF(pDstOBJ);                                              \
+    return(pythonResult);                                            \
+                                                                     \
+  }                                                                  \
+  return(NULL);                                                      \
+}
+
+U_BIN_OP(and,uint32_t,u32,NPY_UINT32);
+U_BIN_OP(and,uint16_t,u16,NPY_UINT16);
+U_BIN_OP(and,uint8_t,u8,NPY_UINT8);
+
+U_BIN_OP(or,uint32_t,u32,NPY_UINT32);
+U_BIN_OP(or,uint16_t,u16,NPY_UINT16);
+U_BIN_OP(or,uint8_t,u8,NPY_UINT8);
+
+U_BIN_OP(xor,uint32_t,u32,NPY_UINT32);
+U_BIN_OP(xor,uint16_t,u16,NPY_UINT16);
+U_BIN_OP(xor,uint8_t,u8,NPY_UINT8);
+
+U_UN_OP(not,uint32_t,u32,NPY_UINT32);
+U_UN_OP(not,uint16_t,u16,NPY_UINT16);
+U_UN_OP(not,uint8_t,u8,NPY_UINT8);
 
 static PyObject *
 cmsis_arm_add_q7(PyObject *obj, PyObject *args)
@@ -8911,6 +9451,191 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_quaternion2rotation_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+  uint32_t nbQuaternions; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    nbQuaternions = arraySizepSrc / 4 ;
+
+    pDst=PyMem_Malloc(9*sizeof(float32_t)*nbQuaternions);
+
+
+    arm_quaternion2rotation_f32(pSrc_converted,pDst,nbQuaternions);
+ FLOATARRAY1(pDstOBJ,9*nbQuaternions,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_rotation2quaternion_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+  uint32_t nbQuaternions; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    nbQuaternions = arraySizepSrc / 9 ;
+
+    pDst=PyMem_Malloc(4*sizeof(float32_t)*nbQuaternions);
+
+
+    arm_rotation2quaternion_f32(pSrc_converted,pDst,nbQuaternions);
+ FLOATARRAY1(pDstOBJ,4*nbQuaternions,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_quaternion_normalize_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+  uint32_t nbQuaternions; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    nbQuaternions = arraySizepSrc / 4 ;
+
+    pDst=PyMem_Malloc(4*sizeof(float32_t)*nbQuaternions);
+
+
+    arm_quaternion_normalize_f32(pSrc_converted,pDst,nbQuaternions);
+ FLOATARRAY1(pDstOBJ,4*nbQuaternions,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_quaternion_norm_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+  uint32_t nbQuaternions; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    nbQuaternions = arraySizepSrc / 4 ;
+
+    pDst=PyMem_Malloc(sizeof(float32_t)*nbQuaternions);
+
+
+    arm_quaternion_norm_f32(pSrc_converted,pDst,nbQuaternions);
+ FLOATARRAY1(pDstOBJ,nbQuaternions,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_quaternion_conjugate_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+  uint32_t nbQuaternions; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    nbQuaternions = arraySizepSrc / 4 ;
+
+    pDst=PyMem_Malloc(4*sizeof(float32_t)*nbQuaternions);
+
+
+    arm_quaternion_conjugate_f32(pSrc_converted,pDst,nbQuaternions);
+ FLOATARRAY1(pDstOBJ,4*nbQuaternions,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_quaternion_inverse_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  float32_t *pDst=NULL; // output
+  uint32_t nbQuaternions; // input
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    nbQuaternions = arraySizepSrc / 4 ;
+
+    pDst=PyMem_Malloc(4*sizeof(float32_t)*nbQuaternions);
+
+
+    arm_quaternion_inverse_f32(pSrc_converted,pDst,nbQuaternions);
+ FLOATARRAY1(pDstOBJ,4*nbQuaternions,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_scale_f32(PyObject *obj, PyObject *args)
@@ -9174,6 +9899,53 @@
   return(NULL);
 }
 
+#define FLOATDIST(NAME)                                                \
+static PyObject *                                                      \
+cmsis_arm_##NAME##_f32(PyObject *obj, PyObject *args)                  \
+{                                                                      \
+                                                                       \
+  PyObject *pSrcA=NULL;                                                \
+  float32_t *pSrcA_converted=NULL;                                     \
+  PyObject *pSrcB=NULL;                                                \
+  float32_t *pSrcB_converted=NULL;                                     \
+  uint32_t blockSize;                                                  \
+  float32_t *result=NULL;                                              \
+                                                                       \
+  if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))                       \
+  {                                                                    \
+                                                                       \
+    GETARGUMENT(pSrcA,NPY_DOUBLE,double,float32_t);                    \
+    GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t);                    \
+    blockSize = arraySizepSrcA ;                                       \
+                                                                       \
+    result=PyMem_Malloc(sizeof(float32_t)*1);                          \
+                                                                       \
+                                                                       \
+    arm_##NAME##_f32(pSrcA_converted,pSrcB_converted,blockSize,result);\
+    PyObject* resultOBJ=Py_BuildValue("f",*result);                    \
+                                                                       \
+    PyObject *pythonResult = Py_BuildValue("O",resultOBJ);             \
+                                                                       \
+    FREEARGUMENT(pSrcA_converted);                                     \
+    FREEARGUMENT(pSrcB_converted);                                     \
+    Py_DECREF(resultOBJ);                                              \
+    return(pythonResult);                                              \
+                                                                       \
+  }                                                                    \
+  return(NULL);                                                        \
+}
+
+#if 0
+FLOATDIST(braycurtis_distance);
+FLOATDIST(canberra_distance);
+FLOATDIST(chebyshev_distance);
+FLOATDIST(cityblock_distance);
+FLOATDIST(correlation_distance);
+FLOATDIST(cosine_distance);
+FLOATDIST(euclidean_distance);
+FLOATDIST(jensenshannon_distance);
+FLOATDIST(minkowski_distance);
+#endif
 
 static PyObject *
 cmsis_arm_dot_prod_f32(PyObject *obj, PyObject *args)
@@ -9417,6 +10189,238 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_clip_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  float32_t low,high; // input
+  float32_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"Off",&pSrc,&low,&high))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    blockSize = arraySizepSrc ;
+
+    pDst=PyMem_Malloc(sizeof(float32_t)*blockSize);
+
+
+    arm_clip_f32(pSrc_converted,pDst,low,high,blockSize);
+ FLOATARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_clip_q31(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q31_t *pSrc_converted=NULL; // input
+  q31_t low,high; // input
+  q31_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"Oii",&pSrc,&low,&high))
+  {
+
+    GETARGUMENT(pSrc,NPY_INT32,int32_t,int32_t);
+    blockSize = arraySizepSrc ;
+
+    pDst=PyMem_Malloc(sizeof(q31_t)*blockSize);
+
+
+    arm_clip_q31(pSrc_converted,pDst,low,high,blockSize);
+ INT32ARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+
+static PyObject *
+cmsis_arm_clip_q15(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q15_t *pSrc_converted=NULL; // input
+  q15_t low,high; // input
+  q15_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"Ohh",&pSrc,&low,&high))
+  {
+
+    GETARGUMENT(pSrc,NPY_INT16,int16_t,int16_t);
+    blockSize = arraySizepSrc ;
+
+    pDst=PyMem_Malloc(sizeof(q15_t)*blockSize);
+
+
+    arm_clip_q15(pSrc_converted,pDst,low,high,blockSize);
+ INT16ARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_clip_q7(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q7_t *pSrc_converted=NULL; // input
+  int32_t low,high; // input
+  q7_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"Oii",&pSrc,&low,&high))
+  {
+
+    GETARGUMENT(pSrc,NPY_BYTE,int8_t,q7_t);
+    blockSize = arraySizepSrc ;
+
+    pDst=PyMem_Malloc(sizeof(q7_t)*blockSize);
+
+
+    arm_clip_q7(pSrc_converted,pDst,(q7_t)low,(q7_t)high,blockSize);
+ INT8ARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_fill_f32(PyObject *obj, PyObject *args)
+{
+
+  float32_t value; // input
+  float32_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"fi",&value,&blockSize))
+  {
+
+    pDst=PyMem_Malloc(sizeof(float32_t)*blockSize);
+
+
+    arm_fill_f32(value,pDst,blockSize);
+ FLOATARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_fill_q31(PyObject *obj, PyObject *args)
+{
+
+  q31_t value; // input
+  q31_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"ii",&value,&blockSize))
+  {
+
+    pDst=PyMem_Malloc(sizeof(q31_t)*blockSize);
+
+
+    arm_fill_q31(value,pDst,blockSize);
+ INT32ARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_fill_q15(PyObject *obj, PyObject *args)
+{
+
+  q15_t value; // input
+  q15_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"hi",&value,&blockSize))
+  {
+
+    pDst=PyMem_Malloc(sizeof(q15_t)*blockSize);
+
+
+    arm_fill_q15(value,pDst,blockSize);
+ INT16ARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_fill_q7(PyObject *obj, PyObject *args)
+{
+
+  q31_t value; // input
+  q7_t *pDst=NULL; // output
+  uint32_t blockSize; // input
+
+  if (PyArg_ParseTuple(args,"ii",&value,&blockSize))
+  {
+
+    pDst=PyMem_Malloc(sizeof(q7_t)*blockSize);
+
+
+    arm_fill_q7((q7_t)value,pDst,blockSize);
+ INT8ARRAY1(pDstOBJ,blockSize,pDst);
+
+    PyObject *pythonResult = Py_BuildValue("O",pDstOBJ);
+
+    Py_DECREF(pDstOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
 
 static PyObject *
 cmsis_arm_offset_f32(PyObject *obj, PyObject *args)
@@ -14752,32 +15756,69 @@
 static PyObject *
 cmsis_arm_min_q7(PyObject *obj, PyObject *args)
 {
-
   PyObject *pSrc=NULL; // input
   q7_t *pSrc_converted=NULL; // input
   uint32_t blockSize; // input
-  q7_t *result=NULL; // output
-  PyObject *index=NULL; // input
-  uint32_t *index_converted=NULL; // input
+  q7_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
 
-  if (PyArg_ParseTuple(args,"OO",&pSrc,&index))
+  if (PyArg_ParseTuple(args,"O",&pSrc))
   {
 
     GETARGUMENT(pSrc,NPY_BYTE,int8_t,q7_t);
-    GETARGUMENT(index,NPY_UINT32,uint32_t,uint32_t);
     blockSize = arraySizepSrc ;
 
-    result=PyMem_Malloc(sizeof(q7_t)*1);
+    pResult=PyMem_Malloc(sizeof(q7_t)*1);
 
 
-    arm_min_q7(pSrc_converted,blockSize,result,index_converted);
-    PyObject* resultOBJ=Py_BuildValue("i",*result);
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
 
-    PyObject *pythonResult = Py_BuildValue("O",resultOBJ);
+
+    arm_min_q7(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("i",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
 
     FREEARGUMENT(pSrc_converted);
-    Py_DECREF(resultOBJ);
-    FREEARGUMENT(index_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
+static PyObject *
+cmsis_arm_absmin_q7(PyObject *obj, PyObject *args)
+{
+  PyObject *pSrc=NULL; // input
+  q7_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  q7_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_BYTE,int8_t,q7_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(q7_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmin_q7(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("i",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
     return(pythonResult);
 
   }
@@ -14822,6 +15863,43 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_absmin_q15(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q15_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  q15_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_INT16,int16_t,int16_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(q15_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmin_q15(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("h",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
 
 static PyObject *
 cmsis_arm_min_q31(PyObject *obj, PyObject *args)
@@ -14860,6 +15938,43 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_absmin_q31(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q31_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  q31_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_INT32,int32_t,int32_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(q31_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmin_q31(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("i",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
 
 static PyObject *
 cmsis_arm_min_f32(PyObject *obj, PyObject *args)
@@ -14898,6 +16013,43 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_absmin_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  float32_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(float32_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmin_f32(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("f",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
 
 static PyObject *
 cmsis_arm_max_q7(PyObject *obj, PyObject *args)
@@ -14936,6 +16088,43 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_absmax_q7(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q7_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  q7_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_BYTE,int8_t,q7_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(q7_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmax_q7(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("i",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
 
 static PyObject *
 cmsis_arm_max_q15(PyObject *obj, PyObject *args)
@@ -14974,6 +16163,43 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_absmax_q15(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q15_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  q15_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_INT16,int16_t,int16_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(q15_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmax_q15(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("h",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
 
 static PyObject *
 cmsis_arm_max_q31(PyObject *obj, PyObject *args)
@@ -15012,6 +16238,43 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_absmax_q31(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  q31_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  q31_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_INT32,int32_t,int32_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(q31_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmax_q31(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("i",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
 
 static PyObject *
 cmsis_arm_max_f32(PyObject *obj, PyObject *args)
@@ -15050,6 +16313,43 @@
   return(NULL);
 }
 
+static PyObject *
+cmsis_arm_absmax_f32(PyObject *obj, PyObject *args)
+{
+
+  PyObject *pSrc=NULL; // input
+  float32_t *pSrc_converted=NULL; // input
+  uint32_t blockSize; // input
+  float32_t *pResult=NULL; // output
+  uint32_t *pIndex=NULL; // output
+
+  if (PyArg_ParseTuple(args,"O",&pSrc))
+  {
+
+    GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
+    blockSize = arraySizepSrc ;
+
+    pResult=PyMem_Malloc(sizeof(float32_t)*1);
+
+
+    pIndex=PyMem_Malloc(sizeof(uint32_t)*1);
+
+
+    arm_absmax_f32(pSrc_converted,blockSize,pResult,pIndex);
+    PyObject* pResultOBJ=Py_BuildValue("f",*pResult);
+    PyObject* pIndexOBJ=Py_BuildValue("i",*pIndex);
+
+    PyObject *pythonResult = Py_BuildValue("OO",pResultOBJ,pIndexOBJ);
+
+    FREEARGUMENT(pSrc_converted);
+    Py_DECREF(pResultOBJ);
+    Py_DECREF(pIndexOBJ);
+    return(pythonResult);
+
+  }
+  return(NULL);
+}
+
 
 static PyObject *
 cmsis_arm_cmplx_mult_cmplx_q15(PyObject *obj, PyObject *args)
@@ -15553,7 +16853,16 @@
 {"arm_mat_trans_f32",  cmsis_arm_mat_trans_f32, METH_VARARGS,""},
 {"arm_mat_trans_q15",  cmsis_arm_mat_trans_q15, METH_VARARGS,""},
 {"arm_mat_trans_q31",  cmsis_arm_mat_trans_q31, METH_VARARGS,""},
+{"arm_mat_trans_q7",  cmsis_arm_mat_trans_q7, METH_VARARGS,""},
+
+
+{"arm_mat_vec_mult_f32",  cmsis_arm_mat_vec_mult_f32, METH_VARARGS,""},
+{"arm_mat_vec_mult_q31",  cmsis_arm_mat_vec_mult_q31, METH_VARARGS,""},
+{"arm_mat_vec_mult_q15",  cmsis_arm_mat_vec_mult_q15, METH_VARARGS,""},
+{"arm_mat_vec_mult_q7",  cmsis_arm_mat_vec_mult_q7, METH_VARARGS,""},
+
 {"arm_mat_mult_f32",  cmsis_arm_mat_mult_f32, METH_VARARGS,""},
+{"arm_mat_mult_q7",  cmsis_arm_mat_mult_q7, METH_VARARGS,""},
 {"arm_mat_mult_q15",  cmsis_arm_mat_mult_q15, METH_VARARGS,""},
 {"arm_mat_mult_fast_q15",  cmsis_arm_mat_mult_fast_q15, METH_VARARGS,""},
 {"arm_mat_mult_q31",  cmsis_arm_mat_mult_q31, METH_VARARGS,""},
@@ -15629,6 +16938,10 @@
 {"arm_shift_q7",  cmsis_arm_shift_q7, METH_VARARGS,""},
 {"arm_shift_q15",  cmsis_arm_shift_q15, METH_VARARGS,""},
 {"arm_shift_q31",  cmsis_arm_shift_q31, METH_VARARGS,""},
+{"arm_clip_f32",  cmsis_arm_clip_f32, METH_VARARGS,""},
+{"arm_clip_q31",  cmsis_arm_clip_q31, METH_VARARGS,""},
+{"arm_clip_q15",  cmsis_arm_clip_q15, METH_VARARGS,""},
+{"arm_clip_q7",  cmsis_arm_clip_q7, METH_VARARGS,""},
 {"arm_offset_f32",  cmsis_arm_offset_f32, METH_VARARGS,""},
 {"arm_offset_q7",  cmsis_arm_offset_q7, METH_VARARGS,""},
 {"arm_offset_q15",  cmsis_arm_offset_q15, METH_VARARGS,""},
@@ -15794,10 +17107,18 @@
 {"arm_min_q15",  cmsis_arm_min_q15, METH_VARARGS,""},
 {"arm_min_q31",  cmsis_arm_min_q31, METH_VARARGS,""},
 {"arm_min_f32",  cmsis_arm_min_f32, METH_VARARGS,""},
+{"arm_absmin_q7",   cmsis_arm_absmin_q7, METH_VARARGS,""},
+{"arm_absmin_q15",  cmsis_arm_absmin_q15, METH_VARARGS,""},
+{"arm_absmin_q31",  cmsis_arm_absmin_q31, METH_VARARGS,""},
+{"arm_absmin_f32",  cmsis_arm_absmin_f32, METH_VARARGS,""},
 {"arm_max_q7",  cmsis_arm_max_q7, METH_VARARGS,""},
 {"arm_max_q15",  cmsis_arm_max_q15, METH_VARARGS,""},
 {"arm_max_q31",  cmsis_arm_max_q31, METH_VARARGS,""},
+{"arm_absmax_q7",  cmsis_arm_absmax_q7, METH_VARARGS,""},
+{"arm_absmax_q15", cmsis_arm_absmax_q15, METH_VARARGS,""},
+{"arm_absmax_q31", cmsis_arm_absmax_q31, METH_VARARGS,""},
 {"arm_max_f32",  cmsis_arm_max_f32, METH_VARARGS,""},
+{"arm_absmax_f32",  cmsis_arm_absmax_f32, METH_VARARGS,""},
 {"arm_cmplx_mult_cmplx_q15",  cmsis_arm_cmplx_mult_cmplx_q15, METH_VARARGS,""},
 {"arm_cmplx_mult_cmplx_q31",  cmsis_arm_cmplx_mult_cmplx_q31, METH_VARARGS,""},
 {"arm_cmplx_mult_cmplx_f32",  cmsis_arm_cmplx_mult_cmplx_f32, METH_VARARGS,""},
@@ -15814,6 +17135,54 @@
 {"arm_bilinear_interp_q15",  cmsis_arm_bilinear_interp_q15, METH_VARARGS,""},
 {"arm_bilinear_interp_q7",  cmsis_arm_bilinear_interp_q7, METH_VARARGS,""},
 
+{"arm_fill_f32",  cmsis_arm_fill_f32, METH_VARARGS,""},
+{"arm_fill_q31",  cmsis_arm_fill_q31, METH_VARARGS,""},
+{"arm_fill_q15",  cmsis_arm_fill_q15, METH_VARARGS,""},
+{"arm_fill_q7",  cmsis_arm_fill_q7, METH_VARARGS,""},
+
+{"arm_mat_cmplx_trans_f32",  cmsis_arm_mat_cmplx_trans_f32, METH_VARARGS,""},
+{"arm_mat_cmplx_trans_q31",  cmsis_arm_mat_cmplx_trans_q31, METH_VARARGS,""},
+{"arm_mat_cmplx_trans_q15",  cmsis_arm_mat_cmplx_trans_q15, METH_VARARGS,""},
+{"arm_levinson_durbin_f32",  cmsis_arm_levinson_durbin_f32, METH_VARARGS,""},
+{"arm_levinson_durbin_q31",  cmsis_arm_levinson_durbin_q31, METH_VARARGS,""},
+
+{"arm_and_u32",  cmsis_arm_and_u32, METH_VARARGS,""},
+{"arm_and_u16",  cmsis_arm_and_u16, METH_VARARGS,""},
+{"arm_and_u8" ,  cmsis_arm_and_u8, METH_VARARGS,""},
+
+{"arm_or_u32",  cmsis_arm_or_u32, METH_VARARGS,""},
+{"arm_or_u16",  cmsis_arm_or_u16, METH_VARARGS,""},
+{"arm_or_u8" ,  cmsis_arm_or_u8, METH_VARARGS,""},
+
+{"arm_xor_u32",  cmsis_arm_xor_u32, METH_VARARGS,""},
+{"arm_xor_u16",  cmsis_arm_xor_u16, METH_VARARGS,""},
+{"arm_xor_u8" ,  cmsis_arm_xor_u8, METH_VARARGS,""},
+
+{"arm_not_u32",  cmsis_arm_not_u32, METH_VARARGS,""},
+{"arm_not_u16",  cmsis_arm_not_u16, METH_VARARGS,""},
+{"arm_not_u8" ,  cmsis_arm_not_u8, METH_VARARGS,""},
+
+{"arm_quaternion_normalize_f32" ,  cmsis_arm_quaternion_normalize_f32, METH_VARARGS,""},
+{"arm_quaternion_conjugate_f32" ,  cmsis_arm_quaternion_conjugate_f32, METH_VARARGS,""},
+{"arm_quaternion_inverse_f32" ,  cmsis_arm_quaternion_inverse_f32, METH_VARARGS,""},
+{"arm_quaternion_norm_f32" ,  cmsis_arm_quaternion_norm_f32, METH_VARARGS,""},
+{"arm_quaternion2rotation_f32" ,  cmsis_arm_quaternion2rotation_f32, METH_VARARGS,""},
+{"arm_rotation2quaternion_f32" ,  cmsis_arm_rotation2quaternion_f32, METH_VARARGS,""},
+{"arm_quaternion_product_f32" ,  cmsis_arm_quaternion_product_f32, METH_VARARGS,""},
+{"arm_quaternion_product_single_f32" ,  cmsis_arm_quaternion_product_single_f32, METH_VARARGS,""},
+
+#if 0
+{"arm_braycurtis_distance_f32", cmsis_arm_braycurtis_distance_f32, METH_VARARGS,""},
+{"arm_canberra_distance_f32",cmsis_arm_canberra_distance_f32, METH_VARARGS,""},
+{"arm_chebyshev_distance_f32",cmsis_arm_chebyshev_distance_f32, METH_VARARGS,""},
+{"arm_cityblock_distance_f32",cmsis_arm_cityblock_distance_f32, METH_VARARGS,""},
+{"arm_correlation_distance_f32",cmsis_arm_correlation_distance_f32, METH_VARARGS,""},
+{"arm_cosine_distance_f32",cmsis_arm_cosine_distance_f32, METH_VARARGS,""},
+{"arm_euclidean_distance_f32",cmsis_arm_euclidean_distance_f32, METH_VARARGS,""},
+{"arm_jensenshannon_distance_f32",cmsis_arm_jensenshannon_distance_f32, METH_VARARGS,""},
+{"arm_minkowski_distance_f32",cmsis_arm_minkowski_distance_f32, METH_VARARGS,""},
+#endif
+
     {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
diff --git a/CMSIS/DSP/PythonWrapper/fixedpoint.py b/CMSIS/DSP/PythonWrapper/fixedpoint.py
new file mode 100755
index 0000000..896de20
--- /dev/null
+++ b/CMSIS/DSP/PythonWrapper/fixedpoint.py
@@ -0,0 +1,49 @@
+import numpy as np
+
+def q31sat(x):
+     if x > 0x7FFFFFFF:
+          return(np.int32(0x7FFFFFFF))
+     elif x < -0x80000000:
+          return(np.int32(0x80000000))
+     else:
+          return(np.int32(x))
+
+q31satV=np.vectorize(q31sat)
+
+def toQ31(x):
+     return(q31satV(np.round(x * (1<<31))))
+
+def q15sat(x):
+     if x > 0x7FFF:
+          return(np.int16(0x7FFF))
+     elif x < -0x8000:
+          return(np.int16(0x8000))
+     else:
+          return(np.int16(x))
+
+q15satV=np.vectorize(q15sat)
+
+def toQ15(x):
+     return(q15satV(np.round(x * (1<<15))))
+
+def q7sat(x):
+     if x > 0x7F:
+          return(np.int8(0x7F))
+     elif x < -0x80:
+          return(np.int8(0x80))
+     else:
+          return(np.int8(x))
+
+q7satV=np.vectorize(q7sat)
+
+def toQ7(x):
+     return(q7satV(np.round(x * (1<<7))))
+
+def Q31toF32(x):
+     return(1.0*x / 2**31)
+
+def Q15toF32(x):
+     return(1.0*x / 2**15)
+
+def Q7toF32(x):
+     return(1.0*x / 2**7)
\ No newline at end of file
diff --git a/CMSIS/DSP/PythonWrapper/setup.py b/CMSIS/DSP/PythonWrapper/setup.py
index 2d6b8cc..a0b3d99 100644
--- a/CMSIS/DSP/PythonWrapper/setup.py
+++ b/CMSIS/DSP/PythonWrapper/setup.py
@@ -58,12 +58,20 @@
 interpolation.remove(os.path.join(ROOT,"Source","InterpolationFunctions","InterpolationFunctions.c"))
 interpolation.remove(os.path.join(ROOT,"Source","InterpolationFunctions","InterpolationFunctionsF16.c"))
 
+quaternion = glob.glob(os.path.join(ROOT,"Source","QuaternionMathFunctions","*.c"))
+quaternion.remove(os.path.join(ROOT,"Source","QuaternionMathFunctions","QuaternionMathFunctions.c"))
+
+#distance = glob.glob(os.path.join(ROOT,"Source","DistanceFunctions","*.c"))
+#distance.remove(os.path.join(ROOT,"Source","DistanceFunctions","DistanceFunctions.c"))
+
+
 #modulesrc = glob.glob(os.path.join("cmsisdsp_pkg","src","*.c"))
 modulesrc = []
 modulesrc.append(os.path.join("cmsisdsp_pkg","src","cmsismodule.c"))
 
 allsrcs = support + fastmath + filtering + matrix + statistics + complexf + basic
 allsrcs = allsrcs + controller + transform + modulesrc + common+ interpolation
+allsrcs = allsrcs + quaternion
 
 def notf16(number):
   if re.search(r'f16',number):
@@ -88,10 +96,10 @@
                               )
 
 setup (name = config.setupName,
-       version = '0.0.1',
+       version = '1.0.0',
        description = config.setupDescription,
        ext_modules = [module1],
-       author = 'Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.',
+       author = 'Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.',
        url="https://github.com/ARM-software/CMSIS_5",
        classifiers=[
         "Programming Language :: Python",
diff --git a/CMSIS/DSP/PythonWrapper/testdsp2.py b/CMSIS/DSP/PythonWrapper/testdsp2.py
new file mode 100755
index 0000000..428d351
--- /dev/null
+++ b/CMSIS/DSP/PythonWrapper/testdsp2.py
@@ -0,0 +1,459 @@
+import cmsisdsp as dsp
+import numpy as np
+from scipy import signal
+from scipy.fftpack import dct 
+import fixedpoint as f
+from pyquaternion import Quaternion
+
+import colorama
+from colorama import init,Fore, Back, Style
+import statsmodels.tsa.stattools
+
+import scipy.spatial
+
+
+init()
+
+def printTitle(s):
+    print("\n" + Fore.GREEN + Style.BRIGHT +  s + Style.RESET_ALL)
+
+def printSubTitle(s):
+    print("\n" + Style.BRIGHT + s + Style.RESET_ALL)
+
+
+def imToReal2D(a):
+    ar=np.zeros(np.array(a.shape) * [1,2])
+    ar[::,0::2]=a.real
+    ar[::,1::2]=a.imag
+    return(ar)
+
+def realToIm2D(ar):
+    return(ar[::,0::2] + 1j * ar[::,1::2])
+
+def normalize(a):
+  return(a/np.max(np.abs(a)))
+
+def autocorr(x):
+    result = np.correlate(x, x, mode='full')
+    return result[result.size//2:]
+
+#################### MAX AND ABSMAX ##################################
+printTitle("Max and AbsMax")
+a=np.array([1.,-3.,4.,0.,-10.,8.])
+
+printSubTitle("Float tests")
+i=dsp.arm_max_f32(a)
+print(i)
+
+i=dsp.arm_absmax_f32(a)
+print(i)
+
+printSubTitle("Fixed point tests")
+
+# Normalize for fixed point tests
+a = a / i[0]
+
+a31 = f.toQ31(a)
+i=dsp.arm_absmax_q31(a31)
+print(f.Q31toF32(i[0]),i[1])
+
+a8 = f.toQ15(a)
+i=dsp.arm_absmax_q15(a8)
+print(f.Q15toF32(i[0]),i[1])
+
+a7 = f.toQ7(a)
+i=dsp.arm_absmax_q7(a7)
+print(f.Q7toF32(i[0]),i[1])
+
+################### MIN AND ABSMIN ################################
+
+printTitle("Min and AbsMin")
+a=np.array([1.,-3.,4.,0.5,-10.,8.])
+
+printSubTitle("Float tests")
+i=dsp.arm_min_f32(a)
+print(i)
+
+i=dsp.arm_absmin_f32(a)
+print(i)
+
+printSubTitle("Fixed point tests")
+
+# Normalize for fixed point tests
+idx=i[1]
+i=dsp.arm_absmax_f32(a)
+a = a / i[0]
+print(a)
+print(a[idx])
+
+a31 = f.toQ31(a)
+i=dsp.arm_absmin_q31(a31)
+print(f.Q31toF32(i[0]),i[1])
+
+a8 = f.toQ15(a)
+i=dsp.arm_absmin_q15(a8)
+print(f.Q15toF32(i[0]),i[1])
+
+a7 = f.toQ7(a)
+i=dsp.arm_absmin_q7(a7)
+print(f.Q7toF32(i[0]),i[1])
+
+##################### CLIPPING ###################
+printTitle("Clipping tests tests")
+a=np.array([1.,-3.,4.,0.5,-10.,8.])
+i=dsp.arm_absmax_f32(a)
+
+minBound =-5.0 
+maxBound =6.0
+b=dsp.arm_clip_f32(a,minBound,maxBound)
+print(a)
+print(b)
+
+a = a / i[0]
+print(a)
+minBound = minBound / i[0]
+maxBound = maxBound / i[0]
+print(minBound,maxBound)
+
+b=dsp.arm_clip_q31(f.toQ31(a),f.toQ31(minBound),f.toQ31(maxBound))
+print(f.Q31toF32(b))
+
+b=dsp.arm_clip_q15(f.toQ15(a),f.toQ15(minBound),f.toQ15(maxBound))
+print(f.Q15toF32(b))
+
+b=dsp.arm_clip_q7(f.toQ7(a),f.toQ7(minBound),f.toQ7(maxBound))
+print(f.Q7toF32(b))
+
+############### MAT VECTOR MULT
+
+printTitle("Matrix x Vector")
+a=np.array([[1.,2,3,4],[5,6,7,8],[9,10,11,12]])
+b=np.array([-2,-1,3,4])
+
+c = np.dot(a,b)
+print(c)
+c = dsp.arm_mat_vec_mult_f32(a,b)
+print(c)
+
+printSubTitle("Fixed point")
+normalizationFactor=2.0*np.sqrt(np.max(np.abs(c)))
+a=a/normalizationFactor
+b=b/normalizationFactor
+print(np.dot(a,b))
+
+c=dsp.arm_mat_vec_mult_q31(f.toQ31(a),f.toQ31(b))
+print(f.Q31toF32(c))
+
+c=dsp.arm_mat_vec_mult_q15(f.toQ15(a),f.toQ15(b))
+print(f.Q15toF32(c))
+
+c=dsp.arm_mat_vec_mult_q7(f.toQ7(a),f.toQ7(b))
+print(f.Q7toF32(c))
+
+############### MATRIX MULTIPLY
+
+printTitle("Matrix x Matrix")
+
+a=np.array([[1.,2,3,4],[5,6,7,8],[9,10,11,12]])
+b=np.array([[1.,2,3],[5.1,6,7],[9.1,10,11],[5,8,4]])
+print(np.dot(a , b))
+c=dsp.arm_mat_mult_f32(a,b)
+print(c[1])
+
+printSubTitle("Fixed point")
+
+normalizationFactor=2.0*np.sqrt(np.max(np.abs(c[1])))
+a = a / normalizationFactor
+b = b / normalizationFactor
+c=dsp.arm_mat_mult_f32(a,b)
+print(c[1])
+
+print("")
+af = f.toQ31(a)
+bf = f.toQ31(b)
+c = dsp.arm_mat_mult_q31(af,bf)
+print(f.Q31toF32(c[1]))
+
+print("")
+af = f.toQ15(a)
+bf = f.toQ15(b)
+s=bf.shape 
+nb=s[0]*s[1]
+tmp=np.zeros(nb)
+c = dsp.arm_mat_mult_q15(af,bf,tmp)
+print(f.Q15toF32(c[1]))
+
+print("")
+af = f.toQ7(a)
+bf = f.toQ7(b)
+s=bf.shape 
+nb=s[0]*s[1]
+tmp=np.zeros(nb)
+c = dsp.arm_mat_mult_q7(af,bf,tmp)
+print(f.Q7toF32(c[1]))
+
+################# MAT TRANSPOSE #################
+
+printTitle("Transposition")
+a=np.array([[1.,2,3,4],[5,6,7,8],[9,10,11,12]])
+normalizationFactor=np.max(np.abs(c[1]))
+a = a / normalizationFactor
+
+print(np.transpose(a))
+print("")
+r=dsp.arm_mat_trans_f32(a)
+print(r[1])
+print("")
+
+r=dsp.arm_mat_trans_q31(f.toQ31(a))
+print(f.Q31toF32(r[1]))
+print("")
+
+r=dsp.arm_mat_trans_q15(f.toQ15(a))
+print(f.Q15toF32(r[1]))
+print("")
+
+r=dsp.arm_mat_trans_q7(f.toQ7(a))
+print(f.Q7toF32(r[1]))
+print("")
+
+################## FILL FUNCTIONS #################
+
+v=0.22 
+nb=10 
+a=np.full((nb,),v)
+print(a)
+
+a=dsp.arm_fill_f32(v,nb)
+print(a)
+
+a=f.Q31toF32(dsp.arm_fill_q31(f.toQ31(v),nb))
+print(a)
+
+a=f.Q15toF32(dsp.arm_fill_q15(f.toQ15(v),nb))
+print(a)
+
+a=f.Q7toF32(dsp.arm_fill_q7(f.toQ7(v),nb))
+print(a)
+
+################# COMPLEX MAT TRANSPOSE #################
+
+printTitle("Complex Transposition")
+a=np.array([[1. + 0.0j ,2 + 1.0j,3 + 0.0j,4 + 2.0j],
+            [5 + 1.0j,6 + 2.0j,7 + 3.0j,8 + 1.0j],
+            [9 - 2.0j,10 + 1.0j,11 - 4.0j,12 + 1.0j]])
+normalizationFactor=np.max(np.abs(c[1]))
+a = a / normalizationFactor
+
+print(np.transpose(a))
+print("")
+r=dsp.arm_mat_cmplx_trans_f32(imToReal2D(a))
+print(realToIm2D(r[1]))
+print("")
+
+r=dsp.arm_mat_cmplx_trans_q31(f.toQ31(imToReal2D(a)))
+print(realToIm2D(f.Q31toF32(r[1])))
+print("")
+
+r=dsp.arm_mat_cmplx_trans_q15(f.toQ15(imToReal2D(a)))
+print(realToIm2D(f.Q15toF32(r[1])))
+print("")
+
+################ Levinson ##################
+
+printTitle("Levinson Durbin")
+na=5
+s = np.random.randn(na+1)
+s = normalize(s)
+phi = autocorr(s)
+phi = normalize(phi)
+
+sigmav,arcoef,pacf,sigma,phi1=statsmodels.tsa.stattools.levinson_durbin(phi,nlags=na,isacov=True)
+      
+print(arcoef)
+print(sigmav)
+
+(a,err)=dsp.arm_levinson_durbin_f32(phi,na)
+print(a)
+print(err)
+
+phiQ31 = f.toQ31(phi)
+(aQ31,errQ31)=dsp.arm_levinson_durbin_q31(phiQ31,na)
+print(f.Q31toF32(aQ31))
+print(f.Q31toF32(errQ31))
+
+################## Bitwise operations #################
+
+printTitle("Bitwise operations")
+def genBitvectors(nb,format):
+    if format == 31:
+       maxVal = 0x7fffffff
+    if format == 15:
+       maxVal = 0x7fff
+    if format == 7:
+       maxVal = 0x7f 
+
+    minVal = -maxVal-1
+    
+    return(np.random.randint(minVal, maxVal, size=nb))
+
+NBSAMPLES=10
+
+
+
+printSubTitle("u32")
+su32A=genBitvectors(NBSAMPLES,31)
+su32B=genBitvectors(NBSAMPLES,31)
+ffff = (np.ones(NBSAMPLES)*(-1)).astype(np.int)
+
+
+ref=np.bitwise_and(su32A, su32B)
+#print(ref)
+result=dsp.arm_and_u32(su32A, su32B).astype(int)
+print(result-ref)
+
+ref=np.bitwise_or(su32A, su32B)
+#print(ref)
+result=dsp.arm_or_u32(su32A, su32B).astype(int)
+print(result-ref)
+
+ref=np.bitwise_xor(su32A, su32B)
+#print(ref)
+result=dsp.arm_xor_u32(su32A, su32B).astype(int)
+print(result-ref)
+
+ref=np.bitwise_xor(ffff, su32A)
+#print(ref)
+result=dsp.arm_not_u32(su32A).astype(int)
+print(result-ref)
+
+printSubTitle("u16")
+su16A=genBitvectors(NBSAMPLES,15)
+su16B=genBitvectors(NBSAMPLES,15)
+
+ffff = (np.ones(NBSAMPLES)*(-1)).astype(np.int)
+
+
+ref=np.bitwise_and(su16A, su16B)
+#print(ref)
+result=dsp.arm_and_u16(su16A, su16B).astype(np.short)
+print(result-ref)
+
+ref=np.bitwise_or(su16A, su16B)
+#print(ref)
+result=dsp.arm_or_u16(su16A, su16B).astype(np.short)
+print(result-ref)
+
+ref=np.bitwise_xor(su16A, su16B)
+#print(ref)
+result=dsp.arm_xor_u16(su16A, su16B).astype(np.short)
+print(result-ref)
+
+ref=np.bitwise_xor(ffff, su16A)
+#print(ref)
+result=dsp.arm_not_u16(su16A).astype(np.short)
+print(result-ref)
+
+printSubTitle("u8")
+
+su8A=genBitvectors(NBSAMPLES,7)
+su8B=genBitvectors(NBSAMPLES,7)
+
+ref=np.bitwise_and(su8A, su8B)
+#print(ref)
+result=dsp.arm_and_u8(su8A, su8B).astype(np.byte)
+print(result-ref)
+
+ref=np.bitwise_or(su8A, su8B)
+#print(ref)
+result=dsp.arm_or_u8(su8A, su8B).astype(np.byte)
+print(result-ref)
+
+ref=np.bitwise_xor(su8A, su8B)
+#print(ref)
+result=dsp.arm_xor_u8(su8A, su8B).astype(np.byte)
+print(result-ref)
+
+ref=np.bitwise_xor(ffff, su8A)
+#print(ref)
+result=dsp.arm_not_u8(su8A).astype(np.byte)
+print(result-ref)
+
+#################### Quaternion tests ##################
+NBSAMPLES=3
+
+def flattenQuat(l):
+    return(np.array([list(x) for x in l]).reshape(4*len(l)))
+
+def flattenRot(l):
+    return(np.array([list(x) for x in l]).reshape(9*len(l)))
+
+# q and -q are representing the same rotation.
+# So there is an ambiguity for the tests.
+# We force the real part of be positive.
+def mkQuaternion(mat):
+    q=Quaternion(matrix=mat)
+    if q.scalar < 0:
+        return(-q)
+    else:
+        return(q)
+
+a=[2.0*Quaternion.random() for x in range(NBSAMPLES)]
+src=flattenQuat(a)
+
+
+res=flattenQuat([x.normalised for x in a])
+print(res)
+output=dsp.arm_quaternion_normalize_f32(src)
+print(output)
+print("")
+
+res=flattenQuat([x.conjugate for x in a])
+print(res)
+output=dsp.arm_quaternion_conjugate_f32(src)
+print(output)
+print("")
+
+res=flattenQuat([x.inverse for x in a])
+print(res)
+output=dsp.arm_quaternion_inverse_f32(src)
+print(output)
+print("")
+
+res=[x.norm for x in a]
+print(res)
+output=dsp.arm_quaternion_norm_f32(src)
+print(output)
+print("")
+
+a=[x.normalised for x in a]
+ra=[x.rotation_matrix for x in a]
+rb=[mkQuaternion(x) for x in ra]
+
+srca=flattenQuat(a)
+resa=dsp.arm_quaternion2rotation_f32(srca)
+resb=dsp.arm_rotation2quaternion_f32(resa)
+
+
+print(ra)
+print(resa)
+print("")
+print(rb)
+print(resb)#
+
+a=[2.0*Quaternion.random() for x in range(NBSAMPLES)]
+b=[2.0*Quaternion.random() for x in range(NBSAMPLES)]
+
+c = np.array(a) * np.array(b)
+print(c)
+
+srca=flattenQuat(a)
+srcb=flattenQuat(b)
+resc=dsp.arm_quaternion_product_f32(srca,srcb)
+
+print(resc)
+
+print(a[0]*b[0])
+res=dsp.arm_quaternion_product_single_f32(srca[0:4],srcb[0:4])
+print(res)
+