?? stats.cpp
字號(hào):
//======================================================================================//
// filename: Stats.cpp //
// //
// author: Pedro V. Sander //
// ATI Research, Inc. //
// 3D Application Research Group //
// email: psander@ati.com //
// //
// Description: Simple statistics/histogram fuctions //
// //
//======================================================================================//
// (C) 2003 ATI Research, Inc. All rights reserved. //
//======================================================================================//
#define STRICT
#include <math.h>
#include <stdio.h>
#include "D3DFont.h"
#include "Stats.h"
#define BIGFLOAT 2E+30f
#define NUMBINS 100
#define INIDATASIZE 360
//needed to draw histogram
void RenderQuad(LPDIRECT3DDEVICE9 pd3dDevice, float x0, float y0, float x1, float y1, D3DCOLOR c);
//-----------------------------------------------------------------------------
// Name: CStats()
// Desc: Constructor; takes and and whether to keep the values in an array
//-----------------------------------------------------------------------------
CStats::CStats(char *strName, bool bKeepData)
{
if(strName != NULL)
{
strcpy(m_strName, strName);
}
else
{
*m_strName = 0;
}
m_pfData = NULL;
m_piBin = new int[NUMBINS];
Reset(bKeepData);
}
//-----------------------------------------------------------------------------
// Name: ~CStats()
// Desc: Destructor
//-----------------------------------------------------------------------------
CStats::~CStats()
{
if(m_pfData != NULL)
{
delete [] m_pfData;
}
delete [] m_piBin;
}
//-----------------------------------------------------------------------------
// Name: Reset()
// Desc: Reset all values to start gathering stats
//-----------------------------------------------------------------------------
void CStats::Reset(bool bKeepData)
{
m_iNum=0;
m_iZeroes=0;
m_fSum=0.f;
m_fSumSq=0.f;
m_fMin=BIGFLOAT;
m_fMax=-BIGFLOAT;
m_iStdevNum = 0;
m_fStdev = 0.f;
m_iMaxNum = INIDATASIZE;
//if keeping data, initialize value array
if(bKeepData)
{
m_bDataAvailable = true;
if(m_pfData == NULL)
m_pfData = new float[INIDATASIZE];
}
else
{
m_bDataAvailable = false;
if(m_pfData != NULL)
{
delete [] m_pfData;
m_pfData = NULL;
}
}
//set all bins to contain zero values
memset(m_piBin, 0, sizeof(int)*NUMBINS);
}
//-----------------------------------------------------------------------------
// Name: Add()
// Desc: Add new value
//-----------------------------------------------------------------------------
void CStats::Add(float f)
{
//update stats variables
m_fSum += f;
m_fSumSq += f*f;
m_fMin = min(m_fMin, f);
m_fMax = max(m_fMax, f);
//reallocate data array if necessary
if(m_bDataAvailable)
{
if(m_iNum == m_iMaxNum)
{
float *pfNewData = new float[m_iMaxNum*2];
memcpy(pfNewData, m_pfData, sizeof(float) * m_iMaxNum);
delete [] m_pfData;
m_pfData = pfNewData;
m_iMaxNum *= 2;
}
m_pfData[m_iNum] = f;
}
//increment zero count, or add to bins for histogram
//NOTE: This is only a histogram on non-zero values
if(f == 0.f)
{
m_iZeroes++;
}
else if(f >= 0.f && f <= 1.f)
{
m_piBin[(int)(f*(float)(NUMBINS-1))]++;
}
m_iNum++;
}
//-----------------------------------------------------------------------------
// Name: GetAvg()
// Desc: Gets the average value
//-----------------------------------------------------------------------------
float CStats::GetAvg()
{
if(m_iNum == 0)
{
return 0.f;
}
else
{
return m_fSum/(float)m_iNum;
}
}
//-----------------------------------------------------------------------------
// Name: GetMax()
// Desc: Gets the max value
//-----------------------------------------------------------------------------
float CStats::GetMax()
{
return m_fMax;
}
//-----------------------------------------------------------------------------
// Name: GetMax()
// Desc: Gets the min value
//-----------------------------------------------------------------------------
float CStats::GetMin()
{
return m_fMin;
}
//-----------------------------------------------------------------------------
// Name: GetRms()
// Desc: Gets the root-mean-square value
//-----------------------------------------------------------------------------
float CStats::GetRms()
{
if(m_iNum == 0)
{
return 0.f;
}
else
{
return (float)sqrt(m_fSumSq/(float)m_iNum);
}
}
//-----------------------------------------------------------------------------
// Name: GetNum()
// Desc: Gets the total number of values
//-----------------------------------------------------------------------------
int CStats::GetNum()
{
return m_iNum;
}
//-----------------------------------------------------------------------------
// Name: GetStdev()
// Desc: Gets the standard deviation
//-----------------------------------------------------------------------------
float CStats::GetStdev()
{
if(m_iNum < 2)
{
return 0.f;
}
if(m_iNum != m_iStdevNum)
{
if(!m_bDataAvailable)
{
return 0.f;
}
float m_fAvg = GetAvg();
m_fStdev = 0.f;
for(int i = 0; i < m_iNum; i++)
{
m_fStdev += (float)pow(m_pfData[i] - m_fAvg, 2.);
}
m_fStdev /= (float)(m_iNum - 1);
m_fStdev = (float)sqrt(m_fStdev);
m_iStdevNum = m_iNum;
}
return m_fStdev;
}
//simple func to convert color to DWORD
static inline DWORD DWORDCOLOR(float r, float g, float b)
{
return (DWORD)(
(255<<24)
+ (((int)(r*255.f))<<16)
+ (((int)(g*255.f))<<8)
+ ((int)(b*255.f))
);
}
//-----------------------------------------------------------------------------
// Name: RenderHistogram()
// Desc: Renders a histogram, give its position and dimensions
//-----------------------------------------------------------------------------
void CStats::RenderHistogram(LPDIRECT3DDEVICE9 pd3dDevice, CD3DFont *font, float x, float y, float w, float h, int sw, int sh)
{
int i;
//render background
RenderQuad(pd3dDevice, x, y, x+w, y+h, 0xFF00FFFF);
x++; y++; w-=2; h-=2;
RenderQuad(pd3dDevice, x, y, x+w, y+h, 0xFF600000);
//render bins as quads
for(i = 0; i < NUMBINS; i++)
{
RenderQuad(pd3dDevice,
x+(((i+1)/(float)(NUMBINS+2)) * w)-1,
y,
x+(((i+2)/(float)(NUMBINS+2)) * w)+1,
y+((m_piBin[i]/(float)(m_iNum-m_iZeroes)) * (h-1))+1,
0xFFFFFFFF);
}
for(i = 0; i < NUMBINS; i++)
{
RenderQuad(pd3dDevice,
x+(((i+1)/(float)(NUMBINS+2)) * w),
y,
x+(((i+2)/(float)(NUMBINS+2)) * w),
y+((m_piBin[i]/(float)(m_iNum-m_iZeroes)) * (h-1)),
DWORDCOLOR(1.f,(100-i)/100.f,0.f));
}
//render stats text
float yText = 20.f;
float ySpacing = 15.f;
char tmp[128];
font->DrawText(x+20.f+sw/2.f, sh/2.f-y-h+yText, D3DCOLOR_ARGB(255,255,255,0), m_strName);
yText += ySpacing;
sprintf(tmp, "Zeroes: %.3f%% (%i/%i)\n", 100.f*m_iZeroes/(float)m_iNum, m_iZeroes, m_iNum);
font->DrawText(x+20.f+sw/2.f, sh/2.f-y-h+yText, D3DCOLOR_ARGB(255,255,255,0), tmp);
yText += ySpacing;
sprintf(tmp, "Avg: %.6f", GetAvg());
font->DrawText(x+20.f+sw/2.f, sh/2.f-y-h+yText, D3DCOLOR_ARGB(255,255,255,0), tmp);
yText += ySpacing;
sprintf(tmp, "Rms: %.6f", GetRms());
font->DrawText(x+20.f+sw/2.f, sh/2.f-y-h+yText, D3DCOLOR_ARGB(255,255,255,0), tmp);
yText += ySpacing;
sprintf(tmp, "Min: %.6f", m_fMin);
font->DrawText(x+20.f+sw/2.f, sh/2.f-y-h+yText, D3DCOLOR_ARGB(255,255,255,0), tmp);
yText += ySpacing;
sprintf(tmp, "Max: %.6f", m_fMax);
font->DrawText(x+20.f+sw/2.f, sh/2.f-y-h+yText, D3DCOLOR_ARGB(255,255,255,0), tmp);
yText += ySpacing;
if(m_iNum > 1 && m_bDataAvailable)
{
sprintf(tmp, "Std: %.6f", GetStdev());
font->DrawText(x+20.f+sw/2.f, sh/2.f-y-h+yText, D3DCOLOR_ARGB(255,255,255,0), tmp);
yText += ySpacing;
}
}
//-----------------------------------------------------------------------------
// Name: OutputInfo()
// Desc: Write stats to text file
//-----------------------------------------------------------------------------
void CStats::OutputInfo(FILE *fp)
{
fprintf(fp, "-------------------------------\n");
fprintf(fp, "%s\n", m_strName);
fprintf(fp, "Zeroes: %.3f%% (%i/%i)\n", 100.f*m_iZeroes/(float)m_iNum, m_iZeroes, m_iNum);
fprintf(fp, "Avg: %.6f\n", GetAvg());
fprintf(fp, "Rms: %.6f\n", GetRms());
fprintf(fp, "Min: %.6f\n", m_fMin);
fprintf(fp, "Max: %.6f\n", m_fMax);
if(m_iNum > 1 && m_bDataAvailable)
{
fprintf(fp, "Std: %.6f\n", GetStdev());
}
fprintf(fp, "-------------------------------\n\n");
}
//-----------------------------------------------------------------------------
// Name: Load()
// Desc: Load from binary stats file
//-----------------------------------------------------------------------------
void CStats::Load(FILE *fp)
{
fread(&m_iNum, sizeof(int), 1, fp);
fread(&m_iMaxNum, sizeof(int), 1, fp);
fread(&m_iZeroes, sizeof(int), 1, fp);
fread(&m_fSum, sizeof(float), 1, fp);
fread(&m_fSumSq, sizeof(float), 1, fp);
fread(&m_fMin, sizeof(float), 1, fp);
fread(&m_fMax, sizeof(float), 1, fp);
fread(m_piBin, sizeof(int), NUMBINS, fp);
fread(&m_iStdevNum, sizeof(int), 1, fp);
fread(&m_fStdev, sizeof(float), 1, fp);
fread(m_strName, sizeof(char), 64, fp);
m_bDataAvailable = false;
if(m_pfData != NULL)
{
delete [] m_pfData;
m_pfData = NULL;
}
}
//-----------------------------------------------------------------------------
// Name: Save()
// Desc: Save to binary stats file
//-----------------------------------------------------------------------------
void CStats::Save(FILE *fp)
{
fwrite(&m_iNum, sizeof(int), 1, fp);
fwrite(&m_iMaxNum, sizeof(int), 1, fp);
fwrite(&m_iZeroes, sizeof(int), 1, fp);
fwrite(&m_fSum, sizeof(float), 1, fp);
fwrite(&m_fSumSq, sizeof(float), 1, fp);
fwrite(&m_fMin, sizeof(float), 1, fp);
fwrite(&m_fMax, sizeof(float), 1, fp);
fwrite(m_piBin, sizeof(int), NUMBINS, fp);
fwrite(&m_iStdevNum, sizeof(int), 1, fp);
fwrite(&m_fStdev, sizeof(float), 1, fp);
fwrite(m_strName, sizeof(char), 64, fp);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -