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:

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