162 lines
4.2 KiB
C++
162 lines
4.2 KiB
C++
//
|
|
// Created by Elie Baier on 23.02.24.
|
|
//
|
|
|
|
#include <cmath>
|
|
#include "iostream"
|
|
#include "string"
|
|
#include "fstream"
|
|
#include "sstream"
|
|
#include "matplot/matplot.h"
|
|
|
|
using namespace std;
|
|
namespace plt = matplot;
|
|
|
|
int MIN_ZERO_SEPARATION = 10;
|
|
|
|
vector<double> findZeroCrossings(const vector<double>& data) {
|
|
vector<double> 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<double, bool> poweredMax(const vector<double>& data, int n) {
|
|
if (data.empty()) {
|
|
return {0.0, false}; // If vector is empty, return false
|
|
}
|
|
|
|
unordered_map<double, int> 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<double, bool> poweredMin(const std::vector<double>& data, int n) {
|
|
if (data.empty()) {
|
|
return {0.0, false}; // If vector is empty, return false
|
|
}
|
|
|
|
std::unordered_map<double, int> freqMap;
|
|
for (double value : data) {
|
|
freqMap[value]++;
|
|
}
|
|
|
|
double minVal = std::numeric_limits<double>::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<double> slice(const std::vector<double>& data, int start, int end) {
|
|
if (start < 0 || end >= static_cast<int>(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<double> 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<double> 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;
|
|
|
|
} |