CMSIS-DSP: New example.
parent
3ba623825a
commit
b70696476b
@ -0,0 +1,8 @@
|
||||
Applications
|
||||
============
|
||||
|
||||
This folder is containing more complex examples of the use of the CMSIS-DSP.
|
||||
|
||||
Those examples are not available as part of the MDK.
|
||||
|
||||
Some examples may rely on external technologies (Arduino ...)
|
||||
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*
|
||||
*
|
||||
* This example reads audio data from the on-board PDM microphones
|
||||
* and try to detect a 1kHz sine signal using a SVM predictor.
|
||||
*
|
||||
* Circuit:
|
||||
* - Arduino Nano 33 BLE board
|
||||
*/
|
||||
|
||||
import processing.serial.*;
|
||||
|
||||
Serial myPort;
|
||||
|
||||
// Color opacity for the test display
|
||||
int n = 0;
|
||||
|
||||
// Decay of color opacity
|
||||
int decay = 5;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(380, 150);
|
||||
myPort = new Serial(this, "COM6", 115200);
|
||||
|
||||
textSize(72); // set text size
|
||||
myPort.clear();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
// If some data is available on the serial port then some signal was detected.
|
||||
if (myPort.available() > 0)
|
||||
{
|
||||
// Opacity is set to maximum.
|
||||
n=255;
|
||||
myPort.clear();
|
||||
}
|
||||
background(255);
|
||||
textAlign(CENTER);
|
||||
|
||||
// Define a green color with some oapcity
|
||||
fill(0, 255, 0, n);
|
||||
|
||||
// Decrease the opacity until it is 0.
|
||||
if (n >= decay)
|
||||
{
|
||||
n = n - decay;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
}
|
||||
|
||||
// Display the word "Detected"
|
||||
text("DETECTED", 190, 95);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
# Sine Detection
|
||||
|
||||
This example is showing how to detect a sine of 1 kHz with Support Vector Machine.
|
||||
|
||||
It is not the simplest nor best way to detect a sine. It is just an example of the use of a SVM classifier which may be extended to signal a bit more complex than a sine by using the same method.
|
||||
|
||||
The performance of the app is highly dependent on the training data which was used.
|
||||
On my tests, it is working well. But if your environment is quite different from mine (more noisy ...), then the training data I have used may not give good results.
|
||||
|
||||
The difficulty with machine learning is to find the right training set which will give a good generalization and a good behavior of unseen data.
|
||||
|
||||
For detection of more complex signals, smart features may be required. In this example, we work on the raw data. There is a bit of pre-processing:
|
||||
|
||||
1 - The data is rescale because SVM are not scale indepdendent ;
|
||||
2 - Energy is used to rescale. We don't use the amplitude to avoid being impacted too much by sample outliers ;
|
||||
3 - An Hanning window is applied. This step may not be needed but we have not experimented without it.
|
||||
|
||||
The training is done with this pre-processing applied to the signals.
|
||||
|
||||
If you want to know how to use a SVM with CMSIS-DSP, you can refer to this tutorial:
|
||||
https://developer.arm.com/solutions/machine-learning-on-arm/developer-material/how-to-guides/implement-classical-ml-with-arm-cmsis-dsp-libraries
|
||||
|
||||
and the DSP/Examples/ARM/arm_svm_example folder.
|
||||
|
||||
## Sine Detection App
|
||||
|
||||
It is an Arduino app. It was tested on an Arduino Nano 33 BLE Sense.
|
||||
It is using the PDM driver coming with this board.
|
||||
|
||||
If you want to use BLE, you'll need to install the ArduinoBLE and define BLEOUTPUT in the codee.
|
||||
Then you'll need to install a BLE scanner on your phone.
|
||||
|
||||
If you don't enable BLE, you can see the detection status in the serial console.
|
||||
|
||||
You can also use the DetectionDisplay app.
|
||||
|
||||
## DetectionDisplay
|
||||
|
||||
This app is using https://processing.org/
|
||||
|
||||
You will have to change the serial port name in the app before building it.
|
||||
|
||||
This app is connecting to the serial port and listening to message from the Arduino.
|
||||
When a sine is detected, it is displaying a green word with some fading.
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*
|
||||
*
|
||||
* This example reads audio data from the on-board PDM microphones
|
||||
* and try to detect a 1kHz sine signal using a SVM predictor.
|
||||
*
|
||||
* Circuit:
|
||||
* - Arduino Nano 33 BLE board
|
||||
*/
|
||||
|
||||
|
||||
#include <PDM.h>
|
||||
|
||||
/*
|
||||
|
||||
The CMSIS-DSP coming with the Arduino Nano 33 BLE board is not yet the
|
||||
latest release and thus is not yet including the SVM predictor.
|
||||
|
||||
So, it is duplicated in this app (svmDef.cpp and svmDef.h)
|
||||
|
||||
*/
|
||||
#include "arm_math.h"
|
||||
#include "svmDef.hpp"
|
||||
|
||||
/*
|
||||
|
||||
Undefine this line if you want to use BLE rather than the serial console
|
||||
for the detection information.
|
||||
|
||||
*/
|
||||
//#define BLEOUTPUT
|
||||
|
||||
#if defined(BLEOUTPUT)
|
||||
#include <ArduinoBLE.h>
|
||||
|
||||
// The UUID are coming from Arduino examples.
|
||||
BLEService svmDetectionService("19B10010-E8F2-537E-4F6C-D104768A1214");
|
||||
BLEBoolCharacteristic svmDetectionStatus("19B10012-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
Use to enable / disable the interrupts
|
||||
|
||||
*/
|
||||
#include <hal/nrf_pdm.h>
|
||||
|
||||
/* Header generated by a training script (not included in this app) */
|
||||
#include "svm.hpp"
|
||||
|
||||
//#define DUMP
|
||||
|
||||
/*
|
||||
|
||||
Dimension of the vector.
|
||||
The training data has used segment of 256 samples.
|
||||
|
||||
*/
|
||||
#define BUFSIZE vectorDimensions
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Hanning window.
|
||||
|
||||
*/
|
||||
const float32_t hanning[BUFSIZE]={0.0f, 0.000151774f, 0.000607004f, 0.00136541f, 0.00242654f, 0.00378975f,
|
||||
0.0054542f, 0.00741888f, 0.00968261f, 0.012244f, 0.0151015f, 0.0182534f,
|
||||
0.0216978f, 0.0254325f, 0.0294554f, 0.0337639f, 0.0383554f, 0.0432273f,
|
||||
0.0483764f, 0.0537997f, 0.0594939f, 0.0654555f, 0.071681f, 0.0781664f,
|
||||
0.084908f, 0.0919015f, 0.0991429f, 0.106628f, 0.114351f, 0.122309f,
|
||||
0.130496f, 0.138907f, 0.147537f, 0.156382f, 0.165435f, 0.174691f, 0.184144f,
|
||||
0.19379f, 0.203621f, 0.213632f, 0.223818f, 0.23417f, 0.244684f, 0.255354f,
|
||||
0.266171f, 0.277131f, 0.288226f, 0.299449f, 0.310794f, 0.322255f, 0.333823f,
|
||||
0.345492f, 0.357254f, 0.369104f, 0.381032f, 0.393033f, 0.405099f, 0.417223f,
|
||||
0.429397f, 0.441614f, 0.453866f, 0.466146f, 0.478447f, 0.490761f, 0.50308f,
|
||||
0.515398f, 0.527706f, 0.539997f, 0.552264f, 0.5645f, 0.576696f, 0.588845f,
|
||||
0.600941f, 0.612976f, 0.624941f, 0.636831f, 0.648638f, 0.660355f, 0.671974f,
|
||||
0.683489f, 0.694893f, 0.706178f, 0.717338f, 0.728366f, 0.739256f, 0.75f,
|
||||
0.760592f, 0.771027f, 0.781296f, 0.791395f, 0.801317f, 0.811056f, 0.820607f,
|
||||
0.829962f, 0.839118f, 0.848067f, 0.856805f, 0.865327f, 0.873626f, 0.881699f,
|
||||
0.88954f, 0.897145f, 0.904508f, 0.911626f, 0.918495f, 0.925109f, 0.931464f,
|
||||
0.937558f, 0.943387f, 0.948946f, 0.954233f, 0.959243f, 0.963976f, 0.968426f,
|
||||
0.972592f, 0.976471f, 0.980061f, 0.983359f, 0.986364f, 0.989074f, 0.991487f,
|
||||
0.993601f, 0.995416f, 0.99693f, 0.998142f, 0.999052f, 0.999659f, 0.999962f,
|
||||
0.999962f, 0.999659f, 0.999052f, 0.998142f, 0.99693f, 0.995416f, 0.993601f,
|
||||
0.991487f, 0.989074f, 0.986364f, 0.983359f, 0.980061f, 0.976471f, 0.972592f,
|
||||
0.968426f, 0.963976f, 0.959243f, 0.954233f, 0.948946f, 0.943387f, 0.937558f,
|
||||
0.931464f, 0.925109f, 0.918495f, 0.911626f, 0.904508f, 0.897145f, 0.88954f,
|
||||
0.881699f, 0.873626f, 0.865327f, 0.856805f, 0.848067f, 0.839118f, 0.829962f,
|
||||
0.820607f, 0.811056f, 0.801317f, 0.791395f, 0.781296f, 0.771027f, 0.760592f,
|
||||
0.75f, 0.739256f, 0.728366f, 0.717338f, 0.706178f, 0.694893f, 0.683489f,
|
||||
0.671974f, 0.660355f, 0.648638f, 0.636831f, 0.624941f, 0.612976f, 0.600941f,
|
||||
0.588845f, 0.576696f, 0.5645f, 0.552264f, 0.539997f, 0.527706f, 0.515398f,
|
||||
0.50308f, 0.490761f, 0.478447f, 0.466146f, 0.453866f, 0.441614f, 0.429397f,
|
||||
0.417223f, 0.405099f, 0.393033f, 0.381032f, 0.369104f, 0.357254f, 0.345492f,
|
||||
0.333823f, 0.322255f, 0.310794f, 0.299449f, 0.288226f, 0.277131f, 0.266171f,
|
||||
0.255354f, 0.244684f, 0.23417f, 0.223818f, 0.213632f, 0.203621f, 0.19379f,
|
||||
0.184144f, 0.174691f, 0.165435f, 0.156382f, 0.147537f, 0.138907f, 0.130496f,
|
||||
0.122309f, 0.114351f, 0.106628f, 0.0991429f, 0.0919015f, 0.084908f,
|
||||
0.0781664f, 0.071681f, 0.0654555f, 0.0594939f, 0.0537997f, 0.0483764f,
|
||||
0.0432273f, 0.0383554f, 0.0337639f, 0.0294554f, 0.0254325f, 0.0216978f,
|
||||
0.0182534f, 0.0151015f, 0.012244f, 0.00968261f, 0.00741888f, 0.0054542f,
|
||||
0.00378975f, 0.00242654f, 0.00136541f, 0.000607004f, 0.000151774f, 0.0f};
|
||||
|
||||
/*
|
||||
|
||||
Sample buffer for samples coming from PDM
|
||||
|
||||
*/
|
||||
short sampleBuffer[512];
|
||||
|
||||
/*
|
||||
|
||||
svm buffer : The PDM samples converted to float,
|
||||
rescaled and multiplied by the Hanning window.
|
||||
|
||||
*/
|
||||
float svmBuffer[BUFSIZE];
|
||||
|
||||
/*
|
||||
|
||||
Number of PDM samples copied to SVM buffer.
|
||||
|
||||
*/
|
||||
int svmSamplesConverted=0;
|
||||
|
||||
/*
|
||||
|
||||
Number of samples read from PDM
|
||||
|
||||
*/
|
||||
volatile int samplesRead=0;
|
||||
|
||||
/*
|
||||
PDM buffer ID.
|
||||
It is used for debugging. Each time a new buffer of smples is
|
||||
received, this number is incremented.
|
||||
|
||||
*/
|
||||
volatile int bufferNb=0;
|
||||
|
||||
/*
|
||||
|
||||
Detection ID : Each time a new sine is detected, this number is incremented.
|
||||
It is to display in the console and help deugging.
|
||||
|
||||
*/
|
||||
int nbDetect=0;
|
||||
|
||||
// Class 0 is signal present
|
||||
// Class 1 is signal missing
|
||||
int32_t classes[2]={0,1};
|
||||
|
||||
/*
|
||||
|
||||
Configuration of the SVM data structure with parameters generated
|
||||
from the training script.
|
||||
|
||||
*/
|
||||
arm_svm_polynomial_instance_f32 svm = {
|
||||
nbSupportVectors,
|
||||
vectorDimensions,
|
||||
intercept,
|
||||
dualCoefs,
|
||||
supportVectors,
|
||||
classes,
|
||||
degree,
|
||||
coef0,
|
||||
gamma
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
PDM.setBufferSize(1024);
|
||||
|
||||
// configure the data receive callback
|
||||
PDM.onReceive(onPDMdata);
|
||||
|
||||
// optionally set the gain, defaults to 20
|
||||
// PDM.setGain(30);
|
||||
|
||||
// initialize PDM with:
|
||||
// - one channel (mono mode)
|
||||
// - a 16 kHz sample rate
|
||||
if (!PDM.begin(1, 16000)) {
|
||||
Serial.println("Failed to start PDM!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
#if defined(BLEOUTPUT)
|
||||
if (!BLE.begin())
|
||||
{
|
||||
Serial.println("starting BLE failed!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
BLE.setLocalName("Sound Detection");
|
||||
BLE.setAdvertisedService(svmDetectionService);
|
||||
svmDetectionService.addCharacteristic(svmDetectionStatus);
|
||||
BLE.addService(svmDetectionService);
|
||||
|
||||
svmDetectionStatus.writeValue(false);
|
||||
|
||||
BLE.advertise();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
#if defined(BLEOUTPUT)
|
||||
BLE.poll();
|
||||
#endif
|
||||
|
||||
// If there are enough samples to apply the SVM prediction
|
||||
if (samplesRead >0)
|
||||
{
|
||||
int i=0;
|
||||
// We copy the received PDM samples to the SVM buffer.
|
||||
// We don't want the sampleBuffer buffer to be modified
|
||||
// while this copy is taking place.
|
||||
// So PDM interrupts are disablsd.
|
||||
NVIC_DisableIRQ(PDM_IRQn);
|
||||
while((svmSamplesConverted < BUFSIZE) && (samplesRead > 0))
|
||||
{
|
||||
svmBuffer[svmSamplesConverted] = (float)sampleBuffer[i];
|
||||
|
||||
svmSamplesConverted++;
|
||||
i++;
|
||||
samplesRead--;
|
||||
}
|
||||
samplesRead = 0;
|
||||
NVIC_EnableIRQ(PDM_IRQn);
|
||||
|
||||
}
|
||||
|
||||
// If the SVM buffer is full, we preprocess the sample
|
||||
// and apply the SVM classifier.
|
||||
if (svmSamplesConverted == BUFSIZE)
|
||||
{
|
||||
float32_t avgEnergy;
|
||||
svmSamplesConverted = 0;
|
||||
float32_t result=0;
|
||||
|
||||
// Convert samples to float and normalize them
|
||||
// since SVM algorithm is not scale invariant.
|
||||
// Clip to avoid outlier sample which would be too big.
|
||||
// Apply the Hanning window.
|
||||
|
||||
arm_rms_f32(svmBuffer,BUFSIZE,&avgEnergy);
|
||||
|
||||
for (int i = 0; i < BUFSIZE; i++) {
|
||||
svmBuffer[i] = svmBuffer[i] / avgEnergy;
|
||||
|
||||
// Analysis of the scaled tests patterns have shown
|
||||
// that most values are between -2 and 2.
|
||||
// So to avoid outliers, we clip between [-2,2].
|
||||
// We have not checked if it is making a difference
|
||||
// to the final quality of the prediction so this
|
||||
// clipping is perhaps not needed.
|
||||
if (svmBuffer[i] < -2)
|
||||
{
|
||||
svmBuffer[i] = -2;
|
||||
}
|
||||
|
||||
if (svmBuffer[i] > 2)
|
||||
{
|
||||
svmBuffer[i] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// We multiply with the Hanning window.
|
||||
arm_mult_f32(svmBuffer,(float32_t*)hanning,svmBuffer,BUFSIZE);
|
||||
|
||||
// We try to classify the result.
|
||||
arm_svm_polynomial_predict_f32(&svm, svmBuffer,&result);
|
||||
|
||||
// If negative then a signal was detected.
|
||||
if (result < 0)
|
||||
{
|
||||
nbDetect = nbDetect + 1;
|
||||
|
||||
#if defined(BLEOUTPUT)
|
||||
if (!svmDetectionStatus.value())
|
||||
{
|
||||
svmDetectionStatus.writeValue(true);
|
||||
}
|
||||
#else
|
||||
Serial.print(" d:");
|
||||
Serial.print(nbDetect);
|
||||
Serial.print(" b:");
|
||||
Serial.print(bufferNb);
|
||||
Serial.print(" ");
|
||||
Serial.println("DETECTED");
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(BLEOUTPUT)
|
||||
if (svmDetectionStatus.value())
|
||||
{
|
||||
svmDetectionStatus.writeValue(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Interrupt handler.
|
||||
Received PDM data is copied into the buffer sampleBuffer.
|
||||
|
||||
*/
|
||||
void onPDMdata() {
|
||||
int bytesAvailable = PDM.available();
|
||||
PDM.read(sampleBuffer , bytesAvailable);
|
||||
samplesRead = bytesAvailable / 2;
|
||||
bufferNb = bufferNb + 1;
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
#include "svm.hpp"
|
||||
const float dualCoefs[155]={
|
||||
-1.000000,-1.000000,-1.000000,-0.718688,-0.678784,-1.000000
|
||||
,-1.000000,-1.000000,-0.005257,-0.972356,-1.000000,-1.000000
|
||||
,-1.000000,-1.000000,-0.657661,-0.144265,-0.228971,-1.000000
|
||||
,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-0.101008
|
||||
,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-0.225662
|
||||
,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000
|
||||
,-0.371067,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000
|
||||
,-0.750365,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000
|
||||
,-1.000000,-1.000000,-1.000000,-1.000000,-0.200459,-0.736618
|
||||
,-1.000000,-1.000000,-0.013296,-1.000000,-1.000000,-1.000000
|
||||
,0.543122,1.000000,0.294495,0.146869,0.411956,0.169854
|
||||
,1.000000,0.246227,0.463989,0.137775,0.347754,0.171902
|
||||
,0.047820,1.000000,0.058865,1.000000,1.000000,1.000000
|
||||
,1.000000,0.723999,1.000000,0.622752,0.702207,0.682727
|
||||
,0.483939,0.316732,1.000000,0.328298,0.166691,0.484577
|
||||
,0.801786,0.057679,0.843401,0.836016,0.303296,0.296567
|
||||
,0.083458,0.380835,0.487379,1.000000,0.280286,0.866654
|
||||
,0.029825,0.423952,0.652876,1.000000,0.601692,0.464190
|
||||
,1.000000,0.074890,0.008204,1.000000,1.000000,1.000000
|
||||
,0.630193,1.000000,1.000000,1.000000,0.702675,0.577836
|
||||
,0.153860,0.539869,0.052447,1.000000,1.000000,0.996619
|
||||
,1.000000,0.636447,0.985060,1.000000,1.000000,0.113309
|
||||
,0.141574,0.186510,0.045323,0.091481,0.291608,0.146172
|
||||
,0.121734,0.096191,0.124460,0.211330,0.095382,0.746746
|
||||
,0.198886,0.937543,0.274358,1.000000,1.000000,0.001097
|
||||
,0.120421,0.575083,0.875442,0.507657,0.581607};
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,15 @@
|
||||
#ifndef _SVM_H_
|
||||
#define _SVM_H_
|
||||
|
||||
#define nbSupportVectors 155
|
||||
#define vectorDimensions 256
|
||||
|
||||
#define degree 3
|
||||
#define coef0 1.000000
|
||||
#define gamma 0.003906
|
||||
#define intercept 0.849596
|
||||
|
||||
extern const float dualCoefs[nbSupportVectors];
|
||||
extern const float supportVectors[nbSupportVectors*vectorDimensions];
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,69 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_svm_polynomial_predict_f32.c
|
||||
* Description: SVM Polynomial Classifier
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M and Cortex-A cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2019 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.
|
||||
*/
|
||||
|
||||
#include "svmDef.hpp"
|
||||
|
||||
#define STEP(x) (x) <= 0 ? 0 : 1
|
||||
|
||||
static float32_t arm_exponent_f32(float32_t x, int32_t nb)
|
||||
{
|
||||
float32_t r = x;
|
||||
nb --;
|
||||
while(nb > 0)
|
||||
{
|
||||
r = r * x;
|
||||
nb--;
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
void arm_svm_polynomial_predict_f32(
|
||||
const arm_svm_polynomial_instance_f32 *S,
|
||||
const float32_t * in,
|
||||
float32_t *pResult)
|
||||
{
|
||||
float32_t sum=S->intercept;
|
||||
float32_t dot=0;
|
||||
uint32_t i,j;
|
||||
const float32_t *pSupport = S->supportVectors;
|
||||
|
||||
for(i=0; i < S->nbOfSupportVectors; i++)
|
||||
{
|
||||
dot=0;
|
||||
for(j=0; j < S->vectorDimension; j++)
|
||||
{
|
||||
dot = dot + in[j]* *pSupport++;
|
||||
}
|
||||
sum += S->dualCoefficients[i] * arm_exponent_f32(S->gamma * dot + S->coef0, S->degree);
|
||||
}
|
||||
|
||||
/*
|
||||
Original CMSIS-DSP is returning the class.
|
||||
Here we are returning the value and the class is computed by the client.
|
||||
|
||||
*/
|
||||
*pResult=sum;
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_svm_polynomial_predict_f32.c
|
||||
* Description: SVM Polynomial Classifier
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M and Cortex-A cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2019 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.
|
||||
*/
|
||||
#ifndef _SVMDEFH_
|
||||
#define _SVMDEFH_
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t nbOfSupportVectors; /**< Number of support vectors */
|
||||
uint32_t vectorDimension; /**< Dimension of vector space */
|
||||
float32_t intercept; /**< Intercept */
|
||||
const float32_t *dualCoefficients; /**< Dual coefficients */
|
||||
const float32_t *supportVectors; /**< Support vectors */
|
||||
const int32_t *classes; /**< The two SVM classes */
|
||||
int32_t degree; /**< Polynomial degree */
|
||||
float32_t coef0; /**< Polynomial constant */
|
||||
float32_t gamma; /**< Gamma factor */
|
||||
} arm_svm_polynomial_instance_f32;
|
||||
|
||||
void arm_svm_polynomial_predict_f32(const arm_svm_polynomial_instance_f32 *S,
|
||||
const float32_t * in,
|
||||
float32_t * pResult);
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue