Browse Source

add quintic polynomial class

neozhaoliang 4 years ago
parent
commit
a0edcee6f5

+ 13 - 22
src/decition/decition_brain/decition/adc_math/quartic_polynomail.cpp

@@ -7,8 +7,7 @@ namespace math {
 
 
 QuarticPolynomial::QuarticPolynomial(const double x0, const double dx0, const double ddx0,
 QuarticPolynomial::QuarticPolynomial(const double x0, const double dx0, const double ddx0,
                                      const double dx1, const double ddx1,
                                      const double dx1, const double ddx1,
-                                     const double t
-                                     )
+                                     const double t)
 {
 {
     t_ = t;
     t_ = t;
     start_condition_[0] = x0;
     start_condition_[0] = x0;
@@ -19,21 +18,15 @@ QuarticPolynomial::QuarticPolynomial(const double x0, const double dx0, const do
     computeCoefficients(x0, dx0, ddx0, dx1, ddx1, t);
     computeCoefficients(x0, dx0, ddx0, dx1, ddx1, t);
 }
 }
 
 
-QuarticPolynomial::QuarticPolynomial(
-    const std::array<double, 3> &start,
-    const std::array<double, 2> &end,
-    const double t)
-    : QuarticPolynomial::QuarticPolynomial(
-        start[0], start[1], start[2],
-        end[0], end[1], t) {}
+QuarticPolynomial::QuarticPolynomial(const std::array<double, 3> &start,
+                                     const std::array<double, 2> &end,
+                                     const double t)
+    : QuarticPolynomial::QuarticPolynomial(start[0], start[1], start[2],
+                                           end[0], end[1], t) {}
 
 
-void QuarticPolynomial::computeCoefficients(const double x0,
-                                            const double dx0,
-                                            const double ddx0,
-                                            const double dx1,
-                                            const double ddx1,
-                                            const double t
-                                            )
+void QuarticPolynomial::computeCoefficients(const double x0, const double dx0, const double ddx0,
+                                            const double dx1, const double ddx1,
+                                            const double t)
 {
 {
     coef_[0] = x0;
     coef_[0] = x0;
     coef_[1] = dx0;
     coef_[1] = dx0;
@@ -53,11 +46,9 @@ double QuarticPolynomial::evaluate(const std::uint32_t order, const double p) co
     switch (order)
     switch (order)
     {
     {
     case 0:
     case 0:
-        return (((coef_[4] * p + coef_[3]) * p + coef_[2]) * p + coef_[1]) * p +
-               coef_[0];
+        return (((coef_[4] * p + coef_[3]) * p + coef_[2]) * p + coef_[1]) * p + coef_[0];
     case 1:
     case 1:
-        return ((4.0 * coef_[4] * p + 3.0 * coef_[3]) * p + 2.0 * coef_[2]) * p +
-               coef_[1];
+        return ((4.0 * coef_[4] * p + 3.0 * coef_[3]) * p + 2.0 * coef_[2]) * p + coef_[1];
     case 2:
     case 2:
         return (12.0 * coef_[4] * p + 6.0 * coef_[3]) * p + 2.0 * coef_[2];
         return (12.0 * coef_[4] * p + 6.0 * coef_[3]) * p + 2.0 * coef_[2];
     case 3:
     case 3:
@@ -69,7 +60,7 @@ double QuarticPolynomial::evaluate(const std::uint32_t order, const double p) co
     }
     }
 }
 }
 
 
-double QuarticPolynomial::coef(const std::int32_t order) const
+double QuarticPolynomial::coef(const size_t order) const
 {
 {
     return coef_[order];
     return coef_[order];
 }
 }
@@ -81,7 +72,7 @@ const std::array<double, 5> &QuarticPolynomial::coef() const
 
 
 std::string QuarticPolynomial::toString() const
 std::string QuarticPolynomial::toString() const
 {
 {
-    return absl::StrCat("QuarticPolynomial(", absl::StrJoin(coef_, ", "), t_, ")\n");
+    return absl::StrCat("QuarticPolynomial(", absl::StrJoin(coef_, ", "), ")");
 }
 }
 }
 }
 }
 }

+ 10 - 5
src/decition/decition_brain/decition/adc_math/quartic_polynomial.h

