Help For Simple Moving Average

i have some datas in data.txt ex:1,3,5,7,8,18,4,1,4,3,5,7...
and i need a variable, (cout<<"enter a number"; cin>>n; ex:3 -- n=3
Result[0]={1} //(1)/1
Result[1]={2} // (1+3)/2
Result[2]={3} // (1+3+5)/n
Result[3]={5} // (3+5+7)/n
Result[4]={6.6} // (5+7+8)/n
Result[5]={11} // (7+8+18)/n
Result[6]={10} // (8+18+4)/n
until my datas ends.
-----ex:3 -- n=5
Result[0]={1} //(1)/1
Result[1]={2} // (1+3)/2
Result[2]={3} // (1+3+5)/3
Result[3]={4} // (1+3+5+7)/4
Result[4]={4,8} // (1+3+5+7+8)/n
Result[5]={8,2} // (3+5+7+8+18)/n
Result[6]={18,4} // (5+7+8+18+4)/n
until my datas ends.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;


int main() {
int l;
cin>>l;//This is my divisor selection
   const int size = 15;
   double N[size] = {1,3,5,7,8,18,4,1,4,3,5,7,5,6,7};
   int l_size = l;
   double sum = 0;
   double mAvg = 0;


 
   for (int i = 0; i <= (size - l_size); i++) {

      sum = 0;                
      cout << "Numbers"<<" : ";   

      
      for (int j = i; j < i + l_size; j++) {
         sum += N[j];          
         cout << N[j] << " ";  
      }

      
      mAvg = sum / l_size;
      cout << endl << "Moving Average: " << mAvg <<endl<<endl;

   }


   return 0;
}
First, l is a horrible name for a variable. Please don't do that.
Describe what your code currently does, and how it is different from what you expect.

It appears that the way you're designing your moving average is that it has a ramp up time of n - 1 before you start shifting.
So break your code into two parts.
- First part is the ramp up section. Your first n-1 averages don't use the full n-value average, so you can just do a loop from 0 to {current iteration}
- Then, once you get to index n - 1, use the for loop like you have.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <fstream>
#include <deque>

int main()
{
    const char file_name[] = "data.txt" ;

    if( std::ifstream file{file_name} ) // if the file was opened for input
    {
        std::cout << "enter moving average window size: " ;
        std::size_t window_sz = 0 ;
        std::cin >> window_sz ;

        if( window_sz > 1 )
        {
            std::deque<int> window ; // window holding the most recent window_sz items
            // we use a deque because we want to add the new numbers at the back of the window
            // and discard the oldest number at the front of the window
            // a tad more efficient: use a circular buffer of size window_sz

            long long total = 0 ; // running total of the numbers currently in the window
            std::size_t cnt = 0 ; // a serial number (for output)
            int number ; // the number to be read from the file

            // initialise the window (read in the first window_sz numbers)
            while( window.size() < window_sz && file >> number ) window.push_back(number) ;

            // process the first window
            for( std::size_t i = 0 ; i < window.size() ; ++i )
            {
                // compute and print the moving average
                total += window[i] ;
                std::cout << cnt++ << ". " << total << " / " << i+1 << " == " << total / double(i+1) << '\n' ;
            }

            // process the remaining items
            while( file >> number ) // for each subsequent number read in
            {
                 // throw the oldest value away and take in the newest number
                total -= window.front() ;
                total += number ;
                window.pop_front() ;
                window.push_back(number) ;

                std::cout << cnt++ << ". " << total << " / " << window_sz << " == " << total / double(window_sz) << '\n' ;
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
   double A[] = { 1, 3, 5, 7, 8, 18, 4, 1, 4, 3, 5, 7, 5, 6, 7 };
   int N = sizeof A / sizeof A[0];
   int window;
   cout << "Input averaging window: ";   cin >> window;

   double sum = 0;
   for ( int i = 0; i < N; i++ )
   {
      sum += A[i];
      if ( i >= window ) sum -= A[i-window];
      cout << i << ": " << sum / min( i + 1, window ) << '\n'; 
   }
}


Input averaging window: 3
0: 1
1: 2
2: 3
3: 5
4: 6.66667
5: 11
6: 10
7: 7.66667
8: 3
9: 2.66667
10: 4
11: 5
12: 5.66667
13: 6
14: 6
Last edited on
Here's another variant.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <algorithm>
#include <valarray>
using namespace std;

int main()
{
   valarray<double> A = { 1, 3, 5, 7, 8, 18, 4, 1, 4, 3, 5, 7, 5, 6, 7 };
   int window;
   cout << "Input averaging window: ";   cin >> window;

   valarray<double> sum = A;
   for ( int i = 1; i < window; i++ ) sum += A.shift( -i );
   for ( int i = 0; i < A.size(); i++ ) cout << i << ": " << sum[i] / min( i + 1, window ) << '\n';
}
Last edited on
Thank u for your advice :). But i cant execute your code ?

9 [Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11
9 [Error] in C++98 'file' must be initialized by constructor, not by '{...}'
So use the suggested option with the compiler to compile as C++11 code. It's telling you what to do.
Thank you @lastchance that was exactly what I was looking for... How do I read from data.txt file ??
How do I read from data.txt file


Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>

int main()
{
	std::ifstream ifs("averages.txt");

	if (!ifs.is_open())
		return (std::cout << "Cannot open file\n"), 1;

	std::vector<double> A;

	for (double v {}; ifs >> v; A.push_back(v));

	int window {};

	std::cout << "Input averaging window: ";
	std::cin >> window;

	double sum {};

	for (int i = 0; i < A.size(); ++i) {
		sum += A[i];

		if (i >= window)
			sum -= A[i - window];

		std::cout << i << ": " << sum / std::min(i + 1, window) << '\n';
	}
}

Thank you so much, but What purpose was there in using a vector? //vector<double> A;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

vector<double> readData( string filename )
{
   vector<double> result;
   ifstream in( filename );
   for ( double value; in >> value; ) result.push_back( value );
   return result;
}

vector<double> movingAverages( const vector<double> &A, int window )
{
   vector<double> result( A.size(), 0.0 );
   double sum = 0;
   for ( int i = 0; i < A.size(); i++ )
   {
      sum += A[i];
      if ( i >= window ) sum -= A[i-window];
      result[i] = sum / min( i + 1, window );
   }
   return result;
}

int main()
{
   int window;
   cout << "Input averaging window: ";   cin >> window;

   vector<double> A = readData( "data.txt" );
   vector<double> av = movingAverages( A, window );
   for ( int i = 0; i < av.size(); i++ ) cout << i << ": " << av[i] << '\n';
}

data.txt is
1  3  5  7  8  18  4  1  4  3  5  7  5  6  7


Use a vector when you don't know a priori how much data there is.
okey I just got it, like int N = sizeof A / sizeof A[0];...
Thank you very much for your help. Your being so helpful made me very happy.
Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>

int main()
{
	std::ifstream ifs("averages.txt");
	std::ofstream myfile("out.txt");

	if (!ifs.is_open() || !myfile.is_open())
		return (std::cout << "Cannot open file\n"), 1;

	std::vector<double> A;

	for (double v {}; ifs >> v; A.push_back(v));

	int window {};

	std::cout << "Input averaging window: ";
	std::cin >> window;

	double sum {};

	for (int i = 0; i < A.size(); ++i) {
		sum += A[i];

		if (i >= window)
			sum -= A[i - window];

		//std::cout << i << ": " << sum / std::min(i + 1, window) << '\n';
		myfile << sum / std::min(i + 1, window) << '\n';
	}
}

Topic archived. No new replies allowed.