8#ifndef META_OCEAN_GEOMETRY_NON_LINEAR_OPTIMIZATION_H 
    9#define META_OCEAN_GEOMETRY_NON_LINEAR_OPTIMIZATION_H 
   44        template <
typename TFirst, 
typename TSecond>
 
   52                using Element = std::pair<Index32, Vector2>;
 
   98                inline void element(
const size_t groupIndex, 
const size_t elementIndex, TFirst& first, TSecond& second) 
const;
 
  106                inline const TFirst& 
firstElement(
const size_t groupIndex, 
const size_t elementIndex) 
const;
 
  114                inline const TSecond& 
secondElement(
const size_t groupIndex, 
const size_t elementIndex) 
const;
 
  236                template <
typename TAccessor>
 
  245                template <
typename TAccessor>
 
  261                template <
typename TAccessor>
 
  277                template <
typename TAccessor>
 
  285                inline size_t addObjectPoint(Elements&& poseIdImagePointPairs);
 
 
  299                inline bool hasSolver() 
const;
 
 
  334                inline Scalar determineError();
 
  343                inline bool determineHessianAndErrorJacobian(
Matrix& hessian, 
Matrix& jacobianError);
 
  350                inline void applyCorrection(
const Matrix& deltas);
 
  356                inline void acceptCorrection();
 
  363                inline bool shouldStop();
 
  369                inline bool hasSolver() 
const;
 
  378                inline bool solve(
const Matrix& hessian, 
const Matrix& jacobianError, 
Matrix& deltas) 
const;
 
 
  401                inline Scalar determineError();
 
  409                inline bool determineParameters();
 
  416                inline void applyCorrection(
const Matrix& deltas);
 
  422                inline void acceptCorrection();
 
  429                inline bool shouldStop();
 
 
  465        template <
typename T>
 
  466        static inline 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);
 
  482        template <
typename T, Estimator::EstimatorType tEstimator>
 
  483        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);
 
  499        template <
typename T>
 
  500        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);
 
  516        template <
typename T, Estimator::EstimatorType tEstimator>
 
  517        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);
 
  532        template <
typename T>
 
  533        static bool advancedDenseOptimization(T& advancedDenseProvider, 
const unsigned int iterations, 
Scalar lambda, 
const Scalar lambdaFactor, 
Scalar* initialError = 
nullptr, 
Scalar* finalError = 
nullptr, 
Scalars* intermediateErrors = 
nullptr);
 
  548        template <
typename T>
 
  549        static bool advancedSparseOptimization(T& advancedSparseProvider, 
const unsigned int iterations, 
Scalar lambda, 
const Scalar lambdaFactor, 
Scalar* initialError = 
nullptr, 
Scalar* finalError = 
nullptr, 
Scalars* intermediateErrors = 
nullptr);
 
  561        template <Estimator::EstimatorType tEstimator>
 
  575        template <Estimator::EstimatorType tEstimator, 
size_t tDimension>
 
  589        template <Estimator::EstimatorType tEstimator>
 
  590        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);
 
  615        template <
size_t tDimension>
 
  632template <
typename TFirst, 
typename TSecond>
 
  638template <
typename TFirst, 
typename TSecond>
 
  640    elementGroups_(elementGroups)
 
 
  645template <
typename TFirst, 
typename TSecond>
 
  647    elementGroups_(std::move(elementGroups))
 
 
 
  652template <
typename TFirst, 
typename TSecond>
 
  654    elementGroups_(accessor.elementGroups_)
 
 
  659template <
typename TFirst, 
typename TSecond>
 
  661    elementGroups_(std::move(accessor.elementGroups_))
 
 
  666template <
typename TFirst, 
typename TSecond>
 
  669    return elementGroups_.size();
 
 
  672template <
typename TFirst, 
typename TSecond>
 
  675    ocean_assert(groupIndex < groups());
 
  677    return elementGroups_[groupIndex].size();
 
 
  680template <
typename TFirst, 
typename TSecond>
 
  683    ocean_assert(groupIndex < groups());
 
  684    ocean_assert(elementIndex < groupElements(groupIndex));
 
  686    const Element& element = elementGroups_[groupIndex][elementIndex];
 
  688    first = element.first;
 
  689    second = element.second;
 
 
  692template <
typename TFirst, 
typename TSecond>
 
  695    ocean_assert(groupIndex < groups());
 
  696    ocean_assert(elementIndex < groupElements(groupIndex));
 
  698    return elementGroups_[groupIndex][elementIndex].first;
 
 
  701template <
typename TFirst, 
typename TSecond>
 
  704    ocean_assert(groupIndex < groups());
 
  705    ocean_assert(elementIndex < groupElements(groupIndex));
 
  707    return elementGroups_[groupIndex][elementIndex].second;
 
 
  710template <
typename TFirst, 
typename TSecond>
 
  717template <
typename TFirst, 
typename TSecond>
 
  720    if (
this != &accessor)
 
  722        elementGroups_ = std::move(accessor.elementGroups_);
 
 
  769    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  775    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  786    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  792    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  798    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  803    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  808    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  819    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  830    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  836    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  842    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  847    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  852    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  858    ocean_assert(
false && 
"Must be implemented in a derived class!");
 
 
  862template <
typename TAccessor>
 
  866    ocean_assert(imagePoints0.size() == imagePoints1.size());
 
  868    for (
size_t n = 0; n < imagePoints0.size(); ++n)
 
 
  878template <
typename TAccessor>
 
  884    for (
size_t n = 0; n < imagePointGroups.size(); ++n)
 
  887        ocean_assert(imagePoints.
size() >= 2);
 
  890        poseIndexImagePoints.reserve(imagePoints.
size());
 
  892        for (
size_t i = 0; i < imagePoints.
size(); ++i)
 
  894            poseIndexImagePoints.emplace_back(
Index32(i), imagePoints[i]);
 
 
  901template <
typename TAccessor>
 
  906    ocean_assert(sequentialImagePointGroups.size() % numberObjectPoints == 0);
 
  908    const unsigned int numberImagePoints = (
unsigned int)(sequentialImagePointGroups.size() / numberObjectPoints);
 
  910    unsigned int index = 0u;
 
  912    for (
size_t n = 0; n < numberObjectPoints; ++n)
 
  915        poseIndexImagePoints.reserve(numberImagePoints);
 
  917        for (
unsigned int i = 0u; i < numberImagePoints; ++i)
 
  919            poseIndexImagePoints.emplace_back(
Index32(i), sequentialImagePointGroups[index++]);
 
 
  926template <
typename TAccessor>
 
  931    ocean_assert(imagePoints.size() % numberObjectPoints == 0);
 
  933    ocean_assert(numberObjectPoints != 0);
 
  934    const unsigned int numberImagePoints = (
unsigned int)(imagePoints.size() / numberObjectPoints);
 
  936    unsigned int poseIndex = 0u;
 
  937    unsigned int index = 0u;
 
  939    for (
size_t n = 0; n < numberImagePoints; ++n)
 
  941        for (
size_t i = 0; i < numberObjectPoints; ++i)
 
 
  953    ocean_assert(!poseIdImagePointPairs.empty());
 
  955    const size_t objectPointIndex = elementGroups_.size();
 
  957    elementGroups_.emplace_back(std::move(poseIdImagePointPairs));
 
  959    return objectPointIndex;
 
 
  968            return denseOptimization<T, Estimator::ET_SQUARE>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
  971            return denseOptimization<T, Estimator::ET_LINEAR>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
  974            return denseOptimization<T, Estimator::ET_HUBER>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
  977            return denseOptimization<T, Estimator::ET_TUKEY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
  980            return denseOptimization<T, Estimator::ET_CAUCHY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
  983            ocean_assert(
false && 
"Invalid estimator!");
 
 
  988template <
typename T, Estimator::EstimatorType tEstimator>
 
  993    ocean_assert(lambda >= 
Numeric::eps() && lambda <= maxLambda);
 
  998    Matrix weightedErrorVector, swapWeightedErrorVector;
 
 1000    Matrix weightVector, swapWeightVector;
 
 1002    Matrix JTJ, jErrors, deltas;
 
 1005    Matrix intermediateCovarianceJacobian;
 
 1006    Matrix intermediateWeightedErrorVector;
 
 1008    Scalar bestError = provider.template determineRobustError<tEstimator>(weightedErrorVector, weightVector, invertedCovariances);
 
 1012        ocean_assert(
false && 
"The initial model was invalid and thus the optimization cannot be applied!");
 
 1016    if (initialError != 
nullptr)
 
 1018        *initialError = bestError;
 
 1021    if (intermediateErrors != 
nullptr)
 
 1023        ocean_assert(intermediateErrors->empty());
 
 1024        intermediateErrors->push_back(bestError);
 
 1027    bool oneValidIteration = 
false;
 
 1029    unsigned int i = 0u;
 
 1030    while (i < iterations)
 
 1032        provider.determineJacobian(jacobian);
 
 1035        if (invertedCovariances)
 
 1083        while (i < iterations)
 
 1090                for (
unsigned int n = 0; n < JTJ.
columns(); ++n)
 
 1092                    JTJ(n, n) = JTJdiagonal(n, 0) * (
Scalar(1) + lambda);
 
 1099            bool solved = 
false;
 
 1101            if (provider.hasSolver())
 
 1103                solved = provider.
solve(JTJ, jErrors, deltas);
 
 1112                oneValidIteration = 
true;
 
 1121                provider.applyCorrection(deltas);
 
 1123                const Scalar iterationError = provider.template determineRobustError<tEstimator>(swapWeightedErrorVector, swapWeightVector, invertedCovariances);
 
 1126                if (iterationError >= bestError)
 
 1129                    if (lambdaFactor > 
Numeric::eps() && lambda > 0 && lambda <= maxLambda)
 
 1131                        lambda *= lambdaFactor;
 
 1135                        ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1145                bestError = iterationError;
 
 1147                if (intermediateErrors != 
nullptr)
 
 1149                    intermediateErrors->push_back(bestError);
 
 1152                provider.acceptCorrection();
 
 1154                std::swap(swapWeightedErrorVector, weightedErrorVector);
 
 1155                std::swap(swapWeightVector, weightVector);
 
 1162                        lambda /= lambdaFactor;
 
 1169            else if (lambda > 
Numeric::eps() && lambda <= maxLambda)
 
 1171                lambda *= lambdaFactor;
 
 1175                ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1185        *finalError = bestError;
 
 1188    return oneValidIteration;
 
 
 1191template <
typename T>
 
 1197            return sparseOptimization<T, Estimator::ET_SQUARE>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
 1200            return sparseOptimization<T, Estimator::ET_LINEAR>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
 1203            return sparseOptimization<T, Estimator::ET_HUBER>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
 1206            return sparseOptimization<T, Estimator::ET_TUKEY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
 1209            return sparseOptimization<T, Estimator::ET_CAUCHY>(provider, iterations, lambda, lambdaFactor, initialError, finalError, invertedCovariances, intermediateErrors);
 
 1212            ocean_assert(
false && 
"Invalid estimator!");
 
 
 1217template <
typename T, Estimator::EstimatorType tEstimator>
 
 1222    ocean_assert(lambda >= 
Numeric::eps() && lambda <= maxLambda);
 
 1227    Matrix weightedErrorVector, swapWeightedErrorVector;
 
 1229    Matrix weightVector, swapWeightVector;
 
 1236    Scalar bestError = provider.template determineRobustError<tEstimator>(weightedErrorVector, weightVector, invertedCovariances);
 
 1240        ocean_assert(
false && 
"The initial model was invalid and thus the optimization cannot be applied!");
 
 1246        *initialError = bestError;
 
 1249    if (intermediateErrors != 
nullptr)
 
 1251        ocean_assert(intermediateErrors->empty());
 
 1252        intermediateErrors->push_back(bestError);
 
 1255    bool oneValidIteration = 
