CMSIS-DSP: Added missing functions to the Python wrapper
Changed the version of Jinja2 required by the wrapper to avoid warnings when using google colab.pull/19/head
parent
65e84e2d05
commit
fb90fab3e7
@ -0,0 +1,272 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Python Wrapper
|
||||
* Title: cmsismodule.h
|
||||
* Description: C code for the CMSIS-DSP Python wrapper
|
||||
*
|
||||
* $Date: 27 April 2021
|
||||
* $Revision: V1.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define MODNAME "cmsisdsp_bayes"
|
||||
#define MODINITNAME cmsisdsp_bayes
|
||||
|
||||
#include "cmsisdsp_module.h"
|
||||
|
||||
|
||||
|
||||
NUMPYVECTORFROMBUFFER(f32,float32_t,NPY_FLOAT);
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
arm_gaussian_naive_bayes_instance_f32 *instance;
|
||||
} dsp_arm_gaussian_naive_bayes_instance_f32Object;
|
||||
|
||||
|
||||
static void
|
||||
arm_gaussian_naive_bayes_instance_f32_dealloc(dsp_arm_gaussian_naive_bayes_instance_f32Object* self)
|
||||
{
|
||||
//printf("Dealloc called\n");
|
||||
if (self->instance)
|
||||
{
|
||||
|
||||
if (self->instance->theta)
|
||||
{
|
||||
PyMem_Free((float32_t*)self->instance->theta);
|
||||
}
|
||||
|
||||
if (self->instance->sigma)
|
||||
{
|
||||
PyMem_Free((float32_t*)self->instance->sigma);
|
||||
}
|
||||
|
||||
if (self->instance->classPriors)
|
||||
{
|
||||
PyMem_Free((float32_t*)self->instance->classPriors);
|
||||
}
|
||||
|
||||
PyMem_Free(self->instance);
|
||||
}
|
||||
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
arm_gaussian_naive_bayes_instance_f32_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
dsp_arm_gaussian_naive_bayes_instance_f32Object *self;
|
||||
//printf("New called\n");
|
||||
|
||||
self = (dsp_arm_gaussian_naive_bayes_instance_f32Object *)type->tp_alloc(type, 0);
|
||||
//printf("alloc called\n");
|
||||
|
||||
if (self != NULL) {
|
||||
|
||||
self->instance = PyMem_Malloc(sizeof(arm_gaussian_naive_bayes_instance_f32));
|
||||
self->instance->theta=NULL;
|
||||
self->instance->sigma=NULL;
|
||||
self->instance->classPriors=NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static int
|
||||
arm_gaussian_naive_bayes_instance_f32_init(dsp_arm_gaussian_naive_bayes_instance_f32Object *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
||||
PyObject *theta=NULL;
|
||||
PyObject *sigma=NULL;
|
||||
PyObject *classPriors=NULL;
|
||||
|
||||
char *kwlist[] = {
|
||||
"vectorDimension",
|
||||
"numberOfClasses",
|
||||
"theta",
|
||||
"sigma",
|
||||
"classPriors",
|
||||
"epsilon",NULL
|
||||
};
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|iiOOOf", kwlist,
|
||||
&self->instance->vectorDimension
|
||||
,&self->instance->numberOfClasses
|
||||
,&theta
|
||||
,&sigma
|
||||
,&classPriors
|
||||
,&self->instance->epsilon
|
||||
))
|
||||
{
|
||||
|
||||
INITARRAYFIELD(theta,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(sigma,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(classPriors,NPY_DOUBLE,double,float32_t);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GETFIELD(arm_gaussian_naive_bayes_instance_f32,vectorDimension,"i");
|
||||
GETFIELD(arm_gaussian_naive_bayes_instance_f32,numberOfClasses,"i");
|
||||
GETFIELD(arm_gaussian_naive_bayes_instance_f32,epsilon,"f");
|
||||
|
||||
|
||||
static PyMethodDef arm_gaussian_naive_bayes_instance_f32_methods[] = {
|
||||
|
||||
{"vectorDimension", (PyCFunction) Method_arm_gaussian_naive_bayes_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
|
||||
{"numberOfClasses", (PyCFunction) Method_arm_gaussian_naive_bayes_instance_f32_numberOfClasses,METH_NOARGS,"numberOfClasses"},
|
||||
{"epsilon", (PyCFunction) Method_arm_gaussian_naive_bayes_instance_f32_epsilon,METH_NOARGS,"epsilon"},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
DSPType(arm_gaussian_naive_bayes_instance_f32,arm_gaussian_naive_bayes_instance_f32_new,arm_gaussian_naive_bayes_instance_f32_dealloc,arm_gaussian_naive_bayes_instance_f32_init,arm_gaussian_naive_bayes_instance_f32_methods);
|
||||
|
||||
|
||||
|
||||
|
||||
void typeRegistration(PyObject *module) {
|
||||
|
||||
|
||||
|
||||
ADDTYPE(arm_gaussian_naive_bayes_instance_f32);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
cmsis_arm_gaussian_naive_bayes_predict_f32(PyObject *obj, PyObject *args)
|
||||
{
|
||||
|
||||
PyObject *S=NULL; // input
|
||||
PyObject *pSrc=NULL; // input
|
||||
float32_t *pSrc_converted=NULL; // input
|
||||
float32_t *pDst=NULL; // output
|
||||
uint32_t nbClasses; // input
|
||||
|
||||
if (PyArg_ParseTuple(args,"OO",&S,&pSrc))
|
||||
{
|
||||
|
||||
dsp_arm_gaussian_naive_bayes_instance_f32Object *selfS = (dsp_arm_gaussian_naive_bayes_instance_f32Object *)S;
|
||||
GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t);
|
||||
|
||||
nbClasses=selfS->instance->numberOfClasses;
|
||||
|
||||
|
||||
pDst=PyMem_Malloc(sizeof(float32_t)*nbClasses);
|
||||
float32_t *temp=PyMem_Malloc(sizeof(float32_t)*nbClasses);
|
||||
|
||||
|
||||
uint32_t res=arm_gaussian_naive_bayes_predict_f32(selfS->instance,pSrc_converted,pDst,temp);
|
||||
FLOATARRAY1(pDstOBJ,nbClasses,pDst);
|
||||
|
||||
PyObject *pythonResult = Py_BuildValue("Ok",pDstOBJ,res);
|
||||
|
||||
FREEARGUMENT(pSrc_converted);
|
||||
PyMem_Free(temp);
|
||||
Py_DECREF(pDstOBJ);
|
||||
return(pythonResult);
|
||||
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static PyMethodDef CMSISDSPMethods[] = {
|
||||
|
||||
|
||||
|
||||
{"arm_gaussian_naive_bayes_predict_f32", cmsis_arm_gaussian_naive_bayes_predict_f32, METH_VARARGS,""},
|
||||
|
||||
|
||||
|
||||
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
#ifdef IS_PY3K
|
||||
static int cmsisdsp_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmsisdsp_clear(PyObject *m) {
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct PyModuleDef moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
MODNAME,
|
||||
NULL,
|
||||
sizeof(struct module_state),
|
||||
CMSISDSPMethods,
|
||||
NULL,
|
||||
cmsisdsp_traverse,
|
||||
cmsisdsp_clear,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define INITERROR return NULL
|
||||
|
||||
PyMODINIT_FUNC
|
||||
CAT(PyInit_,MODINITNAME)(void)
|
||||
|
||||
|
||||
#else
|
||||
#define INITERROR return
|
||||
|
||||
void CAT(init,MODINITNAME)(void)
|
||||
#endif
|
||||
{
|
||||
import_array();
|
||||
|
||||
#ifdef IS_PY3K
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
#else
|
||||
PyObject *module = Py_InitModule(MODNAME, CMSISDSPMethods);
|
||||
#endif
|
||||
|
||||
if (module == NULL)
|
||||
INITERROR;
|
||||
struct module_state *st = GETSTATE(module);
|
||||
|
||||
st->error = PyErr_NewException(MODNAME".Error", NULL, NULL);
|
||||
if (st->error == NULL) {
|
||||
Py_DECREF(module);
|
||||
INITERROR;
|
||||
}
|
||||
|
||||
|
||||
typeRegistration(module);
|
||||
|
||||
#ifdef IS_PY3K
|
||||
return module;
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,308 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Python Wrapper
|
||||
* Title: cmsismodule.h
|
||||
* Description: C code for the CMSIS-DSP Python wrapper
|
||||
*
|
||||
* $Date: 27 April 2021
|
||||
* $Revision: V1.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define MODNAME "cmsisdsp_distance"
|
||||
#define MODINITNAME cmsisdsp_distance
|
||||
|
||||
#include "cmsisdsp_module.h"
|
||||
|
||||
|
||||
NUMPYVECTORFROMBUFFER(f32,float32_t,NPY_FLOAT);
|
||||
|
||||
|
||||
void typeRegistration(PyObject *module) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
#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; \
|
||||
\
|
||||
if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB)) \
|
||||
{ \
|
||||
\
|
||||
GETARGUMENT(pSrcA,NPY_DOUBLE,double,float32_t); \
|
||||
GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t); \
|
||||
blockSize = arraySizepSrcA ; \
|
||||
\
|
||||
\
|
||||
\
|
||||
result=arm_##NAME##_f32(pSrcA_converted,pSrcB_converted,blockSize);\
|
||||
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); \
|
||||
}
|
||||
|
||||
#define FLOAT64DIST(NAME) \
|
||||
static PyObject * \
|
||||
cmsis_arm_##NAME##_f64(PyObject *obj, PyObject *args) \
|
||||
{ \
|
||||
\
|
||||
PyObject *pSrcA=NULL; \
|
||||
float64_t *pSrcA_converted=NULL; \
|
||||
PyObject *pSrcB=NULL; \
|
||||
float64_t *pSrcB_converted=NULL; \
|
||||
uint32_t blockSize; \
|
||||
float64_t result; \
|
||||
\
|
||||
if (PyArg_ParseTuple(args,"OO",&pSrcA,&pSrcB)) \
|
||||
{ \
|
||||
\
|
||||
GETARGUMENT(pSrcA,NPY_DOUBLE,double,float64_t); \
|
||||
GETARGUMENT(pSrcB,NPY_DOUBLE,double,float64_t); \
|
||||
blockSize = arraySizepSrcA ; \
|
||||
\
|
||||
\
|
||||
\
|
||||
result=arm_##NAME##_f64(pSrcA_converted,pSrcB_converted,blockSize);\
|
||||
PyObject* resultOBJ=Py_BuildValue("d",result); \
|
||||
\
|
||||
PyObject *pythonResult = Py_BuildValue("O",resultOBJ); \
|
||||
\
|
||||
FREEARGUMENT(pSrcA_converted); \
|
||||
FREEARGUMENT(pSrcB_converted); \
|
||||
Py_DECREF(resultOBJ); \
|
||||
return(pythonResult); \
|
||||
\
|
||||
} \
|
||||
return(NULL); \
|
||||
}
|
||||
|
||||
FLOAT64DIST(chebyshev_distance);
|
||||
FLOAT64DIST(cityblock_distance);
|
||||
FLOAT64DIST(cosine_distance);
|
||||
FLOAT64DIST(euclidean_distance);
|
||||
|
||||
|
||||
FLOATDIST(braycurtis_distance);
|
||||
FLOATDIST(canberra_distance);
|
||||
FLOATDIST(chebyshev_distance);
|
||||
FLOATDIST(cityblock_distance);
|
||||
FLOATDIST(correlation_distance);
|
||||
FLOATDIST(cosine_distance);
|
||||
FLOATDIST(euclidean_distance);
|
||||
FLOATDIST(jensenshannon_distance);
|
||||
|
||||
static PyObject *
|
||||
cmsis_arm_minkowski_distance_f32(PyObject *obj, PyObject *args)
|
||||
{
|
||||
|
||||
PyObject *pSrcA=NULL;
|
||||
float32_t *pSrcA_converted=NULL;
|
||||
PyObject *pSrcB=NULL;
|
||||
float32_t *pSrcB_converted=NULL;
|
||||
int32_t w;
|
||||
uint32_t blockSize;
|
||||
float32_t result;
|
||||
|
||||
if (PyArg_ParseTuple(args,"OOl",&pSrcA,&pSrcB,&w))
|
||||
{
|
||||
|
||||
GETARGUMENT(pSrcA,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t);
|
||||
|
||||
blockSize = arraySizepSrcA ;
|
||||
|
||||
|
||||
|
||||
result=arm_minkowski_distance_f32(pSrcA_converted,pSrcB_converted,w,blockSize);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#define INTDIST(NAME) \
|
||||
static PyObject * \
|
||||
cmsis_arm_##NAME (PyObject *obj, PyObject *args) \
|
||||
{ \
|
||||
\
|
||||
PyObject *pSrcA=NULL; \
|
||||
uint32_t *pSrcA_converted=NULL; \
|
||||
PyObject *pSrcB=NULL; \
|
||||
uint32_t *pSrcB_converted=NULL; \
|
||||
uint32_t blockSize; \
|
||||
float32_t result; \
|
||||
\
|
||||
\
|
||||
if (PyArg_ParseTuple(args,"OOl",&pSrcA,&pSrcB,&blockSize)) \
|
||||
{ \
|
||||
\
|
||||
GETARGUMENT(pSrcA,NPY_UINT32,uint32_t,uint32_t); \
|
||||
GETARGUMENT(pSrcB,NPY_UINT32,uint32_t,uint32_t); \
|
||||
\
|
||||
\
|
||||
\
|
||||
result=arm_##NAME (pSrcA_converted,pSrcB_converted,blockSize); \
|
||||
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); \
|
||||
}
|
||||
|
||||
|
||||
INTDIST(dice_distance);
|
||||
INTDIST(hamming_distance);
|
||||
INTDIST(jaccard_distance);
|
||||
INTDIST(kulsinski_distance);
|
||||
INTDIST(rogerstanimoto_distance);
|
||||
INTDIST(russellrao_distance);
|
||||
INTDIST(sokalmichener_distance);
|
||||
INTDIST(sokalsneath_distance);
|
||||
INTDIST(yule_distance);
|
||||
|
||||
|
||||
static PyMethodDef CMSISDSPMethods[] = {
|
||||
|
||||
{"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_chebyshev_distance_f64" , cmsis_arm_chebyshev_distance_f64, METH_VARARGS,""},
|
||||
|
||||
{"arm_cityblock_distance_f32", cmsis_arm_cityblock_distance_f32, METH_VARARGS,""},
|
||||
{"arm_cityblock_distance_f64", cmsis_arm_cityblock_distance_f64, 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_cosine_distance_f64", cmsis_arm_cosine_distance_f64, METH_VARARGS,""},
|
||||
|
||||
{"arm_euclidean_distance_f32", cmsis_arm_euclidean_distance_f32, METH_VARARGS,""},
|
||||
{"arm_euclidean_distance_f64", cmsis_arm_euclidean_distance_f64, METH_VARARGS,""},
|
||||
|
||||
{"arm_jensenshannon_distance_f32", cmsis_arm_jensenshannon_distance_f32, METH_VARARGS,""},
|
||||
{"arm_minkowski_distance_f32", cmsis_arm_minkowski_distance_f32, METH_VARARGS,""},
|
||||
|
||||
{"arm_dice_distance",cmsis_arm_dice_distance, METH_VARARGS,""},
|
||||
{"arm_hamming_distance",cmsis_arm_hamming_distance, METH_VARARGS,""},
|
||||
{"arm_jaccard_distance",cmsis_arm_jaccard_distance, METH_VARARGS,""},
|
||||
{"arm_kulsinski_distance",cmsis_arm_kulsinski_distance, METH_VARARGS,""},
|
||||
{"arm_rogerstanimoto_distance",cmsis_arm_rogerstanimoto_distance, METH_VARARGS,""},
|
||||
{"arm_russellrao_distance",cmsis_arm_russellrao_distance, METH_VARARGS,""},
|
||||
{"arm_sokalmichener_distance",cmsis_arm_sokalmichener_distance, METH_VARARGS,""},
|
||||
{"arm_sokalsneath_distance",cmsis_arm_sokalsneath_distance, METH_VARARGS,""},
|
||||
{"arm_yule_distance",cmsis_arm_yule_distance, METH_VARARGS,""},
|
||||
|
||||
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
#ifdef IS_PY3K
|
||||
static int cmsisdsp_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmsisdsp_clear(PyObject *m) {
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct PyModuleDef moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
MODNAME,
|
||||
NULL,
|
||||
sizeof(struct module_state),
|
||||
CMSISDSPMethods,
|
||||
NULL,
|
||||
cmsisdsp_traverse,
|
||||
cmsisdsp_clear,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define INITERROR return NULL
|
||||
|
||||
PyMODINIT_FUNC
|
||||
CAT(PyInit_,MODINITNAME)(void)
|
||||
|
||||
|
||||
#else
|
||||
#define INITERROR return
|
||||
|
||||
void CAT(init,MODINITNAME)(void)
|
||||
#endif
|
||||
{
|
||||
import_array();
|
||||
|
||||
#ifdef IS_PY3K
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
#else
|
||||
PyObject *module = Py_InitModule(MODNAME, CMSISDSPMethods);
|
||||
#endif
|
||||
|
||||
if (module == NULL)
|
||||
INITERROR;
|
||||
struct module_state *st = GETSTATE(module);
|
||||
|
||||
st->error = PyErr_NewException(MODNAME".Error", NULL, NULL);
|
||||
if (st->error == NULL) {
|
||||
Py_DECREF(module);
|
||||
INITERROR;
|
||||
}
|
||||
|
||||
|
||||
typeRegistration(module);
|
||||
|
||||
#ifdef IS_PY3K
|
||||
return module;
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,695 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Python Wrapper
|
||||
* Title: cmsismodule.h
|
||||
* Description: C code for the CMSIS-DSP Python wrapper
|
||||
*
|
||||
* $Date: 27 April 2021
|
||||
* $Revision: V1.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define MODNAME "cmsisdsp_svm"
|
||||
#define MODINITNAME cmsisdsp_svm
|
||||
|
||||
#include "cmsisdsp_module.h"
|
||||
|
||||
|
||||
|
||||
NUMPYVECTORFROMBUFFER(f32,float32_t,NPY_FLOAT);
|
||||
|
||||
|
||||
#define SVMTYPE(NAME) \
|
||||
typedef struct { \
|
||||
PyObject_HEAD \
|
||||
arm_svm_##NAME##_instance_f32 *instance;\
|
||||
} dsp_arm_svm_##NAME##_instance_f32Object;
|
||||
|
||||
SVMTYPE(linear);
|
||||
SVMTYPE(polynomial);
|
||||
SVMTYPE(rbf);
|
||||
SVMTYPE(sigmoid);
|
||||
|
||||
#define SVMTYPEDEALLOC(NAME) \
|
||||
static void \
|
||||
arm_svm_##NAME##_instance_f32_dealloc(dsp_arm_svm_##NAME##_instance_f32Object* self)\
|
||||
{ \
|
||||
if (self->instance) \
|
||||
{ \
|
||||
\
|
||||
if (self->instance->dualCoefficients) \
|
||||
{ \
|
||||
PyMem_Free((float32_t*)self->instance->dualCoefficients); \
|
||||
} \
|
||||
\
|
||||
if (self->instance->supportVectors) \
|
||||
{ \
|
||||
PyMem_Free((float32_t*)self->instance->supportVectors); \
|
||||
} \
|
||||
\
|
||||
if (self->instance->classes) \
|
||||
{ \
|
||||
PyMem_Free((float32_t*)self->instance->classes); \
|
||||
} \
|
||||
\
|
||||
PyMem_Free(self->instance); \
|
||||
} \
|
||||
\
|
||||
Py_TYPE(self)->tp_free((PyObject*)self); \
|
||||
}
|
||||
|
||||
SVMTYPEDEALLOC(linear);
|
||||
SVMTYPEDEALLOC(polynomial);
|
||||
SVMTYPEDEALLOC(rbf);
|
||||
SVMTYPEDEALLOC(sigmoid);
|
||||
|
||||
#define SVMTYPENEW(NAME) \
|
||||
static PyObject * \
|
||||
arm_svm_##NAME##_instance_f32_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\
|
||||
{ \
|
||||
dsp_arm_svm_##NAME##_instance_f32Object *self; \
|
||||
\
|
||||
self = (dsp_arm_svm_##NAME##_instance_f32Object *)type->tp_alloc(type, 0); \
|
||||
\
|
||||
if (self != NULL) { \
|
||||
\
|
||||
self->instance = PyMem_Malloc(sizeof(arm_svm_##NAME##_instance_f32)); \
|
||||
self->instance->dualCoefficients=NULL; \
|
||||
self->instance->supportVectors=NULL; \
|
||||
self->instance->classes=NULL; \
|
||||
\
|
||||
} \
|
||||
\
|
||||
\
|
||||
return (PyObject *)self; \
|
||||
}
|
||||
|
||||
SVMTYPENEW(linear);
|
||||
SVMTYPENEW(polynomial);
|
||||
SVMTYPENEW(rbf);
|
||||
SVMTYPENEW(sigmoid);
|
||||
|
||||
/*
|
||||
|
||||
LINEAR INIT
|
||||
|
||||
*/
|
||||
|
||||
static int
|
||||
arm_svm_linear_instance_f32_init(dsp_arm_svm_linear_instance_f32Object *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
||||
PyObject *dualCoefficients=NULL;
|
||||
PyObject *supportVectors=NULL;
|
||||
PyObject *classes=NULL;
|
||||
|
||||
char *kwlist[] = {
|
||||
"nbOfSupportVectors",
|
||||
"vectorDimension",
|
||||
"intercept",
|
||||
"dualCoefficients",
|
||||
"supportVectors",
|
||||
"classes",
|
||||
NULL
|
||||
};
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOO", kwlist,
|
||||
&self->instance->nbOfSupportVectors
|
||||
,&self->instance->vectorDimension
|
||||
,&self->instance->intercept
|
||||
,&dualCoefficients
|
||||
,&supportVectors
|
||||
,&classes
|
||||
))
|
||||
{
|
||||
|
||||
INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GETFIELD(arm_svm_linear_instance_f32,nbOfSupportVectors,"k");
|
||||
GETFIELD(arm_svm_linear_instance_f32,vectorDimension,"k");
|
||||
GETFIELD(arm_svm_linear_instance_f32,intercept,"f");
|
||||
|
||||
|
||||
static PyMethodDef arm_svm_linear_instance_f32_methods[] = {
|
||||
|
||||
{"nbOfSupportVectors", (PyCFunction) Method_arm_svm_linear_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
|
||||
{"vectorDimension", (PyCFunction) Method_arm_svm_linear_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
|
||||
{"intercept", (PyCFunction) Method_arm_svm_linear_instance_f32_intercept,METH_NOARGS,"intercept"},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
POLYNOMIAl INIT
|
||||
|
||||
*/
|
||||
|
||||
static int
|
||||
arm_svm_polynomial_instance_f32_init(dsp_arm_svm_polynomial_instance_f32Object *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
||||
PyObject *dualCoefficients=NULL;
|
||||
PyObject *supportVectors=NULL;
|
||||
PyObject *classes=NULL;
|
||||
|
||||
char *kwlist[] = {
|
||||
"nbOfSupportVectors",
|
||||
"vectorDimension",
|
||||
"intercept",
|
||||
"dualCoefficients",
|
||||
"supportVectors",
|
||||
"classes",
|
||||
"degree",
|
||||
"coef0",
|
||||
"gamma",
|
||||
NULL
|
||||
};
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOOiff", kwlist,
|
||||
&self->instance->nbOfSupportVectors
|
||||
,&self->instance->vectorDimension
|
||||
,&self->instance->intercept
|
||||
,&dualCoefficients
|
||||
,&supportVectors
|
||||
,&classes
|
||||
,&self->instance->degree
|
||||
,&self->instance->coef0
|
||||
,&self->instance->gamma
|
||||
))
|
||||
{
|
||||
|
||||
INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GETFIELD(arm_svm_polynomial_instance_f32,nbOfSupportVectors,"k");
|
||||
GETFIELD(arm_svm_polynomial_instance_f32,vectorDimension,"k");
|
||||
GETFIELD(arm_svm_polynomial_instance_f32,intercept,"f");
|
||||
GETFIELD(arm_svm_polynomial_instance_f32,degree,"i");
|
||||
GETFIELD(arm_svm_polynomial_instance_f32,coef0,"f");
|
||||
GETFIELD(arm_svm_polynomial_instance_f32,gamma,"f");
|
||||
|
||||
|
||||
static PyMethodDef arm_svm_polynomial_instance_f32_methods[] = {
|
||||
|
||||
{"nbOfSupportVectors", (PyCFunction) Method_arm_svm_polynomial_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
|
||||
{"vectorDimension", (PyCFunction) Method_arm_svm_polynomial_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
|
||||
{"intercept", (PyCFunction) Method_arm_svm_polynomial_instance_f32_intercept,METH_NOARGS,"intercept"},
|
||||
{"degree", (PyCFunction) Method_arm_svm_polynomial_instance_f32_degree,METH_NOARGS,"degree"},
|
||||
{"coef0", (PyCFunction) Method_arm_svm_polynomial_instance_f32_coef0,METH_NOARGS,"coef0"},
|
||||
{"gamma", (PyCFunction) Method_arm_svm_polynomial_instance_f32_gamma,METH_NOARGS,"gamma"},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
RBF INIT
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static int
|
||||
arm_svm_rbf_instance_f32_init(dsp_arm_svm_rbf_instance_f32Object *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
||||
PyObject *dualCoefficients=NULL;
|
||||
PyObject *supportVectors=NULL;
|
||||
PyObject *classes=NULL;
|
||||
|
||||
char *kwlist[] = {
|
||||
"nbOfSupportVectors",
|
||||
"vectorDimension",
|
||||
"intercept",
|
||||
"dualCoefficients",
|
||||
"supportVectors",
|
||||
"classes",
|
||||
"gamma",
|
||||
NULL
|
||||
};
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOOf", kwlist,
|
||||
&self->instance->nbOfSupportVectors
|
||||
,&self->instance->vectorDimension
|
||||
,&self->instance->intercept
|
||||
,&dualCoefficients
|
||||
,&supportVectors
|
||||
,&classes
|
||||
,&self->instance->gamma
|
||||
))
|
||||
{
|
||||
|
||||
INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GETFIELD(arm_svm_rbf_instance_f32,nbOfSupportVectors,"k");
|
||||
GETFIELD(arm_svm_rbf_instance_f32,vectorDimension,"k");
|
||||
GETFIELD(arm_svm_rbf_instance_f32,intercept,"f");
|
||||
GETFIELD(arm_svm_rbf_instance_f32,gamma,"f");
|
||||
|
||||
|
||||
static PyMethodDef arm_svm_rbf_instance_f32_methods[] = {
|
||||
|
||||
{"nbOfSupportVectors", (PyCFunction) Method_arm_svm_rbf_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
|
||||
{"vectorDimension", (PyCFunction) Method_arm_svm_rbf_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
|
||||
{"intercept", (PyCFunction) Method_arm_svm_rbf_instance_f32_intercept,METH_NOARGS,"intercept"},
|
||||
{"gamma", (PyCFunction) Method_arm_svm_rbf_instance_f32_gamma,METH_NOARGS,"gamma"},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
SIGMOID INIT
|
||||
|
||||
*/
|
||||
|
||||
static int
|
||||
arm_svm_sigmoid_instance_f32_init(dsp_arm_svm_sigmoid_instance_f32Object *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
||||
PyObject *dualCoefficients=NULL;
|
||||
PyObject *supportVectors=NULL;
|
||||
PyObject *classes=NULL;
|
||||
|
||||
char *kwlist[] = {
|
||||
"nbOfSupportVectors",
|
||||
"vectorDimension",
|
||||
"intercept",
|
||||
"dualCoefficients",
|
||||
"supportVectors",
|
||||
"classes",
|
||||
"coef0",
|
||||
"gamma",
|
||||
NULL
|
||||
};
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOOff", kwlist,
|
||||
&self->instance->nbOfSupportVectors
|
||||
,&self->instance->vectorDimension
|
||||
,&self->instance->intercept
|
||||
,&dualCoefficients
|
||||
,&supportVectors
|
||||
,&classes
|
||||
,&self->instance->coef0
|
||||
,&self->instance->gamma
|
||||
))
|
||||
{
|
||||
|
||||
INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
|
||||
INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GETFIELD(arm_svm_sigmoid_instance_f32,nbOfSupportVectors,"k");
|
||||
GETFIELD(arm_svm_sigmoid_instance_f32,vectorDimension,"k");
|
||||
GETFIELD(arm_svm_sigmoid_instance_f32,intercept,"f");
|
||||
GETFIELD(arm_svm_sigmoid_instance_f32,coef0,"f");
|
||||
GETFIELD(arm_svm_sigmoid_instance_f32,gamma,"f");
|
||||
|
||||
|
||||
static PyMethodDef arm_svm_sigmoid_instance_f32_methods[] = {
|
||||
|
||||
{"nbOfSupportVectors", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
|
||||
{"vectorDimension", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
|
||||
{"intercept", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_intercept,METH_NOARGS,"intercept"},
|
||||
{"coef0", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_coef0,METH_NOARGS,"coef0"},
|
||||
{"gamma", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_gamma,METH_NOARGS,"gamma"},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
DSPType(arm_svm_linear_instance_f32,arm_svm_linear_instance_f32_new,arm_svm_linear_instance_f32_dealloc,arm_svm_linear_instance_f32_init,arm_svm_linear_instance_f32_methods);
|
||||
DSPType(arm_svm_polynomial_instance_f32,arm_svm_polynomial_instance_f32_new,arm_svm_polynomial_instance_f32_dealloc,arm_svm_polynomial_instance_f32_init,arm_svm_polynomial_instance_f32_methods);
|
||||
DSPType(arm_svm_rbf_instance_f32,arm_svm_rbf_instance_f32_new,arm_svm_rbf_instance_f32_dealloc,arm_svm_rbf_instance_f32_init,arm_svm_rbf_instance_f32_methods);
|
||||
DSPType(arm_svm_sigmoid_instance_f32,arm_svm_sigmoid_instance_f32_new,arm_svm_sigmoid_instance_f32_dealloc,arm_svm_sigmoid_instance_f32_init,arm_svm_sigmoid_instance_f32_methods);
|
||||
|
||||
|
||||
|
||||
|
||||
void typeRegistration(PyObject *module) {
|
||||
|
||||
|
||||
|
||||
ADDTYPE(arm_svm_linear_instance_f32);
|
||||
ADDTYPE(arm_svm_polynomial_instance_f32);
|
||||
ADDTYPE(arm_svm_rbf_instance_f32);
|
||||
ADDTYPE(arm_svm_sigmoid_instance_f32);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
cmsis_arm_svm_linear_init_f32(PyObject *obj, PyObject *args)
|
||||
{
|
||||
|
||||
PyObject *S=NULL; // input
|
||||
uint16_t numTaps; // input
|
||||
PyObject *pdualCoefficients=NULL; // input
|
||||
float32_t *pdualCoefficients_converted=NULL; // input
|
||||
PyObject *psupportVectors=NULL; // input
|
||||
float32_t *psupportVectors_converted=NULL; // input
|
||||
PyObject *pclasses=NULL; // input
|
||||
int32_t *pclasses_converted=NULL; // input
|
||||
uint32_t blockSize; // input
|
||||
|
||||
uint32_t nbOfSupportVectors;
|
||||
uint32_t vectorDimension;
|
||||
float32_t intercept;
|
||||
|
||||
if (PyArg_ParseTuple(args,"OkkfOOO",&S,
|
||||
&nbOfSupportVectors,
|
||||
&vectorDimension,
|
||||
&intercept,
|
||||
&pdualCoefficients,
|
||||
&psupportVectors,
|
||||
&pclasses
|
||||
))
|
||||
{
|
||||
|
||||
dsp_arm_svm_linear_instance_f32Object *selfS = (dsp_arm_svm_linear_instance_f32Object *)S;
|
||||
GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
|
||||
|
||||
arm_svm_linear_init_f32(selfS->instance,
|
||||
nbOfSupportVectors,
|
||||
vectorDimension,
|
||||
intercept,
|
||||
pdualCoefficients_converted,
|
||||
psupportVectors_converted,
|
||||
pclasses_converted);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
cmsis_arm_svm_polynomial_init_f32(PyObject *obj, PyObject *args)
|
||||
{
|
||||
|
||||
PyObject *S=NULL; // input
|
||||
uint16_t numTaps; // input
|
||||
PyObject *pdualCoefficients=NULL; // input
|
||||
float32_t *pdualCoefficients_converted=NULL; // input
|
||||
PyObject *psupportVectors=NULL; // input
|
||||
float32_t *psupportVectors_converted=NULL; // input
|
||||
PyObject *pclasses=NULL; // input
|
||||
int32_t *pclasses_converted=NULL; // input
|
||||
uint32_t blockSize; // input
|
||||
|
||||
uint32_t nbOfSupportVectors;
|
||||
uint32_t vectorDimension;
|
||||
float32_t intercept;
|
||||
int32_t degree;
|
||||
float32_t coef0;
|
||||
float32_t gamma;
|
||||
|
||||
if (PyArg_ParseTuple(args,"OkkfOOOiff",&S,
|
||||
&nbOfSupportVectors,
|
||||
&vectorDimension,
|
||||
&intercept,
|
||||
&pdualCoefficients,
|
||||
&psupportVectors,
|
||||
&pclasses,
|
||||
°ree,
|
||||
&coef0,
|
||||
&gamma
|
||||
))
|
||||
{
|
||||
|
||||
dsp_arm_svm_polynomial_instance_f32Object *selfS = (dsp_arm_svm_polynomial_instance_f32Object *)S;
|
||||
GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
|
||||
|
||||
arm_svm_polynomial_init_f32(selfS->instance,
|
||||
nbOfSupportVectors,
|
||||
vectorDimension,
|
||||
intercept,
|
||||
pdualCoefficients_converted,
|
||||
psupportVectors_converted,
|
||||
pclasses_converted,
|
||||
degree,
|
||||
coef0,
|
||||
gamma
|
||||
);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
cmsis_arm_svm_rbf_init_f32(PyObject *obj, PyObject *args)
|
||||
{
|
||||
|
||||
PyObject *S=NULL; // input
|
||||
uint16_t numTaps; // input
|
||||
PyObject *pdualCoefficients=NULL; // input
|
||||
float32_t *pdualCoefficients_converted=NULL; // input
|
||||
PyObject *psupportVectors=NULL; // input
|
||||
float32_t *psupportVectors_converted=NULL; // input
|
||||
PyObject *pclasses=NULL; // input
|
||||
int32_t *pclasses_converted=NULL; // input
|
||||
uint32_t blockSize; // input
|
||||
|
||||
uint32_t nbOfSupportVectors;
|
||||
uint32_t vectorDimension;
|
||||
float32_t intercept;
|
||||
float32_t gamma;
|
||||
|
||||
if (PyArg_ParseTuple(args,"OkkfOOOf",&S,
|
||||
&nbOfSupportVectors,
|
||||
&vectorDimension,
|
||||
&intercept,
|
||||
&pdualCoefficients,
|
||||
&psupportVectors,
|
||||
&pclasses,
|
||||
&gamma
|
||||
))
|
||||
{
|
||||
|
||||
dsp_arm_svm_rbf_instance_f32Object *selfS = (dsp_arm_svm_rbf_instance_f32Object *)S;
|
||||
GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
|
||||
|
||||
arm_svm_rbf_init_f32(selfS->instance,
|
||||
nbOfSupportVectors,
|
||||
vectorDimension,
|
||||
intercept,
|
||||
pdualCoefficients_converted,
|
||||
psupportVectors_converted,
|
||||
pclasses_converted,
|
||||
gamma
|
||||
);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
cmsis_arm_svm_sigmoid_init_f32(PyObject *obj, PyObject *args)
|
||||
{
|
||||
|
||||
PyObject *S=NULL; // input
|
||||
uint16_t numTaps; // input
|
||||
PyObject *pdualCoefficients=NULL; // input
|
||||
float32_t *pdualCoefficients_converted=NULL; // input
|
||||
PyObject *psupportVectors=NULL; // input
|
||||
float32_t *psupportVectors_converted=NULL; // input
|
||||
PyObject *pclasses=NULL; // input
|
||||
int32_t *pclasses_converted=NULL; // input
|
||||
uint32_t blockSize; // input
|
||||
|
||||
uint32_t nbOfSupportVectors;
|
||||
uint32_t vectorDimension;
|
||||
float32_t intercept;
|
||||
float32_t coef0;
|
||||
float32_t gamma;
|
||||
|
||||
if (PyArg_ParseTuple(args,"OkkfOOOff",&S,
|
||||
&nbOfSupportVectors,
|
||||
&vectorDimension,
|
||||
&intercept,
|
||||
&pdualCoefficients,
|
||||
&psupportVectors,
|
||||
&pclasses,
|
||||
&coef0,
|
||||
&gamma
|
||||
))
|
||||
{
|
||||
|
||||
dsp_arm_svm_sigmoid_instance_f32Object *selfS = (dsp_arm_svm_sigmoid_instance_f32Object *)S;
|
||||
GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
|
||||
GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
|
||||
|
||||
arm_svm_sigmoid_init_f32(selfS->instance,
|
||||
nbOfSupportVectors,
|
||||
vectorDimension,
|
||||
intercept,
|
||||
pdualCoefficients_converted,
|
||||
psupportVectors_converted,
|
||||
pclasses_converted,
|
||||
coef0,
|
||||
gamma
|
||||
);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
#define SVMPREDICT(NAME) \
|
||||
static PyObject * \
|
||||
cmsis_arm_svm_##NAME##_predict_f32(PyObject *obj, PyObject *args) \
|
||||
{ \
|
||||
\
|
||||
PyObject *S=NULL; \
|
||||
PyObject *pSrc=NULL; \
|
||||
float32_t *pSrc_converted=NULL; \
|
||||
int32_t dst; \
|
||||
uint32_t blockSize; \
|
||||
\
|
||||
if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) \
|
||||
{ \
|
||||
\
|
||||
dsp_arm_svm_##NAME##_instance_f32Object *selfS = (dsp_arm_svm_##NAME##_instance_f32Object *)S;\
|
||||
GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t); \
|
||||
\
|
||||
\
|
||||
\
|
||||
arm_svm_##NAME##_predict_f32(selfS->instance,pSrc_converted,&dst); \
|
||||
PyObject* resultOBJ=Py_BuildValue("i",dst); \
|
||||
PyObject *pythonResult = Py_BuildValue("O",resultOBJ); \
|
||||
\
|
||||
FREEARGUMENT(pSrc_converted); \
|
||||
Py_DECREF(resultOBJ); \
|
||||
return(pythonResult); \
|
||||
\
|
||||
} \
|
||||
return(NULL); \
|
||||
}
|
||||
|
||||
SVMPREDICT(linear);
|
||||
SVMPREDICT(polynomial);
|
||||
SVMPREDICT(rbf);
|
||||
SVMPREDICT(sigmoid);
|
||||
|
||||
static PyMethodDef CMSISDSPMethods[] = {
|
||||
|
||||
|
||||
{"arm_svm_linear_init_f32", cmsis_arm_svm_linear_init_f32, METH_VARARGS,""},
|
||||
{"arm_svm_linear_predict_f32", cmsis_arm_svm_linear_predict_f32, METH_VARARGS,""},
|
||||
|
||||
{"arm_svm_polynomial_init_f32", cmsis_arm_svm_polynomial_init_f32, METH_VARARGS,""},
|
||||
{"arm_svm_polynomial_predict_f32", cmsis_arm_svm_polynomial_predict_f32, METH_VARARGS,""},
|
||||
|
||||
{"arm_svm_rbf_init_f32", cmsis_arm_svm_rbf_init_f32, METH_VARARGS,""},
|
||||
{"arm_svm_rbf_predict_f32", cmsis_arm_svm_rbf_predict_f32, METH_VARARGS,""},
|
||||
|
||||
{"arm_svm_sigmoid_init_f32", cmsis_arm_svm_sigmoid_init_f32, METH_VARARGS,""},
|
||||
{"arm_svm_sigmoid_predict_f32", cmsis_arm_svm_sigmoid_predict_f32, METH_VARARGS,""},
|
||||
|
||||
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
#ifdef IS_PY3K
|
||||
static int cmsisdsp_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmsisdsp_clear(PyObject *m) {
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct PyModuleDef moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
MODNAME,
|
||||
NULL,
|
||||
sizeof(struct module_state),
|
||||
CMSISDSPMethods,
|
||||
NULL,
|
||||
cmsisdsp_traverse,
|
||||
cmsisdsp_clear,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define INITERROR return NULL
|
||||
|
||||
PyMODINIT_FUNC
|
||||
CAT(PyInit_,MODINITNAME)(void)
|
||||
|
||||
|
||||
#else
|
||||
#define INITERROR return
|
||||
|
||||
void CAT(init,MODINITNAME)(void)
|
||||
#endif
|
||||
{
|
||||
import_array();
|
||||
|
||||
#ifdef IS_PY3K
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
#else
|
||||
PyObject *module = Py_InitModule(MODNAME, CMSISDSPMethods);
|
||||
#endif
|
||||
|
||||
if (module == NULL)
|
||||
INITERROR;
|
||||
struct module_state *st = GETSTATE(module);
|
||||
|
||||
st->error = PyErr_NewException(MODNAME".Error", NULL, NULL);
|
||||
if (st->error == NULL) {
|
||||
Py_DECREF(module);
|
||||
INITERROR;
|
||||
}
|
||||
|
||||
|
||||
typeRegistration(module);
|
||||
|
||||
#ifdef IS_PY3K
|
||||
return module;
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,185 @@
|
||||
import cmsisdsp as dsp
|
||||
import numpy as np
|
||||
import scipy.spatial.distance as d
|
||||
from numpy.testing import assert_allclose
|
||||
|
||||
a=[1,2,3]
|
||||
b=[1,5,2]
|
||||
|
||||
print("\nBray-Curtis")
|
||||
ref=d.braycurtis(a,b)
|
||||
res=dsp.arm_braycurtis_distance_f32(a,b)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
|
||||
print("\nCanberra")
|
||||
ref=d.canberra(a,b)
|
||||
res=dsp.arm_canberra_distance_f32(a,b)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nChebyshev")
|
||||
ref=d.chebyshev(a,b)
|
||||
res=dsp.arm_chebyshev_distance_f32(a,b)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
res=dsp.arm_chebyshev_distance_f64(a,b)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10)
|
||||
|
||||
print("\nCity Block")
|
||||
ref=d.cityblock(a,b)
|
||||
res=dsp.arm_cityblock_distance_f32(a,b)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
res=dsp.arm_cityblock_distance_f64(a,b)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10)
|
||||
|
||||
print("\nCorrelation")
|
||||
ref=d.correlation(a,b)
|
||||
res=dsp.arm_correlation_distance_f32(a,b)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nCosine")
|
||||
ref=d.cosine(a,b)
|
||||
res=dsp.arm_cosine_distance_f32(a,b)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
res=dsp.arm_cosine_distance_f64(a,b)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10)
|
||||
|
||||
print("\nEuclidean")
|
||||
ref=d.euclidean(a,b)
|
||||
res=dsp.arm_euclidean_distance_f32(a,b)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
res=dsp.arm_euclidean_distance_f64(a,b)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10)
|
||||
|
||||
print("\nJensen-Shannon")
|
||||
pa=a/np.sum(a)
|
||||
pb=b/np.sum(b)
|
||||
ref=d.jensenshannon(pa,pb)
|
||||
res=dsp.arm_jensenshannon_distance_f32(pa,pb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nMinkowski")
|
||||
w=3
|
||||
ref=d.minkowski(a,b,w)
|
||||
res=dsp.arm_minkowski_distance_f32(a,b,w)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
# Int distance
|
||||
# For CMSIS-DSP the bool must be packed as bit arrays
|
||||
|
||||
# Pack an array of boolean into uint32
|
||||
def packset(a):
|
||||
b = np.packbits(a)
|
||||
newSize = int(np.ceil(b.shape[0] / 4.0)) * 4
|
||||
c = np.copy(b)
|
||||
c.resize(newSize)
|
||||
#print(c)
|
||||
vecSize = round(newSize/4)
|
||||
c=c.reshape(vecSize,4)
|
||||
#print(c)
|
||||
r = np.zeros(vecSize)
|
||||
result = []
|
||||
for i in range(0,vecSize):
|
||||
#print(c[i,:])
|
||||
#print("%X %X %X %X" % (c[i,0],c[i,1],c[i,2],c[i,3]))
|
||||
d = (c[i,0] << 24) | (c[i,1] << 16) | (c[i,2] << 8) | c[i,3]
|
||||
result.append(np.uint32(d))
|
||||
return(result)
|
||||
|
||||
nb = 34
|
||||
va = np.random.choice([0,1],nb)
|
||||
# Array of word32 containing all of our bits
|
||||
pva = packset(va)
|
||||
|
||||
|
||||
vb = np.random.choice([0,1],nb)
|
||||
# Array of word32 containing all of our bits
|
||||
pvb = packset(vb)
|
||||
|
||||
print("\nDice")
|
||||
ref=d.dice(va,vb)
|
||||
res=dsp.arm_dice_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nHamming")
|
||||
ref=d.hamming(va,vb)
|
||||
res=dsp.arm_hamming_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nJaccard-Needham")
|
||||
ref=d.jaccard(va,vb)
|
||||
res=dsp.arm_jaccard_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nKulsinski")
|
||||
ref=d.kulsinski(va,vb)
|
||||
res=dsp.arm_kulsinski_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nRogers-Tanimoto")
|
||||
ref=d.rogerstanimoto(va,vb)
|
||||
res=dsp.arm_rogerstanimoto_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nRussell-Rao")
|
||||
ref=d.russellrao(va,vb)
|
||||
res=dsp.arm_russellrao_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nSokal-Michener")
|
||||
ref=d.sokalmichener(va,vb)
|
||||
res=dsp.arm_sokalmichener_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nSokal-Sneath")
|
||||
ref=d.sokalsneath(va,vb)
|
||||
res=dsp.arm_sokalsneath_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("\nYule")
|
||||
ref=d.yule(va,vb)
|
||||
res=dsp.arm_yule_distance(pva,pvb,nb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
@ -0,0 +1,490 @@
|
||||
import cmsisdsp as dsp
|
||||
import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
from scipy.stats import entropy,tstd, tvar
|
||||
from scipy.special import logsumexp
|
||||
from scipy.linalg import cholesky,ldl,solve_triangular
|
||||
from scipy import signal
|
||||
|
||||
def imToReal1D(a):
|
||||
ar=np.zeros(np.array(a.shape) * 2)
|
||||
ar[0::2]=a.real
|
||||
ar[1::2]=a.imag
|
||||
return(ar)
|
||||
|
||||
def realToIm1D(ar):
|
||||
return(ar[0::2] + 1j * ar[1::2])
|
||||
|
||||
print("Max and AbsMax")
|
||||
a=np.array([1.,-3.,4.,0.,-10.,8.])
|
||||
|
||||
i=dsp.arm_absmax_no_idx_f32(a)
|
||||
print(i)
|
||||
assert i==10.0
|
||||
|
||||
i=dsp.arm_absmax_no_idx_f64(a)
|
||||
print(i)
|
||||
assert i==10.0
|
||||
|
||||
r,i=dsp.arm_absmax_f64(a)
|
||||
assert i==4
|
||||
assert r==10.0
|
||||
|
||||
r,i=dsp.arm_max_f64(a)
|
||||
assert i==5
|
||||
assert r==8.0
|
||||
|
||||
i=dsp.arm_max_no_idx_f32(a)
|
||||
print(i)
|
||||
assert i==8
|
||||
|
||||
i=dsp.arm_max_no_idx_f64(a)
|
||||
print(i)
|
||||
assert i==8
|
||||
|
||||
print("Min and AbsMin")
|
||||
a=np.array([1.,-3.,4.,0.5,-10.,8.])
|
||||
|
||||
i=dsp.arm_absmin_no_idx_f32(a)
|
||||
print(i)
|
||||
assert i==0.5
|
||||
|
||||
i=dsp.arm_absmin_no_idx_f64(a)
|
||||
print(i)
|
||||
assert i==0.5
|
||||
|
||||
r,i=dsp.arm_absmin_f64(a)
|
||||
assert i==3
|
||||
assert r==0.5
|
||||
|
||||
r,i=dsp.arm_min_f64(a)
|
||||
assert i==4
|
||||
assert r==-10
|
||||
|
||||
i=dsp.arm_min_no_idx_f32(a)
|
||||
print(i)
|
||||
assert i==-10
|
||||
|
||||
i=dsp.arm_min_no_idx_f64(a)
|
||||
print(i)
|
||||
assert i==-10
|
||||
|
||||
print("Barycenter")
|
||||
|
||||
a=[0] * 12
|
||||
w=np.array([[2] * 12])
|
||||
w[0,11]=3
|
||||
a[0] =[0., 0., -0.951057]
|
||||
a[1] =[0., 0., 0.951057]
|
||||
a[2] =[-0.850651, 0., -0.425325]
|
||||
a[3] =[0.850651, 0., 0.425325]
|
||||
a[4] =[0.688191, -0.5, -0.425325]
|
||||
a[5] =[0.688191, 0.5, -0.425325]
|
||||
a[6] =[-0.688191, -0.5, 0.425325]
|
||||
a[7] =[-0.688191, 0.5, 0.425325]
|
||||
a[8] =[-0.262866, -0.809017, -0.425325]
|
||||
a[9] =[-0.262866, 0.809017, -0.425325]
|
||||
a[10]=[0.262866, -0.809017, 0.425325]
|
||||
a[11]=[0.262866, 0.809017, 0.425325]
|
||||
|
||||
scaled=a * w.T
|
||||
ref=np.sum(scaled,axis=0)/np.sum(w)
|
||||
print(ref)
|
||||
|
||||
result=dsp.arm_barycenter_f32(np.array(a).reshape(12*3),w.reshape(12),12,3)
|
||||
print(result)
|
||||
|
||||
assert_allclose(ref,result,1e-6)
|
||||
|
||||
print("Weighted sum")
|
||||
|
||||
nb=10
|
||||
s = np.random.randn(nb)
|
||||
w = np.random.randn(nb)
|
||||
|
||||
ref=np.dot(s,w)/np.sum(w)
|
||||
print(ref)
|
||||
|
||||
res=dsp.arm_weighted_sum_f32(s,w)
|
||||
print(res)
|
||||
|
||||
assert_allclose(ref,res,2e-5)
|
||||
|
||||
print("Entropy")
|
||||
s = np.abs(np.random.randn(nb))
|
||||
s = s / np.sum(s)
|
||||
|
||||
ref=entropy(s)
|
||||
print(ref)
|
||||
res=dsp.arm_entropy_f32(s)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
res=dsp.arm_entropy_f64(s)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10)
|
||||
|
||||
print("Kullback-Leibler")
|
||||
sa = np.abs(np.random.randn(nb))
|
||||
sa = sa / np.sum(sa)
|
||||
|
||||
sb = np.abs(np.random.randn(nb))
|
||||
sb = sb / np.sum(sb)
|
||||
|
||||
ref=entropy(sa,sb)
|
||||
print(ref)
|
||||
res=dsp.arm_kullback_leibler_f32(sa,sb)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
res=dsp.arm_kullback_leibler_f64(sa,sb)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10)
|
||||
|
||||
print("Logsumexp")
|
||||
s = np.abs(np.random.randn(nb))
|
||||
s = s / np.sum(s)
|
||||
|
||||
ref=logsumexp(s)
|
||||
print(ref)
|
||||
res=dsp.arm_logsumexp_f32(s)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
print("Logsumexp dot prod")
|
||||
sa = np.abs(np.random.randn(nb))
|
||||
sa = sa / np.sum(sa)
|
||||
|
||||
sb = np.abs(np.random.randn(nb))
|
||||
sb = sb / np.sum(sb)
|
||||
|
||||
d = 0.001
|
||||
# It is a proba so must be in [0,1]
|
||||
# But restricted to ]d,1] so that the log exists
|
||||
sa = (1-d)*sa + d
|
||||
sb = (1-d)*sb + d
|
||||
|
||||
ref=np.log(np.dot(sa,sb))
|
||||
print(ref)
|
||||
|
||||
sa = np.log(sa)
|
||||
sb = np.log(sb)
|
||||
|
||||
res=dsp.arm_logsumexp_dot_prod_f32(sa,sb)
|
||||
print(res)
|
||||
assert_allclose(ref,res,3e-6)
|
||||
|
||||
print("vexp")
|
||||
sa = np.random.randn(nb)
|
||||
|
||||
ref = np.exp(sa)
|
||||
print(ref)
|
||||
|
||||
res=dsp.arm_vexp_f32(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6)
|
||||
|
||||
res=dsp.arm_vexp_f64(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10)
|
||||
|
||||
|
||||
print("vlog")
|
||||
sa = np.abs(np.random.randn(nb)) + 0.001
|
||||
|
||||
ref = np.log(sa)
|
||||
print(ref)
|
||||
|
||||
res=dsp.arm_vlog_f32(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,2e-5,1e-5)
|
||||
|
||||
res=dsp.arm_vlog_f64(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,2e-9,1e-9)
|
||||
|
||||
print("Cholesky")
|
||||
|
||||
a=np.array([[4,12,-16],[12,37,-43],[-16,-43,98]])
|
||||
ref=cholesky(a,lower=True)
|
||||
print(ref)
|
||||
|
||||
status,res=dsp.arm_mat_cholesky_f32(a)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6,1e-6)
|
||||
|
||||
status,res=dsp.arm_mat_cholesky_f64(a)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("LDLT")
|
||||
|
||||
def swaprow(m,k,j):
|
||||
tmp = np.copy(m[j,:])
|
||||
m[j,:] = np.copy(m[k,:])
|
||||
m[k,:] = tmp
|
||||
return(m)
|
||||
|
||||
# F32 test
|
||||
status,resl,resd,resperm=dsp.arm_mat_ldlt_f32(a)
|
||||
n=3
|
||||
p=np.identity(n)
|
||||
for k in range(0,n):
|
||||
p = swaprow(p,k,resperm[k])
|
||||
|
||||
res=resl.dot(resd).dot(resl.T)
|
||||
|
||||
permutedSrc=p.dot(a).dot(p.T)
|
||||
print(res)
|
||||
print(permutedSrc)
|
||||
|
||||
assert_allclose(permutedSrc,res,1e-5,1e-5)
|
||||
|
||||
# F64 test
|
||||
print("LDLT F64")
|
||||
status,resl,resd,resperm=dsp.arm_mat_ldlt_f64(a)
|
||||
n=3
|
||||
p=np.identity(n)
|
||||
for k in range(0,n):
|
||||
p = swaprow(p,k,resperm[k])
|
||||
|
||||
res=resl.dot(resd).dot(resl.T)
|
||||
|
||||
permutedSrc=p.dot(a).dot(p.T)
|
||||
print(res)
|
||||
print(permutedSrc)
|
||||
|
||||
assert_allclose(permutedSrc,res,1e-9,1e-9)
|
||||
|
||||
print("Solve lower triangular")
|
||||
a = np.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]])
|
||||
b = np.array([[4,2,4,2],[8,4,8,4]]).T
|
||||
x = solve_triangular(a, b,lower=True)
|
||||
print(a)
|
||||
print(b)
|
||||
print(x)
|
||||
|
||||
b = np.array([[4,2,4,2],[8,4,8,4]]).T
|
||||
status,res=dsp.arm_mat_solve_lower_triangular_f32(a,b)
|
||||
print(res)
|
||||
assert_allclose(x,res,1e-5,1e-5)
|
||||
|
||||
|
||||
b = np.array([[4,2,4,2],[8,4,8,4]]).T
|
||||
status,res=dsp.arm_mat_solve_lower_triangular_f64(a,b)
|
||||
print(res)
|
||||
assert_allclose(x,res,1e-9,1e-9)
|
||||
|
||||
|
||||
print("Solve upper triangular")
|
||||
a = np.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]])
|
||||
b = np.array([[4,2,4,2],[8,4,8,4]]).T
|
||||
x = solve_triangular(a.T, b,lower=False)
|
||||
print(a.T)
|
||||
print(b)
|
||||
print(x)
|
||||
|
||||
b = np.array([[4,2,4,2],[8,4,8,4]]).T
|
||||
status,res=dsp.arm_mat_solve_upper_triangular_f32(a.T,b)
|
||||
print(res)
|
||||
assert_allclose(x,res,1e-5,1e-5)
|
||||
|
||||
|
||||
b = np.array([[4,2,4,2],[8,4,8,4]]).T
|
||||
status,res=dsp.arm_mat_solve_upper_triangular_f64(a.T,b)
|
||||
print(res)
|
||||
assert_allclose(x,res,1e-9,1e-9)
|
||||
|
||||
|
||||
print("Mat mult f64")
|
||||
a = np.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]])
|
||||
b = np.array([[4,2,4,2],[8,4,8,4]]).T
|
||||
|
||||
ref =a.dot(b)
|
||||
print(ref)
|
||||
|
||||
status,res = dsp.arm_mat_mult_f64(a,b)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("mat sub f64")
|
||||
a = np.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]])
|
||||
b = a.T
|
||||
|
||||
ref = a - b
|
||||
print(ref)
|
||||
|
||||
status,res = dsp.arm_mat_sub_f64(a,b)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("abs f64")
|
||||
s = np.random.randn(nb)
|
||||
ref = np.abs(s)
|
||||
res=dsp.arm_abs_f64(s)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("add f64")
|
||||
sa = np.random.randn(nb)
|
||||
sb = np.random.randn(nb)
|
||||
ref = sa + sb
|
||||
res=dsp.arm_add_f64(sa,sb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("sub f64")
|
||||
sa = np.random.randn(nb)
|
||||
sb = np.random.randn(nb)
|
||||
ref = sa - sb
|
||||
res=dsp.arm_sub_f64(sa,sb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("dot prod f64")
|
||||
sa = np.random.randn(nb)
|
||||
sb = np.random.randn(nb)
|
||||
ref = sa.dot(sb)
|
||||
res=dsp.arm_dot_prod_f64(sa,sb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("mult f64")
|
||||
sa = np.random.randn(nb)
|
||||
sb = np.random.randn(nb)
|
||||
ref = sa * sb
|
||||
res=dsp.arm_mult_f64(sa,sb)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("negate f64")
|
||||
sa = np.random.randn(nb)
|
||||
ref = -sa
|
||||
res=dsp.arm_negate_f64(sa)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("offset f64")
|
||||
sa = np.random.randn(nb)
|
||||
ref = sa + 0.1
|
||||
res=dsp.arm_offset_f64(sa,0.1)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("scale f64")
|
||||
sa = np.random.randn(nb)
|
||||
ref = sa * 0.1
|
||||
res=dsp.arm_scale_f64(sa,0.1)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("mean f64")
|
||||
sa = np.random.randn(nb)
|
||||
ref = np.mean(sa)
|
||||
res=dsp.arm_mean_f64(sa)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("power f64")
|
||||
sa = np.random.randn(nb)
|
||||
ref = np.sum(sa * sa)
|
||||
res=dsp.arm_power_f64(sa)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("std f64")
|
||||
sa = np.random.randn(nb)
|
||||
ref = tstd(sa)
|
||||
res=dsp.arm_std_f64(sa)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("variance f64")
|
||||
sa = np.random.randn(nb)
|
||||
ref = tvar(sa)
|
||||
res=dsp.arm_var_f64(sa)
|
||||
print(ref)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("fill f64")
|
||||
nb=20
|
||||
ref = np.ones(nb)*4.0
|
||||
res = dsp.arm_fill_f64(4.0,nb)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("copy f64")
|
||||
nb=20
|
||||
sa = np.random.randn(nb)
|
||||
ref = sa
|
||||
res = dsp.arm_copy_f64(sa)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("arm_div_q63_to_q31")
|
||||
den=0x7FFF00000000
|
||||
num=0x10000
|
||||
ref=den//num
|
||||
|
||||
res=dsp.arm_div_q63_to_q31(den,num)
|
||||
print(ref)
|
||||
print(res)
|
||||
|
||||
print("fir f64")
|
||||
|
||||
firf64 = dsp.arm_fir_instance_f64()
|
||||
dsp.arm_fir_init_f64(firf64,3,[1.,2,3],[0,0,0,0,0,0,0])
|
||||
filtered_x = signal.lfilter([3,2,1.], 1.0, [1,2,3,4,5,1,2,3,4,5])
|
||||
print(filtered_x)
|
||||
ra=dsp.arm_fir_f64(firf64,[1,2,3,4,5])
|
||||
rb=dsp.arm_fir_f64(firf64,[1,2,3,4,5])
|
||||
assert ((filtered_x == np.hstack([ra,rb])).all)
|
||||
|
||||
print("arm_cmplx_mag")
|
||||
sa = np.random.randn(nb)
|
||||
ca = realToIm1D(sa)
|
||||
ref = np.abs(ca)
|
||||
print(ref)
|
||||
res=dsp.arm_cmplx_mag_f32(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6,1e-6)
|
||||
res=dsp.arm_cmplx_mag_f64(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("arm_cmplx_mag_squared")
|
||||
sa = np.random.randn(nb)
|
||||
ca = realToIm1D(sa)
|
||||
ref = np.abs(ca) * np.abs(ca)
|
||||
print(ref)
|
||||
res=dsp.arm_cmplx_mag_squared_f32(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6,1e-6)
|
||||
res=dsp.arm_cmplx_mag_squared_f64(sa)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
|
||||
print("cmplx mult")
|
||||
sa = np.random.randn(nb)
|
||||
ca = realToIm1D(sa)
|
||||
sb = np.random.randn(nb)
|
||||
cb = realToIm1D(sb)
|
||||
ref = imToReal1D(ca * cb)
|
||||
print(ref)
|
||||
res = dsp.arm_cmplx_mult_cmplx_f32(sa,sb)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-6,1e-6)
|
||||
|
||||
res = dsp.arm_cmplx_mult_cmplx_f64(sa,sb)
|
||||
print(res)
|
||||
assert_allclose(ref,res,1e-10,1e-10)
|
||||
@ -0,0 +1,185 @@
|
||||
import cmsisdsp as dsp
|
||||
import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
from scipy.interpolate import CubicSpline
|
||||
from sklearn.naive_bayes import GaussianNB
|
||||
from sklearn import svm
|
||||
import math
|
||||
|
||||
a=[1,4,2,6,7,0,-3,5]
|
||||
ref=sorted(a)
|
||||
print(ref)
|
||||
|
||||
SORT_BITONIC=0
|
||||
SORT_BUBBLE=1
|
||||
SORT_HEAP=2
|
||||
SORT_INSERTION=3
|
||||
SORT_QUICK=4
|
||||
SORT_SELECTION=5
|
||||
|
||||
|
||||
SORT_DESCENDING = 0
|
||||
SORT_ASCENDING = 1
|
||||
|
||||
sortinst=dsp.arm_sort_instance_f32()
|
||||
|
||||
for mode in range(6):
|
||||
dsp.arm_sort_init_f32(sortinst,mode,SORT_ASCENDING)
|
||||
res=dsp.arm_sort_f32(sortinst,a)
|
||||
print(res)
|
||||
assert (res==ref).all()
|
||||
|
||||
print("")
|
||||
ref.reverse()
|
||||
print(ref)
|
||||
|
||||
for mode in range(6):
|
||||
# Problem with bitonic probably in the C code
|
||||
if mode > 0:
|
||||
dsp.arm_sort_init_f32(sortinst,mode,SORT_DESCENDING)
|
||||
res=dsp.arm_sort_f32(sortinst,a)
|
||||
print(res)
|
||||
assert (res==ref).all()
|
||||
|
||||
print("Spline")
|
||||
|
||||
x = np.arange(0, 2*np.pi+np.pi/4, np.pi/4)
|
||||
y = np.sin(x)
|
||||
xnew = np.arange(0, 2*np.pi+np.pi/16, np.pi/16)
|
||||
ynew = CubicSpline(x,y,bc_type="natural")
|
||||
yref=ynew(xnew)
|
||||
print(yref)
|
||||
|
||||
splineInst = dsp.arm_spline_instance_f32()
|
||||
dsp.arm_spline_init_f32(splineInst,0,x,y)
|
||||
yres=dsp.arm_spline_f32(splineInst,xnew)
|
||||
print(yres)
|
||||
|
||||
assert_allclose(yref,yres,1e-6,1e-6)
|
||||
|
||||
print("Bayes")
|
||||
# Reusing example from https://developer.arm.com/documentation/102052/0000/Train-your-Bayesian-estimator-with-scikit-learn
|
||||
|
||||
NBVECS = 100
|
||||
VECDIM = 2
|
||||
|
||||
# 3 cluster of points are generated (3 classes)
|
||||
ballRadius = 1.0
|
||||
x1 = [1.5, 1] + ballRadius * np.random.randn(NBVECS,VECDIM)
|
||||
x2 = [-1.5, 1] + ballRadius * np.random.randn(NBVECS,VECDIM)
|
||||
x3 = [0, -3] + ballRadius * np.random.randn(NBVECS,VECDIM)
|
||||
|
||||
# All points are concatenated
|
||||
X_train=np.concatenate((x1,x2,x3))
|
||||
|
||||
# The classes are 0,1 and 2.
|
||||
Y_train=np.concatenate((np.zeros(NBVECS),np.ones(NBVECS),2*np.ones(NBVECS)))
|
||||
|
||||
gnb = GaussianNB()
|
||||
gnb.fit(X_train, Y_train)
|
||||
|
||||
src1=[1.5,1.0]
|
||||
src2=[-1.5,1]
|
||||
src3=[0,-3]
|
||||
ref1 = gnb.predict([src1])
|
||||
print(ref1)
|
||||
|
||||
ref2 = gnb.predict([src2])
|
||||
print(ref2)
|
||||
|
||||
ref3 = gnb.predict([src3])
|
||||
print(ref3)
|
||||
|
||||
#print(gnb.predict_log_proba([src]))
|
||||
|
||||
theta=list(np.reshape(gnb.theta_,np.size(gnb.theta_)))
|
||||
|
||||
# Gaussian variances
|
||||
sigma=list(np.reshape(gnb.var_,np.size(gnb.var_)))
|
||||
|
||||
# Class priors
|
||||
prior=list(np.reshape(gnb.class_prior_,np.size(gnb.class_prior_)))
|
||||
|
||||
epsilon=gnb.epsilon_
|
||||
|
||||
bayesInst = dsp.arm_gaussian_naive_bayes_instance_f32(
|
||||
vectorDimension=VECDIM,numberOfClasses=3,
|
||||
theta=theta,sigma=sigma,classPriors=prior,epsilon=epsilon)
|
||||
|
||||
_,res1=dsp.arm_gaussian_naive_bayes_predict_f32(bayesInst,src1)
|
||||
print(res1)
|
||||
|
||||
_,res2=dsp.arm_gaussian_naive_bayes_predict_f32(bayesInst,src2)
|
||||
print(res2)
|
||||
|
||||
_,res3=dsp.arm_gaussian_naive_bayes_predict_f32(bayesInst,src3)
|
||||
print(res3)
|
||||
|
||||
assert res1 == ref1
|
||||
assert res2 == ref2
|
||||
assert res3 == ref3
|
||||
|
||||
print("SVM")
|
||||
|
||||
NBVECS = 100
|
||||
VECDIM = 2
|
||||
|
||||
ballRadius = 0.5
|
||||
x = ballRadius * np.random.randn(NBVECS, 2)
|
||||
|
||||
angle = 2.0 * math.pi * np.random.randn(1, NBVECS)
|
||||
radius = 3.0 + 0.1 * np.random.randn(1, NBVECS)
|
||||
|
||||
xa = np.zeros((NBVECS,2))
|
||||
xa[:, 0] = radius * np.cos(angle)
|
||||
xa[:, 1] = radius * np.sin(angle)
|
||||
|
||||
X_train = np.concatenate((x, xa))
|
||||
Y_train = np.concatenate((np.zeros(NBVECS), np.ones(NBVECS)))
|
||||
|
||||
clf = svm.SVC(kernel='poly', gamma='auto', coef0=1.1)
|
||||
clf.fit(X_train, Y_train)
|
||||
|
||||
test1 = np.array([0.4,0.1])
|
||||
test1 = test1.reshape(1,-1)
|
||||
|
||||
refpredicted1 = clf.predict(test1)
|
||||
print(refpredicted1)
|
||||
|
||||
test2 = np.array([3.1,0.1])
|
||||
test2 = test2.reshape(1,-1)
|
||||
|
||||
refpredicted2 = clf.predict(test2)
|
||||
print(refpredicted2)
|
||||
|
||||
supportShape = clf.support_vectors_.shape
|
||||
|
||||
nbSupportVectors = supportShape[0]
|
||||
vectorDimensions = supportShape[1]
|
||||
|
||||
degree=clf.degree
|
||||
coef0=clf.coef0
|
||||
gamma=clf._gamma
|
||||
|
||||
intercept=clf.intercept_
|
||||
|
||||
dualCoefs = clf.dual_coef_
|
||||
dualCoefs = dualCoefs.reshape(nbSupportVectors)
|
||||
supportVectors = clf.support_vectors_
|
||||
supportVectors = supportVectors.reshape(nbSupportVectors * VECDIM)
|
||||
|
||||
svmInst=dsp.arm_svm_polynomial_instance_f32()
|
||||
dsp.arm_svm_polynomial_init_f32(svmInst,nbSupportVectors,vectorDimensions,
|
||||
intercept,dualCoefs,supportVectors,
|
||||
[0,1],degree,coef0,gamma)
|
||||
|
||||
test1 = np.array([0.4,0.1])
|
||||
predicted1 = dsp.arm_svm_polynomial_predict_f32(svmInst,test1)
|
||||
print(predicted1)
|
||||
|
||||
test2 = np.array([3.1,0.1])
|
||||
predicted2 = dsp.arm_svm_polynomial_predict_f32(svmInst,test2)
|
||||
print(predicted2)
|
||||
|
||||
assert predicted1==refpredicted1
|
||||
assert predicted2==refpredicted2
|
||||
@ -1 +1 @@
|
||||
__version__ = "1.2.2"
|
||||
__version__ = "1.3.0"
|
||||
|
||||
Loading…
Reference in New Issue