标准差阈值滤波
这是一个使用标准差阈值滤波器的C++实现。对于每个数据点,我们将计算其邻近点的标准差。如果该点的值与均值之差大于标准差的阈值倍数,则将其替换为其邻近点的平均值。
#include <iostream>
#include <vector>
#include <cmath>
std::vector<double> standard_deviation_filter(const std::vector<double>& data, int window_size) {
std::vector<double> filtered_data;
int n = data.size();
filtered_data.reserve(n);
for (int i = 0; i < n; i++) {
int start = std::max(0, i - window_size / 2);
int end = std::min(n - 1, i + window_size / 2);
double sum = 0;
double sum_square = 0;
int count = end - start + 1;
for (int j = start; j <= end; j++) {
sum += data[j];
sum_square += data[j] * data[j];
}
double mean = sum / count;
double variance = (sum_square / count) - (mean * mean);
double std_dev = std::sqrt(variance);
double threshold = 2.0 * std_dev;
if (std::abs(data[i] - mean) > threshold) {
filtered_data.push_back(mean);
} else {
filtered_data.push_back(data[i]);
}
}
return filtered_data;
}
int main() {
std::vector<double> data = {33.741, 31.651, 30.298, 29.332, 28.582, 28.024, 27.584, 27.214,
26.924, 26.685, 26.471, 26.331, 26.166, 26.04, 25.948, 25.846,
25.762, 25.686, 25.618, 25.565, 25.535, 25.468, 25.43, 25.373,
25.339, 25.296, 25.26, 25.235, 25.21, 25.159, 25.103, 25.105,
25.071, 25.048, 25.015, 25.012, 24.985, 24.96, 24.902, 24.908,
24.894, 24.867, 24.817, 24.825, 24.806, 24.798, 24.745};
int window_size = 3;
std::vector<double> filtered_data = standard_deviation_filter(data, window_size);
for (const auto& value : filtered_data) {
std::cout << value << " ";
}
std::cout << std::endl;
return 0;
}
在此示例中,我们将阈值设置为滑动窗口内标准差的2倍。请注意,动态阈值可能会导致过滤效果与固定阈值不同。您可以根据需要调整窗口大小和阈值倍数。
以下是使用Qt平台实现标准差滤波器的示例
#include <QCoreApplication>
#include <QVector>
#include <QDebug>
#include <cmath>
QVector<double> standard_deviation_filter(const QVector<double>& data, int window_size) {
QVector<double> filtered_data;
int n = data.size();
filtered_data.reserve(n);
for (int i = 0; i < n; i++) {
int start = std::max(0, i - window_size / 2);
int end = std::min(n - 1, i + window_size / 2);
double sum = 0;
double sum_square = 0;
int count = end - start + 1;
for (int j = start; j <= end; j++) {
sum += data[j];
sum_square += data[j] * data[j];
}
double mean = sum / count;
double variance = (sum_square / count) - (mean * mean);
double std_dev = std::sqrt(variance);
double threshold = 2.0 * std_dev;
if (std::abs(data[i] - mean) > threshold) {
filtered_data.push_back(mean);
} else {
filtered_data.push_back(data[i]);
}
}
return filtered_data;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<double> data = {33.741, 31.651, 30.298, 29.332, 28.582, 28.024, 27.584, 27.214,
26.924, 26.685, 26.471, 26.331, 26.166, 26.04, 25.948, 25.846,
25.762, 25.686, 25.618, 25.565, 25.535, 25.468, 25.43, 25.373,
25.339, 25.296, 25.26, 25.235, 25.21, 25.159, 25.103, 25.105,
25.071, 25.048, 25.015, 25.012, 24.985, 24.96, 24.902, 24.908,
24.894, 24.867, 24.817, 24.825, 24.806, 24.798, 24.745};
int window_size = 3;
QVector<double> filtered_data = standard_deviation_filter(data, window_size);
for (const auto& value : filtered_data) {
qDebug() << value;
}
return a.exec();
}
移动平均滤波
以下是使用Qt平台实现平滑滤波器的示例
#include <QCoreApplication>
#include <QVector>
#include <QDebug>
#include <cmath>
QVector<double> moving_average_filter(const QVector<double>& data, int window_size) {
QVector<double> filtered_data;
int n = data.size();
filtered_data.reserve(n);
for (int i = 0; i < n; i++) {
int start = std::max(0, i - window_size / 2);
int end = std::min(n - 1, i + window_size / 2);
double sum = 0;
int count = end - start + 1;
for (int j = start; j <= end; j++) {
sum += data[j];
}
filtered_data.push_back(sum / count);
}
return filtered_data;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<double> data = {33.741, 31.651, 30.298, 29.332, 28.582, 28.024, 27.584, 27.214,
26.924, 26.685, 26.471, 26.331, 26.166, 26.04, 25.948, 25.846,
25.762, 25.686, 25.618, 25.565, 25.535, 25.468, 25.43, 25.373,
25.339, 25.296, 25.26, 25.235, 25.21, 25.159, 25.103, 25.105,
25.071, 25.048, 25.015, 25.012, 24.985, 24.96, 24.902, 24.908,
24.894, 24.867, 24.817, 24.825, 24.806, 24.798, 24.745};
int window_size = 3;
QVector<double> filtered_data = moving_average_filter(data, window_size);
for (const auto& value : filtered_data) {
qDebug() << value;
}
return a.exec();
}
线性拟合
使用最小二乘法实现线性拟合
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
double linear_fit(vector<double> x, vector<double> y, double& a, double& b) {
int n = x.size();
double x_bar = 0.0, y_bar = 0.0, cov_xy = 0.0, var_x = 0.0;
for (int i = 0; i < n; i++) {
x_bar += x[i];
y_bar += y[i];
}
x_bar /= n;
y_bar /= n;
for (int i = 0; i < n; i++) {
cov_xy += (x[i] - x_bar) * (y[i] - y_bar);
var_x += (x[i] - x_bar) * (x[i] - x_bar);
}
a = cov_xy / var_x;
b = y_bar - a * x_bar;
double residual_sum_of_squares = 0.0;
for (int i = 0; i < n; i++) {
double y_fit = a * x[i] + b;
residual_sum_of_squares += (y[i] - y_fit) * (y[i] - y_fit);
}
double rmse = sqrt(residual_sum_of_squares / n);
return rmse;
}
int main() {
vector<double> x = {1.0, 2.0, 3.0, 4.0, 5.0};
vector<double> y = {2.0, 4.0, 5.0, 4.5, 6.0};
double a, b;
double rmse = linear_fit(x, y, a, b);
cout << "回归系数a: " << a << endl;
cout << "截距b: " << b << endl;
cout << "均方根误差RMSE: " << rmse << endl;
return 0;
}