mirror of
				https://github.com/PaddlePaddle/FastDeploy.git
				synced 2025-10-31 20:02:53 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			230 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // This file is part of Eigen, a lightweight C++ template library
 | |
| // for linear algebra.
 | |
| //
 | |
| // Copyright (C) 2010-2011 Hauke Heibel <heibel@gmail.com>
 | |
| //
 | |
| // This Source Code Form is subject to the terms of the Mozilla
 | |
| // Public License v. 2.0. If a copy of the MPL was not distributed
 | |
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | |
| 
 | |
| #include "main.h"
 | |
| 
 | |
| #include <unsupported/Eigen/Splines>
 | |
| 
 | |
| namespace Eigen {
 | |
| 
 | |
| // lets do some explicit instantiations and thus
 | |
| // force the compilation of all spline functions...
 | |
| template class Spline<double, 2, Dynamic>;
 | |
| template class Spline<double, 3, Dynamic>;
 | |
| 
 | |
| template class Spline<double, 2, 2>;
 | |
| template class Spline<double, 2, 3>;
 | |
| template class Spline<double, 2, 4>;
 | |
| template class Spline<double, 2, 5>;
 | |
| 
 | |
| template class Spline<float, 2, Dynamic>;
 | |
| template class Spline<float, 3, Dynamic>;
 | |
| 
 | |
| template class Spline<float, 3, 2>;
 | |
| template class Spline<float, 3, 3>;
 | |
| template class Spline<float, 3, 4>;
 | |
| template class Spline<float, 3, 5>;
 | |
| }
 | |
| 
 | |
| Spline<double, 2, Dynamic> closed_spline2d() {
 | |
|   RowVectorXd knots(12);
 | |
|   knots << 0, 0, 0, 0, 0.867193179093898, 1.660330955342408, 2.605084834823134,
 | |
|       3.484154586374428, 4.252699478956276, 4.252699478956276,
 | |
|       4.252699478956276, 4.252699478956276;
 | |
| 
 | |
|   MatrixXd ctrls(8, 2);
 | |
|   ctrls << -0.370967741935484, 0.236842105263158, -0.231401860693277,
 | |
|       0.442245185027632, 0.344361228532831, 0.773369994120753,
 | |
|       0.828990216203802, 0.106550882647595, 0.407270163678382,
 | |
|       -1.043452922172848, -0.488467813584053, -0.390098582530090,
 | |
|       -0.494657189446427, 0.054804824897884, -0.370967741935484,
 | |
|       0.236842105263158;
 | |
|   ctrls.transposeInPlace();
 | |
| 
 | |
|   return Spline<double, 2, Dynamic>(knots, ctrls);
 | |
| }
 | |
| 
 | |
| /* create a reference spline */
 | |
| Spline<double, 3, Dynamic> spline3d() {
 | |
|   RowVectorXd knots(11);
 | |
|   knots << 0, 0, 0, 0.118997681558377, 0.162611735194631, 0.498364051982143,
 | |
|       0.655098003973841, 0.679702676853675, 1.000000000000000,
 | |
|       1.000000000000000, 1.000000000000000;
 | |
| 
 | |
|   MatrixXd ctrls(8, 3);
 | |
|   ctrls << 0.959743958516081, 0.340385726666133, 0.585267750979777,
 | |
|       0.223811939491137, 0.751267059305653, 0.255095115459269,
 | |
|       0.505957051665142, 0.699076722656686, 0.890903252535799,
 | |
|       0.959291425205444, 0.547215529963803, 0.138624442828679,
 | |
|       0.149294005559057, 0.257508254123736, 0.840717255983663,
 | |
|       0.254282178971531, 0.814284826068816, 0.243524968724989,
 | |
|       0.929263623187228, 0.349983765984809, 0.196595250431208,
 | |
|       0.251083857976031, 0.616044676146639, 0.473288848902729;
 | |
|   ctrls.transposeInPlace();
 | |
| 
 | |
|   return Spline<double, 3, Dynamic>(knots, ctrls);
 | |
| }
 | |
| 
 | |
| /* compares evaluations against known results */
 | |
