[Delphi]根据 高斯正态分布随机函数RandG发生的数据 绘正态分布曲线(原创)

原创 2005年04月29日 01:13:00

{*

采用RandG(0,1)来生成标准正态分布数据

1、一次生成10k个数据进行统计,速度相当快(Celeron 1.1G +256M ddr266)<1秒

2、绘出的曲线因为选择范围是8,故看起来并不是十分陡峭,可以将其改为16,那么就更加陡峭了

3、算法:映射到1..1000个数据点,大于等于+8的,正向封顶,设其为1000;小于等于 -8 的,负向封底,设其为1;如上面所说,为了使曲线看起来更加陡峭,可以在这里改为16封顶。其实,我最初是用+2-2来封及+4-4来封定封底的,效果已经不错了。

}

unit Unit1;

{dawnsong,2005-6-22}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Math;

type

  TfrmMain = class(TForm)
    imgAxis: TImage;
    btnRandG: TButton;
    GroupBox1: TGroupBox;
    Splitter1: TSplitter;
    grpControl: TGroupBox;
    chkLogFrequency: TCheckBox;
    chkDrawEdge: TCheckBox;
    chkDrawLines: TCheckBox;
    cboxCopyMode: TComboBox;
    procedure FormShow(Sender: TObject);
    procedure btnRandGClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    totalCount  :Integer;
    sampleDatas :array[1..1000] of Integer;
    procedure DrawAxis;
    procedure GaussIt(const ASampleData:Extended);
    procedure ReDraw;
    procedure DrawEdge;//画边

    procedure Log(const logName:string);
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}
procedure TfrmMain.DrawAxis;
begin
  imgAxis.Canvas.Pen.Color :=clLime;
  imgAxis.Canvas.Pen.Mode  :=pmXor;
  imgAxis.Canvas.MoveTo(imgAxis.Width div 2,imgAxis.Height);
  imgAxis.Canvas.LineTo(imgAxis.Width div 2,0);
  imgAxis.Canvas.MoveTo(0,imgAxis.Height -10);
  imgAxis.Canvas.LineTo(imgAxis.Width,imgAxis.Height -10);
end;
procedure TfrmMain.ReDraw;
var
  bmp :TBitmap;
  i   :Integer;
begin//根据数组里面的数和totalCount重新画图
  bmp :=TBitmap.Create;
  try
    bmp.Width :=imgAxis.Width;
    bmp.Height:=imgAxis.Height;
    bmp.Canvas.Brush.Color :=clBlack;
    bmp.Canvas.FillRect(bmp.Canvas.ClipRect);
    bmp.Canvas.Pen.Color :=clRed;
    bmp.Canvas.Pen.Width :=1;
    //根据Image高度和1->1000发生的频数设置画线的高度
    //应该计算出图像所能反映的最小分辨率,应能体现到频数有1的变化
    for i:=1 to 1000 do
    begin
      sampleDatas[i] :=(sampleDatas[i]*(bmp.Height-10))  *250 div totalCount;//频数->频率->实际图像高度值
      sampleDatas[i] :=bmp.Height-10 -sampleDatas[i];//高度转换为实际坐标
      bmp.Canvas.MoveTo(i,bmp.Height-10);
      if chkDrawLines.Checked then
        bmp.Canvas.LineTo(i,sampleDatas[i]);
    end;
    //Log('height.txt');
    if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmBlackness' then
      imgAxis.Canvas.CopyMode :=cmBlackness
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmDstInvert' then
      imgAxis.Canvas.CopyMode :=cmDstInvert
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmMergeCopy' then
      imgAxis.Canvas.CopyMode :=cmMergeCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmMergePaint' then
      imgAxis.Canvas.CopyMode :=cmMergePaint
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmNotSrcCopy' then
      imgAxis.Canvas.CopyMode :=cmNotSrcCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmNotSrcErase' then
      imgAxis.Canvas.CopyMode :=cmNotSrcErase
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmPatCopy' then
      imgAxis.Canvas.CopyMode :=cmPatCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmPatInvert' then
      imgAxis.Canvas.CopyMode :=cmPatInvert
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmPatPaint' then
      imgAxis.Canvas.CopyMode :=cmPatPaint
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcAnd' then
      imgAxis.Canvas.CopyMode :=cmSrcAnd
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcCopy' then
      imgAxis.Canvas.CopyMode :=cmSrcCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcErase' then
      imgAxis.Canvas.CopyMode :=cmSrcErase
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcInvert' then
      imgAxis.Canvas.CopyMode :=cmSrcInvert
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcPaint' then
      imgAxis.Canvas.CopyMode :=cmSrcPaint
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmWhiteness' then
      imgAxis.Canvas.CopyMode :=cmWhiteness;

    imgAxis.Canvas.CopyRect(imgAxis.Canvas.ClipRect,bmp.Canvas,bmp.Canvas.ClipRect);
    //imgAxis.Canvas.Draw(0,0,bmp);//这个不能控制CopyMode
  finally
    bmp.Destroy;
  end;
end;
procedure TfrmMain.GaussIt(const ASampleData:Extended);
var
  x :Integer;
begin
  Inc(totalCount);
  //ShowMessage(FloatToStr(ASampleData));
  //将这个随机数映射到1..1000,正数:500->1000,负数500->1
  //ASampleData>=8  ---1000
  //           =0   ---500
  //           <=-8 ---1
  x :=Round(ASampleData *1000);
  //确定范围
  if x>=4000 then x:=4000
  else if x<=-4000 then x:=-4000;
 
  x := (x +4001) shr 3;
  Inc(sampleDatas[x]);//记录发生的频数,除以总次数就是频率了
  //ShowMessage(IntToStr(x));
  //ShowMessage(IntToStr(sampleDatas[x]));
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
  DoubleBuffered :=true;
  DrawAxis;
end;

procedure TfrmMain.btnRandGClick(Sender: TObject);
var
  i:Integer;
begin
  totalCount :=0;
  for i:=1 to 1000 do
    sampleDatas[i]:=0;
  for i:=1 to 100000 do//总计10000次
    GaussIt(RandG(0,1));//标准正态分布

  if chkLogFrequency.Checked then
    Log('afterBtn.txt');

  ReDraw;
  if chkDrawEdge.Checked then
    DrawEdge;
  DrawAxis;
end;

procedure TfrmMain.FormShow(Sender: TObject);
begin
  Left :=0;
  btnRandG.Click;
end;

procedure TfrmMain.Log(const logName:string);
var
  i:Integer;
  log:TStringList;
  str:string;
begin
  log :=TStringList.Create;
  try
    for i:=1 to 1000 do
    begin
      str :=Format('%.4d : %d(频数)',[i,sampleDatas[i]]);
      log.Add(str);
    end;
    str :=Format('总数:%d',[totalCount]);
    log.Add(str);

    totalCount :=0;
    for i:=1 to 1000 do
      inc(totalCount,sampleDatas[i]);
    str :=Format('实际总数:%d',[totalCount]);
    log.Add(str);

    log.SaveToFile(logName);
  finally
    log.Destroy;
  end;
end;

procedure TfrmMain.DrawEdge;//画边
var
  i:Integer;
  points :array[1..1000] of TPoint;
begin
  for i:=1 to 1000 do
  begin
    points[i].x :=i;
    points[i].y :=sampleDatas[i];
  end;
  imgAxis.Canvas.Polyline(points);
end;

end.

--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------

下面是Unit1.dfm

--------------------------------------------------------------------------------------------

object frmMain: TfrmMain
  Left = 0
  Top = 0
  Width = 1012
  Height = 455
  Caption = 'frmMain'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object Splitter1: TSplitter
    Left = 0
    Top = 369
    Width = 1004
    Height = 4
    Cursor = crVSplit
    Align = alBottom
  end
  object GroupBox1: TGroupBox
    Left = 0
    Top = 0
    Width = 1004
    Height = 369
    Align = alClient
    Caption = 'GroupBox1'
    TabOrder = 0
    object imgAxis: TImage
      Left = 2
      Top = 15
      Width = 1000
      Height = 352
      Align = alClient
      Constraints.MaxWidth = 1000
      Constraints.MinWidth = 1000
    end
  end
  object grpControl: TGroupBox
    Left = 0
    Top = 373
    Width = 1004
    Height = 48
    Align = alBottom
    Caption = 'grpControl'
    Constraints.MaxHeight = 48
    Constraints.MinHeight = 24
    TabOrder = 1
    object btnRandG: TButton
      Left = 16
      Top = 16
      Width = 75
      Height = 25
      Caption = 'btnRandG'
      TabOrder = 0
      OnClick = btnRandGClick
    end
    object chkLogFrequency: TCheckBox
      Left = 128
      Top = 16
      Width = 97
      Height = 17
      Caption = 'chkLogFrequency'
      TabOrder = 1
    end
    object chkDrawEdge: TCheckBox
      Left = 240
      Top = 16
      Width = 97
      Height = 17
      Caption = 'chkDrawEdge'
      Checked = True
      Enabled = False
      State = cbChecked
      TabOrder = 2
    end
    object chkDrawLines: TCheckBox
      Left = 344
      Top = 16
      Width = 97
      Height = 17
      Caption = 'chkDrawLines'
      TabOrder = 3
    end
    object cboxCopyMode: TComboBox
      Left = 464
      Top = 16
      Width = 145
      Height = 21
      ItemHeight = 13
      ItemIndex = 0
      TabOrder = 4
      Text = 'cmBlackness'
      Items.Strings = (
        'cmBlackness'
        'cmDstInvert'
        'cmMergeCopy'
        'cmMergePaint'
        'cmNotSrcCopy'
        'cmNotSrcErase'
        'cmPatCopy'
        'cmPatInvert'
        'cmPatPaint'
        'cmSrcAnd'
        'cmSrcCopy'
        'cmSrcErase'
        'cmSrcInvert'
        'cmSrcPaint'
        'cmWhiteness')
    end
  end
end

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

正态分布(Normal distribution)又名高斯分布(Gaussian distribution)

转自:http://blog.csdn.net/rns521/article/details/6953591 正态分布(Normal distribution)又名高斯分布(Gaussian dis...

线性回归 高斯曲线 对数正态分布

线性回归         回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间...

正态分布(Normal distribution)与高斯分布(Gaussian distribution)

正态分布(Normal distribution)又名高斯分布(Gaussian distribution),是一个在数学、物理及工程等领域都非常重要的概率分布,在统计学的许多方面有着重大的影响力。 ...

概率论:高斯/正态分布

http://blog.csdn.net/pipisorry/article/details/49516209 正态分布(高斯分布) 若随机变量X服从一个数学期望为μ、方差为σ^2的高斯分布,记为...

正态分布(即高斯函数)积分

  • 2017年11月20日 12:01
  • 29KB
  • 下载

正态分布模式的贝叶斯分类数据

  • 2014年11月12日 11:22
  • 136KB
  • 下载

C#产生正态分布、泊松分布、指数分布、负指数分布随机数(原创)

http://blog.sina.com.cn/s/blog_76c31b8e0100qskf.html 在编程过程中,由于数据仿真模拟的需要,我们经常需要产生一些随机数,在C#中,产生一般...

C#产生正态分布、泊松分布、指数分布、负指数分布随机数(原创)

http://blog.sina.com.cn/s/blog_76c31b8e0100qskf.html 在编程过程中,由于数据仿真模拟的需要,我们经常需要产生一些随机数,在C#中,产生一般...

-正态分布曲线

  • 2014年04月26日 23:32
  • 209KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[Delphi]根据 高斯正态分布随机函数RandG发生的数据 绘正态分布曲线(原创)
举报原因:
原因补充:

(最多只允许输入30个字)