false;
 
 1257    unsigned int i = 0u;
 
 1258    while (i < iterations)
 
 1260        provider.determineJacobian(jacobian);
 
 1263        if (invertedCovariances)
 
 1275                JTJ = jacobianTransposed * (invertedCovarianceMatrix * jacobian);
 
 1281                JTJ = jacobianTransposed * (invertedCovarianceMatrix * (
SparseMatrix(weightVector.
rows(), weightVector.
rows(), weightVector, 
true) * jacobian));
 
 1286            jErrors = jacobianTransposed * (invertedCovarianceMatrix * weightedErrorVector);
 
 1301                JTJ = jacobianTransposed * jacobian;
 
 1307                JTJ = jacobianTransposed * 
SparseMatrix(weightVector.
rows(), weightVector.
rows(), weightVector, 
true) * jacobian;
 
 1312            jErrors = jacobianTransposed * weightedErrorVector;
 
 1318        while (i < iterations)
 
 1325                for (
unsigned int n = 0; n < JTJ.
columns(); ++n)
 
 1327                    if (JTJdiagonal(n, 0) != 
Scalar(0))
 
 1329                        ocean_assert(!JTJ.
isZero(n, n));
 
 1330                        JTJ(n, n) = JTJdiagonal(n, 0) * (
Scalar(1) + lambda);
 
 1338            bool solved = 
false;
 
 1340            if (provider.hasSolver())
 
 1342                solved = provider.
solve(JTJ, jErrors, deltas);
 
 1346                solved = JTJ.
solve(jErrors, deltas);
 
 1351                oneValidIteration = 
true;
 
 1360                provider.applyCorrection(deltas);
 
 1362                const Scalar iterationError = provider.template determineRobustError<tEstimator>(swapWeightedErrorVector, swapWeightVector, invertedCovariances);
 
 1365                if (iterationError >= bestError)
 
 1368                    if (lambdaFactor > 
Numeric::eps() && lambda > 0 && lambda <= maxLambda)
 
 1370                        lambda *= lambdaFactor;
 
 1374                        ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1384                bestError = iterationError;
 
 1386                if (intermediateErrors != 
nullptr)
 
 1388                    intermediateErrors->push_back(bestError);
 
 1391                provider.acceptCorrection();
 
 1393                std::swap(swapWeightedErrorVector, weightedErrorVector);
 
 1394                std::swap(swapWeightVector, weightVector);
 
 1401                        lambda /= lambdaFactor;
 
 1408            else if (lambda > 
Numeric::eps() && lambda <= maxLambda)
 
 1410                lambda *= lambdaFactor;
 
 1414                ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1424        *finalError = bestError;
 
 1427    return oneValidIteration;
 
 
 1430template <
typename T>
 
 1435    ocean_assert(lambda >= 
Scalar(0) && lambda <= maxLambda);
 
 1436    ocean_assert((lambda == 
Scalar(0) && lambdaFactor == 
Scalar(1)) || (lambda > 
Scalar(0) && lambdaFactor > 
Scalar(1)));
 
 1438    const bool useLevenbergMarquardt = (lambda > 0 && lambdaFactor > 1);
 
 1441    Scalar bestError = (useLevenbergMarquardt || initialError) ? advancedDenseProvider.determineError() : 
Numeric::minValue();
 
 1445        ocean_assert(
false && 
"The initial model was invalid and thus the optimization cannot be applied!");
 
 1451        *initialError = bestError;
 
 1454    if (intermediateErrors != 
nullptr)
 
 1456        ocean_assert(intermediateErrors->empty());
 
 1457        intermediateErrors->push_back(bestError);
 
 1460    bool oneValidIteration = 
false;
 
 1462    Matrix hessian, jacobianError, deltas;
 
 1464    unsigned int i = 0u;
 
 1465    while (!advancedDenseProvider.shouldStop() && i < iterations)
 
 1473        if (!advancedDenseProvider.determineHessianAndErrorJacobian(hessian, jacobianError))
 
 1475            ocean_assert(
false && 
"The Hessian and the Jacobian with combined error values could not be determined!");
 
 1479        ocean_assert(hessian.
rows() == hessian.
columns());
 
 1480        ocean_assert(hessian.
rows() == jacobianError.
rows() && jacobianError.
columns() == 1);
 
 1485        ocean_assert(hessianDiagonal.
rows() == hessian.
rows() && hessianDiagonal.
columns() == 1);
 
 1487        while (!advancedDenseProvider.shouldStop() && i++ < iterations)
 
 1493                for (
unsigned int n = 0; n < hessian.
columns(); ++n)
 
 1495                    hessian(n, n) = hessianDiagonal(n, 0) * (
Scalar(1) + lambda);
 
 1501            bool solved = 