@@ -42,8 +42,7 @@ public:
     */
     */
     QuarticPolynomial(const double x0, const double dx0, const double ddx0,
     QuarticPolynomial(const double x0, const double dx0, const double ddx0,
                       const double dx1, const double ddx1,
                       const double dx1, const double ddx1,
-                      const double t
-                      );
+                      const double t);
 
 
     /**
     /**
     * @brief You can also pack the boundary conditions into two arrays.
     * @brief You can also pack the boundary conditions into two arrays.
@@ -62,7 +61,7 @@ public:
     /**
     /**
     * @brief Return the coefficient of the k-th term.
     * @brief Return the coefficient of the k-th term.
     */
     */
-    double coef(const std::int32_t order) const;
+    double coef(const size_t order) const;
 
 
     /**
     /**
     * @brief Return all coefficients as a std::array.
     * @brief Return all coefficients as a std::array.
@@ -74,6 +73,13 @@ public:
     */
     */
     std::string toString() const;
     std::string toString() const;
 
 
+    size_t order() const { return 4; }
+
+    /**
+    * @brief Return the length of the fitting interval [0, t]
+    */
+    double paramLength() const { return t_; }
+
 private:
 private:
 
 
     /**
     /**
@@ -81,8 +87,7 @@ private:
     */
     */
     void computeCoefficients(const double x0, const double dx0, const double ddx0,
     void computeCoefficients(const double x0, const double dx0, const double ddx0,
                              const double dx1, const double ddx1,
                              const double dx1, const double ddx1,
-                             const double t
-                             );
+                             const double t);
 
 
     double t_;
     double t_;
     std::array<double, 3> start_condition_;
     std::array<double, 3> start_condition_;

+ 98 - 0
src/decition/decition_brain/decition/adc_math/quintic_polynomial.cpp

@@ -0,0 +1,98 @@
+#include "quintic_polynomial.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+
+namespace iv {
+namespace math {
+
+QuinticPolynomial::QuinticPolynomial(const double x0, const double dx0, const double ddx0,
+                                     const double x1, const double dx1, const double ddx1,
+                                     const double t)
+{
+    t_ = t;
+    start_condition_[0] = x0;
+    start_condition_[1] = dx0;
+    start_condition_[2] = ddx0;
+    end_condition_[0] = x1;
+    end_condition_[1] = dx1;
+    end_condition_[2] = ddx1;
+    computeCoefficients(x0, dx0, ddx0, x1, dx1, ddx1, t);
+}
+
+QuinticPolynomial::QuinticPolynomial(const std::array<double, 3> &start,
+                                     const std::array<double, 3> &end,
+                                     const double t)
+    : QuinticPolynomial::QuinticPolynomial(start[0], start[1], start[2],
+                                           end[0], end[1], end[2], t) {}
+
+double QuinticPolynomial::evaluate(std::uint32_t order, const double p) const
+{
+    switch (order)
+    {
+    case 0:
+        return ((((coef_[5] * p + coef_[4]) * p + coef_[3]) * p + coef_[2]) * p + coef_[1]) * p + coef_[0];
+    case 1:
+        return (((5.0 * coef_[5] * p + 4.0 * coef_[4]) * p + 3.0 * coef_[3]) * p + 2.0 * coef_[2]) * p + coef_[1];
+    case 2:
+        return (((20.0 * coef_[5] * p + 12.0 * coef_[4]) * p) + 6.0 * coef_[3]) * p + 2.0 * coef_[2];
+    case 3:
+        return (60.0 * coef_[5] * p + 24.0 * coef_[4]) * p + 6.0 * coef_[3];
+    case 4:
+        return 120.0 * coef_[5] * p + 24.0 * coef_[4];
+    case 5:
+        return 120.0 * coef_[5];
+    default:
+        return 0.0;
+    }
+}
+
+void QuinticPolynomial::fitByBoundaryConditions(const double x0, const double dx0, const double ddx0,
+                                                const double x1, const double dx1, const double ddx1,
+                                                const double t)
+{
+    t_ = t;
+    start_condition_[0] = x0;
+    start_condition_[1] = dx0;
+    start_condition_[2] = ddx0;
+    end_condition_[0] = x1;
+    end_condition_[1] = dx1;
+    end_condition_[2] = ddx1;
+    computeCoefficients(x0, dx0, ddx0, x1, dx1, ddx1, t);
+}
+
+double QuinticPolynomial::coef(const size_t order) const
+{
+    return coef_[order];
+}
+
+const std::array<double, 6> &QuinticPolynomial::coef() const
+{
+    return coef_;
+}
+
+void QuinticPolynomial::computeCoefficients(const double x0, const double dx0, const double ddx0,
+                                            const double x1, const double dx1, const double ddx1,
+                                            const double t)
+{
+    coef_[0] = x0;
+    coef_[1] = dx0;
+    coef_[2] = 0.5 * ddx0;
+
+    double t2 = t * t;
+    double t3 = t * t2;
+
+    double c0 = (x1 - 0.5 * t2 * ddx0 - dx0 * t - x0) / t3;
+    double c1 = (dx1 - ddx0 * t - dx0) / t2;
+    double c2 = (ddx1 - ddx0) / t;
+
+    coef_[3] = 0.5 * (20.0 * c0 - 8.0 * c1 + c2);
+    coef_[4] = (-15.0 * c0 + 7.0 * c1 - c2) / t;
+    coef_[5] = (6.0 * c0 - 3.0 * c1 + 0.5 * c2) / t2;
+}
+
+std::string QuinticPolynomial::toString() const
+{
+    return absl::StrCat("QuinticPolynomial(", absl::StrJoin(coef_, ", "), ")");
+}
+}
+}

+ 93 - 0
src/decition/decition_brain/decition/adc_math/quintic_polynomial.h

@@ -0,0 +1,93 @@
+/****************************************
+ * Class:    Quintic Polynomial class
+ * Purpose:  Fitting a quinticc polynomial on interval [0, t] by given
+ *     boundary conditions.
+ * Author:   Zhao Liang
+ * Last Updated:  2021/02/24
+*****************************************
+*
+* Note: The polynomial is defined on interval [0, t] and has form
+*
+*     f(t) = a0 + a1*t + a2*t^2 + a3*t^3 + a4*t^4 + a5*t^5
+*
+* Boundary conditions are given by:
+* 1. x0=f(0), dx0=f'(0), ddx0=f''(0)
+* 2. x1=f(t), dx1=f'(t), ddx1=f''(t)
+*/
+#ifndef QUINTIC_POLYNOMIAL_H
+#define QUINTIC_POLYNOMIAL_H
+
+#pragma once
+
+#include <array>
+
+namespace iv {
+namespace math {
+
+class QuinticPolynomial
+{
+public:
+    QuinticPolynomial() = default;
+    ~QuinticPolynomial() = default;
+
+    /**
+    * @brief Initialize a quintic polynomial by given boundary conditions.
+    * @param x0: start point at x=0
+    * @param dx0: first order derivative at the start point
+    * @param ddx0: second order derivative at the start point
+    * @param x1: end point at x=t
+    * @param dx1: first order derivative at the end point x=t.
+    * @param ddx1: second order derivative at the end point x=t.
+    * @param t: parameter length.
+    */
+    QuinticPolynomial(const double x0, const double dx0, const double ddx0,
+                      const double x1, const double dx1, const double ddx1,
+                      const double t);
+
+    QuinticPolynomial(const std::array<double, 3> &start,
+                      const std::array<double, 3> &end,
+                      const double t);
+
+    void fitByBoundaryConditions(const double x0, const double dx0, const double ddx0,
+                                 const double x1, const double dx1, const double ddx1,
+                                 const double t);
+
+    /**
+    * @brief Evaluate the n-th derivative of this polynomial at a given point p.
+    * @param order: the order of the derivative to be evaluated.
+    * @param p: the point to be evaluated.
+    */
+    double evaluate(const std::uint32_t order, const double p) const;
+
+    /**
+    * @brief Return the coefficient of the k-th term.
+    */
+    double coef(const size_t order) const;
+
+    /**
+    * @brief Return all coefficients as a std::array.
+    */
+    const std::array<double, 6> &coef() const;
+
+    /**
+    * @brief Return a pretty string representation of this polynomial
+    */
+    std::string toString() const;
+
+    size_t order() const { return 5; }
+    double paramLength() const { return t_; }
+
+private:
+    void computeCoefficients(const double x0, const double dx0, const double ddx0,
+                             const double x1, const double dx1, const double ddx1,
+                             const double t);
+
+    double t_;
+    std::array<double, 3> start_condition_;
+    std::array<double, 3> end_condition_;
+    std::array<double, 6> coef_;
+};
+}
+}
+
+#endif // QUINTIC_POLYNOMIAL_H