// // Created by Elie Baier on 23.02.24. // #include #include "iostream" #include "string" #include "fstream" #include "sstream" #include "matplot/matplot.h" using namespace std; namespace plt = matplot; int MIN_ZERO_SEPARATION = 10; vector findZeroCrossings(const vector& data) { vector zeroCrossings; for (int i = 1; i < data.size(); ++i) { if (data[i - 1] * data[i] < 0 || data[i - 1] * data[i] == 0) { // Cleaning the duplicate zero which are +-MIN_ZERO_SEPARATION if(zeroCrossings.size() >= 1) { if(zeroCrossings[zeroCrossings.size() - 1] - MIN_ZERO_SEPARATION < i && zeroCrossings[zeroCrossings.size() - 1] + MIN_ZERO_SEPARATION > i) { // cout << "Found duplicate zero: " << i << endl; continue; } } zeroCrossings.push_back(i); } } return zeroCrossings; } pair poweredMax(const vector& data, int n) { if (data.empty()) { return {0.0, false}; // If vector is empty, return false } unordered_map freqMap; for (double value : data) { freqMap[value]++; } double maxVal = data[0]; // Initialize maxVal with the first element int maxFreq = freqMap[maxVal]; for (const auto& entry : freqMap) { if (entry.second >= n && entry.first > maxVal) { maxVal = entry.first; maxFreq = entry.second; } } bool found = maxFreq >= n; return {maxVal, found}; } std::pair poweredMin(const std::vector& data, int n) { if (data.empty()) { return {0.0, false}; // If vector is empty, return false } std::unordered_map freqMap; for (double value : data) { freqMap[value]++; } double minVal = std::numeric_limits::max(); // Initialize minVal with maximum double value int minFreq = freqMap[minVal]; for (const auto& entry : freqMap) { if (entry.second >= n && entry.first < minVal) { minVal = entry.first; minFreq = entry.second; } } bool found = minFreq >= n; return {minVal, found}; } std::vector slice(const std::vector& data, int start, int end) { if (start < 0 || end >= static_cast(data.size()) || start > end) { std::cerr << "Invalid slice indices." << std::endl; return {}; } return {data.begin() + start, data.begin() + end + 1}; } int main() { ifstream dataFile; dataFile.open("/Users/eliebaier/Workspace/Physique/TP8/DATA/ALL0000/F0000CH1.CSV"); if (!dataFile.is_open()) { std::cerr << "Error opening file." << std::endl; return 1; } string line; // Skipping TEKTRONICS DEFINITION lines for(auto i = 0; i < 18; i++) { getline(dataFile, line); } std::vector xData, yData; while(getline(dataFile, line)) { // Cleaning the lines line.erase(0, 3); line.erase(line.size() - 1, line.size()); std::string cleanedLine; for (char c : line) { if (std::isdigit(c) || c == '.' || c == ',') { cleanedLine += c; } } double x, y; istringstream iss(line); char comma; if (!(iss >> x >> comma >> y)) { std::cerr << "Error parsing line: " << line << std::endl; continue; } xData.push_back(x); yData.push_back(y); } dataFile.close(); plt::plot(xData, yData); plt::xlabel("X Label"); plt::ylabel("Y Label"); plt::title("Line Plot"); vector zeroCrossings = findZeroCrossings(yData); // Drawing lines on the found zeros for(auto zero : zeroCrossings) { cout << "Zero: " << zero << endl; plt::line(xData[zero], -2, xData[zero], 2); } // Finding the powered max between 2 zeros auto max = poweredMax(slice(yData, zeroCrossings[0], zeroCrossings[1]), 5); auto min = poweredMin(slice(yData, zeroCrossings[1], zeroCrossings[2]), 5); cout << max.first << endl; cout << min.first << endl; // Show the plot plt::show(); return 0; }