I'm writing this program to calculate the best fit line. It's not finished. I'm doing it step to step to make sure it runs so I don't get lots of errors and totally freak out at the end. Right now it runs fine, but something is really off with the calculations I have so far. The loop for the input works great, but the averages are really wrong, and the for the sum of squares calculation it is only calculating the square of the last value. Where am I going wrong?

#include <iostream>
#include <cmath>

using namespace std;

double avg(double[], int);
double sumsq(double[], int);

int main ()
{
	int n;
	cout << "How many points do you want to plot? ";
	cin >> n;
	
	double x[n];
	double y[n];
	
	for (int i=1; i<=n; i++)
	{
		cout << "Please enter the value for x " << i << ": ";
		cin >> x[n];
		cout << "Please enter the value for y " << i << ": ";
		cin >> y[n];
	}
	
	cout << avg(x,n) << endl; 
	cout << avg(y,n) << endl;
	cout << sumsq(x,n) << endl;
	cout << sumsq(y,n) << endl;
	
	return 0;
}

double avg(double z[], int n)
{
	double sum=0;
	
	for (int i=1; i<=n; i++)
	{
		sum+=z[i];
	}
	
	return sum/n;
}

double sumsq(double z[], int n)
{ 
	double sum=0;
	double sumsq=0;
	
	for (int i=1; i<=n; i++)
	{
		sumsq=sum+(z[i]*z[i]);
	}
	
	return sumsq;
}

Dani AI

Generated

The thread shows three classic C++ mistakes that produced the wrong averages and “only the last value” behaviour: wrong indices, off-by-one bounds, and repeated recomputation instead of a single pass. correctly spotted the immediate bug (using x[n]/y[n] instead of x[i]/y[i]), and highlighted the loop that iterates only once. The final version still has unsafe indexing (i <= n) and uses double x[n] (a non-standard VLA). The safest pattern is zero-based indexing with for (size_t i = 0; i < n; ++i) and std::vector<double> for storage.

A compact, robust approach is to compute all needed sums in one pass (Σx, Σy, Σx², Σy², Σxy). That avoids repeated loops and keeps the math simple and efficient:

#include <vector>
#include <cstddef>
#include <cmath>

// aggregate sums in one pass
void aggregate(const std::vector<double>& x, const std::vector<double>& y,
               double &sumx, double &sumy, double &sumx2, double &sumy2, double &sumxy)
{
    sumx = sumy = sumx2 = sumy2 = sumxy = 0.0;
    for (std::size_t i = 0; i < x.size(); ++i) {
        double xi = x[i], yi = y[i];
        sumx  += xi;
        sumy  += yi;
        sumx2 += xi * xi;
        sumy2 += yi * yi;
        sumxy += xi * yi;
    }
}

From those aggregates, linear-regression formulas are straightforward and numerically stable when checked: slope m = (Σxy − Σx·Σy/n) / (Σx² − (Σx)²/n); intercept b = (Σy − m·Σx)/n. Correlation r uses the analogous covariance/variance expression. Always check n>1 and that the denominator is not zero (all x equal => vertical line, slope undefined). For better numerical stability on large values, center by the mean (work with xi−x̄) or use Kahan summation.

Finally, consolidate repeated code into a small helper that returns (slope, intercept, r) or a struct. That keeps main readable and prevents the repetition visible in ’s earlier versions.

Recommended Answers

All 9 Replies

array indexes start at 0 and it's always 1 less than the size shown
for example array[9] has elements 0-8

First I did 0 but then I changed it to 1 because when it asked for the x and y values the first ones were x0 and y0 and I wanted it to say x1 and y1. Then, for the sum and sumsq arrays I thought maybe it was giving me the wrong answer because it was starting in a different place, so I changed it from 0 to 1 but that didn't change anything (I changed those back to i=0 now).

I see now the problem

for (int i=1; i<=n; i++)
	{
		cout << "Please enter the value for x " << i << ": ";
		cin >> x[n];
		cout << "Please enter the value for y " << i << ": ";
		cin >> y[n];
	}

your accessing the wrong index that should be x and y

Thank you. That fixes the problem I was having with the sum, but why won't the sumsq work? It is only squaring the last value I enter.

