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

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


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


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

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

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

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

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


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

  5.         u1=uniform(0.0,1.0,seed);
  6.         u2=uniform(0.0,1.0,seed);

  7.         if(u1<0.5)
  8.         {
  9.                 x=-beta*log(1.0-u2);
  10.         }
  11.         else
  12.         {
  13.                 x=beta*log(u2);
  14.         }
  15.         return x;
  16. }
26327612375666a541.png

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

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

  8.         return x;
  9. }
36659612375d305012.png

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

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

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

  7.         return x;
  8. }
87031612376884eec7.png

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

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

  8.         return x;
  9. }
46462612376de476e2.png

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

  6.         for(u=1.0,i=1;i<m;i++)
  7.         {
  8.                 u*=uniform(0.0,1.0,seed);
  9.         }
  10.         x=-beta*log(u);

  11.         return x;

  12. }
320956123772e61053.png

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

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

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

  6.         if(u<p)
  7.         {
  8.                 x=guass(mean,sigma,seed);
  9.         }
  10.         else
  11.         {
  12.                 x=0.0;
  13.         }
  14.         return x;
  15. }
5507612377e527afd.png

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

  10.         return x;
  11. }
52669612378513c23b.png

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

  6.         a=exp(-lamuda);
  7.         do
  8.         {
  9.                 u=uniform(0.0,1.0,seed);
  10.                 b*=u;
  11.                 i++;
  12.         }while(b>=a);
  13.         x=i-1;

  14.         return x;
  15. }
351706123789e242c5.png

