int main(int argc, const char * argv[]) {
    // the integral of 1/sqrt(1-x^2) is arcsin(x)
    double exact = asin(0.99) - asin(0);
    double a = 0.0;
    double b = 0.99;
    std::vector<double> nodes;
    nodes.push_back(101);
    nodes.push_back(201);
    nodes.push_back(1001);
    nodes.push_back(2001);
    
    CompTrapRule ctp(&f, &fDoublePrime, a, b, nodes);
    std::vector<double> results = ctp.getResult();
    std::vector<double> hSteps = ctp.getHStep();
    std::vector<double> errorBounds = ctp.getErrorBound();
    
    std::cout << "Exact Value: " << exact << std::endl;
    for(unsigned i = 0; i < results.size(); i++){
        std::cout << "Composite Trapezoidal Rule approximation: " << std::setprecision(9)
            << results[i] << " with h step of " << hSteps[i] << ", an absolute erorr of "
            << absoluteError(exact, results[i]) << ", and error bound of "
            << errorBounds[i] << '.' << std::endl;
    }
    
    std::vector<double> extrp = extrapolation(results);
    for(unsigned i = 0; i < extrp.size(); i++){
        std::cout << "Richardson's Extrapolation approximation: " << std::setprecision(9)
        << extrp[i] << " with an absolute error of " << absoluteError(exact, extrp[i]) << std::endl;
    }
    return 0;
}
int main(){
    int i, N;
    char c, file[100];
    
    // check that gnuplot is present on the system
    int gnupl = control();
    if(gnupl == 1){
        printf("\nYou need gnuplot to graph the results.");
        printf("\nInstall it with: sudo apt-get install gnuplot\n\n");
        exit(2);
    }
    
    printf("Enter the name or path of file: ");
    fgets(file,sizeof(file),stdin);
    file[strlen(file)-1] = '\0';
    
    // the file's lines number is the number of points to be saved
    N = linesFile(file);
    if(N <= 2){
        printf("\nError: insufficient data number.\n");
        exit(2);
    }
    
    // creating data's arrays
    double *x = calloc(N,sizeof(double));
    double *y = calloc(N,sizeof(double));
    double *errors = calloc(N,sizeof(double));
    if(x == NULL || y == NULL || errors == NULL){
            perror("\nerror");
            printf("\n");
            exit(1);
    }
    
    // reading from file
    FILE *inputFile = fopen(file,"r");
    if(inputFile == NULL){
        perror("\nError");
        exit(1);
    }
    
    for(i=0; i<N; i++){
        fscanf(inputFile,"%lf %lf %lf\n",&x[i],&y[i],&errors[i]);
    }
    
    fclose(inputFile);
    
    // determine linear coefficients
    double M = Mbest(N,x,y,errors);
    double Q = Qbest(N,x,y,errors,M);
    double sigmaM = fabs(uM(N,x,y,errors,M,Q));
    double sigmaQ = fabs(uQ(N,x,errors,sigmaM));
    
    // defining best sigma(Y) and correlation coefficient
    double sigmaY = fabs(bestSigma(N,x,y,M,Q)); // <-- residuals analysis
    double cov = covariance(N,x,y);
    double cor = correlation(N,x,y);
    double lCov = linearParamCovariance(N,mean(x,N),sigma(x,N,mean(x,N)),sigmaY,M,Q);
    double lCor = linearParamCorrelation(N,x);
    
    // Chi-square test
    int freedomDegrees = N - 2; // infer 2 parameters (): M and Q
    double chi2 = 0, rChi2;
    
    for(i=0; i<N; i++){
        chi2 += pow(y[i] - ((M * x[i]) + Q),2) / pow(errors[i],2);
    }
    
    rChi2 = chi2 / freedomDegrees;
    
    printf("\nThe best linear fit Y = mX + q is:");
    printf("\nm = %.3lf\tsigma(m) = %.3lf\nq = %.3lf\tsigma(q) = %.3lf",M,sigmaM,Q,sigmaQ);
    printf("\n\nBest sigma(Y) = %.3lf",sigmaY);
    printf("\nCov(X,Y) = %.3lf",cov);
    printf("\nCor(X,Y) = %.3lf",cor);
    printf("\nCov(m,c) = %.3lf",lCov);
    printf("\nCor(m,c) = %.3lf",lCor);
    //printf("\nChi square = %.3lf",chi2);
    printf("\nReduced Chi square = %.3lf",rChi2);
    
    // interpolation and extrapolation
    int choice;
    double pointX, pointY, sigmaPointY, alpha;
    printf("\n\nDo you want to extrapolate a point with the calculated linear regression? (1 = YES | 0 = NO): ");
    scanf("%d",&choice);
    if(choice == 1){
        extrapolation(N,x,errors,sigmaY,M,Q);
    }
    
    // creating fit
    printf("\nPlotting fit...\n");
    FILE *data = fopen("data.dat","w");
    if(data == NULL){
        perror("\nError");
        exit(1);
    }
    
    // writing experimental datas
    for(i=0; i<N; i++){
        fprintf(data,"%lf %lf %lf\n",x[i],y[i],errors[i]);
    }
    
    fclose(data);
    
    // creating fit points
    //fit(M,Q,x,N); // gnuplot feature
    
    free(x);
    free(y);
       
    return 0;
}