[英]calculate moving average of an static array in c
我編寫了這段代碼來計算 c 中數組的移動平均值。
Array_MovingAverage(const int inputSeries[],
size_t inputSize,
size_t window,
float output[],
size_t outputSize) {
if (inputSeries && output != NULL){
for(size_t i = 0; i < window ; i++)
if (window < inputSize)
if (inputSeries != NULL && output != NULL) {
if(outputSize >= inputSize) {
size_t inputSize[11] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const uint8_t window = 5;
{
const int inputSeries[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2,1};
double window = 5;
double c = 2.0;
double d = 2.0;
for(int i = 0; i < window; i++)
{
c += inputSeries[i];
d = c / window;
}
return true;
}
}
}
}
}
我一直在嘗試計算 C 中數組的移動平均值並獲得所需的 output 但它似乎不起作用。 您能否給我一個建議,如何計算 C 中 static 數組的移動平均值?
Output 應該是:
Moving Average: 1 2 2 3 6 8 9 2 1 2 1
0 0 0 0 3 4 6 6 5 4 3
讓我們從頭開始。 您嘗試修改此代碼只會使您非常不清楚您要做什么,並且原始代碼在任何情況下似乎都有缺陷。 處理代碼的問題可能是徒勞的。
首先,對於移動平均值 N,您保留最后 N 個值的總和,對於每個新樣本,您:
采用您的接口,但省略了冗余的outputSize
- output 與輸入的大小相同),實現可能如下所示:
void Array_MovingAverage( const int* inputSeries,
size_t inputSize,
size_t window,
float* output )
{
int sum = 0 ;
if( inputSeries != NULL && output != 0 )
{
for( size_t i = 0; i < inputSize; i++ )
{
// Add newest sample
sum += inputSeries[i] ;
// Subtract oldest sample
if( i >= window )
{
sum -= inputSeries[i - window] ;
}
output[i] = (float)sum / window ;
}
}
}
要使用它,您可能有:
int main()
{
const int input[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const size_t size = sizeof(input) / sizeof(*input) ;
float output[size] ;
Array_MovingAverage( input, size, 5, output ) ;
for( size_t i = 0; i < size; i++ )
{
printf( "%.2f\n", output[i]) ;
}
return 0;
}
對於您的樣本數據{1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1}
,output 是:
{0.20, 0.60, 1.00, 1.60, 2.80, 4.20, 5.60, 5.60, 5.20, 4.40, 3.00}
現在您的問題尚不清楚,但形成其他評論似乎您希望破解此 function 以忽略調用者提供的輸入,因為您無法修改調用者。 坦率地說,這很奇怪,但這是一種“安全”的方式。 讓我們假設outputSize
將被恢復,因為顯然您需要它來避免調用者 output 緩沖區溢出。 最簡單的解決方案是將 function 的整個主體包裹起來,這是一個附加的 shell 大括號 {...} 允許您創建覆蓋輸入參數的陰影變量,而不會觸及代碼的 Z65E8800B5C6800AAD896F8AFCZ2:
void Array_MovingAverage( const int* inputSeries,
size_t inputSize,
size_t window,
float* output,
size_t outputSize )
{
// Prevent unused warnings
(void)inputSeries ;
(void)inputSize ;
(void)window ;
// Create block to allow variables to be "shadowed"
{
// Override inputs
// NASTY HACK
const size_t inputSize = 11 ;
const int inputSeries[11] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const size_t window = 5 ;
int sum = 0 ;
if( inputSeries != NULL && output != 0 )
{
for( size_t i = 0; i < inputSize; i++ )
{
// Add newest sample
sum += inputSeries[i] ;
// Subtract oldest sample
if( i >= window )
{
sum -= inputSeries[i - window] ;
}
// Only write to caller output if index in bounds
if( i < outputSize )
{
output[i] = (float)sum / window ;
}
}
}
}
}
當然,您可以簡單地更改變量名稱並忽略輸入參數,但如果在任何復雜的現有工作代碼中執行此操作,上述 hack 可能不太容易出錯(不重命名變量)。 也就是說,這樣的解決方案可能如下所示:
void Array_MovingAverage( const int* inputSeries,
size_t inputSize,
size_t window,
float* output,
size_t outputSize )
{
// Prevent unused warnings
(void)inputSeries ;
(void)inputSize ;
(void)window ;
// Local "input" data
const int input[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const size_t size = sizeof(input) / sizeof(*input) ;
const size_t width = 5 ;
int sum = 0 ;
if( input != NULL && output != 0 )
{
for( size_t i = 0; i < size; i++ )
{
// Add newest sample
sum += input[i] ;
// Subtract oldest sample
if( i >= window )
{
sum -= input[i - width] ;
}
// Only write to caller output if index in bounds
if( i < outputSize )
{
output[i] = (float)sum / window ;
}
}
}
}
您的代碼中有很多問題:
Array_MovingAverage(const int inputSeries[], size_t inputSize, size_t window, float output[],
size_t outputSize) {
if (inputSeries && output != NULL){
for(size_t i = 0; i < window ; i++)
if (window < inputSize)
if (inputSeries != NULL && output != NULL) { << This is same as if statemend 3 lines above
if(outputSize >= inputSize) {
size_t inputSize[11] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1}; //<< this hides parameter. And has totally different type.
const uint8_t window = 5; // Also hiding parameter
{
const int inputSeries[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2,1}; // again hiding
double window = 5; // more hiding of variables and parameters
double c = 2.0; // Where does this value come from?
double d = 2.0;
for(int i = 0; i < window; i++) // Same loop variable as outer loop.
{
c += inputSeries[i];
d = c / window;
}
return true; // You return after first iteration of outer loop.
// No printf so far
// No value assigned to output[] so far.
// The only result is return value true.
}
}
}
}
}
您使用不同的類型將window
隱藏了兩次。 除非那是一些混淆競賽,否則這是不可以的。 其他參數也隱藏在不同類型的變量中。
外循環完全沒有效果,因為它永遠不會達到第二次迭代。
一次又一次地檢查循環內的參數(如果它被多次執行)是浪費 CPU 時間。
讓我們重新排序您的代碼並刪除一些奇怪的東西(代碼未經測試,任何發現拼寫錯誤的人都可以保留它們。;))
void Array_MovingAverage(const int inputSeries[], size_t inputSize, size_t window, float output[],
size_t outputSize) {
if ( window < inputSize
&& inputSeries != NULL && output != NULL
&& outputSize >= inputSize ) {
double c = 0.0;
double avg;
int i;
// first fill partial window at begin
for (int i = 0; i < window; i++)
{
c += inputSeries[i];
avg = c / (i+1);
output[i] = avg;
}
// Then handle full windows until we reach the end
// c now contains sum of entries 0..window-1
// i points to entry 'window'
for ( ; i < inputSize; i++)
{
// Move the window by adding 1 new element and remove 1 old element
c += inputSeries[i];
c -= inputSeries[i-window]
avg = c / window;
output[i] = avg;
}
}
}
int main(void)
{
int input[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2,1};
size_t Size = sizeof(input)/(input[0]);
float output[Size] = {0};
Array_MovingAverage(intput, Size, 5, output, Size);
printf("Moving avarage:\n");
for (int i = 0; i < Size; i++)
{
printf("%d ", input[i]);
}
for (int i = 0; i < Size; i++)
{
printf("%f ", (int)(output[i]+0.5));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.