Создается C#-приложение, иллюстрирующее следующие имеющиеся в библиотеке IMSL распределения случайных чисел:
Описание распределений можно найти в интернете. br> Для иллюстрации распределений создается приведенная на рис. 1 форма
Рис. 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();
}
}
}