CMSIS-DSP: Added new functions to Python wrapper

pull/19/head
Christophe Favergeon 4 years ago
parent 29cb70ce55
commit 1eb1a2ef43

@ -512,6 +512,83 @@ cmsis_arm_vlog_f64(PyObject *obj, PyObject *args)
return(NULL); return(NULL);
} }
static PyObject *
cmsis_arm_atan2_q31(PyObject *obj, PyObject *args)
{
q31_t x,y; // input
q31_t pOut;
if (PyArg_ParseTuple(args,"ii",&y,&x))
{
arm_status returnValue = arm_atan2_q31(y,x,&pOut);
PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
PyObject* pOutOBJ=Py_BuildValue("i",pOut);
PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pOutOBJ);
Py_DECREF(theReturnOBJ);
Py_DECREF(pOutOBJ);
return(pythonResult);
}
return(NULL);
}
static PyObject *
cmsis_arm_atan2_q15(PyObject *obj, PyObject *args)
{
q15_t x,y; // input
q15_t pOut;
if (PyArg_ParseTuple(args,"hh",&y,&x))
{
arm_status returnValue = arm_atan2_q15(y,x,&pOut);
PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
PyObject* pOutOBJ=Py_BuildValue("h",pOut);
PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pOutOBJ);
Py_DECREF(theReturnOBJ);
Py_DECREF(pOutOBJ);
return(pythonResult);
}
return(NULL);
}
static PyObject *
cmsis_arm_atan2_f32(PyObject *obj, PyObject *args)
{
float32_t x,y; // input
float32_t pOut;
if (PyArg_ParseTuple(args,"ff",&y,&x))
{
arm_status returnValue = arm_atan2_f32(y,x,&pOut);
PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
PyObject* pOutOBJ=Py_BuildValue("f",pOut);
PyObject *pythonResult = Py_BuildValue("OO",theReturnOBJ,pOutOBJ);
Py_DECREF(theReturnOBJ);
Py_DECREF(pOutOBJ);
return(pythonResult);
}
return(NULL);
}
static PyMethodDef CMSISDSPMethods[] = { static PyMethodDef CMSISDSPMethods[] = {
@ -538,6 +615,9 @@ static PyMethodDef CMSISDSPMethods[] = {
{"arm_vlog_f32", cmsis_arm_vlog_f32, METH_VARARGS,""}, {"arm_vlog_f32", cmsis_arm_vlog_f32, METH_VARARGS,""},
{"arm_vexp_f64", cmsis_arm_vexp_f64, METH_VARARGS,""}, {"arm_vexp_f64", cmsis_arm_vexp_f64, METH_VARARGS,""},
{"arm_vlog_f64", cmsis_arm_vlog_f64, METH_VARARGS,""}, {"arm_vlog_f64", cmsis_arm_vlog_f64, METH_VARARGS,""},
{"arm_atan2_f32", cmsis_arm_atan2_f32, METH_VARARGS,""},
{"arm_atan2_q31", cmsis_arm_atan2_q31, METH_VARARGS,""},
{"arm_atan2_q15", cmsis_arm_atan2_q15, METH_VARARGS,""},
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL}, {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
}; };

@ -2082,6 +2082,186 @@ cmsis_arm_logsumexp_dot_prod_f32(PyObject *obj, PyObject *args)
return(NULL); return(NULL);
} }
static PyObject *
cmsis_arm_mse_q7(PyObject *obj, PyObject *args)
{
PyObject *pSrcA=NULL; // input
q7_t *pSrcA_converted=NULL; // input
PyObject *pSrcB=NULL; // input
q7_t *pSrcB_converted=NULL; // input
uint32_t blockSize; // input
q7_t pResult; // output
if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
{
GETARGUMENT(pSrcA,NPY_BYTE,int8_t,q7_t);
GETARGUMENT(pSrcB,NPY_BYTE,int8_t,q7_t);
blockSize = arraySizepSrcA ;
arm_mse_q7(pSrcA_converted,pSrcB_converted, blockSize,&pResult);
PyObject* pResultOBJ=Py_BuildValue("i",pResult);
PyObject *pythonResult = Py_BuildValue("O",pResultOBJ);
FREEARGUMENT(pSrcA_converted);
FREEARGUMENT(pSrcB_converted);
Py_DECREF(pResultOBJ);
return(pythonResult);
}
return(NULL);
}
static PyObject *
cmsis_arm_mse_q15(PyObject *obj, PyObject *args)
{
PyObject *pSrcA=NULL; // input
q15_t *pSrcA_converted=NULL; // input
PyObject *pSrcB=NULL; // input
q15_t *pSrcB_converted=NULL; // input
uint32_t blockSize; // input
q15_t pResult; // output
if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
{
GETARGUMENT(pSrcA,NPY_INT16,int16_t,q15_t);
GETARGUMENT(pSrcB,NPY_INT16,int16_t,q15_t);
blockSize = arraySizepSrcA ;
arm_mse_q15(pSrcA_converted,pSrcB_converted,blockSize,&pResult);
PyObject* pResultOBJ=Py_BuildValue("i",pResult);
PyObject *pythonResult = Py_BuildValue("O",pResultOBJ);
FREEARGUMENT(pSrcA_converted);
FREEARGUMENT(pSrcB_converted);
Py_DECREF(pResultOBJ);
return(pythonResult);
}
return(NULL);
}
static PyObject *
cmsis_arm_mse_q31(PyObject *obj, PyObject *args)
{
PyObject *pSrcA=NULL; // input
q31_t *pSrcA_converted=NULL; // input
PyObject *pSrcB=NULL; // input
q31_t *pSrcB_converted=NULL; // input
uint32_t blockSize; // input
q31_t pResult; // output
if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
{
GETARGUMENT(pSrcA,NPY_INT32,int32_t,q31_t);
GETARGUMENT(pSrcB,NPY_INT32,int32_t,q31_t);
blockSize = arraySizepSrcA ;
arm_mse_q31(pSrcA_converted,pSrcB_converted,blockSize,&pResult);
PyObject* pResultOBJ=Py_BuildValue("i",pResult);
PyObject *pythonResult = Py_BuildValue("O",pResultOBJ);
FREEARGUMENT(pSrcA_converted);
FREEARGUMENT(pSrcB_converted);
Py_DECREF(pResultOBJ);
return(pythonResult);
}
return(NULL);
}
static PyObject *
cmsis_arm_mse_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
uint32_t blockSize; // input
float32_t pResult; // output
if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
{
GETARGUMENT(pSrcA,NPY_DOUBLE,double,float32_t);
GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t);
blockSize = arraySizepSrcA ;
arm_mse_f32(pSrcA_converted,pSrcB_converted,blockSize,&pResult);
PyObject* pResultOBJ=Py_BuildValue("f",pResult);
PyObject *pythonResult = Py_BuildValue("O",pResultOBJ);
FREEARGUMENT(pSrcA_converted);
FREEARGUMENT(pSrcB_converted);
Py_DECREF(pResultOBJ);
return(pythonResult);
}
return(NULL);
}
static PyObject *
cmsis_arm_mse_f64(PyObject *obj, PyObject *args)
{
PyObject *pSrcA=NULL; // input
float64_t *pSrcA_converted=NULL; // input
PyObject *pSrcB=NULL; // input
float64_t *pSrcB_converted=NULL; // input
uint32_t blockSize; // input
float64_t pResult; // output
if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB))
{
GETARGUMENT(pSrcA,NPY_DOUBLE,double,float64_t);
GETARGUMENT(pSrcB,NPY_DOUBLE,double,float64_t);
blockSize = arraySizepSrcA ;
arm_mse_f64(pSrcA_converted,pSrcB_converted,blockSize,&pResult);
PyObject* pResultOBJ=Py_BuildValue("d",pResult);
PyObject *pythonResult = Py_BuildValue("O",pResultOBJ);
FREEARGUMENT(pSrcA_converted);
FREEARGUMENT(pSrcB_converted);
Py_DECREF(pResultOBJ);
return(pythonResult);
}
return(NULL);
}
static PyMethodDef CMSISDSPMethods[] = { static PyMethodDef CMSISDSPMethods[] = {
@ -2160,6 +2340,11 @@ static PyMethodDef CMSISDSPMethods[] = {
{"arm_logsumexp_f32", cmsis_arm_logsumexp_f32, METH_VARARGS,""}, {"arm_logsumexp_f32", cmsis_arm_logsumexp_f32, METH_VARARGS,""},
{"arm_logsumexp_dot_prod_f32", cmsis_arm_logsumexp_dot_prod_f32, METH_VARARGS,""}, {"arm_logsumexp_dot_prod_f32", cmsis_arm_logsumexp_dot_prod_f32, METH_VARARGS,""},
{"arm_mse_q7", cmsis_arm_mse_q7, METH_VARARGS,""},
{"arm_mse_q15", cmsis_arm_mse_q15, METH_VARARGS,""},
{"arm_mse_q31", cmsis_arm_mse_q31, METH_VARARGS,""},
{"arm_mse_f32", cmsis_arm_mse_f32, METH_VARARGS,""},
{"arm_mse_f64", cmsis_arm_mse_f64, METH_VARARGS,""},
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL}, {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},

@ -0,0 +1,116 @@
# New functions for version 1.4 of the Python wrapper
import cmsisdsp as dsp
import cmsisdsp.fixedpoint as f
import numpy as np
import math
import colorama
from colorama import init,Fore, Back, Style
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)
printTitle("ArcTan2")
angles=[0,
math.pi/4,
math.pi/2,
3*math.pi/4,
math.pi,
5*math.pi/4,
3*math.pi/2,
7*math.pi/4
]
x = np.cos(angles)
y = np.sin(angles)
vals=list(zip(y,x))
printSubTitle("Atan2 Referebce")
ref=np.array([np.arctan2(yv,xv) for (yv,xv) in vals])/math.pi*180
print(ref)
printSubTitle("Atan2 F32")
resf32=np.array([dsp.arm_atan2_f32(yv,xv)[1] for (yv,xv) in vals])/math.pi*180
print(resf32)
print(np.isclose(ref,resf32,1e-6,1e-6))
printSubTitle("Atan2 Q31")
xQ31=f.toQ31(x)
yQ31=f.toQ31(y)
valsQ31=list(zip(yQ31,xQ31))
resq31=4*f.Q31toF32(np.array([dsp.arm_atan2_q31(yv,xv)[1] for (yv,xv) in valsQ31]))/math.pi*180
print(resq31)
print(np.isclose(ref,resq31,1e-8,1e-8))
printSubTitle("Atan2 Q15")
xQ15=f.toQ15(x)
yQ15=f.toQ15(y)
valsQ15=list(zip(yQ15,xQ15))
resq15=4*f.Q15toF32(np.array([dsp.arm_atan2_q15(yv,xv)[1] for (yv,xv) in valsQ15]))/math.pi*180
print(resq15)
print(np.isclose(ref,resq15,1e-3,1e-3))
printTitle("MSE")
NBSAMPLES = 50
def mse(a,b):
err = a - b
return(np.dot(err,err) / len(a))
a=np.random.randn(NBSAMPLES)
a = a / np.max(np.abs(a))
b=np.random.randn(NBSAMPLES)
b = b / np.max(np.abs(b))
printSubTitle("MSE Reference")
ref = mse(a,b)
print(ref)
printSubTitle("MSE f64")
resf64= dsp.arm_mse_f64(a,b)
print(resf64)
print(np.isclose(ref,resf64,1e-14,1e-14))
printSubTitle("MSE f32")
resf32 = dsp.arm_mse_f32(a,b)
print(resf32)
print(np.isclose(ref,resf32,1e-7,1e-7))
printSubTitle("MSE Q31")
aQ31 = f.toQ31(a)
bQ31 = f.toQ31(b)
resQ31 = f.Q31toF32(dsp.arm_mse_q31(aQ31,bQ31))
print(resQ31)
print(np.isclose(ref,resQ31,1e-7,1e-7))
aQ15 = f.toQ15(a)
bQ15 = f.toQ15(b)
printSubTitle("MSE Q15")
resQ15 = dsp.arm_mse_q15(aQ15,bQ15)
print("%04X" % resQ15)
resQ15 = f.Q15toF32(resQ15)
print(resQ15)
print(np.isclose(ref,resQ15,1e-4,1e-4))
aQ7 = f.toQ7(a)
bQ7 = f.toQ7(b)
printSubTitle("MSE Q7")
resQ7 = dsp.arm_mse_q7(aQ7,bQ7)
print("%04X" % resQ7)
resQ7 = f.Q7toF32(resQ7)
print(resQ7)
print(np.isclose(ref,resQ7,1e-2,1e-2))

@ -3,13 +3,13 @@
* Title: arm_atan2_f16.c * Title: arm_atan2_f16.c
* Description: float16 Arc tangent of y/x * Description: float16 Arc tangent of y/x
* *
* $Date: 06 July 2021 * $Date: 22 April 2022
* $Revision: V1.10.0 * $Revision: V1.10.0
* *
* Target Processor: Cortex-M and Cortex-A cores * Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
/* /*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *

@ -3,13 +3,13 @@
* Title: arm_atan2_f32.c * Title: arm_atan2_f32.c
* Description: float32 Arc tangent of y/x * Description: float32 Arc tangent of y/x
* *
* $Date: 06 July 2021 * $Date: 22 April 2022
* $Revision: V1.10.0 * $Revision: V1.10.0
* *
* Target Processor: Cortex-M and Cortex-A cores * Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
/* /*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *

@ -3,13 +3,13 @@
* Title: arm_atan2_q15.c * Title: arm_atan2_q15.c
* Description: float32 Arc tangent of y/x * Description: float32 Arc tangent of y/x
* *
* $Date: 06 July 2021 * $Date: 22 April 2022
* $Revision: V1.10.0 * $Revision: V1.10.0
* *
* Target Processor: Cortex-M and Cortex-A cores * Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
/* /*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
@ -55,8 +55,6 @@ static const q15_t atan2_coefs_q15[ATAN2_NB_COEFS_Q15]={0x0000
,0xfbdb ,0xfbdb
}; };
#include <stdio.h>
__STATIC_FORCEINLINE q15_t arm_atan_limited_q15(q15_t x) __STATIC_FORCEINLINE q15_t arm_atan_limited_q15(q15_t x)
{ {
q31_t res=(q31_t)atan2_coefs_q15[ATAN2_NB_COEFS_Q15-1]; q31_t res=(q31_t)atan2_coefs_q15[ATAN2_NB_COEFS_Q15-1];

@ -3,13 +3,13 @@
* Title: arm_atan2_q31.c * Title: arm_atan2_q31.c
* Description: float32 Arc tangent of y/x * Description: float32 Arc tangent of y/x
* *
* $Date: 06 July 2021 * $Date: 22 April 2022
* $Revision: V1.10.0 * $Revision: V1.10.0
* *
* Target Processor: Cortex-M and Cortex-A cores * Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
/* /*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *

@ -22,10 +22,11 @@ __version__ = cmsisdsp.version.__version__
cmsis_dsp_version="1.10.0" cmsis_dsp_version="1.10.0"
# Commit hash used to build the wrapper # CMSIS-DSP Commit hash used to build the wrapper
commit_hash="7106010d41b3bf810403e954c36c2643d98c58e7" commit_hash="244e279d7989057d0eef417dfefa806062ec9afd"
# True if development version used # True if development version of CMSIS-DSP used
# (So several CMSIS-DSP versions may have same version number hence the commit hash)
developmentVersion=True developmentVersion=True
__all__ = ["datatype", "fixedpoint", "mfcc"] __all__ = ["datatype", "fixedpoint", "mfcc"]

@ -129,18 +129,18 @@ except:
transformMod = transform + common + basic + complexf + fastmath + matrix + statistics transformMod = transform + common + basic + complexf + fastmath + matrix + statistics
statisticsMod = statistics + common + fastmath + basic statisticsMod = statistics + common + fastmath + basic
interpolationMod = interpolation + common interpolationMod = interpolation + common
filteringMod = filtering + common + support + fastmath filteringMod = filtering + common + support + fastmath + basic
controllerMod = controller + common controllerMod = controller + common
matrixMod = matrix matrixMod = matrix
supportMod = support supportMod = support
complexfMod = complexf + fastmath + common complexfMod = complexf + fastmath + common + basic
basicMod = basic basicMod = basic
quaternionMod = quaternion quaternionMod = quaternion
fastmathMod = fastmath + common fastmathMod = basic + fastmath + common
distanceMod = distance + common + basic + statistics + fastmath distanceMod = distance + common + basic + statistics + fastmath
bayesMod = bayes + fastmath + common + statistics + basic bayesMod = bayes + fastmath + common + statistics + basic
svmMod = svm + fastmath + common svmMod = svm + fastmath + common + basic
filteringMod.append(os.path.join("PythonWrapper","cmsisdsp_pkg","src","cmsisdsp_filtering.c")) filteringMod.append(os.path.join("PythonWrapper","cmsisdsp_pkg","src","cmsisdsp_filtering.c"))

Loading…
Cancel
Save