十七、测试平台:GD32F450ZiT6


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

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

  10. */

  11. #include "usart.h"
  12. #include "systick.h"
  13. #include "led.h"
  14. #include "key.h"
  15. #include "eeprom.h"
  16. #include "rng.h"


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

  19. static void rng_uniform_test(void)
  20. {
  21.         double a,b,x;
  22.         int i,j;
  23.         long int s;
  24.         a=0.0;
  25.         b=1.0;
  26.         s=13579;
  27.         for(i=0;i<10;i++)
  28.         {
  29.                 for(j=0;j<5;j++)
  30.                 {
  31.                         x=uniform(a,b,&s);
  32.                         printf("%13.7f",x);
  33.                 }
  34.                 printf("\r\n");
  35.         }
  36. }

  37. static void rng_guass_test(void)
  38. {
  39.         int i,j;
  40.         long int s=13579;
  41.         double mean=0.0;
  42.         double sigma=1.0;
  43.         double x;

  44.         for(i=0;i<10;i++)
  45.         {
  46.                 for(j=0;j<5;j++)
  47.                 {
  48.                         x=guass(mean,sigma,&s);
  49.                         printf("%13.7lf",x);
  50.                 }
  51.                 printf("\r\n");
  52.         }
  53. }

  54. static void rng_exponent_test(void)
  55. {
  56.         int i,j;
  57.         long int s=13579;
  58.         double x;
  59.         double beta=2.0;

  60.         for(i=0;i<10;i++)
  61.         {
  62.                 for(j=0;j<5;j++)
  63.                 {
  64.                         x=exponent(beta,&s);
  65.                         printf("%13.7lf",x);
  66.                 }
  67.                 printf("\r\n");
  68.         }
  69. }

  70. static void rng_laplace_test(void)
  71. {
  72.         int i,j;
  73.         long int s=13579;
  74.         double x,beta=1.5;

  75.         for(i=0;i<10;i++)
  76.         {
  77.                 for(j=0;j<5;j++)
  78.                 {
  79.                         x=laplace(beta,&s);
  80.                         printf("%13.7lf",x);
  81.                 }
  82.                 printf("\r\n");
  83.         }
  84. }

  85. static void rng_rayleigh_test(void)
  86. {
  87.         int i,j;
  88.         long int s=13579;
  89.         double x,sigma=1.0;

  90.         for(i=0;i<10;i++)
  91.         {
  92.                 for(j=0;j<5;j++)
  93.                 {
  94.                         x=rayleigh(sigma,&s);
  95.                         printf("%13.7lf",x);
  96.                 }
  97.                 printf("\r\n");
  98.         }
  99. }

  100. static void rng_logform_test(void)
  101. {
  102.         int i,j;
  103.         long int s=13579;
  104.         double x,u=0.0,sigma=0.5;

  105.         for(i=0;i<10;i++)
  106.         {
  107.                 for(j=0;j<5;j++)
  108.                 {
  109.                         x=logform(u,sigma,&s);
  110.                         printf("%13.7lf",x);
  111.                 }
  112.                 printf("\r\n");
  113.         }
  114. }


  115. static void rng_cauchy_test(void)
  116. {
  117.         int i,j;
  118.         long int s=13579;
  119.         double x,a=1.0,b=1.0;

  120.         for(i=0;i<10;i++)
  121.         {
  122.                 for(j=0;j<5;j++)
  123.                 {
  124.                         x=cauchy(a,b,&s);
  125.                         printf("%13.7lf",x);
  126.                 }
  127.                 printf("\r\n");
  128.         }
  129. }

  130. static void rng_weibull_test(void)
  131. {
  132.         int i,j;
  133.         long int s=13579;
  134.         double x,a=2.0,b=1.0;
  135.         for(i=0;i<10;i++)
  136.         {
  137.                 for (j=0;j<5;j++)
  138.                 {
  139.                         x=weibull(a,b,&s);
  140.                         printf("%13.7lf",x);
  141.                 }
  142.                 printf("\r\n");
  143.         }
  144. }

  145. static void rng_erlang_test(void)
  146. {
  147.         int i,j,m=3;
  148.         double x,beta=1.0;
  149.         long int s=13579;

  150.         for(i=0;i<10;i++)
  151.         {
  152.                 for(j=0;j<5;j++)
  153.                 {
  154.                         x=erlang(m,beta,&s);
  155.                         printf("%13.7lf",x);
  156.                 }
  157.                 printf("\r\n");
  158.         }
  159. }

  160. static void rng_bn_test(void)
  161. {
  162.         int i,j,x;
  163.         long int s=13579;
  164.         double p=0.7;
  165.         for (i=0;i<10;i++)
  166.         {
  167.                 for(j=0;j<5;j++)
  168.                 {
  169.                         x=bn(p,&s);
  170.                         printf("%11d",x);
  171.                 }
  172.                 printf("\r\n");
  173.         }
  174. }

  175. static void rng_bn_gauss_test(void)
  176. {
  177.         int i,j;
  178.         long int s=13579;
  179.         double x,p=0.4,mean=0.0,sigma=1;

  180.         for(i=0;i<10;i++)
  181.         {
  182.                 for(j=0;j<5;j++)
  183.                 {
  184.                         x=bn_gauss(p,mean,sigma,&s);
  185.                         printf("%13.7lf",x);
  186.                 }
  187.                 printf("\r\n");
  188.         }
  189. }

  190. static void rng_bin__test(void)
  191. {
  192.         int i,j,n=5,x;
  193.         long int s=13579;
  194.         double p=0.7;

  195.         for(i=0;i<10;i++)
  196.         {
  197.                 for(j=0;j<5;j++)
  198.                 {
  199.                         x=bin_(n,p,&s);
  200.                         printf("%11d",x);
  201.                 }
  202.                 printf("\r\n");
  203.         }
  204. }

  205. static void rng_poisson_test(void)
  206. {
  207.         int i,j,x;
  208.         long int s=13579;
  209.         double n=4.0;

  210.         for(i=0;i<10;i++)
  211.         {
  212.                 for(j=0;j<5;j++)
  213.                 {
  214.                         x=poisson(n,&s);
  215.                         printf("%11d",x);
  216.                 }
  217.                 printf("\r\n");
  218.         }
  219. }

  220. int main(void)
  221. {
  222.         nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
  223.         systick_set(200);
  224.    
  225.         eeprom_io_set();
  226.        
  227.         usart_config(115200);
  228.         mem_size[0]=mem_size_get(mem_flash);
  229.         mem_size[1]=mem_size_get(mem_sram);
  230.         get_cpu_uid(uid);
  231.        
  232.         led_set();
  233.         key_set();
  234.        
  235.        
  236.         printf("welcome to use platform of GD32F450\r\n");
  237.         printf("cpu flash size:%d,sram size:%d\r\n",mem_size[0],mem_size[1]);
  238.         printf("cpu uid code:0X%X%X%X\r\n",uid[0],uid[1],uid[2]);
  239.        
  240.        
  241.         eeprom_write_byte(0,241);
  242.         eeprom_wait_standby_state();
  243.         printf("%d\r\n",eeprom_read_byte(0));
  244.        
  245.         eeprom_write_u16(1,565);
  246.         printf("%d\r\n",eeprom_read_u16(1));
  247.        
  248.         eeprom_write_int(3,-3000);
  249.         printf("%d\r\n",eeprom_read_int(3));
  250.        
  251.         eeprom_write_u32(7,3000);
  252.         printf("%d\r\n",eeprom_read_u32(7));
  253.        
  254.         eeprom_write_float(11,5.214);
  255.         printf("%f\r\n",eeprom_read_float(11));
  256.        
  257.         printf("\r\n");
  258.         printf("服从均匀分布随机数测试:\r\n");
  259.         rng_uniform_test();
  260.        
  261.         printf("\r\n");
  262.         printf("服从正态分布随机数测试:\r\n");
  263.         rng_guass_test();
  264.        
  265.         printf("\r\n");
  266.         printf("服从指数分布随机数测试:\r\n");
  267.         rng_exponent_test();
  268.        
  269.         printf("\r\n");
  270.         printf("服从拉普拉斯分布随机数测试:\r\n");
  271.         rng_laplace_test();
  272.        
  273.         printf("\r\n");
  274.         printf("服从瑞利分布随机数测试:\r\n");
  275.         rng_rayleigh_test();
  276.        
  277.         printf("\r\n");
  278.         printf("服从对数-正态分布随机数测试:\r\n");
  279.         rng_logform_test();
  280.        
  281.         printf("\r\n");
  282.         printf("服从柯西分布随机数测试:\r\n");
  283.         rng_cauchy_test();
  284.        
  285.         printf("\r\n");
  286.         printf("服从韦伯分布随机数测试:\r\n");
  287.         rng_weibull_test();
  288.        
  289.         printf("\r\n");
  290.         printf("服从埃尔朗分布随机数测试:\r\n");
  291.         rng_erlang_test();
  292.        
  293.         printf("\r\n");
  294.         printf("服从伯努利分布随机数测试:\r\n");
  295.         rng_bn_test();
  296.        
  297.         printf("\r\n");
  298.         printf("服从伯努利-高斯分布随机数测试:\r\n");
  299.         rng_bn_gauss_test();
  300.        
  301.         printf("\r\n");
  302.         printf("服从二项式分布随机数测试:\r\n");
  303.         rng_bin__test();
  304.        
  305.         printf("\r\n");
  306.         printf("服从泊松分布随机数测试:\r\n");
  307.         rng_poisson_test();
  308.        
  309.        
  310.     while (1)
  311.         {
  312.                
  313.                 led=!led;
  314.                 delay_ms(1000);
  315.     }
  316. }


十九、工程文件

测试平台

测试平台
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

1991

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部