Список работ

C#: пример употребления IMSL Stat; распределения случайных величин

Содержание

Введение

Создается C#-приложение, иллюстрирующее следующие имеющиеся в библиотеке IMSL распределения случайных чисел:

Описание распределений можно найти в интернете. br> Для иллюстрации распределений создается приведенная на рис. 1 форма

Форма, для иллюстрация случайных распределений IMSL

Рис. 1. Иллюстрация случайных распределений библиотеки IMSL

Тип проекта - Windows Form Application. Форма, создаваемая при начале нового проекта, и весь связанный с ней код удаляются. Взамен используется приводимая в следующем разделе программа.
Форма, наблюдаемая на рис. 1, генерируется этой программой. Детали построения формы см. в приводимом коде и сопутствующем комментарии.
Подключение недостающих ссылок осуществляется обычным способом: Solution Explorer – References – правая кнопка мыши – Add Reference.
Приводимый код основан на примере, имеющемся в проекте IMSLDemo, поставляемом с библиотекой C#-IMSL.

Реализация

using System;
using System.Drawing;
using System.Windows.Forms;
using Imsl.Chart2D;
using Imsl.Stat;

namespace WindowsFormsApplicationIMSL
{
    static class Program
    {
        // Точка входа приложения
        [STAThread]
        static void Main()
        {
            Application.Run(new Random2());
        }
    }
    public class Random2 : System.Windows.Forms.Form
    {
        private int selected = 1;
        private String selName = "Равномерное";
        private TextBox[] tb = new TextBox[3];
        private System.Windows.Forms.Panel1;
        private System.Windows.Forms.Button1;
        private Imsl.Chart2D.PanelChart panelChart1;
        private Imsl.Chart2D.Bar bar;
        private Imsl.Stat.Random r;

