我必须创建一个类似的函数,但我需要它来处理一堆近乎垂直的斜坡。我从 Cassio Neri 的代码开始,然后对其进行了修改,以在围绕线 x=y 镜像每个点后重新计算看起来比 1 更陡的斜率(这可以通过切换 x 和 y 值轻松完成)。然后它会将其镜像回来并返回更准确的斜率。
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
double slope(const std::vector<double>& x, const std::vector<double>& y) {
const double n = x.size();
const double s_x = std::accumulate(x.begin(), x.end(), 0.0);
const double s_y = std::accumulate(y.begin(), y.end(), 0.0);
const double s_xx = std::inner_product(x.begin(), x.end(), x.begin(), 0.0);
const double s_xy = std::inner_product(x.begin(), x.end(), y.begin(), 0.0);
const double numer = n * s_xy - s_x * s_y; // The same regardless of inversion (both terms here are commutative)
const double denom = n * s_xx - s_x * s_x; // Will change if inverted; use this for now
double a;
if (denom == 0) a = 2; // If slope is vertical, force variable inversion calculation
else a = numer / denom;
if (std::abs(a) > 1) { // Redo with variable inversion if slope is steeper than 1
const double s_yy = std::inner_product(y.begin(), y.end(), y.begin(), 0.0);
const double new_denom = n * s_yy - s_y * s_y;
a = new_denom / numer; // Invert the fraction because we've mirrored it around x=y
}
return a;
}
int main() {
std::vector<double> x{6, 5, 11, 7, 5, 4, 4};
std::vector<double> y{2, 3, 9, 1, 8, 7, 5};
std::cout << slope(x, y) << '\n';
}