| void eval_spline3d() {
 | |
|   Spline3d spline = spline3d();
 | |
| 
 | |
|   RowVectorXd u(10);
 | |
|   u << 0.351659507062997, 0.830828627896291, 0.585264091152724,
 | |
|       0.549723608291140, 0.917193663829810, 0.285839018820374,
 | |
|       0.757200229110721, 0.753729094278495, 0.380445846975357,
 | |
|       0.567821640725221;
 | |
| 
 | |
|   MatrixXd pts(10, 3);
 | |
|   pts << 0.707620811535916, 0.510258911240815, 0.417485437023409,
 | |
|       0.603422256426978, 0.529498282727551, 0.270351549348981,
 | |
|       0.228364197569334, 0.423745615677815, 0.637687289287490,
 | |
|       0.275556796335168, 0.350856706427970, 0.684295784598905,
 | |
|       0.514519311047655, 0.525077224890754, 0.351628308305896,
 | |
|       0.724152914315666, 0.574461155457304, 0.469860285484058,
 | |
|       0.529365063753288, 0.613328702656816, 0.237837040141739,
 | |
|       0.522469395136878, 0.619099658652895, 0.237139665242069,
 | |
|       0.677357023849552, 0.480655768435853, 0.422227610314397,
 | |
|       0.247046593173758, 0.380604672404750, 0.670065791405019;
 | |
|   pts.transposeInPlace();
 | |
| 
 | |
|   for (int i = 0; i < u.size(); ++i) {
 | |
|     Vector3d pt = spline(u(i));
 | |
|     VERIFY((pt - pts.col(i)).norm() < 1e-14);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /* compares evaluations on corner cases */
 | |
| void eval_spline3d_onbrks() {
 | |
|   Spline3d spline = spline3d();
 | |
| 
 | |
|   RowVectorXd u = spline.knots();
 | |
| 
 | |
|   MatrixXd pts(11, 3);
 | |
|   pts << 0.959743958516081, 0.340385726666133, 0.585267750979777,
 | |
|       0.959743958516081, 0.340385726666133, 0.585267750979777,
 | |
|       0.959743958516081, 0.340385726666133, 0.585267750979777,
 | |
|       0.430282980289940, 0.713074680056118, 0.720373307943349,
 | |
|       0.558074875553060, 0.681617921034459, 0.804417124839942,
 | |
|       0.407076008291750, 0.349707710518163, 0.617275937419545,
 | |
|       0.240037008286602, 0.738739390398014, 0.324554153129411,
 | |
|       0.302434111480572, 0.781162443963899, 0.240177089094644,
 | |
|       0.251083857976031, 0.616044676146639, 0.473288848902729,
 | |
|       0.251083857976031, 0.616044676146639, 0.473288848902729,
 | |
|       0.251083857976031, 0.616044676146639, 0.473288848902729;
 | |
|   pts.transposeInPlace();
 | |
| 
 | |
|   for (int i = 0; i < u.size(); ++i) {
 | |
|     Vector3d pt = spline(u(i));
 | |
|     VERIFY((pt - pts.col(i)).norm() < 1e-14);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void eval_closed_spline2d() {
 | |
|   Spline2d spline = closed_spline2d();
 | |
| 
 | |
|   RowVectorXd u(12);
 | |
|   u << 0, 0.332457030395796, 0.356467130532952, 0.453562180176215,
 | |
|       0.648017921874804, 0.973770235555003, 1.882577647219307,
 | |
|       2.289408593930498, 3.511951429883045, 3.884149321369450,
 | |
|       4.236261590369414, 4.252699478956276;
 | |
| 
 | |
|   MatrixXd pts(12, 2);
 | |
|   pts << -0.370967741935484, 0.236842105263158, -0.152576775123250,
 | |
|       0.448975001279334, -0.133417538277668, 0.461615613865667,
 | |
|       -0.053199060826740, 0.507630360006299, 0.114249591147281,
 | |
|       0.570414135097409, 0.377810316891987, 0.560497102875315,
 | |
|       0.665052120135908, -0.157557441109611, 0.516006487053228,
 | |
|       -0.559763292174825, -0.379486035348887, -0.331959640488223,
 | |
|       -0.462034726249078, -0.039105670080824, -0.378730600917982,
 | |
|       0.225127015099919, -0.370967741935484, 0.236842105263158;
 | |
|   pts.transposeInPlace();
 | |
| 
 | |
|   for (int i = 0; i < u.size(); ++i) {
 | |
|     Vector2d pt = spline(u(i));
 | |
|     VERIFY((pt - pts.col(i)).norm() < 1e-14);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void check_global_interpolation2d() {
 | |
|   typedef Spline2d::PointType PointType;
 | |
|   typedef Spline2d::KnotVectorType KnotVectorType;
 | |
|   typedef Spline2d::ControlPointVectorType ControlPointVectorType;
 | |
| 
 | |
|   ControlPointVectorType points = ControlPointVectorType::Random(2, 100);
 | |
| 
 | |
|   KnotVectorType chord_lengths;  // knot parameters
 | |
|   Eigen::ChordLengths(points, chord_lengths);
 | |
| 
 | |
|   // interpolation without knot parameters
 | |
|   {
 | |
|     const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points, 3);
 | |
| 
 | |
|     for (Eigen::DenseIndex i = 0; i < points.cols(); ++i) {
 | |
|       PointType pt = spline(chord_lengths(i));
 | |
|       PointType ref = points.col(i);
 | |
|       VERIFY((pt - ref).matrix().norm() < 1e-14);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // interpolation with given knot parameters
 | |
|   {
 | |
|     const Spline2d spline =
 | |
|         SplineFitting<Spline2d>::Interpolate(points, 3, chord_lengths);
 | |
| 
 | |
|     for (Eigen::DenseIndex i = 0; i < points.cols(); ++i) {
 | |
|       PointType pt = spline(chord_lengths(i));
 | |
|       PointType ref = points.col(i);
 | |
|       VERIFY((pt - ref).matrix().norm() < 1e-14);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void check_global_interpolation_with_derivatives2d() {
 | |
|   typedef Spline2d::PointType PointType;
 | |
|   typedef Spline2d::KnotVectorType KnotVectorType;
 | |
| 
 | |
|   const Eigen::DenseIndex numPoints = 100;
 | |
|   const unsigned int dimension = 2;
 | |
|   const unsigned int degree = 3;
 | |
| 
 | |
|   ArrayXXd points = ArrayXXd::Random(dimension, numPoints);
 | |
| 
 | |
|   KnotVectorType knots;
 | |
|   Eigen::ChordLengths(points, knots);
 | |
| 
 | |
|   ArrayXXd derivatives = ArrayXXd::Random(dimension, numPoints);
 | |
|   VectorXd derivativeIndices(numPoints);
 | |
| 
 | |
|   for (Eigen::DenseIndex i = 0; i < numPoints; ++i)
 | |
|     derivativeIndices(i) = static_cast<double>(i);
 | |
| 
 | |
|   const Spline2d spline = SplineFitting<Spline2d>::InterpolateWithDerivatives(
 | |
|       points, derivatives, derivativeIndices, degree);
 | |
| 
 | |
|   for (Eigen::DenseIndex i = 0; i < points.cols(); ++i) {
 | |
|     PointType point = spline(knots(i));
 | |
|     PointType referencePoint = points.col(i);
 | |
|     VERIFY_IS_APPROX(point, referencePoint);
 | |
|     PointType derivative = spline.derivatives(knots(i), 1).col(1);
 | |
|     PointType referenceDerivative = derivatives.col(i);
 | |
|     VERIFY_IS_APPROX(derivative, referenceDerivative);
 | |
|   }
 | |
| }
 | |
| 
 | |
| EIGEN_DECLARE_TEST(splines) {
 | |
|   for (int i = 0; i < g_repeat; ++i) {
 | |
|     CALL_SUBTEST(eval_spline3d());
 | |
|     CALL_SUBTEST(eval_spline3d_onbrks());
 | |
|     CALL_SUBTEST(eval_closed_spline2d());
 | |
|     CALL_SUBTEST(check_global_interpolation2d());
 | |
|     CALL_SUBTEST(check_global_interpolation_with_derivatives2d());
 | |
|   }
 | |
| }
 | 
