首页 > 解决方案 > 如何从麦克斯韦分布中绘制直方图?

问题描述

是我之前关于 Maxwell 发行版的问题,您可以在其中找到源代码。

以下代码旨在从 Maxwell 分布中获取直方图,该分布在上述代码之上工作。

using ZedGraph;

public static class Normalization
{
    public static int Normalize(double n_bins, double mu, double sigma, double gaussian)
    {
        var z = (gaussian - mu) / sigma;

        if (z > 3 || z < -3)
        {
            return -1;
        }
        else
        {
            return (int)((z + 3) * n_bins / 6d);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        const double N = 1000000;
        int time = (int)N;
        int binsCount = 51;

        Random rand = new Random();
        int[] bins = new int[binsCount];

        double mass = 14 * 1.67e-27;
        double T = 300;

        for (int i = 0; i < time; i++)
        {
            double gauss = MaxwellBolzman.Next(rand, mass, T);

            int index = Normalization.Normalize(binsCount, mass, T, gauss);

            if (index >= 0)
            {
                bins[index]++;
            }
        }

        PointPairList list = new PointPairList();
        for (int i = 0; i < bins.Length; i++)
        {
            list.Add(i, bins[i]);
        }

        PlotForm form = new PlotForm("Maxwell-Bolzman");
        form.AddBar(list, "Actual", Color.Blue);
        form.AxisChange();
        form.ShowDialog();
    }
}

输出:

根据此链接,图表应如下所示:

在此处输入图像描述

标签: c#probability-distribution

解决方案


正如我在上一个问题中所说,使用单元分析来查找错误。当时这是很好的建议,现在也是很好的建议。

让我们检查一下您的方法:

public static int Normalize(
  double n_bins, 
  double mu,  
  double sigma, 
  double gaussian)

它返回一个 bin 索引,因此它应该是一个整数。

它需要一个 bin 计数;那应该是一个整数,而不是一个双精度数。它不是物理量。

什么是亩?这是分布的平均值。分布是什么?速度。所以 mu 的单位是米每秒。

什么是西格玛?它是速度分布的标准偏差,所以它也有米每秒的单位。

什么是高斯?它是分布中的一个样本,因此它也有米每秒的单位。

但在你的电话中:

Normalization.Normalize(binsCount, mass, T, gauss);

您已经通过了垃圾箱计数 - 这是正确的。

你已经通过了一个质量——我们预计每秒米,你已经通过了公斤,所以这不可能是正确的。

你已经超过了一个温度——我们预计每秒米数而你已经超过了开尔文,所以这不可能是正确的。

你已经通过了一个样本,所以这是正确的。

你应该传递的是你在上一个答案中计算的平均速度,以及速度的标准偏差,你可以估计它,因为你有一个速度分量的已知标准偏差,这就足够了猜测。

再次重申:单元分析是发现错误的有力工具。我希望 C# 更容易将单位分配给双精度数;然后编译器会捕获这些类型的问题。F#有这个功能,非常好用。


更新:我注意到原始发帖人不明白我所说的单元分析是什么意思。

单元分析是将“类型”与物理问题中的每个数量相关联,然后通过问题跟踪该类型的技术。如果在任何时候你发现你有“混合”类型,你就知道有问题了。

单位分析的基本规则是单位只与相同的单位相加,单位的乘除使用标准的乘除法规则。

例如,假设我们有一些数量:10 公斤、5 米、2 秒。假设我们将千克乘以米再除以秒;一个 10 公斤 的 物体 在 2 秒 内 移动 5 米 的 动量 是 25公斤 米 / 秒.

如果稍后在我们的问题中我们有一个量,例如能量,并且我们错误地将动量添加到能量中,我们的单位分析告诉我们这是错误的。25 kg*m/s不能添加到任何有能量单位的东西上,因为能量有单位kg*m*m/(s*s),所以我们知道我们在某个地方犯了错误。

同样,在上一个问题中,我注意到我们可以使用单位分析来确定何时以克为单位进行计算,但我们期望以千克为单位。在那种情况下,至少我们有两个都是质量的东西,但是当期望公斤时使用克是一个严重的错误,并且单位分析可以检测到这个问题。

这在编程中特别有用,因为正如我们刚刚看到的,如果你有一个需要速度的方法并且你传递了一个温度,这是很容易出错的,这是没有意义的。你输入的速度值 300K 恰好在正确的范围内,这只是运气,因为 300m/s 对于氮分子来说也是一个合理的速度。但那是运气。正确的做法是弄清楚通过的正确速度是多少。


推荐阅读