GD32的随机数生成(可服从任意分布函数)正态、柯...

[复制链接]
5221|0
手机看帖
扫描二维码
随时随地手机跟帖
zeshoufx|  楼主 | 2021-8-23 18:41 | 显示全部楼层 |阅读模式
#申请原创#@21小跑堂
一、实际项目中,经常需要产生一些符合某某分布的随机数,如(服从均匀分布的随机数、服从柯西分布的随机数等);


二、GD32F450本身自带的真随机数发生器是通过连续模拟噪声生成一个 32 位的随机数值,但无法确定服从什么分布;另一方面不带真随机数发生器的单片机也有很多。


三、通过ADC采集随机噪声作为随机数同自带的真随机数发生器一样,无法确定噪声服从是满分布;综上所述,需要产生服从某某分布的随机数需要从算法进行解决。关键对带不带真随机数发生器的单片机都可以适用

四、服从均匀分布随机数
338446123738fba074.png
//均匀分布
double uniform(double a,double b,long int * seed)
{
        double t;
        * seed=2045*(*seed)+1;
        * seed=*seed-(*seed/1048576)*1048576;
        t=(*seed)/1048576.0;
        t=a+(b-a)*t;
        return t;
}
93705612373daaeeb3.png

五、服从高斯分布(正态分布)的随机数
724306123744c02f90.png
//高斯(正态)分布
double guass(double mean,double sigma,long int *seed)
{
        int i;
        double x,y;

        for (x=0,i=0;i<12;i++)
        {
                x+=uniform(0.0,1.0,seed);
        }
        x-=6.0;
        y=mean+x*sigma;
        return y;
}
163986123746832c13.png

六、服从指数分布的随机数生成
94906612374d7496cd.png
//指数分布
double exponent(double beta,long int *seed)
{
        double u,x;
        u=uniform(0.0,1.0,seed);
        x=-beta*log(u);
        return x;
}
8452612374f3002cb.png


七、服从拉普拉斯分布的随机数
6801761237547cb3ea.png
//拉普拉斯分布
double laplace(double beta,long int *seed)
{
        double u1,u2,x;

        u1=uniform(0.0,1.0,seed);
        u2=uniform(0.0,1.0,seed);

        if(u1<0.5)
        {
                x=-beta*log(1.0-u2);
        }
        else
        {
                x=beta*log(u2);
        }
        return x;
}
26327612375666a541.png

八、服从瑞利分布的随机数生成

43834612375b649b89.png
//瑞利分布
double rayleigh(double sigma,long int *seed)
{
        double u,x;
        u=uniform(0.0,1.0,seed);
        x=-2.0*log(u);
        x=sigma*sqrt(x);

        return x;
}
36659612375d305012.png

九、服从对数正态分布的随机数生成
51036123761cac3e8.png
//对数-正态分布
double logform(double u,double sigma,long int *seed)
{
        double x,y;
        y=guass(u,sigma,seed);

        x=exp(y);
        return x;
}
656416123762d99f7a.png

十、服从柯西分布的随机数生成
464506123767957236.png
//柯西分布
double cauchy(double a,double b,long int *seed)
{
        double u,x;
        u=uniform(0.0,1.0,seed);
        x=a-b/tan(3.1492653*u);

        return x;
}
87031612376884eec7.png

十一、服从韦伯分布的随机数生成
10882612376ca800da.png
//韦伯分布
double weibull(double a,double b,long int *seed)
{
        double u,x;

        u=uniform(0.0,1.0,seed);
        u=-log(u);
        x=b*pow(u,1.0/a);

        return x;
}
46462612376de476e2.png

十二、服从埃尔朗分布的随机数生成
684836123771db4a94.png
//埃尔朗分布
double erlang(int m,double beta,long int *seed)
{
        int i;
        double u,x;

        for(u=1.0,i=1;i<m;i++)
        {
                u*=uniform(0.0,1.0,seed);
        }
        x=-beta*log(u);

        return x;

}
320956123772e61053.png

十三、服从伯努利分布的随机数生成
6740612377770c65f.png
//伯努利分布
int bn(double p,long int *seed)
{
        int x;
        double u;
        u=uniform(0.0,1.0,seed);

        x=(u<p)?1:0;
        return x;
}
121316123778af0532.png

十四、服从伯努利-高斯分布的随机数生成
3572612377d11206c.png
//伯努利-高斯分布
double bn_gauss(double p,double mean,double sigma,long int *seed)
{
        double u,x;
        u=uniform(0.0,1.0,seed);

        if(u<p)
        {
                x=guass(mean,sigma,seed);
        }
        else
        {
                x=0.0;
        }
        return x;
}
5507612377e527afd.png

十五、服从二项式分布的随机数生成
72968612378416baa4.png
//二项式分布
int bin_(int n,double p,long int *seed)
{
        int i;
        int x;
        for(x=0,i=0;i<n;i++)
        {
                x+=bn(p,seed);
        }

        return x;
}
52669612378513c23b.png

十六、服从泊松分布的随机数生成
5252961237890a16bc.png
//泊松分布
int poisson(double lamuda,long int *seed)
{
        int i=0,x;
        double a,b=1.0,u;

        a=exp(-lamuda);
        do
        {
                u=uniform(0.0,1.0,seed);
                b*=u;
                i++;
        }while(b>=a);
        x=i-1;

        return x;
}
351706123789e242c5.png

十七、测试平台:GD32F450ZiT6


十八、测试主函数
/*!
    \file    main.c
    \brief   design by 张恩寿
   
    \version 2021-08-15, V1.0.0, SDK for keria
   
*/

/*
    昆明电器科学研究所.

*/

