ipa: raspberrypi: Compute inverse of piecewise linear function
Add a method to the piecewise linear function (Pwl) class to compute the inverse of a given Pwl. If the input function is non-monotonic we can only produce a best effort "pseudo" inverse, and we signal this to the caller. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
dbcf4d8247
commit
1a6a7d4a8e
2 changed files with 33 additions and 0 deletions
|
@ -114,6 +114,36 @@ Pwl::PerpType Pwl::Invert(Point const &xy, Point &perp, int &span,
|
||||||
return PerpType::None;
|
return PerpType::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pwl Pwl::Inverse(bool *true_inverse, const double eps) const
|
||||||
|
{
|
||||||
|
bool appended = false, prepended = false, neither = false;
|
||||||
|
Pwl inverse;
|
||||||
|
|
||||||
|
for (Point const &p : points_) {
|
||||||
|
if (inverse.Empty())
|
||||||
|
inverse.Append(p.y, p.x, eps);
|
||||||
|
else if (std::abs(inverse.points_.back().x - p.y) <= eps ||
|
||||||
|
std::abs(inverse.points_.front().x - p.y) <= eps)
|
||||||
|
/* do nothing */;
|
||||||
|
else if (p.y > inverse.points_.back().x) {
|
||||||
|
inverse.Append(p.y, p.x, eps);
|
||||||
|
appended = true;
|
||||||
|
} else if (p.y < inverse.points_.front().x) {
|
||||||
|
inverse.Prepend(p.y, p.x, eps);
|
||||||
|
prepended = true;
|
||||||
|
} else
|
||||||
|
neither = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is not a proper inverse if we found ourselves putting points
|
||||||
|
// onto both ends of the inverse, or if there were points that couldn't
|
||||||
|
// go on either.
|
||||||
|
if (true_inverse)
|
||||||
|
*true_inverse = !(neither || (appended && prepended));
|
||||||
|
|
||||||
|
return inverse;
|
||||||
|
}
|
||||||
|
|
||||||
Pwl Pwl::Compose(Pwl const &other, const double eps) const
|
Pwl Pwl::Compose(Pwl const &other, const double eps) const
|
||||||
{
|
{
|
||||||
double this_x = points_[0].x, this_y = points_[0].y;
|
double this_x = points_[0].x, this_y = points_[0].y;
|
||||||
|
|
|
@ -80,6 +80,9 @@ public:
|
||||||
};
|
};
|
||||||
PerpType Invert(Point const &xy, Point &perp, int &span,
|
PerpType Invert(Point const &xy, Point &perp, int &span,
|
||||||
const double eps = 1e-6) const;
|
const double eps = 1e-6) const;
|
||||||
|
// Compute the inverse function. Indicate if it is a proper (true)
|
||||||
|
// inverse, or only a best effort (e.g. input was non-monotonic).
|
||||||
|
Pwl Inverse(bool *true_inverse = nullptr, const double eps = 1e-6) const;
|
||||||
// Compose two Pwls together, doing "this" first and "other" after.
|
// Compose two Pwls together, doing "this" first and "other" after.
|
||||||
Pwl Compose(Pwl const &other, const double eps = 1e-6) const;
|
Pwl Compose(Pwl const &other, const double eps = 1e-6) const;
|
||||||
// Apply function to (x,y) values at every control point.
|
// Apply function to (x,y) values at every control point.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue