1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Python Wrapper
3 * Title: cmsismodule.h
4 * Description: C code for the CMSIS-DSP Python wrapper
5 *
6 * $Date: 27 April 2021
7 * $Revision: V1.0
8 *
9 * Target Processor: Cortex-M cores
10 * -------------------------------------------------------------------- */
11 /*
12 * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13 *
14 * SPDX-License-Identifier: Apache-2.0
15 *
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28
29 #define MODNAME "cmsisdsp_svm"
30 #define MODINITNAME cmsisdsp_svm
31
32 #include "cmsisdsp_module.h"
33
34
35
36 NUMPYVECTORFROMBUFFER(f32,float32_t,NPY_FLOAT);
37
38
39 #define SVMTYPE(NAME) \
40 typedef struct { \
41 PyObject_HEAD \
42 arm_svm_##NAME##_instance_f32 *instance;\
43 } dsp_arm_svm_##NAME##_instance_f32Object;
44
45 SVMTYPE(linear);
46 SVMTYPE(polynomial);
47 SVMTYPE(rbf);
48 SVMTYPE(sigmoid);
49
50 #define SVMTYPEDEALLOC(NAME) \
51 static void \
52 arm_svm_##NAME##_instance_f32_dealloc(dsp_arm_svm_##NAME##_instance_f32Object* self)\
53 { \
54 if (self->instance) \
55 { \
56 \
57 if (self->instance->dualCoefficients) \
58 { \
59 PyMem_Free((float32_t*)self->instance->dualCoefficients); \
60 } \
61 \
62 if (self->instance->supportVectors) \
63 { \
64 PyMem_Free((float32_t*)self->instance->supportVectors); \
65 } \
66 \
67 if (self->instance->classes) \
68 { \
69 PyMem_Free((float32_t*)self->instance->classes); \
70 } \
71 \
72 PyMem_Free(self->instance); \
73 } \
74 \
75 Py_TYPE(self)->tp_free((PyObject*)self); \
76 }
77
78 SVMTYPEDEALLOC(linear);
79 SVMTYPEDEALLOC(polynomial);
80 SVMTYPEDEALLOC(rbf);
81 SVMTYPEDEALLOC(sigmoid);
82
83 #define SVMTYPENEW(NAME) \
84 static PyObject * \
85 arm_svm_##NAME##_instance_f32_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\
86 { \
87 dsp_arm_svm_##NAME##_instance_f32Object *self; \
88 \
89 self = (dsp_arm_svm_##NAME##_instance_f32Object *)type->tp_alloc(type, 0); \
90 \
91 if (self != NULL) { \
92 \
93 self->instance = PyMem_Malloc(sizeof(arm_svm_##NAME##_instance_f32)); \
94 self->instance->dualCoefficients=NULL; \
95 self->instance->supportVectors=NULL; \
96 self->instance->classes=NULL; \
97 \
98 } \
99 \
100 \
101 return (PyObject *)self; \
102 }
103
104 SVMTYPENEW(linear);
105 SVMTYPENEW(polynomial);
106 SVMTYPENEW(rbf);
107 SVMTYPENEW(sigmoid);
108
109 /*
110
111 LINEAR INIT
112
113 */
114
115 static int
arm_svm_linear_instance_f32_init(dsp_arm_svm_linear_instance_f32Object * self,PyObject * args,PyObject * kwds)116 arm_svm_linear_instance_f32_init(dsp_arm_svm_linear_instance_f32Object *self, PyObject *args, PyObject *kwds)
117 {
118
119 PyObject *dualCoefficients=NULL;
120 PyObject *supportVectors=NULL;
121 PyObject *classes=NULL;
122
123 char *kwlist[] = {
124 "nbOfSupportVectors",
125 "vectorDimension",
126 "intercept",
127 "dualCoefficients",
128 "supportVectors",
129 "classes",
130 NULL
131 };
132
133 if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOO", kwlist,
134 &self->instance->nbOfSupportVectors
135 ,&self->instance->vectorDimension
136 ,&self->instance->intercept
137 ,&dualCoefficients
138 ,&supportVectors
139 ,&classes
140 ))
141 {
142
143 INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
144 INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
145 INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
146 }
147 return 0;
148 }
149
150 GETFIELD(arm_svm_linear_instance_f32,nbOfSupportVectors,"k");
151 GETFIELD(arm_svm_linear_instance_f32,vectorDimension,"k");
152 GETFIELD(arm_svm_linear_instance_f32,intercept,"f");
153
154
155 static PyMethodDef arm_svm_linear_instance_f32_methods[] = {
156
157 {"nbOfSupportVectors", (PyCFunction) Method_arm_svm_linear_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
158 {"vectorDimension", (PyCFunction) Method_arm_svm_linear_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
159 {"intercept", (PyCFunction) Method_arm_svm_linear_instance_f32_intercept,METH_NOARGS,"intercept"},
160
161 {NULL} /* Sentinel */
162 };
163
164 /*
165
166 POLYNOMIAl INIT
167
168 */
169
170 static int
arm_svm_polynomial_instance_f32_init(dsp_arm_svm_polynomial_instance_f32Object * self,PyObject * args,PyObject * kwds)171 arm_svm_polynomial_instance_f32_init(dsp_arm_svm_polynomial_instance_f32Object *self, PyObject *args, PyObject *kwds)
172 {
173
174 PyObject *dualCoefficients=NULL;
175 PyObject *supportVectors=NULL;
176 PyObject *classes=NULL;
177
178 char *kwlist[] = {
179 "nbOfSupportVectors",
180 "vectorDimension",
181 "intercept",
182 "dualCoefficients",
183 "supportVectors",
184 "classes",
185 "degree",
186 "coef0",
187 "gamma",
188 NULL
189 };
190
191 if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOOiff", kwlist,
192 &self->instance->nbOfSupportVectors
193 ,&self->instance->vectorDimension
194 ,&self->instance->intercept
195 ,&dualCoefficients
196 ,&supportVectors
197 ,&classes
198 ,&self->instance->degree
199 ,&self->instance->coef0
200 ,&self->instance->gamma
201 ))
202 {
203
204 INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
205 INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
206 INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
207 }
208 return 0;
209 }
210
211 GETFIELD(arm_svm_polynomial_instance_f32,nbOfSupportVectors,"k");
212 GETFIELD(arm_svm_polynomial_instance_f32,vectorDimension,"k");
213 GETFIELD(arm_svm_polynomial_instance_f32,intercept,"f");
214 GETFIELD(arm_svm_polynomial_instance_f32,degree,"i");
215 GETFIELD(arm_svm_polynomial_instance_f32,coef0,"f");
216 GETFIELD(arm_svm_polynomial_instance_f32,gamma,"f");
217
218
219 static PyMethodDef arm_svm_polynomial_instance_f32_methods[] = {
220
221 {"nbOfSupportVectors", (PyCFunction) Method_arm_svm_polynomial_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
222 {"vectorDimension", (PyCFunction) Method_arm_svm_polynomial_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
223 {"intercept", (PyCFunction) Method_arm_svm_polynomial_instance_f32_intercept,METH_NOARGS,"intercept"},
224 {"degree", (PyCFunction) Method_arm_svm_polynomial_instance_f32_degree,METH_NOARGS,"degree"},
225 {"coef0", (PyCFunction) Method_arm_svm_polynomial_instance_f32_coef0,METH_NOARGS,"coef0"},
226 {"gamma", (PyCFunction) Method_arm_svm_polynomial_instance_f32_gamma,METH_NOARGS,"gamma"},
227
228 {NULL} /* Sentinel */
229 };
230
231 /*
232
233 RBF INIT
234
235 */
236
237
238 static int
arm_svm_rbf_instance_f32_init(dsp_arm_svm_rbf_instance_f32Object * self,PyObject * args,PyObject * kwds)239 arm_svm_rbf_instance_f32_init(dsp_arm_svm_rbf_instance_f32Object *self, PyObject *args, PyObject *kwds)
240 {
241
242 PyObject *dualCoefficients=NULL;
243 PyObject *supportVectors=NULL;
244 PyObject *classes=NULL;
245
246 char *kwlist[] = {
247 "nbOfSupportVectors",
248 "vectorDimension",
249 "intercept",
250 "dualCoefficients",
251 "supportVectors",
252 "classes",
253 "gamma",
254 NULL
255 };
256
257 if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOOf", kwlist,
258 &self->instance->nbOfSupportVectors
259 ,&self->instance->vectorDimension
260 ,&self->instance->intercept
261 ,&dualCoefficients
262 ,&supportVectors
263 ,&classes
264 ,&self->instance->gamma
265 ))
266 {
267
268 INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
269 INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
270 INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
271 }
272 return 0;
273 }
274
275 GETFIELD(arm_svm_rbf_instance_f32,nbOfSupportVectors,"k");
276 GETFIELD(arm_svm_rbf_instance_f32,vectorDimension,"k");
277 GETFIELD(arm_svm_rbf_instance_f32,intercept,"f");
278 GETFIELD(arm_svm_rbf_instance_f32,gamma,"f");
279
280
281 static PyMethodDef arm_svm_rbf_instance_f32_methods[] = {
282
283 {"nbOfSupportVectors", (PyCFunction) Method_arm_svm_rbf_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
284 {"vectorDimension", (PyCFunction) Method_arm_svm_rbf_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
285 {"intercept", (PyCFunction) Method_arm_svm_rbf_instance_f32_intercept,METH_NOARGS,"intercept"},
286 {"gamma", (PyCFunction) Method_arm_svm_rbf_instance_f32_gamma,METH_NOARGS,"gamma"},
287
288 {NULL} /* Sentinel */
289 };
290
291 /*
292
293 SIGMOID INIT
294
295 */
296
297 static int
arm_svm_sigmoid_instance_f32_init(dsp_arm_svm_sigmoid_instance_f32Object * self,PyObject * args,PyObject * kwds)298 arm_svm_sigmoid_instance_f32_init(dsp_arm_svm_sigmoid_instance_f32Object *self, PyObject *args, PyObject *kwds)
299 {
300
301 PyObject *dualCoefficients=NULL;
302 PyObject *supportVectors=NULL;
303 PyObject *classes=NULL;
304
305 char *kwlist[] = {
306 "nbOfSupportVectors",
307 "vectorDimension",
308 "intercept",
309 "dualCoefficients",
310 "supportVectors",
311 "classes",
312 "coef0",
313 "gamma",
314 NULL
315 };
316
317 if (PyArg_ParseTupleAndKeywords(args, kwds, "|kkfOOOff", kwlist,
318 &self->instance->nbOfSupportVectors
319 ,&self->instance->vectorDimension
320 ,&self->instance->intercept
321 ,&dualCoefficients
322 ,&supportVectors
323 ,&classes
324 ,&self->instance->coef0
325 ,&self->instance->gamma
326 ))
327 {
328
329 INITARRAYFIELD(dualCoefficients,NPY_DOUBLE,double,float32_t);
330 INITARRAYFIELD(supportVectors,NPY_DOUBLE,double,float32_t);
331 INITARRAYFIELD(classes,NPY_INT32,int32_t,int32_t);
332 }
333 return 0;
334 }
335
336 GETFIELD(arm_svm_sigmoid_instance_f32,nbOfSupportVectors,"k");
337 GETFIELD(arm_svm_sigmoid_instance_f32,vectorDimension,"k");
338 GETFIELD(arm_svm_sigmoid_instance_f32,intercept,"f");
339 GETFIELD(arm_svm_sigmoid_instance_f32,coef0,"f");
340 GETFIELD(arm_svm_sigmoid_instance_f32,gamma,"f");
341
342
343 static PyMethodDef arm_svm_sigmoid_instance_f32_methods[] = {
344
345 {"nbOfSupportVectors", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_nbOfSupportVectors,METH_NOARGS,"nbOfSupportVectors"},
346 {"vectorDimension", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_vectorDimension,METH_NOARGS,"vectorDimension"},
347 {"intercept", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_intercept,METH_NOARGS,"intercept"},
348 {"coef0", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_coef0,METH_NOARGS,"coef0"},
349 {"gamma", (PyCFunction) Method_arm_svm_sigmoid_instance_f32_gamma,METH_NOARGS,"gamma"},
350
351 {NULL} /* Sentinel */
352 };
353
354 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);
355 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);
356 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);
357 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);
358
359
360
361
typeRegistration(PyObject * module)362 void typeRegistration(PyObject *module) {
363
364
365
366 ADDTYPE(arm_svm_linear_instance_f32);
367 ADDTYPE(arm_svm_polynomial_instance_f32);
368 ADDTYPE(arm_svm_rbf_instance_f32);
369 ADDTYPE(arm_svm_sigmoid_instance_f32);
370
371
372 }
373
374 static PyObject *
cmsis_arm_svm_linear_init_f32(PyObject * obj,PyObject * args)375 cmsis_arm_svm_linear_init_f32(PyObject *obj, PyObject *args)
376 {
377
378 PyObject *S=NULL; // input
379 uint16_t numTaps; // input
380 PyObject *pdualCoefficients=NULL; // input
381 float32_t *pdualCoefficients_converted=NULL; // input
382 PyObject *psupportVectors=NULL; // input
383 float32_t *psupportVectors_converted=NULL; // input
384 PyObject *pclasses=NULL; // input
385 int32_t *pclasses_converted=NULL; // input
386 uint32_t blockSize; // input
387
388 uint32_t nbOfSupportVectors;
389 uint32_t vectorDimension;
390 float32_t intercept;
391
392 if (PyArg_ParseTuple(args,"OkkfOOO",&S,
393 &nbOfSupportVectors,
394 &vectorDimension,
395 &intercept,
396 &pdualCoefficients,
397 &psupportVectors,
398 &pclasses
399 ))
400 {
401
402 dsp_arm_svm_linear_instance_f32Object *selfS = (dsp_arm_svm_linear_instance_f32Object *)S;
403 GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
404 GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
405 GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
406
407 arm_svm_linear_init_f32(selfS->instance,
408 nbOfSupportVectors,
409 vectorDimension,
410 intercept,
411 pdualCoefficients_converted,
412 psupportVectors_converted,
413 pclasses_converted);
414 Py_RETURN_NONE;
415
416 }
417 return(NULL);
418 }
419
420 static PyObject *
cmsis_arm_svm_polynomial_init_f32(PyObject * obj,PyObject * args)421 cmsis_arm_svm_polynomial_init_f32(PyObject *obj, PyObject *args)
422 {
423
424 PyObject *S=NULL; // input
425 uint16_t numTaps; // input
426 PyObject *pdualCoefficients=NULL; // input
427 float32_t *pdualCoefficients_converted=NULL; // input
428 PyObject *psupportVectors=NULL; // input
429 float32_t *psupportVectors_converted=NULL; // input
430 PyObject *pclasses=NULL; // input
431 int32_t *pclasses_converted=NULL; // input
432 uint32_t blockSize; // input
433
434 uint32_t nbOfSupportVectors;
435 uint32_t vectorDimension;
436 float32_t intercept;
437 int32_t degree;
438 float32_t coef0;
439 float32_t gamma;
440
441 if (PyArg_ParseTuple(args,"OkkfOOOiff",&S,
442 &nbOfSupportVectors,
443 &vectorDimension,
444 &intercept,
445 &pdualCoefficients,
446 &psupportVectors,
447 &pclasses,
448 °ree,
449 &coef0,
450 &gamma
451 ))
452 {
453
454 dsp_arm_svm_polynomial_instance_f32Object *selfS = (dsp_arm_svm_polynomial_instance_f32Object *)S;
455 GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
456 GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
457 GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
458
459 arm_svm_polynomial_init_f32(selfS->instance,
460 nbOfSupportVectors,
461 vectorDimension,
462 intercept,
463 pdualCoefficients_converted,
464 psupportVectors_converted,
465 pclasses_converted,
466 degree,
467 coef0,
468 gamma
469 );
470 Py_RETURN_NONE;
471
472 }
473 return(NULL);
474 }
475
476 static PyObject *
cmsis_arm_svm_rbf_init_f32(PyObject * obj,PyObject * args)477 cmsis_arm_svm_rbf_init_f32(PyObject *obj, PyObject *args)
478 {
479
480 PyObject *S=NULL; // input
481 uint16_t numTaps; // input
482 PyObject *pdualCoefficients=NULL; // input
483 float32_t *pdualCoefficients_converted=NULL; // input
484 PyObject *psupportVectors=NULL; // input
485 float32_t *psupportVectors_converted=NULL; // input
486 PyObject *pclasses=NULL; // input
487 int32_t *pclasses_converted=NULL; // input
488 uint32_t blockSize; // input
489
490 uint32_t nbOfSupportVectors;
491 uint32_t vectorDimension;
492 float32_t intercept;
493 float32_t gamma;
494
495 if (PyArg_ParseTuple(args,"OkkfOOOf",&S,
496 &nbOfSupportVectors,
497 &vectorDimension,
498 &intercept,
499 &pdualCoefficients,
500 &psupportVectors,
501 &pclasses,
502 &gamma
503 ))
504 {
505
506 dsp_arm_svm_rbf_instance_f32Object *selfS = (dsp_arm_svm_rbf_instance_f32Object *)S;
507 GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
508 GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
509 GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
510
511 arm_svm_rbf_init_f32(selfS->instance,
512 nbOfSupportVectors,
513 vectorDimension,
514 intercept,
515 pdualCoefficients_converted,
516 psupportVectors_converted,
517 pclasses_converted,
518 gamma
519 );
520 Py_RETURN_NONE;
521
522 }
523 return(NULL);
524 }
525
526 static PyObject *
cmsis_arm_svm_sigmoid_init_f32(PyObject * obj,PyObject * args)527 cmsis_arm_svm_sigmoid_init_f32(PyObject *obj, PyObject *args)
528 {
529
530 PyObject *S=NULL; // input
531 uint16_t numTaps; // input
532 PyObject *pdualCoefficients=NULL; // input
533 float32_t *pdualCoefficients_converted=NULL; // input
534 PyObject *psupportVectors=NULL; // input
535 float32_t *psupportVectors_converted=NULL; // input
536 PyObject *pclasses=NULL; // input
537 int32_t *pclasses_converted=NULL; // input
538 uint32_t blockSize; // input
539
540 uint32_t nbOfSupportVectors;
541 uint32_t vectorDimension;
542 float32_t intercept;
543 float32_t coef0;
544 float32_t gamma;
545
546 if (PyArg_ParseTuple(args,"OkkfOOOff",&S,
547 &nbOfSupportVectors,
548 &vectorDimension,
549 &intercept,
550 &pdualCoefficients,
551 &psupportVectors,
552 &pclasses,
553 &coef0,
554 &gamma
555 ))
556 {
557
558 dsp_arm_svm_sigmoid_instance_f32Object *selfS = (dsp_arm_svm_sigmoid_instance_f32Object *)S;
559 GETARGUMENT(pdualCoefficients,NPY_DOUBLE,double,float32_t);
560 GETARGUMENT(psupportVectors,NPY_DOUBLE,double,float32_t);
561 GETARGUMENT(pclasses,NPY_INT32,int32_t,int32_t);
562
563 arm_svm_sigmoid_init_f32(selfS->instance,
564 nbOfSupportVectors,
565 vectorDimension,
566 intercept,
567 pdualCoefficients_converted,
568 psupportVectors_converted,
569 pclasses_converted,
570 coef0,
571 gamma
572 );
573 Py_RETURN_NONE;
574
575 }
576 return(NULL);
577 }
578
579
580 #define SVMPREDICT(NAME) \
581 static PyObject * \
582 cmsis_arm_svm_##NAME##_predict_f32(PyObject *obj, PyObject *args) \
583 { \
584 \
585 PyObject *S=NULL; \
586 PyObject *pSrc=NULL; \
587 float32_t *pSrc_converted=NULL; \
588 int32_t dst; \
589 uint32_t blockSize; \
590 \
591 if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) \
592 { \
593 \
594 dsp_arm_svm_##NAME##_instance_f32Object *selfS = (dsp_arm_svm_##NAME##_instance_f32Object *)S;\
595 GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t); \
596 \
597 \
598 \
599 arm_svm_##NAME##_predict_f32(selfS->instance,pSrc_converted,&dst); \
600 PyObject* resultOBJ=Py_BuildValue("i",dst); \
601 PyObject *pythonResult = Py_BuildValue("O",resultOBJ); \
602 \
603 FREEARGUMENT(pSrc_converted); \
604 Py_DECREF(resultOBJ); \
605 return(pythonResult); \
606 \
607 } \
608 return(NULL); \
609 }
610
611 SVMPREDICT(linear);
612 SVMPREDICT(polynomial);
613 SVMPREDICT(rbf);
614 SVMPREDICT(sigmoid);
615
616 static PyMethodDef CMSISDSPMethods[] = {
617
618
619 {"arm_svm_linear_init_f32", cmsis_arm_svm_linear_init_f32, METH_VARARGS,""},
620 {"arm_svm_linear_predict_f32", cmsis_arm_svm_linear_predict_f32, METH_VARARGS,""},
621
622 {"arm_svm_polynomial_init_f32", cmsis_arm_svm_polynomial_init_f32, METH_VARARGS,""},
623 {"arm_svm_polynomial_predict_f32", cmsis_arm_svm_polynomial_predict_f32, METH_VARARGS,""},
624
625 {"arm_svm_rbf_init_f32", cmsis_arm_svm_rbf_init_f32, METH_VARARGS,""},
626 {"arm_svm_rbf_predict_f32", cmsis_arm_svm_rbf_predict_f32, METH_VARARGS,""},
627
628 {"arm_svm_sigmoid_init_f32", cmsis_arm_svm_sigmoid_init_f32, METH_VARARGS,""},
629 {"arm_svm_sigmoid_predict_f32", cmsis_arm_svm_sigmoid_predict_f32, METH_VARARGS,""},
630
631 {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
632 {NULL, NULL, 0, NULL} /* Sentinel */
633 };
634
635 #ifdef IS_PY3K
cmsisdsp_traverse(PyObject * m,visitproc visit,void * arg)636 static int cmsisdsp_traverse(PyObject *m, visitproc visit, void *arg) {
637 Py_VISIT(GETSTATE(m)->error);
638 return 0;
639 }
640
cmsisdsp_clear(PyObject * m)641 static int cmsisdsp_clear(PyObject *m) {
642 Py_CLEAR(GETSTATE(m)->error);
643 return 0;
644 }
645
646
647 static struct PyModuleDef moduledef = {
648 PyModuleDef_HEAD_INIT,
649 MODNAME,
650 NULL,
651 sizeof(struct module_state),
652 CMSISDSPMethods,
653 NULL,
654 cmsisdsp_traverse,
655 cmsisdsp_clear,
656 NULL
657 };
658
659 #define INITERROR return NULL
660
661 PyMODINIT_FUNC
CAT(PyInit_,MODINITNAME)662 CAT(PyInit_,MODINITNAME)(void)
663
664
665 #else
666 #define INITERROR return
667
668 void CAT(init,MODINITNAME)(void)
669 #endif
670 {
671 import_array();
672
673 #ifdef IS_PY3K
674 PyObject *module = PyModule_Create(&moduledef);
675 #else
676 PyObject *module = Py_InitModule(MODNAME, CMSISDSPMethods);
677 #endif
678
679 if (module == NULL)
680 INITERROR;
681 struct module_state *st = GETSTATE(module);
682
683 st->error = PyErr_NewException(MODNAME".Error", NULL, NULL);
684 if (st->error == NULL) {
685 Py_DECREF(module);
686 INITERROR;
687 }
688
689
690 typeRegistration(module);
691
692 #ifdef IS_PY3K
693 return module;
694 #endif
695 }