frankzappa
Well-known member
I wrote a class that does some calculations. It compares a 1d signal with a template of a peak and calculates the absolute difference after normalisation. I have a function that triggers based on a threshold but I want to only trigger signals of a certain shape and this class does this.
I'm using the circular buffer library to store previous values, it's inside the m_dataStorage referenced member.
Note that I'm only using the ComputeManhattan method called from the "ExecuteAndStore" method and I'm creating the object at compile time. Can I speed this up somehow? It works great but it's too slow. I'm planning to prune the values because I can calculate on every other sensor reading but if something more can be done I'm all ears. I'm using the teensy 4.
Here is the .h file:
Here is the .cpp file:
I'm using the circular buffer library to store previous values, it's inside the m_dataStorage referenced member.
Note that I'm only using the ComputeManhattan method called from the "ExecuteAndStore" method and I'm creating the object at compile time. Can I speed this up somehow? It works great but it's too slow. I'm planning to prune the values because I can calculate on every other sensor reading but if something more can be done I'm all ears. I'm using the teensy 4.
Here is the .h file:
Code:
#pragma once
#include <cmath>
#include <algorithm>
#include "ProcessedSensorData.h"
class CrossCorrelation {
private:
float* m_templateSignal;
float* m_targetSignal;
const int m_signalLength;
ProcessedSensorData& m_dataStorage;
public:
CrossCorrelation(const float* templateSignal, const int signalLength, ProcessedSensorData& dataStorage);
~CrossCorrelation() {
delete[] m_templateSignal;
delete[] m_targetSignal;
}
float ExecuteAndStore(int sensorID) {
//calculate similarity of signals with a template signal
float xCorr = 0.0f;
xCorr = ComputeManhattan(sensorID);
xCorr = std::min(xCorr, 30.0f);
//store the result in buffer
m_dataStorage.headPeakSimilarity.at(sensorID).push_front(xCorr);
return xCorr;
}
private:
void NormalizeSignal(int sensorID);
float Compute(int sensorID);
inline float ComputeManhattan(int sensorID) {
NormalizeSignal(sensorID);
float result = 0.0f;
for (int i = 0; i < m_signalLength; i++) {
result += (std::fabs(m_targetSignal[i] - m_templateSignal[i]));
}
return result;
}
};
Here is the .cpp file:
Code:
#include "CrossCorrelation.h"
CrossCorrelation::CrossCorrelation(const float* templateSignal, const int signalLength, ProcessedSensorData& dataStorage)
:
m_signalLength(signalLength),
m_dataStorage(dataStorage)
{
m_templateSignal = new float[signalLength];
m_targetSignal = new float[signalLength];
for (int i = 0; i < m_signalLength; i++) {
m_templateSignal[i] = templateSignal[i];
m_targetSignal[i] = 0.0f;
}
std::reverse(m_templateSignal, m_templateSignal + m_signalLength);
//normalise template signal
float max = 0.0f;
//float average = 0.0f;
for (int i = 0; i < m_signalLength; i++) {
max = std::max(m_templateSignal[i], max);
//average += m_templateSignal[i];
}
//average /= m_signalLength;
//max -= average;
//std::max(max, 10.0f);
for (int i = 0; i < m_signalLength; i++) {
m_templateSignal[i] /= max;
}
}
float CrossCorrelation::Compute(int sensorID) {
NormalizeSignal(sensorID);
float result = 0.0f;
for (int i = 0; i < m_signalLength; i++) {
result += m_targetSignal[i] * m_templateSignal[i];
}
return result;
}
void CrossCorrelation::NormalizeSignal(int sensorID) {
float max = 0.0f;
//float average = 0.0f;
for (int i = 0; i < m_signalLength; i++) {
m_targetSignal[i] = m_dataStorage.headSimilaritySignal.at(sensorID).peek(i);
if(m_targetSignal[i] > max) {
max = m_targetSignal[i];
}
//average += m_targetSignal[i];
}
//average /= m_signalLength;
//max -= average;
std::max(max, 10.0f);
for (int i = 0; i < m_signalLength; i++) {
m_targetSignal[i] /= max;
}
}