false;
 
 1503            if (advancedDenseProvider.hasSolver())
 
 1505                solved = advancedDenseProvider.
solve(hessian, jacobianError, deltas);
 
 1514                oneValidIteration = 
true;
 
 1523                advancedDenseProvider.applyCorrection(deltas);
 
 1525                const Scalar iterationError = (useLevenbergMarquardt || intermediateErrors) ? advancedDenseProvider.determineError() : 
Numeric::minValue();
 
 1528                if (useLevenbergMarquardt && iterationError >= bestError)
 
 1531                    if (lambda > 0 && lambda <= maxLambda)
 
 1533                        lambda *= lambdaFactor;
 
 1537                        ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1547                bestError = iterationError;
 
 1549                if (intermediateErrors != 
nullptr)
 
 1551                    intermediateErrors->push_back(bestError);
 
 1554                advancedDenseProvider.acceptCorrection();
 
 1561                        lambda /= lambdaFactor;
 
 1568            else if (lambda > 
Numeric::eps() && lambda <= maxLambda)
 
 1570                lambda *= lambdaFactor;
 
 1574                ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1585        if (!useLevenbergMarquardt && !intermediateErrors)
 
 1587            bestError = advancedDenseProvider.determineError();
 
 1590        *finalError = bestError;
 
 1593    return oneValidIteration;
 
 
 1596template <
typename T>
 
 1601    ocean_assert(lambda >= 
Scalar(0) && lambda <= maxLambda);
 
 1602    ocean_assert((lambda == 
Scalar(0) && lambdaFactor == 
Scalar(1)) || (lambda > 
Scalar(0) && lambdaFactor > 
Scalar(1)));
 
 1604    const bool useLevenbergMarquardt = (lambda > 0 && lambdaFactor > 1);
 
 1607    Scalar bestError = (useLevenbergMarquardt || initialError) ? advancedSparseProvider.determineError() : 
Numeric::minValue();
 
 1611        ocean_assert(
false && 
"The initial model was invalid and thus the optimization cannot be applied!");
 
 1617        *initialError = bestError;
 
 1620    if (intermediateErrors != 
nullptr)
 
 1622        ocean_assert(intermediateErrors->empty());
 
 1623        intermediateErrors->push_back(bestError);
 
 1626    bool oneValidIteration = 
false;
 
 1630    unsigned int i = 0u;
 
 1631    while (!advancedSparseProvider.shouldStop() && i < iterations)
 
 1637        if (!advancedSparseProvider.determineParameters())
 
 1639            ocean_assert(
false && 
"The provider failed to determine the abstract parameters.");
 
 1643        while (!advancedSparseProvider.shouldStop() && i++ < iterations)
 
 1645            ocean_assert(lambda >= 
Scalar(0));
 
 1646            if (advancedSparseProvider.solve(deltas, lambda))
 
 1648                oneValidIteration = 
true;
 
 1657                advancedSparseProvider.applyCorrection(deltas);
 
 1659                const Scalar iterationError = (useLevenbergMarquardt || intermediateErrors) ? advancedSparseProvider.determineError() : 
Numeric::minValue();
 
 1662                if (useLevenbergMarquardt && iterationError >= bestError)
 
 1665                    if (lambda > 0 && lambda <= maxLambda)
 
 1667                        lambda *= lambdaFactor;
 
 1671                        ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1681                bestError = iterationError;
 
 1683                if (intermediateErrors != 
nullptr)
 
 1685                    intermediateErrors->push_back(bestError);
 
 1688                advancedSparseProvider.acceptCorrection();
 
 1695                        lambda /= lambdaFactor;
 
 1702            else if (lambda > 
Numeric::eps() && lambda <= maxLambda)
 
 1704                lambda *= lambdaFactor;
 
 1708                ocean_assert(oneValidIteration && 
"At this moment we should have at least one valid iteration!");
 
 1719        if (!useLevenbergMarquardt && !intermediateErrors)
 
 1721            bestError = advancedSparseProvider.determineError();
 
 1724        *finalError = bestError;
 
 1727    return oneValidIteration;
 
 
 1730template <Estimator::EstimatorType tEstimator>
 
 1734    const Scalar sqrSigma = Estimator::needSigma<tEstimator>() ? 
