算法一产生12个(0,1)平均分布的随机函数,用大数定理可以模拟出正态分布。
算法二用到了数学中的雅可比变换,直接生成正态分布,但此算法在计算很大规模的数时
会出现溢出错误。
测试程序:
#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
double _random(void)
{
int a
double r
a=rand()%32767
r=(a+0.00)/32767.00
return r
}
double _sta(double mu,double sigma)
{
int i
double r,sum=0.0
if(sigma<=0.0) { printf("Sigma<=0.0 in _sta!") exit(1) }
for(i=1i<=12i++)
sum = sum + _random()
r=(sum-6.00)*sigma+mu
return r
}
double _sta2(double mu,double sigma)
{
double r1,r2
r1=_random()
r2=_random()
return sqrt(-2*log(r1))*cos(2*M_PI*r2)*sigma+mu
}
int main()
{
int i
double mu,sigma
srand( (unsigned)time( NULL ) )
mu=0.0
sigma=1.0
printf("Algorithm 1:\n")
for(i=0i<10i++)
printf("%lf\t",_sta(mu,sigma))
printf("Algorithm 2:\n")
for(i=0i<10i++)
printf("%lf\t",_sta2(mu,sigma))
return 0
}
//由均匀分布的随机数得到正态分布的随机数
#include <math.h>
float gasdev(idum)
int *idum
{
static int iset=0
static float gset
float fac,r,v1,v2
float ran1()//产生均匀分布的随机数,可利用系统函数改写
if (iset == 0) {
do {
v1=2.0*ran1(idum)-1.0
v2=2.0*ran1(idum)-1.0
r=v1*v1+v2*v2
} while (r >= 1.0)
fac=sqrt(-2.0*log(r)/r)
gset=v1*fac
iset=1
return v2*fac
} else {
iset=0
return gset
}
}
原理可找本数值算法方面的书看看。
可以采用Box_Muller的方法。
Box-Muller方法是以两组独立的随机数U和V,这两组数在(0,1]上均匀分布,用U和V生成两组独立的标准常态分布随机变量X和Y
x=sqrt((-2)*ln(U))*cos(2*pi*V)
Y=sqrt((-2)*ln(U))*sin(2*pi*V)
matlab 程序
function Norm_Distribution_Box_Mullerclear allclc%清屏
m=input('请输入平均值:')
n=input('请输入标准差:')
t=input('请输入数据长度:') %产生正态分布的随机数
for i=1:t
a=rand
b=rand
X1(i)=sqrt((-2)*log(a))*cos(2*pi*b)
X2(i)=sqrt((-2)*log(a))*sin(2*pi*b)
Y1=X1*n+m
Y2=X2*n+m
end
disp(Y1) %求平均值和标准差
M1=mean(Y1) N1=std(Y1) disp(M1) disp(N1) disp(Y1) %求平均值和标准差
M2=mean(Y2) N2=std(Y2) disp(M2) disp(N2) %将数据写入文本文件
fid=fopen('xiefei1.dat','w') Z1=Y1 fprintf(fid,'%f\t',Z1)
fclose(fid) %将数据写入文本文件
fid=fopen('xiefei2.dat','w') Z2=Y2
fprintf(fid,'%f\t',Z2) fclose(fid)
%绘图
subplot(2,1,1) histfit(Y1)
xlabel('随机数') ylabel('出现的次数')
%绘图
subplot(2,1,2)histfit(Y2)
xlabel('随机数')ylabel('出现的次数')
%检验
h1=lillietest(Y1)%若结果h1为1,则说明零假设不成立,拒绝零假设;否则,结果为0,零假设成立,即原分布为正态分布
disp(h1)
h2=lillietest(Y2)%若结果h2为1,则说明零假设不成立,拒绝零假设;否则,结果为0,零假设成立,即原分布为正态分布
disp(h2)
如何用matlab标准正态分布图?
这个问题可以通过下列方法来实现:
1、用mu=7.45来表示均值,用sigma=1来表示标准差
2、创建自定义的正态分布函数,即
func=@(x)1/(sqrt(2*pi)*sigma).*exp(-(x-mu).^2/(2*sigma))
3、确定x的变化范围,如
x=-5:0.1:20
4、计算对应于x的正态分布值,即
y=func(x)
5、使用plot函数绘制正态分布图,即
plot(x,y)
xlabel('x')ylabel('y(x)')
6、运行结果图
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)