Search code examples
c++cumulative-summontecarlo

Cumulative sum with array in C++


#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <sstream>
using namespace std;
  
int iData, tData;

void randgen(int max, int min){
  srand((unsigned) time(0));
}

int main()
{
  cout << "Masukkan jumlah data: ";
  cin >> iData;
  int jData[iData], randNum[iData], fProb[iData];
  double probkei[iData], tKumul[iData],tepiA[iData], tepiB[iData];
  int tData;


  for(int i=1; i<=iData; i++){
    cout << "Masukkan data ke-" << i << ": ";
    cin >> jData[i];
    tData += jData[i];            //jumlahkan seluruh data untuk mencari probabilitas tiap variabel
  }system("cls");

  probkei[0]=0;

  cout << setw(10) << "Data ke" << setw(10) << "Frekuensi" << setw(15) << "Probabilitas" << setw(20) << "Kumulatif" << setw(10) << "Interval" << endl;
  for(int i=0; i<iData; i++){
    probkei[i] = (double) jData[i]/tData;         //typecast integer to double for the probability
    if(jData[i]==jData[1]){
      tKumul[i] = probkei[i];
    }else if(i<i+i){
      tKumul[i] = probkei[i] + probkei[i+1];       //for cumulative sum 1 way
    }
    probkei[i] = round(probkei[i] * 1000.0) / 1000.0; //rounding the probability
    tKumul[i] = round(tKumul[i] * 1000.0) / 1000.0;
    cout << setw(10) << i+1 << setw(10) << jData[i] << setw(15) << probkei[i] << setw(20);
    int temp;
    cout<<"data "<<probkei[i]+probkei[i+1];        //for cumulative sum 2 way
    
    
    cout << setw(10) << tKumul[i] << endl;
    /*if (i == iData || jData[i] != jData[i - 1])
        {
            temp += count;
            cout << "Cumulative frequency of " << jData[i - 1] << " in the array is: " << temp << endl;
            count = 1;

        }else{
          count++;
        }*/
  }
  cout << setw(20) << "Total data: " << tData << endl;
 return 0;    
}

I want to count cumulative frequency from my array data. First is entering the value/total of the number of data in the array. Next is entering the value for each data one by one and then counting all probabilities of each data(the possibilities are declared in double). And then counting the cumulative which is sum the n data with the n+1 data. And the last is making the top and bottom edges for each data to be used as a random number interval. I've done my best and finding the solution but I still confused why it's doesn't work. I was trying to count it in 2 ways but all of them do nothing. This is a Monte Carlo Simulation.

example Table


Solution

  • This:

    int iData;
    cin >> iData;
    int jData[iData];
    

    is using variable-length arrays, which are not standard C++. Rather use std::vector instead:

    int iData;
    cin >> iData;
    std::vector<int> jData(iData);
    

    The tData local variable is uninitialized:

    int tData;
    ...
    tData += jData[i];
    

    It should be initialized to 0.


    The condition i<i+i doesn't make sense.

    There is something weird going on with the indexes. The input is loaded from index 1 but the second loop starts from 0. This loading from 1 is also not accounted in size of the arrays, so the last element will overflow the array.

    There is something wrong with this too:

    tKumul[i] = probkei[i] + probkei[i+1];
    

    If this is supposed to be cumulative sum then tKumul should appear on the right side too.


    If we load data from 0, then the second loop should look like this:

    for (int i = 0; i < iData; i++) {
        probkei[i] = (double) jData[i] / tData;
        if (i == 0) {
            tKumul[i] = probkei[i];
        } else {
            tKumul[i] = probkei[i] + tKumul[i-1];
        }
    

    With this code (see godbolt) the output is:

       Data ke Frekuensi   Probabilitas           Kumulatif
             1         5          0.067               0.067
             2        10          0.133                 0.2
             3        15            0.2                 0.4
             4        20          0.267               0.667
             5        25          0.333                   1
            Total data: 75
    

    In addition I would suggest using fixed and setprecision(3) instead of manual rounding:

    cout << fixed << setprecision(3);
    

    and using algorithms instead of loops. Calculating probabilities can be replaced by std::transform and calculating cumulative sum can be replaced by std::partial_sum:

    std::transform(
            jData.begin(), jData.end(),
            probkei.begin(),
            [tData](auto elem) { return (double) elem / tData; }
    );
    std::partial_sum(probkei.begin(), probkei.end(), tKumul.begin());
    

    With this code (see godbolt) the output is:

       Data ke Frekuensi   Probabilitas           Kumulatif
             1         5          0.067               0.067
             2        10          0.133               0.200
             3        15          0.200               0.400
             4        20          0.267               0.667
             5        25          0.333               1.000
            Total data: 75