8 #ifndef META_OCEAN_GEOMETRY_NON_LINEAR_OPTIMIZATION_H
9 #define META_OCEAN_GEOMETRY_NON_LINEAR_OPTIMIZATION_H
45 template <
typename TFirst,
typename TSecond>
53 typedef std::pair<Index32, Vector2>
Element;
99 inline void element(
const size_t groupIndex,
const size_t elementIndex, TFirst& first, TSecond& second)
const;
107 inline const TFirst&
firstElement(
const size_t groupIndex,
const size_t elementIndex)
const;
115 inline const TSecond&
secondElement(
const size_t groupIndex,
const size_t elementIndex)
const;
237 template <
typename TAccessor>
246 template <
typename TAccessor>
262 template <
typename TAccessor>
278 template <
typename TAccessor>
286 inline size_t addObjectPoint(Elements&& poseIdImagePointPairs);
300 inline bool hasSolver()
const;
335 inline Scalar determineError();
344 inline bool determineHessianAndErrorJacobian(
Matrix& hessian,
Matrix& jacobianError);
351 inline void applyCorrection(
const Matrix& deltas);
357 inline void acceptCorrection();
364 inline bool shouldStop();
370 inline bool hasSolver()
const;
379 inline bool solve(
const Matrix& hessian,
const Matrix& jacobianError,
Matrix& deltas)
const;
402 inline Scalar determineError();
410 inline bool determineParameters();
417 inline void applyCorrection(
const Matrix& deltas);
423 inline void acceptCorrection();
430 inline bool shouldStop();
466 template <
typename T>
483 template <
typename T, Estimator::EstimatorType tEstimator>
484 static bool denseOptimization(T& provider,
const unsigned int iterations = 5u,
Scalar lambda =
Scalar(0.001),
const Scalar lambdaFactor =
Scalar(5),
Scalar* initialError =
nullptr,
Scalar* finalError =
nullptr,
const Matrix* invertedCovariances =
nullptr,
Scalars* intermediateErrors =
nullptr);
500 template <
typename T>
517 template <
typename T, Estimator::EstimatorType tEstimator>
518 static bool sparseOptimization(T& provider,
const unsigned int iterations = 5u,
Scalar lambda =
Scalar(0.001),
const Scalar lambdaFactor =
Scalar(5),
Scalar* initialError =
nullptr,
Scalar* finalError =
nullptr,
const Matrix* invertedCovariances =
nullptr,
Scalars* intermediateErrors =
nullptr);
533 template <
typename T>
534 static bool advancedDenseOptimization(T& advancedDenseProvider,
const unsigned int iterations,
Scalar lambda,
const Scalar lambdaFactor,
Scalar* initialError =
nullptr,
Scalar* finalError =
nullptr,
Scalars* intermediateErrors =
nullptr);
549 template <
typename T>
550 static bool advancedSparseOptimization(T& advancedSparseProvider,
const unsigned int iterations,
Scalar lambda,
const Scalar lambdaFactor,
Scalar* initialError =
nullptr,
Scalar* finalError =
nullptr,
Scalars* intermediateErrors =
nullptr);
562 template <Estimator::EstimatorType tEstimator>
576 template <Estimator::EstimatorType tEstimator,
size_t tDimension>
590 template <Estimator::EstimatorType tEstimator>
591 static Scalar sqrErrors2robustErrors_i(
const Scalars& sqrErrors,
const size_t modelParameters,
const size_t dimension,
Scalar* weightedErrors_i,
Scalar* weightVectors_i,
const Matrix* transposedInvertedCovariances_i);
616 template <
size_t tDimension>
633 template <
typename TFirst,
typename TSecond>
639 template <
typename TFirst,
typename TSecond>
641 elementGroups_(elementGroups)
646 template <
typename TFirst,
typename TSecond>
648 elementGroups_(std::move(elementGroups))
653 template <
typename TFirst,
typename TSecond>
655 elementGroups_(accessor.elementGroups_)
660 template <
typename TFirst,
typename TSecond>
662 elementGroups_(std::move(accessor.elementGroups_))
667 template <
typename TFirst,
typename TSecond>
670 return elementGroups_.size();
673 template <
typename TFirst,
typename TSecond>
676 ocean_assert(groupIndex < groups());
678 return elementGroups_[groupIndex].size();
681 template <
typename TFirst,
typename TSecond>
684 ocean_assert(groupIndex < groups());
685 ocean_assert(elementIndex < groupElements(groupIndex));
687 const Element& element = elementGroups_[groupIndex][elementIndex];
689 first = element.first;
690 second = element.second;
693 template <
typename TFirst,
typename TSecond>
696 ocean_assert(groupIndex < groups());
697 ocean_assert(elementIndex < groupElements(groupIndex));
699 return elementGroups_[groupIndex][elementIndex].first;
702 template <
typename TFirst,
typename TSecond>
705 ocean_assert(groupIndex < groups());
706 ocean_assert(elementIndex < groupElements(groupIndex));
708 return elementGroups_[groupIndex][elementIndex].second;
711 template <
typename TFirst,
typename TSecond>
718 template <
typename TFirst,
typename TSecond>
721 if (
this != &accessor)
723 elementGroups_ = std::move(accessor.elementGroups_);
770 ocean_assert(
false &&
"Must be implemented in a derived class!");
776 ocean_assert(
false &&
"Must be implemented in a derived class!");
787 ocean_assert(
false &&
"Must be implemented in a derived class!");
793 ocean_assert(
false &&
"Must be implemented in a derived class!");
799 ocean_assert(
false &&
"Must be implemented in a derived class!");
804 ocean_assert(
false &&
"Must be implemented in a derived class!");
809 ocean_assert(
false &&
"Must be implemented in a derived class!");
820 ocean_assert(
false &&
"Must be implemented in a derived class!");
831 ocean_assert(
false &&
"Must be implemented in a derived class!");
837 ocean_assert(
false &&
"Must be implemented in a derived class!");
843 ocean_assert(
false &&
"Must be implemented in a derived class!");
848 ocean_assert(
false &&
"Must be implemented in a derived class!");
853 ocean_assert(
false &&
"Must be implemented in a derived class!");
859 ocean_assert(
false &&
"Must be implemented in a derived class!");
863 template <
typename TAccessor>
867 ocean_assert(imagePoints0.size() == imagePoints1.size());
869 for (
size_t n = 0; n < imagePoints0.size(); ++n)
879 template <
typename TAccessor>
885 for (
size_t n = 0; n < imagePointGroups.size(); ++n)
888 ocean_assert(imagePoints.
size() >= 2);
891 poseIndexImagePoints.reserve(imagePoints.
size());
893 for (
size_t i = 0; i < imagePoints.
size(); ++i)
895 poseIndexImagePoints.emplace_back(
Index32(i), imagePoints[i]);
902 template <
typename TAccessor>
907 ocean_assert(sequentialImagePointGroups.size() % numberObjectPoints == 0);
909 const unsigned int numberImagePoints = (
unsigned int)(sequentialImagePointGroups.size() / numberObjectPoints);
911 unsigned int index = 0u;
913 for (
size_t n = 0; n < numberObjectPoints; ++n)
916 poseIndexImagePoints.reserve(numberImagePoints);
918 for (
unsigned int i = 0u; i < numberImagePoints; ++i)
920 poseIndexImagePoints.emplace_back(
Index32(i), sequentialImagePointGroups[index++]);
927 template <
typename TAccessor>
932 ocean_assert(imagePoints.size() % numberObjectPoints == 0);
934 ocean_assert(numberObjectPoints != 0);
935 const unsigned int numberImagePoints = (
unsigned int)(imagePoints.size() / numberObjectPoints);
937 unsigned int poseIndex = 0u;
938 unsigned int index = 0u;
940 for (
size_t n = 0; n < numberImagePoints; ++n)
942 for (
size_t i = 0; i < numberObjectPoints; ++i)
954 ocean_assert(!poseIdImagePointPairs.empty());
956 const size_t objectPointIndex = elementGroups_.size();
958 elementGroups_.emplace_back(std::move(poseIdImagePointPairs));
960 return objectPointIndex;
963 template <
typename T>
969 return denseOptimization<T, Estimator::ET_SQUARE>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
972 return denseOptimization<T, Estimator::ET_LINEAR>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
975 return denseOptimization<T, Estimator::ET_HUBER>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
978 return denseOptimization<T, Estimator::ET_TUKEY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
981 return denseOptimization<T, Estimator::ET_CAUCHY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
984 ocean_assert(
false &&
"Invalid estimator!");
989 template <
typename T, Estimator::EstimatorType tEstimator>
994 ocean_assert(lambda >=
Numeric::eps() && lambda <= maxLambda);
999 Matrix weightedErrorVector, swapWeightedErrorVector;
1001 Matrix weightVector, swapWeightVector;
1003 Matrix JTJ, jErrors, deltas;
1006 Matrix intermediateCovarianceJacobian;
1007 Matrix intermediateWeightedErrorVector;
1009 Scalar bestError = provider.template determineRobustError<tEstimator>(weightedErrorVector, weightVector, invertedCovariances);
1013 ocean_assert(
false &&
"The initial model was invalid and thus the optimization cannot be applied!");
1017 if (initialError !=
nullptr)
1019 *initialError = bestError;
1022 if (intermediateErrors !=
nullptr)
1024 ocean_assert(intermediateErrors->empty());
1025 intermediateErrors->push_back(bestError);
1028 bool oneValidIteration =
false;
1030 unsigned int i = 0u;
1031 while (i < iterations)
1033 provider.determineJacobian(jacobian);
1036 if (invertedCovariances)
1084 while (i < iterations)
1091 for (
unsigned int n = 0; n < JTJ.
columns(); ++n)
1093 JTJ(n, n) = JTJdiagonal(n, 0) * (
Scalar(1) + lambda);
1100 bool solved =
false;
1102 if (provider.hasSolver())
1104 solved = provider.
solve(JTJ, jErrors, deltas);
1113 oneValidIteration =
true;
1122 provider.applyCorrection(deltas);
1124 const Scalar iterationError = provider.template determineRobustError<tEstimator>(swapWeightedErrorVector, swapWeightVector, invertedCovariances);
1127 if (iterationError >= bestError)
1130 if (lambdaFactor >
Numeric::eps() && lambda > 0 && lambda <= maxLambda)
1132 lambda *= lambdaFactor;
1136 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1146 bestError = iterationError;
1148 if (intermediateErrors !=
nullptr)
1150 intermediateErrors->push_back(bestError);
1153 provider.acceptCorrection();
1155 std::swap(swapWeightedErrorVector, weightedErrorVector);
1156 std::swap(swapWeightVector, weightVector);
1163 lambda /= lambdaFactor;
1170 else if (lambda >
Numeric::eps() && lambda <= maxLambda)
1172 lambda *= lambdaFactor;
1176 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1186 *finalError = bestError;
1189 return oneValidIteration;
1192 template <
typename T>
1198 return sparseOptimization<T, Estimator::ET_SQUARE>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
1201 return sparseOptimization<T, Estimator::ET_LINEAR>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
1204 return sparseOptimization<T, Estimator::ET_HUBER>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
1207 return sparseOptimization<T, Estimator::ET_TUKEY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
1210 return sparseOptimization<T, Estimator::ET_CAUCHY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
1213 ocean_assert(
false &&
"Invalid estimator!");
1218 template <
typename T, Estimator::EstimatorType tEstimator>
1223 ocean_assert(lambda >=
Numeric::eps() && lambda <= maxLambda);
1228 Matrix weightedErrorVector, swapWeightedErrorVector;
1230 Matrix weightVector, swapWeightVector;
1237 Scalar bestError = provider.template determineRobustError<tEstimator>(weightedErrorVector, weightVector, invertedCovariances);
1241 ocean_assert(
false &&
"The initial model was invalid and thus the optimization cannot be applied!");
1247 *initialError = bestError;
1250 if (intermediateErrors !=
nullptr)
1252 ocean_assert(intermediateErrors->empty());
1253 intermediateErrors->push_back(bestError);
1256 bool oneValidIteration =
false;
1258 unsigned int i = 0u;
1259 while (i < iterations)
1261 provider.determineJacobian(jacobian);
1264 if (invertedCovariances)
1276 JTJ = jacobianTransposed * (invertedCovarianceMatrix * jacobian);
1282 JTJ = jacobianTransposed * (invertedCovarianceMatrix * (
SparseMatrix(weightVector.
rows(), weightVector.
rows(), weightVector,
true) * jacobian));
1287 jErrors = jacobianTransposed * (invertedCovarianceMatrix * weightedErrorVector);
1302 JTJ = jacobianTransposed * jacobian;
1308 JTJ = jacobianTransposed *
SparseMatrix(weightVector.
rows(), weightVector.
rows(), weightVector,
true) * jacobian;
1313 jErrors = jacobianTransposed * weightedErrorVector;
1319 while (i < iterations)
1326 for (
unsigned int n = 0; n < JTJ.
columns(); ++n)
1328 if (JTJdiagonal(n, 0) !=
Scalar(0))
1330 ocean_assert(!JTJ.
isZero(n, n));
1331 JTJ(n, n) = JTJdiagonal(n, 0) * (
Scalar(1) + lambda);
1339 bool solved =
false;
1341 if (provider.hasSolver())
1343 solved = provider.
solve(JTJ, jErrors, deltas);
1347 solved = JTJ.
solve(jErrors, deltas);
1352 oneValidIteration =
true;
1361 provider.applyCorrection(deltas);
1363 const Scalar iterationError = provider.template determineRobustError<tEstimator>(swapWeightedErrorVector, swapWeightVector, invertedCovariances);
1366 if (iterationError >= bestError)
1369 if (lambdaFactor >
Numeric::eps() && lambda > 0 && lambda <= maxLambda)
1371 lambda *= lambdaFactor;
1375 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1385 bestError = iterationError;
1387 if (intermediateErrors !=
nullptr)
1389 intermediateErrors->push_back(bestError);
1392 provider.acceptCorrection();
1394 std::swap(swapWeightedErrorVector, weightedErrorVector);
1395 std::swap(swapWeightVector, weightVector);
1402 lambda /= lambdaFactor;
1409 else if (lambda >
Numeric::eps() && lambda <= maxLambda)
1411 lambda *= lambdaFactor;
1415 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1425 *finalError = bestError;
1428 return oneValidIteration;
1431 template <
typename T>
1436 ocean_assert(lambda >=
Scalar(0) && lambda <= maxLambda);
1437 ocean_assert((lambda ==
Scalar(0) && lambdaFactor ==
Scalar(1)) || (lambda >
Scalar(0) && lambdaFactor >
Scalar(1)));
1439 const bool useLevenbergMarquardt = (lambda > 0 && lambdaFactor > 1);
1442 Scalar bestError = (useLevenbergMarquardt || initialError) ? advancedDenseProvider.determineError() :
Numeric::minValue();
1446 ocean_assert(
false &&
"The initial model was invalid and thus the optimization cannot be applied!");
1452 *initialError = bestError;
1455 if (intermediateErrors !=
nullptr)
1457 ocean_assert(intermediateErrors->empty());
1458 intermediateErrors->push_back(bestError);
1461 bool oneValidIteration =
false;
1463 Matrix hessian, jacobianError, deltas;
1465 unsigned int i = 0u;
1466 while (!advancedDenseProvider.shouldStop() && i < iterations)
1474 if (!advancedDenseProvider.determineHessianAndErrorJacobian(hessian, jacobianError))
1476 ocean_assert(
false &&
"The Hessian and the Jacobian with combined error values could not be determined!");
1480 ocean_assert(hessian.
rows() == hessian.
columns());
1481 ocean_assert(hessian.
rows() == jacobianError.
rows() && jacobianError.
columns() == 1);
1486 ocean_assert(hessianDiagonal.
rows() == hessian.
rows() && hessianDiagonal.
columns() == 1);
1488 while (!advancedDenseProvider.shouldStop() && i++ < iterations)
1494 for (
unsigned int n = 0; n < hessian.
columns(); ++n)
1496 hessian(n, n) = hessianDiagonal(n, 0) * (
Scalar(1) + lambda);
1502 bool solved =
false;
1504 if (advancedDenseProvider.hasSolver())
1506 solved = advancedDenseProvider.
solve(hessian, jacobianError, deltas);
1515 oneValidIteration =
true;
1524 advancedDenseProvider.applyCorrection(deltas);
1526 const Scalar iterationError = (useLevenbergMarquardt || intermediateErrors) ? advancedDenseProvider.determineError() :
Numeric::minValue();
1529 if (useLevenbergMarquardt && iterationError >= bestError)
1532 if (lambda > 0 && lambda <= maxLambda)
1534 lambda *= lambdaFactor;
1538 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1548 bestError = iterationError;
1550 if (intermediateErrors !=
nullptr)
1552 intermediateErrors->push_back(bestError);
1555 advancedDenseProvider.acceptCorrection();
1562 lambda /= lambdaFactor;
1569 else if (lambda >
Numeric::eps() && lambda <= maxLambda)
1571 lambda *= lambdaFactor;
1575 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1586 if (!useLevenbergMarquardt && !intermediateErrors)
1588 bestError = advancedDenseProvider.determineError();
1591 *finalError = bestError;
1594 return oneValidIteration;
1597 template <
typename T>
1602 ocean_assert(lambda >=
Scalar(0) && lambda <= maxLambda);
1603 ocean_assert((lambda ==
Scalar(0) && lambdaFactor ==
Scalar(1)) || (lambda >
Scalar(0) && lambdaFactor >
Scalar(1)));
1605 const bool useLevenbergMarquardt = (lambda > 0 && lambdaFactor > 1);
1608 Scalar bestError = (useLevenbergMarquardt || initialError) ? advancedSparseProvider.determineError() :
Numeric::minValue();
1612 ocean_assert(
false &&
"The initial model was invalid and thus the optimization cannot be applied!");
1618 *initialError = bestError;
1621 if (intermediateErrors !=
nullptr)
1623 ocean_assert(intermediateErrors->empty());
1624 intermediateErrors->push_back(bestError);
1627 bool oneValidIteration =
false;
1631 unsigned int i = 0u;
1632 while (!advancedSparseProvider.shouldStop() && i < iterations)
1638 if (!advancedSparseProvider.determineParameters())
1640 ocean_assert(
false &&
"The provider failed to determine the abstract parameters.");
1644 while (!advancedSparseProvider.shouldStop() && i++ < iterations)
1646 ocean_assert(lambda >=
Scalar(0));
1647 if (advancedSparseProvider.solve(deltas, lambda))
1649 oneValidIteration =
true;
1658 advancedSparseProvider.applyCorrection(deltas);
1660 const Scalar iterationError = (useLevenbergMarquardt || intermediateErrors) ? advancedSparseProvider.determineError() :
Numeric::minValue();
1663 if (useLevenbergMarquardt && iterationError >= bestError)
1666 if (lambda > 0 && lambda <= maxLambda)
1668 lambda *= lambdaFactor;
1672 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1682 bestError = iterationError;
1684 if (intermediateErrors !=
nullptr)
1686 intermediateErrors->push_back(bestError);
1689 advancedSparseProvider.acceptCorrection();
1696 lambda /= lambdaFactor;
1703 else if (lambda >
Numeric::eps() && lambda <= maxLambda)
1705 lambda *= lambdaFactor;
1709 ocean_assert(oneValidIteration &&
"At this moment we should have at least one valid iteration!");
1720 if (!useLevenbergMarquardt && !intermediateErrors)
1722 bestError = advancedSparseProvider.determineError();
1725 *finalError = bestError;
1728 return oneValidIteration;
1731 template <Estimator::EstimatorType tEstimator>
1735 const Scalar sqrSigma = Estimator::needSigma<tEstimator>() ?
Numeric::sqr(Estimator::determineSigmaSquare<tEstimator>(sqrErrors.data(), sqrErrors.size(), modelParameters)) : 0;
1739 for (
size_t n = 0; n < sqrErrors.size(); ++n)
1745 const Scalar weight = max(
Numeric::weakEps(), Estimator::robustWeightSquare<tEstimator>(sqrErrors[n], sqrSigma));
1748 if (transposedInvertedCovariances)
1750 robustError += (transposedInvertedCovariances[n].
transposed() * weightedErrors[n]).
sqr() * weight;
1754 robustError += sqrErrors[n] * weight;
1757 weightedErrors[n] *= weight;
1759 weightVectors[n] =
Vector2(weight, weight);
1763 return robustError /
Scalar(sqrErrors.size());
1766 template <Estimator::EstimatorType tEstimator,
size_t tDimension>
1769 ocean_assert(transposedInvertedCovariances ==
nullptr &&
"Currently not implemenated");
1770 OCEAN_SUPPRESS_UNUSED_WARNING(transposedInvertedCovariances);
1773 const Scalar sqrSigma = Estimator::needSigma<tEstimator>() ?
Numeric::sqr(Estimator::determineSigmaSquare<tEstimator>(sqrErrors.data(), sqrErrors.size(), modelParameters)) : 0;
1777 for (
size_t n = 0; n < sqrErrors.size(); ++n)
1786 const Scalar weight = max(
Numeric::weakEps(), Estimator::robustWeightSquare<tEstimator>(sqrErrors[n], sqrSigma));
1789 robustError += sqrErrors[n] * weight;
1791 for (
size_t d = 0; d < tDimension; ++d)
1793 weightedErrorsPointer[d] *= weight;
1794 weightVectorsPointer[d] = weight;
1799 return robustError /
Scalar(sqrErrors.size());
1802 template <Estimator::EstimatorType tEstimator>
1805 ocean_assert(transposedInvertedCovariances_i ==
nullptr &&
"Currently not implemenated");
1806 OCEAN_SUPPRESS_UNUSED_WARNING(transposedInvertedCovariances_i);
1809 const Scalar sqrSigma = Estimator::needSigma<tEstimator>() ?
Numeric::sqr(Estimator::determineSigmaSquare<tEstimator>(sqrErrors.data(), sqrErrors.size(), modelParameters)) : 0;
1813 for (
size_t n = 0; n < sqrErrors.size(); ++n)
1815 Scalar*
const weightedErrorsPointer = weightedErrors_i + n * dimension;
1816 Scalar*
const weightVectorsPointer = weightVectors_i + n * dimension;
1821 const Scalar weight = Estimator::robustWeightSquare<tEstimator>(sqrErrors[n], sqrSigma);
1824 robustError += sqrErrors[n] * weight;
1826 for (
size_t d = 0; d < dimension; ++d)
1828 weightedErrorsPointer[d] *= weight;
1829 weightVectorsPointer[d] = weight;
1834 return robustError /
Scalar(sqrErrors.size());
1842 return sqrErrors2robustErrors2<Estimator::ET_SQUARE>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1845 return sqrErrors2robustErrors2<Estimator::ET_LINEAR>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1848 return sqrErrors2robustErrors2<Estimator::ET_HUBER>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1851 return sqrErrors2robustErrors2<Estimator::ET_TUKEY>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1854 return sqrErrors2robustErrors2<Estimator::ET_CAUCHY>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1857 ocean_assert(
false &&
"Invalid estimator!");
1862 template <
size_t tDimension>
1868 return sqrErrors2robustErrors<Estimator::ET_SQUARE, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1871 return sqrErrors2robustErrors<Estimator::ET_LINEAR, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1874 return sqrErrors2robustErrors<Estimator::ET_HUBER, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1877 return sqrErrors2robustErrors<Estimator::ET_TUKEY, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1880 return sqrErrors2robustErrors<Estimator::ET_CAUCHY, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
1883 ocean_assert(
false &&
"Invalid estimator!");
1893 return sqrErrors2robustErrors_i<Estimator::ET_SQUARE>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
1896 return sqrErrors2robustErrors_i<Estimator::ET_LINEAR>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
1899 return sqrErrors2robustErrors_i<Estimator::ET_HUBER>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
1902 return sqrErrors2robustErrors_i<Estimator::ET_TUKEY>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
1905 return sqrErrors2robustErrors_i<Estimator::ET_CAUCHY>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
1908 ocean_assert(
false &&
"Invalid estimator!");
virtual size_t size() const =0
Returns the number of accessible elements of this accessor object.
EstimatorType
Definition of individual robust estimator types.
Definition: Estimator.h:34
@ ET_HUBER
The Huber estimator type.
Definition: Estimator.h:84
@ ET_TUKEY
The Tukey estimator.
Definition: Estimator.h:102
@ ET_SQUARE
The standard square error estimator (L2).
Definition: Estimator.h:52
@ ET_LINEAR
The linear estimator (L1).
Definition: Estimator.h:66
@ ET_CAUCHY
The Cauchy estimator.
Definition: Estimator.h:118
This class implements the base for an advanced dense optimization provider.
Definition: NonLinearOptimization.h:327
void acceptCorrection()
Accepts the current model candidate a new (better) model than the previous one.
Definition: NonLinearOptimization.h:802
Scalar determineError()
Determines the error for the current model candidate (not the actual model).
Definition: NonLinearOptimization.h:785
bool determineHessianAndErrorJacobian(Matrix &hessian, Matrix &jacobianError)
Determines the Hessian matrix and the Error-Jacobian vector based on the actual/current model (the tr...
Definition: NonLinearOptimization.h:791
bool hasSolver() const
Returns whether the provider comes with an own solver for the linear equation.
Definition: NonLinearOptimization.h:813
bool shouldStop()
Returns whether the optimization process should stop e.g., due to an external event.
Definition: NonLinearOptimization.h:807
bool solve(const Matrix &hessian, const Matrix &jacobianError, Matrix &deltas) const
Solves the linear equation Hessian * deltas = -jacobianError.
Definition: NonLinearOptimization.h:818
AdvancedDenseOptimizationProvider()
Protected default constructor.
Definition: NonLinearOptimization.h:780
void applyCorrection(const Matrix &deltas)
Creates a new model candidate by adjusting the current model with delta values.
Definition: NonLinearOptimization.h:797
This class implements the base class for an advanced sparse optimization provider.
Definition: NonLinearOptimization.h:394
void acceptCorrection()
Accepts the current model candidate a new (better) model than the previous one.
Definition: NonLinearOptimization.h:846
bool determineParameters()
Determines any kind of (abstract) parameters based on the current/actual model (not the model candida...
Definition: NonLinearOptimization.h:835
bool shouldStop()
Returns whether the optimization process should stop e.g., due to an external event.
Definition: NonLinearOptimization.h:851
Scalar determineError()
Determines the error for the current model candidate (not the actual/actual model).
Definition: NonLinearOptimization.h:829
bool solve(Matrix &deltas, const Scalar lambda=Scalar(0))
Solves the linear equation Hessian * deltas = -jacobianError based on the internal data.
Definition: NonLinearOptimization.h:857
void applyCorrection(const Matrix &deltas)
Creates a new model candidate by adjusting the current/actual model with delta values.
Definition: NonLinearOptimization.h:841
AdvancedSparseOptimizationProvider()
Protected default constructor.
Definition: NonLinearOptimization.h:824
This class implements the base class for an accessor of groups of pairs.
Definition: NonLinearOptimization.h:47
CorrespondenceGroupsAccessor(CorrespondenceGroupsAccessor< TFirst, TSecond > &&accessor)
Move constructor.
Definition: NonLinearOptimization.h:661
size_t groupElements(const size_t groupIndex) const
Returns the number of elements within a specified group.
Definition: NonLinearOptimization.h:674
size_t groups() const
Returns the number of groups of this accessor.
Definition: NonLinearOptimization.h:668
const TSecond & secondElement(const size_t groupIndex, const size_t elementIndex) const
Returns the first element of a pair of a specific group of this object.
Definition: NonLinearOptimization.h:703
CorrespondenceGroupsAccessor< TFirst, TSecond > & operator=(CorrespondenceGroupsAccessor< TFirst, TSecond > &&accessor)
Move constructor.
Definition: NonLinearOptimization.h:719
CorrespondenceGroupsAccessor(const ElementGroups &elementGroups)
Creates a new accessor object.
Definition: NonLinearOptimization.h:640
CorrespondenceGroupsAccessor< TFirst, TSecond > & operator=(const CorrespondenceGroupsAccessor< TFirst, TSecond > &accessor)
Copy constructor.
Definition: NonLinearOptimization.h:712
void element(const size_t groupIndex, const size_t elementIndex, TFirst &first, TSecond &second) const
Returns one pair of a specific group of this object.
Definition: NonLinearOptimization.h:682
std::vector< Elements > ElementGroups
Definition of a vector holding a group of elements.
Definition: NonLinearOptimization.h:63
const TFirst & firstElement(const size_t groupIndex, const size_t elementIndex) const
Returns the first element of a pair of a specific group of this object.
Definition: NonLinearOptimization.h:694
std::vector< Element > Elements
Definition of a vector holding elements.
Definition: NonLinearOptimization.h:58
CorrespondenceGroupsAccessor()
Creates a new accessor object.
Definition: NonLinearOptimization.h:634
CorrespondenceGroupsAccessor(const CorrespondenceGroupsAccessor< TFirst, TSecond > &accessor)
Copy constructor.
Definition: NonLinearOptimization.h:654
CorrespondenceGroupsAccessor(ElementGroups &&elementGroups)
Creates a new accessor object.
Definition: NonLinearOptimization.h:647
ElementGroups elementGroups_
The groups of elements of this accessor.
Definition: NonLinearOptimization.h:151
std::pair< Index32, Vector2 > Element
Definition of a pair combining an object point id with an image point.
Definition: NonLinearOptimization.h:53
This class implements an abstract specialization of the accessor for groups of pairs for object point...
Definition: NonLinearOptimization.h:159
ObjectPointGroupsAccessor()
Creates a new accessor object.
Definition: NonLinearOptimization.h:729
This class implements a group accessor providing access to pairs of poses and image points.
Definition: NonLinearOptimization.h:223
size_t addObjectPoint(Elements &&poseIdImagePointPairs)
Adds the observations of a new object point to this accessor.
Definition: NonLinearOptimization.h:952
ObjectPointToPoseIndexImagePointCorrespondenceAccessor()=default
Default constructor.
This class implements the base optimization provider.
Definition: NonLinearOptimization.h:293
bool solve(const Matrix &JTJ, const Matrix &jErrors, Matrix &deltas) const
Solves the linear equation JTJ * deltas = jErrors.
Definition: NonLinearOptimization.h:768
bool hasSolver() const
Returns whether the provider comes with an own solver for the linear equation.
Definition: NonLinearOptimization.h:763
This class implements an abstract specialization of the accessor for groups of pairs for poses.
Definition: NonLinearOptimization.h:185
PoseGroupsAccessor()
Creates a new accessor object.
Definition: NonLinearOptimization.h:746
This class implements the basic functions for least square or robust optimization algorithms for non ...
Definition: NonLinearOptimization.h:34
static bool denseOptimization(T &provider, const unsigned int iterations=5u, const Estimator::EstimatorType estimator=Estimator::ET_SQUARE, Scalar lambda=Scalar(0.001), const Scalar lambdaFactor=Scalar(5), Scalar *initialError=nullptr, Scalar *finalError=nullptr, const Matrix *invertedCovariances=nullptr, Scalars *intermediateErrors=nullptr)
Invokes the optimization of a dense (matrix) optimization problem.
Definition: NonLinearOptimization.h:964
static bool sparseOptimization(T &provider, const unsigned int iterations=5u, const Estimator::EstimatorType estimator=Estimator::ET_SQUARE, Scalar lambda=Scalar(0.001), const Scalar lambdaFactor=Scalar(5), Scalar *initialError=nullptr, Scalar *finalError=nullptr, const Matrix *invertedCovariances=nullptr, Scalars *intermediateErrors=nullptr)
Invokes the optimization of a sparse (matrix) optimization problem.
Definition: NonLinearOptimization.h:1193
static Scalar sqrErrors2robustErrors_i(const Scalars &sqrErrors, const size_t modelParameters, const size_t dimension, Scalar *weightedErrors_i, Scalar *weightVectors_i, const Matrix *transposedInvertedCovariances_i)
Translates the n/i squared errors that correspond to n elements in the error vector to robust errors.
Definition: NonLinearOptimization.h:1803
static Scalar sqrErrors2robustErrors2(const Scalars &sqrErrors, const size_t modelParameters, Vector2 *weightedErrors, Vector2 *weightVectors, const SquareMatrix2 *transposedInvertedCovariances)
Translates the n/2 squared errors that correspond to n elements in the error vector to robust errors.
Definition: NonLinearOptimization.h:1732
static bool advancedDenseOptimization(T &advancedDenseProvider, const unsigned int iterations, Scalar lambda, const Scalar lambdaFactor, Scalar *initialError=nullptr, Scalar *finalError=nullptr, Scalars *intermediateErrors=nullptr)
Invokes the optimization of a dense (matrix) optimization problem using an advanced optimization prov...
Definition: NonLinearOptimization.h:1432
static Scalar sqrErrors2robustErrors(const Scalars &sqrErrors, const size_t modelParameters, StaticBuffer< Scalar, tDimension > *weightedErrors, StaticBuffer< Scalar, tDimension > *weightVectors, const Matrix *transposedInvertedCovariances)
Translates the n/i squared errors that correspond to n elements in the error vector to robust errors.
Definition: NonLinearOptimization.h:1767
static bool advancedSparseOptimization(T &advancedSparseProvider, const unsigned int iterations, Scalar lambda, const Scalar lambdaFactor, Scalar *initialError=nullptr, Scalar *finalError=nullptr, Scalars *intermediateErrors=nullptr)
Invokes the optimization of a sparse (matrix) optimization problem using an advanced optimization pro...
Definition: NonLinearOptimization.h:1598
This class implements an optimization for universal dense problems with one model (optimization probl...
Definition: NonLinearUniversalOptimizationDense.h:32
void weightedSelfTransposedSquareMatrix(const MatrixT< T > &weightDiagonal, MatrixT< T > &result) const
Returns the matrix product of transposed matrix of this matrix and this matrix and applies a further ...
MatrixT< T > diagonal() const
Returns a vector containing the values of the diagonal.
size_t columns() const
Returns the count of columns.
Definition: Matrix.h:698
MatrixT< T > selfTransposedSquareMatrix() const
Returns the matrix product of transposed matrix of this matrix and this matrix.
MatrixT< T > transposedMultiply(const MatrixT< T > &right) const
Multiplies this transposed matrix with a second matrix.
size_t elements() const
Returns the number of entire elements, which is the product of rows and columns.
Definition: Matrix.h:704
T norm() const
Determines the L1 norm (sum of absolute elements) of this matrix.
Definition: Matrix.h:772
@ MP_SYMMETRIC
The matrix is symmetric.
Definition: Matrix.h:79
size_t rows() const
Returns the count of rows.
Definition: Matrix.h:692
bool selfSquareDiagonalMatrixMultiply(const MatrixT< T > &right, MatrixT< T > &result) const
Interprets this matrix as diagonal matrix and multiplies a second matrix on the right of the interpre...
bool solve(const MatrixT< T > &b, MatrixT< T > &x, const MatrixProperty matrixProperty=MP_UNKNOWN) const
Solves the given linear system.
Definition: Matrix.h:710
static constexpr T minValue()
Returns the min scalar value.
Definition: Numeric.h:3250
static constexpr T weakEps()
Returns a weak epsilon.
static constexpr bool isWeakEqualEps(const T value)
Returns whether a value is smaller than or equal to a weak epsilon.
Definition: Numeric.h:2162
static constexpr T eps()
Returns a small epsilon.
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition: Numeric.h:2386
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition: Numeric.h:1495
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition: Numeric.h:2087
static constexpr bool isNotEqualEps(const T value)
Returns whether a value is not smaller than or equal to a small epsilon.
Definition: Numeric.h:2237
static T summedSqr(const T *values, const size_t number)
Returns the summed squares of a given values.
Definition: Numeric.h:1514
static constexpr T maxValue()
Returns the max scalar value.
Definition: Numeric.h:3244
This class implements a sparse matrix using a float type for its elements that is specified by T.
Definition: SparseMatrix.h:61
bool isZero(const size_t row, const size_t column) const
Returns whether a specified elements is zero.
size_t rows() const
Returns the number of rows this matrix has.
size_t columns() const
Returns the number of columns this matrix has.
bool solve(const MatrixT< T > &b, MatrixT< T > &x) const
Solves the given linear system.
MatrixT< T > diagonal() const
Returns a vector containing the values of the diagonal.
SparseMatrixT< T > transposed() const
Returns the transposes matrix of this matrix.
This class implements a 2x2 square matrix.
Definition: SquareMatrix2.h:73
SquareMatrixT2< T > transposed() const
Returns the transposed of this matrix.
Definition: SquareMatrix2.h:663
This class implements a static buffer that has a fixed capacity.
Definition: StaticBuffer.h:24
const T * data() const
Returns the buffer data pointer.
Definition: StaticBuffer.h:240
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition: base/Utilities.h:1029
uint32_t Index32
Definition of a 32 bit index value.
Definition: Base.h:84
SparseMatrixT< Scalar > SparseMatrix
Definition of the SparseMatrix object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with s...
Definition: SparseMatrix.h:23
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Scalar > Scalars
Definition of a vector holding Scalar objects.
Definition: Math.h:144
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15