一、步骤
-
计算数据的均值和标准差:计算数据的均值(μ)和标准差(σ)。
-
定义正态分布函数:使用正态分布的概率密度函数(PDF)来计算每个点的值。
-
绘制曲线:使用Qt的绘图功能(如
QPainter
)来绘制曲线。
二、例子
1. 代码
-
数据准备:
data
是绘制正态分布曲线的数据集。 -
计算均值和标准差:
calculateMeanAndStdDev
函数计算数据的均值和标准差。 -
正态分布函数:
normalPDF
函数计算给定点的正态分布概率密度值。 -
绘制曲线:在
paintEvent
中使用QPainter
绘制曲线。
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QVector>
#include <cmath>
#include <algorithm>class NormalDistributionWidget : public QWidget {
public:NormalDistributionWidget(QWidget *parent = nullptr) : QWidget(parent) {// 示例数据data = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9};calculateMeanAndStdDev();}protected:void paintEvent(QPaintEvent *event) override {Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing); //防走样("锯齿"现象)函数// 设置绘制区域int width = this->width();int height = this->height();painter.setPen(Qt::blue);// 绘制正态分布曲线for (int x = 0; x < width; ++x) {double xval = xmin + (xmax - xmin) * x / width;double yval = normalPDF(xval, mean, stddev);int y = height - (yval * height / ymax);painter.drawPoint(x, y);}}private:QVector<double> data;double mean, stddev;double xmin = 0, xmax = 10; // X轴范围double ymax = 0.5; // Y轴最大值void calculateMeanAndStdDev() {double sum = std::accumulate(data.begin(), data.end(), 0.0);mean = sum / data.size();double sq_sum = std::inner_product(data.begin(), data.end(), data.begin(), 0.0);stddev = std::sqrt(sq_sum / data.size() - mean * mean);}double normalPDF(double x, double mu, double sigma) {static const double inv_sqrt_2pi = 0.3989422804014327; //注解1double a = (x - mu) / sigma;return inv_sqrt_2pi / sigma * std::exp(-0.5 * a * a);}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);NormalDistributionWidget widget;widget.resize(800, 600);widget.show();return app.exec();
}
a. 注解
1. 示例:static const double inv_sqrt_2pi = 0.3989422804014327;
- 作用:预计算正态分布概率密度函数(PDF)中的一个常数部分,以提高计算效率。
- 正态分布的概率密度函数(PDF)公式如下:
- 代码化:
#include <cmath> // 用于 std::exp 和 std::sqrtdouble normalPDF(double x, double mu, double sigma) {// 计算常数部分:1 / (sigma * sqrt(2 * pi))static const double inv_sqrt_2pi = 0.3989422804014327; // 1 / sqrt(2 * pi)double normalization = inv_sqrt_2pi / sigma;// 计算指数部分:exp(-0.5 * ((x - mu) / sigma)^2)double exponent = -0.5 * std::pow((x - mu) / sigma, 2);// 返回概率密度值return normalization * std::exp(exponent);
}//调用#include <iostream>int main() {double x = 1.0; // 输入值double mu = 0.0; // 均值double sigma = 1.0; // 标准差double pdf_value = normalPDF(x, mu, sigma);std::cout << "正态分布概率密度值: " << pdf_value << std::endl;return 0;
}