#include "usart.h"
#include "systick.h"
#include "led.h"
#include "key.h"
#include "eeprom.h"
#include "rng.h"


u16 mem_size[2]={0};
u32 uid[3]={0};

static void rng_uniform_test(void)
{
        double a,b,x;
        int i,j;
        long int s;
        a=0.0;
        b=1.0;
        s=13579;
        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=uniform(a,b,&s);
                        printf("%13.7f",x);
                }
                printf("\r\n");
        }
}

static void rng_guass_test(void)
{
        int i,j;
        long int s=13579;
        double mean=0.0;
        double sigma=1.0;
        double x;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=guass(mean,sigma,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_exponent_test(void)
{
        int i,j;
        long int s=13579;
        double x;
        double beta=2.0;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=exponent(beta,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_laplace_test(void)
{
        int i,j;
        long int s=13579;
        double x,beta=1.5;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=laplace(beta,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_rayleigh_test(void)
{
        int i,j;
        long int s=13579;
        double x,sigma=1.0;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=rayleigh(sigma,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_logform_test(void)
{
        int i,j;
        long int s=13579;
        double x,u=0.0,sigma=0.5;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=logform(u,sigma,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}


static void rng_cauchy_test(void)
{
        int i,j;
        long int s=13579;
        double x,a=1.0,b=1.0;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=cauchy(a,b,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_weibull_test(void)
{
        int i,j;
        long int s=13579;
        double x,a=2.0,b=1.0;
        for(i=0;i<10;i++)
        {
                for (j=0;j<5;j++)
                {
                        x=weibull(a,b,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_erlang_test(void)
{
        int i,j,m=3;
        double x,beta=1.0;
        long int s=13579;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=erlang(m,beta,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_bn_test(void)
{
        int i,j,x;
        long int s=13579;
        double p=0.7;
        for (i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=bn(p,&s);
                        printf("%11d",x);
                }
                printf("\r\n");
        }
}

static void rng_bn_gauss_test(void)
{
        int i,j;
        long int s=13579;
        double x,p=0.4,mean=0.0,sigma=1;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=bn_gauss(p,mean,sigma,&s);
                        printf("%13.7lf",x);
                }
                printf("\r\n");
        }
}

static void rng_bin__test(void)
{
        int i,j,n=5,x;
        long int s=13579;
        double p=0.7;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=bin_(n,p,&s);
                        printf("%11d",x);
                }
                printf("\r\n");
        }
}

static void rng_poisson_test(void)
{
        int i,j,x;
        long int s=13579;
        double n=4.0;

        for(i=0;i<10;i++)
        {
                for(j=0;j<5;j++)
                {
                        x=poisson(n,&s);
                        printf("%11d",x);
                }
                printf("\r\n");
        }
}

int main(void)
{
        nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
        systick_set(200);
   
        eeprom_io_set();
       
        usart_config(115200);
        mem_size[0]=mem_size_get(mem_flash);
        mem_size[1]=mem_size_get(mem_sram);
        get_cpu_uid(uid);
       
        led_set();
        key_set();
       
       
        printf("welcome to use platform of GD32F450\r\n");
        printf("cpu flash size:%d,sram size:%d\r\n",mem_size[0],mem_size[1]);
        printf("cpu uid code:0X%X%X%X\r\n",uid[0],uid[1],uid[2]);
       
       
        eeprom_write_byte(0,241);
        eeprom_wait_standby_state();
        printf("%d\r\n",eeprom_read_byte(0));
       
        eeprom_write_u16(1,565);
        printf("%d\r\n",eeprom_read_u16(1));
       
        eeprom_write_int(3,-3000);
        printf("%d\r\n",eeprom_read_int(3));
       
        eeprom_write_u32(7,3000);
        printf("%d\r\n",eeprom_read_u32(7));
       
        eeprom_write_float(11,5.214);
        printf("%f\r\n",eeprom_read_float(11));
       
        printf("\r\n");
        printf("服从均匀分布随机数测试:\r\n");
        rng_uniform_test();
       
        printf("\r\n");
        printf("服从正态分布随机数测试:\r\n");
        rng_guass_test();
       
        printf("\r\n");
        printf("服从指数分布随机数测试:\r\n");
        rng_exponent_test();
       
        printf("\r\n");
        printf("服从拉普拉斯分布随机数测试:\r\n");
        rng_laplace_test();
       
        printf("\r\n");
        printf("服从瑞利分布随机数测试:\r\n");
        rng_rayleigh_test();
       
        printf("\r\n");
        printf("服从对数-正态分布随机数测试:\r\n");
        rng_logform_test();
       
        printf("\r\n");
        printf("服从柯西分布随机数测试:\r\n");
        rng_cauchy_test();
       
        printf("\r\n");
        printf("服从韦伯分布随机数测试:\r\n");
        rng_weibull_test();
       
        printf("\r\n");
        printf("服从埃尔朗分布随机数测试:\r\n");
        rng_erlang_test();
       
        printf("\r\n");
        printf("服从伯努利分布随机数测试:\r\n");
        rng_bn_test();
       
        printf("\r\n");
        printf("服从伯努利-高斯分布随机数测试:\r\n");
        rng_bn_gauss_test();
       
        printf("\r\n");
        printf("服从二项式分布随机数测试:\r\n");
        rng_bin__test();
       
        printf("\r\n");
        printf("服从泊松分布随机数测试:\r\n");
        rng_poisson_test();
       
       
    while (1)
        {
               
                led=!led;
                delay_ms(1000);
    }
}


十九、工程文件

测试平台

测试平台

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

66

主题

1945

帖子

14

粉丝