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: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; } };

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; } }