#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include “doctest.h”
#include
#include
#include
#include
struct Result
{
double A;
double B;
};
class Regression
{
struct Point
{
double x;
double y;
bool operator==(Point const& other) const noexcept
{
return x == other.x && y == other.y;
}
};
std::vector points{};
public:
void add(double x, double y)
{
Point const p{x, y};
points.push_back(p);
}
void add(Point const p)
{
points.push_back(p);
}
int N = points.size();
double sum_x(std::vector points)
{
double sum = 0;
for (Point n : points){
sum = sum + n.x;
}
return sum;
}
double sum_y(std::vector points)
{
double sum = 0;
for (Point n : points){
sum = sum + n.y;
}
return sum;
}
double sum_xy(std::vector points)
{
double sum = 0;
for (Point n : points){
sum = sum + (n.x * n.y);
}
return sum;
}
double sum_x2(std::vector points)
{
double sum = 0;
for (Point n : points){
sum = sum + (n.x * n.x);
}
return sum;
}
double sum_x_ = sum_x(points);
double sum_y_ = sum_y(points);
double sum_xy_ = sum_xy(points);
double sum_x2_ = sum_x2(points);
Result fit() const
{
double const d = (N * sum_x2_ - sum_x_ * sum_x_);
//assert(N >= 2); // un po' brutale
if (N < 2) {
throw std::runtime_error{"not enough points"};
}
if (d == 0.) {
throw std::runtime_error{"vertical line"};
}
double const a = (sum_y_ * sum_x2_ - sum_x_ * sum_xy_) / d;
double const b = (N * sum_xy_ - sum_x_ * sum_y_) / d;
return {a, b};
}
int size()
{
return points.size();
}
bool empty() const noexcept
{
return N == 0;
}
bool remove(double x, double y) noexcept
{
Point const p{x,y};
auto const it = std::find(points.begin(), points.end(), p);
if (it != points.end()) {
points.erase(it);
return true;
} else {
return false;
}
}
};
auto fit(Regression const& reg)
{
// the following call would fail compilation if the fit method weren’t const
return reg.fit();
}
TEST_CASE(“testing Regression”)
{
Regression reg;
REQUIRE(reg.size() == 0);
SUBCASE(“fitting on two points”)
{
reg.add(0., 0.);
reg.add(1., 1.);
auto result = reg.fit();
CHECK(result.A == doctest::Approx(0));
CHECK(result.B == doctest::Approx(1));
}
SUBCASE(“fitting on two points, negative slope”)
{
reg.add(0., 1.);
reg.add(1., 0.);
auto result = reg.fit();
CHECK(result.A == doctest::Approx(1));
CHECK(result.B == doctest::Approx(-1));
}
SUBCASE(“fitting on two points aligned vertically throws”)
{
reg.add(1., 0.);
reg.add(1., 2.);
CHECK_THROWS(reg.fit());
}
SUBCASE(“fitting on five points”)
{
reg.add(2.1, 3.2);
reg.add(6.9, 7.3);
reg.add(2.2, 3.0);
reg.add(0.1, 1.3);
reg.add(4.7, 5.6);
auto result = reg.fit();
CHECK(result.A == doctest::Approx(1.2).epsilon(0.01));
CHECK(result.B == doctest::Approx(0.9).epsilon(0.01));
}
SUBCASE(“a case from a student, using free function”)
{
reg.add(1, 1);
reg.add(3, 5);
reg.add(3.7, 10.2);
reg.add(4.2, 11.8);
auto result = fit(reg);
CHECK(result.A == doctest::Approx(-3.04).epsilon(0.01));
CHECK(result.B == doctest::Approx(3.37).epsilon(0.01));
}
}
I can’t make this code work, and I don’t understand the error. Can someone help? Thank you very much