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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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,
|
||||
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.
|
||||
Pwl Compose(Pwl const &other, const double eps = 1e-6) const;
|
||||
// Apply function to (x,y) values at every control point.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue