日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > 嵌入式微處理器
[導(dǎo)讀][導(dǎo)讀] 在嵌入式產(chǎn)品開(kāi)發(fā)中,有時(shí)會(huì)需要利用一些數(shù)學(xué)統(tǒng)計(jì)的一些知識(shí),并利用代碼的方式實(shí)施在產(chǎn)品的應(yīng)用中。有人會(huì)說(shuō)均值有啥好聊的,不就是加起來(lái)除一下嘛?不妨來(lái)讀一讀。 本文目的不是數(shù)學(xué),而在于分享如何進(jìn)行工程應(yīng)用實(shí)現(xiàn)。 什么是均值? 對(duì)于離散數(shù)據(jù)集

[導(dǎo)讀] 在嵌入式產(chǎn)品開(kāi)發(fā)中,有時(shí)會(huì)需要利用一些數(shù)學(xué)統(tǒng)計(jì)的一些知識(shí),并利用代碼的方式實(shí)施在產(chǎn)品的應(yīng)用中。有人會(huì)說(shuō)均值有啥好聊的,不就是加起來(lái)除一下嘛?不妨來(lái)讀一讀。

本文目的不是數(shù)學(xué),而在于分享如何進(jìn)行工程應(yīng)用實(shí)現(xiàn)。

什么是均值?

對(duì)于離散數(shù)據(jù)集,算術(shù)平均值也稱為期望值或簡(jiǎn)稱為平均值,是離散數(shù)據(jù)集合的中心值。假設(shè)有這樣的數(shù)據(jù)序列: ,其均值由下面的式子計(jì)算:
對(duì),你說(shuō)的沒(méi)錯(cuò)就是加起來(lái)求平均。有盆友或許會(huì)問(wèn),為什么均值有的地方寫(xiě)的是 ,而這里寫(xiě)成 ,這其實(shí)是有緣由的:
  • 樣本均值(sample mean):某類隨機(jī)變量有限樣本的算術(shù)平均值。
  • 總體均值(population mean):從隨機(jī)變量概率分布的角度對(duì)隨機(jī)變量趨勢(shì)的度量,所以從這個(gè)角度而言,下面的公式正是描述了這個(gè)概念:
弄這樣兩個(gè)概念有什么必要呢?總體均值反應(yīng)的是事務(wù)的總體規(guī)律,實(shí)際研究中,往往很難得到所有的數(shù)據(jù),比如產(chǎn)品的某項(xiàng)指標(biāo)規(guī)律,如果每一個(gè)產(chǎn)品都去測(cè),代價(jià)可能極其高昂,實(shí)際往往是對(duì)產(chǎn)品進(jìn)行抽樣檢測(cè)。(公式中多寫(xiě)了個(gè)X)
大數(shù)定律指出樣本數(shù)量越大,樣本均值越接近總體均值
如此一來(lái)這就有實(shí)用意義了。
均值除了上面這種算術(shù)平均值之外,還有幾何平均值、諧波均值、功率均值、加權(quán)均值、截?cái)嗑?、函?shù)泛化均值等,有興趣的可以去了解一下。

如何計(jì)算均值?

這里主要討論對(duì)于嵌入式電子系統(tǒng)編程中,樣本均值的計(jì)算方法以及C代碼。分享直接法和遞推法計(jì)算均值,重點(diǎn)介紹遞推法。

直接法

按照公式定義,加和求平均。這個(gè)編代碼很容易:

   
float mean(float *pSample,int size)
{
    if(pSample== NULL || size<= 0)
        return NAN;
  
    float sum =  0;
    for( int i= 0;i<size;i++)
   {
     sum += *pSample;
     pSample++;
   }

    return (sum/size);
}
該方法簡(jiǎn)單直接,但是缺點(diǎn)是在內(nèi)存比較小的單片機(jī)系統(tǒng)中如需要計(jì)算大樣本集的場(chǎng)合,就捉襟見(jiàn)肘了。比如幾萬(wàn)樣本時(shí),內(nèi)存可能就不夠了!

遞推法

因?yàn)闃颖揪涤?jì)算公式如下:
那么前 個(gè)樣本的均值為:
不難得出:
從而
這樣就可以編代碼了:

   
float recursive_mean(float xn,int size)
{
   static  int index =  0;
   static  float last_mean =  0.0f;
   float mean =  0.0f;

   if(index<size -1)
  {
    index++;
    mean = last_mean+(xn-last_mean)/index;
  }
   else
  {
    mean = last_mean+(xn-last_mean)/size;
    index     =  0;
    last_mean =  0.0f;
  }

  last_mean = mean;
   return mean;
}
這個(gè)代碼很容易理解:
  • 在樣本窗未滿時(shí),按實(shí)際傳入樣本大小遞推。
  • 在樣本窗滿后,按實(shí)際傳入樣本大小遞推,并復(fù)位索引。
函數(shù)內(nèi)靜態(tài)變量不推薦使用,但這里函數(shù)使用了內(nèi)部靜態(tài)變量,為什么使用靜態(tài)變量呢?因?yàn)樗鶎?shí)現(xiàn)的需求對(duì)外部不可見(jiàn),這種需求本身的作用域就在函數(shù)本體內(nèi)部。這樣寫(xiě)個(gè)人理解會(huì)更好一些。
關(guān)于static的用法,前面寫(xiě)過(guò)兩篇文章,有興趣的可以去點(diǎn)進(jìn)去看看:
  • 實(shí)例分析如何遠(yuǎn)離漫天飛舞的全局變量

  • 由static來(lái)談?wù)勀K封裝

在嵌入式應(yīng)用中,如果所需要統(tǒng)計(jì)的樣本非常大時(shí),這種算法將非常有實(shí)用價(jià)值,只需要極小的內(nèi)存開(kāi)銷。 尤其在一些傳感器測(cè)量應(yīng)用中,該方法非常有價(jià)值。

測(cè)試一下


   
#include <stdio.h>
#include <stdbool.h>
#include <math.h>

float mean(float *pSample,int size)
{
    if(pSample== NULL || size<= 0)
        return NAN;
    float sum =  0;
    for( int i= 0;i<size;i++)
   {
     sum += *pSample;
     pSample++;
   }

    return (sum/size);
}

float recursive_mean(float xn,int size)
{
   static  int index =  0;
   static  float last_mean =  0.0f;
   float mean =  0.0f;

   if(index<size -1)
  {
    index++;
    mean = last_mean+(xn-last_mean)/index;
  }
   else
  {
    mean = last_mean+(xn-last_mean)/size;
    index     =  0;
    last_mean =  0.0f;
  }

  last_mean = mean;
   return mean;
}
#define N            (1000)
#define SAMPLE_SIZE  (100)
int main(int argc, char *argv[])
{
     float sim[N];
     float out[N/SAMPLE_SIZE];

     for( int i= 0;i<N;i++)
    {
        sim[i]=i* 5+rand()% 10;
    }
     printf( "\n\n");
     int j= 0;
     for( int i= 0;i<N;i=i+SAMPLE_SIZE)
    {
        out[j] = mean(&sim[i],SAMPLE_SIZE);
        j++;
    }

     for(j= 0;j<N/SAMPLE_SIZE;j++)
    {
         printf( "%.2f,",out[j]);
    }
     printf( "\n");
    j =  0;
     for( int i= 0;i<N;i++)
    {
        out[j]=recursive_mean(sim[i],SAMPLE_SIZE);

         if((i+ 1)%SAMPLE_SIZE== 0)
            j++;
    }
     for(j= 0;j<N/SAMPLE_SIZE;j++)
    {
         printf( "%.2f,",out[j]);
    }
     printf( "\n");
     return  0;
}
看一下結(jié)果:

   
252.14, 752.38, 1251.85, 1751.82, 2252.57, 2752.25, 3251.78, 3751.58, 4252.06, 4752.02,
252.14, 752.38, 1251.85, 1751.82, 2252.57, 2752.25, 3251.78, 3751.58, 4252.06, 4752.02,
兩種計(jì)算方法效果一樣,但是第二種方法消耗極小的內(nèi)存。當(dāng)然這增加了函數(shù)調(diào)用次數(shù),但是在大樣本計(jì)算時(shí)非常有利。

總結(jié)一下

在實(shí)際應(yīng)用中,常常需要求取測(cè)量的均值,或者依據(jù)均值做相應(yīng)的應(yīng)用,而且均值是計(jì)算信號(hào)序列或者樣本集其他數(shù)學(xué)統(tǒng)計(jì)規(guī)律的基礎(chǔ)計(jì)算,比如要計(jì)算方差、協(xié)方差等等。那么實(shí)際應(yīng)用中學(xué)會(huì)如何計(jì)算均值并進(jìn)行編碼實(shí)現(xiàn)時(shí)很必要的。尤其在一些內(nèi)存受限的場(chǎng)景,學(xué)會(huì)利用遞推規(guī)律進(jìn)行計(jì)算很有學(xué)習(xí)掌握的價(jià)值。


-END-


本文授權(quán)轉(zhuǎn)載自嵌入式客棧,作者:逸珺




推薦閱讀



【01】C語(yǔ)言內(nèi)存泄露很嚴(yán)重,如何應(yīng)對(duì)?
【02】編譯C語(yǔ)言程序,使用 gcc 指令,而C++程序則推薦使用 g++指令!
【03】C語(yǔ)言:優(yōu)雅的字符串函數(shù)庫(kù)
【04】在C 語(yǔ)言中,請(qǐng)一定記得初始化局部變量!
【05】嵌入式編程是否應(yīng)該用C++替代C語(yǔ)言


免責(zé)聲明:整理文章為傳播相關(guān)技術(shù),版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系刪除

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

嵌入式ARM

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