You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB内置函数转C/C++:能否获取源码实现findpeaks功能?

Converting MATLAB's findpeaks with MinPeakProminence to C++

Great question—let’s break this down into two clear parts since you’ve got two key concerns here.

Can you access the underlying code for MATLAB built-in functions?

Short answer: No, you can’t get the full source code for most MATLAB built-ins. MathWorks keeps these implementations closed-source to protect intellectual property and maintain optimized performance (many are written in low-level, tuned C/Fortran under the hood).

That said, you don’t need the source code to convert findpeaks to C++—MATLAB offers an official tool for this: MATLAB Coder. It can translate MATLAB code (including calls to findpeaks with MinPeakProminence) into standalone C/C++ code, complete with header files and compiled libraries. This is the most reliable way to get an equivalent implementation without reinventing the wheel.

Manual implementation of findpeaks with MinPeakProminence in C++

If you want to build it from scratch (for learning, or to avoid MATLAB dependencies), here’s how to approach it—starting with understanding what MinPeakProminence actually means:

What is peak prominence?

A peak’s prominence measures how "standout" it is from surrounding data. For a peak at index i with value p:

  1. Left valley: Traverse left from i until you hit a point higher than p. The minimum value between i and that higher point (or the start of the array if no higher point exists) is the left valley.
  2. Right valley: Traverse right from i until you hit a point higher than p. The minimum value between i and that higher point (or the end of the array if no higher point exists) is the right valley.
  3. Prominence: p - max(left_valley, right_valley) (this takes the highest of the two surrounding valleys, as that’s the "lowest barrier" the peak has to rise above).

Step-by-step C++ implementation

Here’s a simplified, working example that finds peaks meeting a minimum prominence threshold:

#include <vector>
#include <algorithm>
#include <iostream>

// Struct to store peak details: index, value, calculated prominence
struct Peak {
    int index;
    double value;
    double prominence;
};

// First, find all local peaks in the dataset
std::vector<Peak> findLocalPeaks(const std::vector<double>& data) {
    std::vector<Peak> peaks;
    int n = data.size();
    if (n < 3) return peaks;

    // Check inner points (not edges)
    for (int i = 1; i < n - 1; ++i) {
        if (data[i] > data[i-1] && data[i] > data[i+1]) {
            peaks.push_back({i, data[i], 0.0});
        }
    }
    // Optional: handle edge peaks (MATLAB's findpeaks can include these with settings)
    if (data[0] > data[1]) {
        peaks.push_back({0, data[0], 0.0});
    }
    if (data.back() > data[n-2]) {
        peaks.push_back({n-1, data.back(), 0.0});
    }
    return peaks;
}

// Calculate prominence for a single peak
double calculateProminence(const std::vector<double>& data, int peakIndex) {
    double peakVal = data[peakIndex];
    int n = data.size();

    // Find left valley
    double leftValley = peakVal;
    int leftPtr = peakIndex - 1;
    bool foundHigherLeft = false;
    while (leftPtr >= 0) {
        if (data[leftPtr] > peakVal) {
            foundHigherLeft = true;
            break;
        }
        if (data[leftPtr] < leftValley) {
            leftValley = data[leftPtr];
        }
        leftPtr--;
    }
    // If no higher point left, use min from start to peak
    if (!foundHigherLeft) {
        leftValley = *std::min_element(data.begin(), data.begin() + peakIndex + 1);
    }

    // Find right valley
    double rightValley = peakVal;
    int rightPtr = peakIndex + 1;
    bool foundHigherRight = false;
    while (rightPtr < n) {
        if (data[rightPtr] > peakVal) {
            foundHigherRight = true;
            break;
        }
        if (data[rightPtr] < rightValley) {
            rightValley = data[rightPtr];
        }
        rightPtr++;
    }
    // If no higher point right, use min from peak to end
    if (!foundHigherRight) {
        rightValley = *std::min_element(data.begin() + peakIndex, data.end());
    }

    // Prominence is peak minus the higher of the two valleys
    return peakVal - std::max(leftValley, rightValley);
}

// Filter peaks to only those meeting the minimum prominence threshold
std::vector<Peak> filterPeaksByProminence(std::vector<Peak> peaks, const std::vector<double>& data, double minProminence) {
    std::vector<Peak> filtered;
    for (auto& peak : peaks) {
        peak.prominence = calculateProminence(data, peak.index);
        if (peak.prominence >= minProminence) {
            filtered.push_back(peak);
        }
    }
    return filtered;
}

// Example usage
int main() {
    std::vector<double> data = {1.0, 3.0, 0.5, 4.0, 2.0, 5.0, 1.0, 6.0, 0.0};
    double minProminence = 2.0;

    std::vector<Peak> peaks = findLocalPeaks(data);
    std::vector<Peak> filteredPeaks = filterPeaksByProminence(peaks, data, minProminence);

    std::cout << "Filtered peaks (prominence >= " << minProminence << "):\n";
    for (const auto& peak : filteredPeaks) {
        std::cout << "Index: " << peak.index << ", Value: " << peak.value << ", Prominence: " << peak.prominence << "\n";
    }

    return 0;
}

Notes on this implementation

  • This is a simplified version—MATLAB’s findpeaks has extra features (like handling plateaus, width constraints, and noise reduction) that you can add if your use case requires them.
  • For large datasets, optimize the calculateProminence function (e.g., precompute prefix/suffix minima to avoid repeated min calculations).

内容的提问来源于stack exchange,提问作者Khalid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:14:39