Numeric::sqr(Estimator::determineSigmaSquare<tEstimator>(sqrErrors.data(), sqrErrors.size(), modelParameters)) : 0;
 
 1738    for (
size_t n = 0; n < sqrErrors.size(); ++n)
 
 1744        const Scalar weight = max(
Numeric::weakEps(), Estimator::robustWeightSquare<tEstimator>(sqrErrors[n], sqrSigma));
 
 1747        if (transposedInvertedCovariances)
 
 1749            robustError += (transposedInvertedCovariances[n].
transposed() * weightedErrors[n]).
sqr() * weight;
 
 1753            robustError += sqrErrors[n] * weight;
 
 1756        weightedErrors[n] *= weight;
 
 1758        weightVectors[n] = 
Vector2(weight, weight);
 
 1762    return robustError / 
Scalar(sqrErrors.size());
 
 
 1765template <Estimator::EstimatorType tEstimator, 
size_t tDimension>
 
 1768    ocean_assert(transposedInvertedCovariances == 
nullptr && 
"Currently not implemented");
 
 1769    OCEAN_SUPPRESS_UNUSED_WARNING(transposedInvertedCovariances);
 
 1772    const Scalar sqrSigma = Estimator::needSigma<tEstimator>() ? 
Numeric::sqr(Estimator::determineSigmaSquare<tEstimator>(sqrErrors.data(), sqrErrors.size(), modelParameters)) : 0;
 
 1776    for (
size_t n = 0; n < sqrErrors.size(); ++n)
 
 1785        const Scalar weight = max(
Numeric::weakEps(), Estimator::robustWeightSquare<tEstimator>(sqrErrors[n], sqrSigma));
 
 1788        robustError += sqrErrors[n] * weight;
 
 1790        for (
size_t d = 0; d < tDimension; ++d)
 
 1792            weightedErrorsPointer[d] *= weight;
 
 1793            weightVectorsPointer[d] = weight;
 
 1798    return robustError / 
Scalar(sqrErrors.size());
 
 
 1801template <Estimator::EstimatorType tEstimator>
 
 1804    ocean_assert(transposedInvertedCovariances_i == 
nullptr && 
"Currently not implemented");
 
 1805    OCEAN_SUPPRESS_UNUSED_WARNING(transposedInvertedCovariances_i);
 
 1808    const Scalar sqrSigma = Estimator::needSigma<tEstimator>() ? 
Numeric::sqr(Estimator::determineSigmaSquare<tEstimator>(sqrErrors.data(), sqrErrors.size(), modelParameters)) : 0;
 
 1812    for (
size_t n = 0; n < sqrErrors.size(); ++n)
 
 1814        Scalar* 
const weightedErrorsPointer = weightedErrors_i + n * dimension;
 
 1815        Scalar* 
const weightVectorsPointer = weightVectors_i + n * dimension;
 
 1820        const Scalar weight = Estimator::robustWeightSquare<tEstimator>(sqrErrors[n], sqrSigma);
 
 1823        robustError += sqrErrors[n] * weight;
 
 1825        for (
size_t d = 0; d < dimension; ++d)
 
 1827            weightedErrorsPointer[d] *= weight;
 
 1828            weightVectorsPointer[d] = weight;
 
 1833    return robustError / 
Scalar(sqrErrors.size());
 
 
 1841            return sqrErrors2robustErrors2<Estimator::ET_SQUARE>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1844            return sqrErrors2robustErrors2<Estimator::ET_LINEAR>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1847            return sqrErrors2robustErrors2<Estimator::ET_HUBER>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1850            return sqrErrors2robustErrors2<Estimator::ET_TUKEY>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1853            return sqrErrors2robustErrors2<Estimator::ET_CAUCHY>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1856            ocean_assert(
false && 
"Invalid estimator!");
 
 
 1861template <