        public Random2()
        {
            InitializeComponent();
            this.AcceptButton = button1;
            r = new Imsl.Stat.Random(new MersenneTwister(123457));
            UpdateChart();
        }
        private void InitializeComponent()
        {
            RadioButton[] rb = new RadioButton[23];
            for (int k = 0; k < 23; k++) rb[k] = new System.Windows.Forms.RadioButton();
            RadioButton rbK;
            // Массив имен распределений
            string[] rbT = {"Равномерное", "Нормальное", "Биномиальное", "Хи–квадрат", "Геометрическое",
                             "Логарифмическое", "Пуассона", "Экспоненциальное (mix)", "Треугольное", "Фон Мизеса", " Рэлея",
                             "Бета", "Нормальное (AR)", "Коши", "Гамма", "Гипергеометрическое",
                             "Отрицательное биномиальное", "Экспоненциальное", "Логнормальное", "Стьюдента", "Вейбулла",
                             "Фишера (F)", "Экстремальных значений"};
            this.panel1 = new System.Windows.Forms.Panel();
            this.panel1.SuspendLayout();
            this.SuspendLayout();
            int yf = 520; // Высота формы
            int d = 4; // Расстояние по X между panel1 и panelChart1, а также отступ от краев формы
            // Панель 1 с радиокнопками
            int xp = 432; // Ширина панели 1 с радиокнопками
            int yp = 288; // Высота панели 1 с радиокнопками
            int yp1 = 144; // Y-координата положения панели 1
            this.panel1.Location = new System.Drawing.Point(d, yp1);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(xp, yp);
            this.panel1.TabIndex = 5;
            this.Controls.Add(this.panel1);
            // radioButtons 1-23
            int x = 0, y = 0;
            for (int k = 0; k < 23; k++)
            {
                rbK = rb[k];
                if(k == 0) rbK.Checked = true;
                // Times New Roman, Microsoft Sans Serif
                rbK.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
                if (k == 12)
                {
                    x = xp / 2;
                    y = 24;
                }
                rbK.Location = new Point(x, y);
                y += 24;
                rbK.Name = "radioButton" + (k + 1);
                rbK.Size = new System.Drawing.Size(xp / 2, 24);
                rbK.TabIndex = 3;
                if (k == 0) rbK.TabStop = true;
                rbK.Text = rbT[k];
                rbK.CheckedChanged += new System.EventHandler(this.radioButton_CheckedChanged);
                this.panel1.Controls.Add(rbK);
            }
            // labels 1-2
            Label[] lb = new Label[2];
            for (int k = 0; k < 2; k++) lb[k] = new System.Windows.Forms.Label();
            Label lbK;
            string[] lbT = { "Число точек:", "Число столбцов:" };
            x = 24;
            y = 16;
            for (int k = 0; k < 2; k++)
            {
                lbK = lb[k];
                lbK.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
                lbK.Location = new System.Drawing.Point(x, y);
                y = 64;
                lbK.Name = "label" + (k + 1);
                lbK.Size = new System.Drawing.Size(160, 24);
                lbK.TabIndex = 1;
                lbK.Text = lbT[k];
                lbK.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
                this.Controls.Add(lbK);
            }
            // textBoxes 1-3
            for (int k = 0; k < 3; k++) tb[k] = new System.Windows.Forms.TextBox();
            TextBox tbK;
            string[] tbT = { "1000", "20", "Сведения о распределении" };
            x = 190;
            y = 16;
            Single h = 11F;
            int t = 2, xs = 88, ys = 26;
            for (int k = 0; k < 3; k++)
            {
                tbK = tb[k];
                if (k == 1) y = 64;
                if (k == 2)
                {
                    h = 10F;
                    x = d;
                    y = yp + yp1;
                    tbK.Multiline = true;
                    t = 4;
                    xs = xp;
                    ys = yf - y - d;
                }
                else
                    tbK.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
                tbK.Font = new System.Drawing.Font("Microsoft Sans Serif", h, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
                tbK.Location = new System.Drawing.Point(x, y);
                tbK.Name = "textBox" + (k + 1);
                tbK.Size = new System.Drawing.Size(xs, ys);
                tbK.TabIndex = t;
                tbK.Text = tbT[k];
                this.Controls.Add(tbK);
            }
            // button1
            this.button1 = new System.Windows.Forms.Button();
            this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            this.button1.Location = new System.Drawing.Point(136, 104);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(96, 32);
            this.button1.TabIndex = 6;
            this.button1.Text = "Применить";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.Controls.Add(this.button1);
            // panelChart1
            int xc = 432; // Ширина столбчатой диаграммы
            this.panelChart1 = new Imsl.Chart2D.PanelChart();
            this.panelChart1.Location = new System.Drawing.Point(2 * d + xp, d);
            this.panelChart1.Name = "panelChart1";
            this.panelChart1.Size = new System.Drawing.Size(xc, yf - 2 * d);
            this.panelChart1.TabIndex = 7;
            this.Controls.Add(this.panelChart1);
            //
            // Random
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(3 * d + xp + xc, yf);
            this.Location = new System.Drawing.Point(64, 64);
            this.Name = "Random";
            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
            this.Text = "Распределения случайных чисел";
            this.BackColor = Color.Chocolate;
            this.panel1.ResumeLayout(false);
            this.ResumeLayout(false);
        }
        double RandomValue(Imsl.Stat.Random r)
        {
            double nr = 0.0;
            if (selected == 1) nr = r.NextDouble();
            if (selected == 2) nr = r.NextNormal();
            if (selected == 3) nr = r.NextBinomial(5, 0.5d);
            if (selected == 4) nr = r.NextChiSquared(5);
            if (selected == 5) nr = r.NextGeometric(0.5d);
            if (selected == 6) nr = r.NextLogarithmic(0.5d);
            if (selected == 7) nr = r.NextPoisson(10d);
            if (selected == 8) nr = r.NextExponentialMix(30d, 10d, 0.5d) / 100; // уменьшаем в 100 раз для графика
            if (selected == 9) nr = r.NextTriangular();
            if (selected == 10) nr = r.NextVonMises(1.0e-7d);
            if (selected == 11) nr = r.NextRayleigh(5);
            if (selected == 12) nr = r.NextBeta(1.0d, 0.5d);
            if (selected == 13) nr = r.NextNormalAR();
            if (selected == 14) nr = r.NextCauchy() / 100.0; // уменьшаем в 100 раз для графика
            if (selected == 15) nr = r.NextGamma(0.5d);
            if (selected == 16) nr = r.NextHypergeometric(5, 5, 11);
            if (selected == 17) nr = r.NextNegativeBinomial(0.5d, 0.5d);
            if (selected == 18) nr = r.NextExponential();
            if (selected == 19) nr = r.NextLogNormal(0d, 1d);
            if (selected == 20) nr = r.NextStudentsT(5.0d);
            if (selected == 21) nr = r.NextWeibull(5d);
            if (selected == 22) nr = r.NextF(5, 5);
            if (selected == 23) nr = r.NextExtremeValue(0.1, 0.5);
            return nr;
        }
        private void UpdateChart()
        {
            int numPoints = 1000;
            int numBins = 20;
            try
            {
                numPoints = Int32.Parse(tb[0].Text.Trim());
            }
            catch (System.FormatException)
            {
                System.Windows.Forms.MessageBox.Show("Плохое число точек", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            try
            {
                numBins = Int32.Parse(tb[1].Text.Trim());
            }
            catch (System.FormatException)
            {
                System.Windows.Forms.MessageBox.Show("Плохое число столбцов", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            panelChart1.Chart = new Imsl.Chart2D.Chart();
            Imsl.Chart2D.Chart chart = panelChart1.Chart;
            tb[2].Text = SetupThis(chart, numPoints, numBins);
            SetupThis(chart, numPoints, numBins);
            Refresh();
        }
        private String SetupThis(Imsl.Chart2D.Chart chart, int numPoints, int numBins)
        {
            bar = null;
            AxisXY axis = new AxisXY(chart);
            double[] v = new double[numPoints];
            String[] x = new String[numBins];
            double[] y = new double[numBins];
            // Очиистка гистограммы
            for (int k = 0; k < numBins; k++) y[k] = 0;
            double maxv = -10000;
            double minv = 10000;
            for (int i = 0; i < numPoints; i++)
            {
                v[i] = RandomValue(r);
                // Min/Max значения
                if (maxv < v[i]) maxv = v[i];
                if (minv > v[i]) minv = v[i];
            }
            double wx = (maxv - minv) / numBins;
            for (int k = 0; k < v.Length; k++)
            {
                int i;
                if (maxv == v[k])
                {
                    i = numBins - 1;
                }
                else
                {
                    i = (int)((v[k] - minv) / wx);
                }
                y[i] = y[i] + 1;
            }
            // Настройка X-оси гистограммы
            String spacer = " : ";
            String[] labels = new String[numBins];
            String fmt = "####0.00";
            labels[0] = minv.ToString(fmt) + spacer + (minv + wx).ToString(fmt);
            for (int i = 1; i < numBins - 1; i++)
            {
                labels[i] = (minv + i * wx).ToString(fmt) + spacer + (minv + (i + 1) * wx).ToString(fmt);
            }
            labels[numBins - 1] = (maxv - wx).ToString(fmt) + spacer + maxv.ToString(fmt);
            // Выводим диаграмму в виде столбцов
            bar = new Bar(axis, y);
            chart.ChartTitle.SetTitle("Распределение " + selName);
            chart.ChartTitle.FontSize = 12;
            chart.ChartTitle.FontStyle = FontStyle.Underline;
            bar.FillOutlineType = ChartNode.FILL_TYPE_SOLID;
            bar.GetBarSet(0).FillColor = Color.Red;
            bar.SetLabels(labels, ChartNode.BAR_TYPE_VERTICAL);
            axis.AxisX.AxisLabel.TextAngle = 90;
            axis.SetViewport(0.12, 0.95, 0.1, 0.8);
            axis.AxisY.TextFormat = "###0";
            // Сведения о диаграмме
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append("Случайное распределение: " + selName + "\r\n");
            sb.Append("Число точек: " + numPoints);
            sb.Append("; число столбцов: " + numBins + "\r\n");
            sb.Append("Максимальное значение: " + maxv + "\r\n");
            sb.Append("Минимальное значение: " + minv + "\r\n");
            return sb.ToString();
        }
        private void radioButton_CheckedChanged(object sender, System.EventArgs e)
        {
            String nm = ((RadioButton)sender).Name;
            selected = Convert.ToInt32(nm.Substring(11));
            selName = ((RadioButton)sender).Text;
            UpdateChart();
        }
        private void button1_Click(object sender, System.EventArgs e)
        {
            UpdateChart();
        }
    }
}

Список работ

Рейтинг@Mail.ru