Actually it's working the way you code it.
the last iteration will be the final value of sumsq and that will be returned

maybe you could use a loop to pass every index of the array to the function

This is my new function for sumsq, and this works:

double sumsq(double z[], int n)
{ 
	double sum=0;
	
	for (int i=0; i<=n; i++)
	{
		sum+=z[i]*z[i];
	}
	
	return sum;
}

Now my question is, I know each function works separately on it's own (they don't share values or anything). But what if I wanted to get the average of all the square values. Is there a way to add that to the same function or would I need to create a new function for that?

I decided to just make each statement it's own function (because I don't know any better way to do it). I'm stuck at this one. I want it to multiply each x and y and then add them together. Right now the code is giving me 0 as the sum.

double sumprod(double z[], double a[], int n)
{ 
	double sum=0;
	
	for (int i=0; i<=0; i++)
	{
		sum+=z[i]*a[i];
	}

	return sum;
}

for (int i=0; i<=0; i++) -- look carefully...

Thank you everyone for your help. Below is the finished code. I'm just wondering if there is a way to combine some of the functions, like the ones where I got the sum of the squares and then needed the average of that sum. Also, the part of the code where I put the equation using the functions looks really messy. There has to be a better way to do it.

#include <iostream>
#include <cmath>

using namespace std;

double avg(double[], int);
double sumsq(double[], int);
double avgsq(double[], int);
double sumprod(double [], double [], int);
double avgprod(double [], double [], int);

int main ()
{
	int n;
	cout << "How many points do you want to plot? ";
	cin >> n;
	
	double x[n];
	double y[n];
	
	for (int i=1; i<=n; i++)
	{
		cout << "Please enter the value for x " << i << ": ";
		cin >> x[i];
		cout << "Please enter the value for y " << i << ": ";
		cin >> y[i];
	}
	
	cout << "The average value of x is: " << avg(x,n) << endl; 
	cout << "The average value of y is: " << avg(y,n) << endl;
	cout << "The sum of squares of x is: " << sumsq(x,n) << endl;
	cout << "The sum of squares of y is: " << sumsq(y,n) << endl;
	cout << "The average square of x is: " << avgsq(x,n) << endl;
	cout << "The average square of y is: " << avgsq(y,n) << endl;
	cout << "The sum of product of x and y values is: " << sumprod(x,y,n) << endl;
	cout << "The average product of x and y values is: " << avgprod(x,y,n) << endl;
	
	cout << "The equation for the best fit line is: y= " << (avgprod(x,y,n)-avg(x,n)*avg(y,n))/(avgsq(x,n)-avg(x,n)*avg(x,n)) << "x+" << avg(y,n)-((avgprod(x,y,n)-avg(x,n)*avg(y,n))/(avgsq(x,n)-avg(x,n)*avg(x,n)))*avg(x,n) << endl;
	cout << "The correlation constant is: r= " << (sumprod(x,y,n)-n*avg(x,n)*avg(y,n))/sqrt((sumsq(x,n)-n*avg(x,n)*avg(x,n))*(sumsq(y,n)-n*avg(y,n)*avg(y,n))) << endl;
	
	return 0;
}

double avg(double z[], int n)
{
	double sum=0;
	
	for (int i=0; i<=n; i++)
	{
		sum+=z[i];
	}
	
	return sum/n;
}

double sumsq(double z[], int n)
{ 
	double sum=0;
	
	for (int i=0; i<=n; i++)
	{
		sum+=z[i]*z[i];
	}
	
	return sum;
}

double avgsq(double z[], int n)
{
	double sum=0;

	for (int i=0; i<=n; i++)
	{
		sum+=z[i]*z[i];
	}

	return sum/n;
}

double sumprod(double z[], double a[], int n)
{ 
	double sum=0;
	
	for (int i=0; i<=n; i++)
	{
		sum+=z[i]*a[i];
	}

	return sum;
}

double avgprod(double z[], double a[], int n)
{ 
	double sum=0;
	
	for (int i=0; i<=n; i++)
	{
		sum+=z[i]*a[i];
	}
	
	return sum/n;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.