size_t tDimension>
 
 1867            return sqrErrors2robustErrors<Estimator::ET_SQUARE, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1870            return sqrErrors2robustErrors<Estimator::ET_LINEAR, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1873            return sqrErrors2robustErrors<Estimator::ET_HUBER, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1876            return sqrErrors2robustErrors<Estimator::ET_TUKEY, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1879            return sqrErrors2robustErrors<Estimator::ET_CAUCHY, tDimension>(sqrErrors, modelParameters, weightedErrors, weightVectors, transposedInvertedCovariances);
 
 1882            ocean_assert(
false && 
"Invalid estimator!");
 
 
 1892            return sqrErrors2robustErrors_i<Estimator::ET_SQUARE>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
 
 1895            return sqrErrors2robustErrors_i<Estimator::ET_LINEAR>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
 
 1898            return sqrErrors2robustErrors_i<Estimator::ET_HUBER>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
 
 1901            return sqrErrors2robustErrors_i<Estimator::ET_TUKEY>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
 
 1904            return sqrErrors2robustErrors_i<Estimator::ET_CAUCHY>(sqrErrors, modelParameters, dimension, weightedErrors_i, weightVectors_i, transposedInvertedCovariances_i);
 
 1907            ocean_assert(
false && 
"Invalid estimator!");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
virtual size_t size() const =0
Returns the number of accessible elements of this accessor object.
This class implements a base class for all indexed-based accessors allowing a constant reference acce...
Definition Accessor.h:241
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:326
void acceptCorrection()
Accepts the current model candidate a new (better) model than the previous one.
Definition NonLinearOptimization.h:801
Scalar determineError()
Determines the error for the current model candidate (not the actual model).
Definition NonLinearOptimization.h:784
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:790
bool hasSolver() const
Returns whether the provider comes with an own solver for the linear equation.
Definition NonLinearOptimization.h:812
bool shouldStop()
Returns whether the optimization process should stop e.g., due to an external event.
Definition NonLinearOptimization.h:806
bool solve(const Matrix &hessian, const Matrix &jacobianError, Matrix &deltas) const
Solves the linear equation Hessian * deltas = -jacobianError.
Definition NonLinearOptimization.h:817
AdvancedDenseOptimizationProvider()
Protected default constructor.
Definition NonLinearOptimization.h:779
void applyCorrection(const Matrix &deltas)
Creates a new model candidate by adjusting the current model with delta values.
Definition NonLinearOptimization.h:796
This class implements the base class for an advanced sparse optimization provider.
Definition NonLinearOptimization.h:393
void acceptCorrection()
Accepts the current model candidate a new (better) model than the previous one.
Definition NonLinearOptimization.h:845
bool determineParameters()
Determines any kind of (abstract) parameters based on the current/actual model (not the model candida...
Definition NonLinearOptimization.h:834
bool shouldStop()
Returns whether the optimization process should stop e.g., due to an external event.
Definition NonLinearOptimization.h:850
Scalar determineError()
Determines the error for the current model candidate (not the actual/actual model).
Definition NonLinearOptimization.h:828
bool solve(Matrix &deltas, const Scalar lambda=Scalar(0))
Solves the linear equation Hessian * deltas = -jacobianError based on the internal data.
Definition NonLinearOptimization.h:856
void applyCorrection(const Matrix &deltas)
Creates a new model candidate by adjusting the current/actual model with delta values.
Definition NonLinearOptimization.h:840
AdvancedSparseOptimizationProvider()
Protected default constructor.
Definition NonLinearOptimization.h:823
This class implements the base class for an accessor of groups of pairs.
Definition NonLinearOptimization.h:46
CorrespondenceGroupsAccessor(CorrespondenceGroupsAccessor< TFirst, TSecond > &&accessor)
Move constructor.
Definition NonLinearOptimization.h:660
size_t groupElements(const size_t groupIndex) const
Returns the number of elements within a specified group.
Definition NonLinearOptimization.h:673
size_t groups() const
Returns the number of groups of this accessor.
Definition NonLinearOptimization.h:667
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:702
CorrespondenceGroupsAccessor< TFirst, TSecond > & operator=(CorrespondenceGroupsAccessor< TFirst, TSecond > &&accessor)
Move constructor.
Definition NonLinearOptimization.h:718
CorrespondenceGroupsAccessor(const ElementGroups &elementGroups)
Creates a new accessor object.
Definition NonLinearOptimization.h:639
CorrespondenceGroupsAccessor< TFirst, TSecond > & operator=(const CorrespondenceGroupsAccessor< TFirst, TSecond > &accessor)
Copy constructor.
Definition NonLinearOptimization.h:711
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:681
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:693
CorrespondenceGroupsAccessor()
Creates a new accessor object.
Definition NonLinearOptimization.h:633
std::vector< Elements > ElementGroups
Definition of a vector holding a group of elements.
Definition NonLinearOptimization.h:62
CorrespondenceGroupsAccessor(const CorrespondenceGroupsAccessor< TFirst, TSecond > &accessor)
Copy constructor.
Definition NonLinearOptimization.h:653
std::vector< Element > Elements
Definition of a vector holding elements.
Definition NonLinearOptimization.h:57
std::pair< Index32, Vector2 > Element
Definition of a pair combining an object point id with an image point.
Definition NonLinearOptimization.h:52
CorrespondenceGroupsAccessor(ElementGroups &&elementGroups)
Creates a new accessor object.
Definition NonLinearOptimization.h:646
ElementGroups elementGroups_
The groups of elements of this accessor.
Definition NonLinearOptimization.h:150
This class implements an abstract specialization of the accessor for groups of pairs for object point...
Definition NonLinearOptimization.h:158
ObjectPointGroupsAccessor()
Creates a new accessor object.
Definition NonLinearOptimization.h:728
This class implements a group accessor providing access to pairs of poses and image points.
Definition NonLinearOptimization.h:222
size_t addObjectPoint(Elements &&poseIdImagePointPairs)
Adds the observations of a new object point to this accessor.
Definition NonLinearOptimization.h:951
ObjectPointToPoseIndexImagePointCorrespondenceAccessor()=default
Default constructor.
This class implements the base optimization provider.
Definition NonLinearOptimization.h:292
bool solve(const Matrix &JTJ, const Matrix &jErrors, Matrix &deltas) const
Solves the linear equation JTJ * deltas = jErrors.
Definition NonLinearOptimization.h:767
bool hasSolver() const
Returns whether the provider comes with an own solver for the linear equation.
Definition NonLinearOptimization.h:762
This class implements an abstract specialization of the accessor for groups of pairs for poses.
Definition NonLinearOptimization.h:184
PoseGroupsAccessor()
Creates a new accessor object.
Definition NonLinearOptimization.h:745
This class implements the basic functions for least square or robust optimization algorithms for non ...
Definition NonLinearOptimization.h:33
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:963
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:1192
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:1802
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:1731
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:1431
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:1766
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:1597
This class implements an optimization for universal dense problems with one model (optimization probl...
Definition NonLinearUniversalOptimizationDense.h:32
MatrixT< T > transposedMultiply(const MatrixT< T > &right) const
Multiplies this transposed matrix with a second matrix.
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 ...
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.
size_t elements() const
Returns the number of entire elements, which is the product of rows and columns.
Definition Matrix.h:704
MatrixT< T > diagonal() const
Returns a vector containing the values of the diagonal.
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:3253
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:2165
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:2389
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:2090
static constexpr bool isNotEqualEps(const T value)
Returns whether a value is not smaller than or equal to a small epsilon.
Definition Numeric.h:2240
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:3247
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.
SparseMatrixT< T > transposed() const
Returns the transposes matrix of this matrix.
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.
This class implements a 2x2 square matrix.
Definition SquareMatrix2.h:73
SquareMatrixT2< T > transposed() const
Returns the transposed of this matrix.
Definition SquareMatrix2.h:665
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:1053
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:30
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Scalar > Scalars
Definition of a vector holding Scalar objects.
Definition Math.h:145
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15