21 #ifndef BOGUS_CADOUX_HPP
22 #define BOGUS_CADOUX_HPP
24 #include "../Core/BlockSolvers/ConstrainedSolverBase.impl.hpp"
26 #include "../Extra/SecondOrder.impl.hpp"
27 #include "../Core/Utils/CppTools.hpp"
44 template<
unsigned Dimension,
typename WType,
typename Method,
typename MatrixT >
45 static typename WType::Scalar solveCadoux(
47 const typename WType::Scalar* b,
const typename WType::Scalar* mu,
48 ConstrainedSolverBase< Method, MatrixT > &minimizer,
49 typename WType::Scalar *r,
const unsigned cadouxIterations,
50 const Signal<unsigned, typename WType::Scalar> *callback = BOGUS_NULL_PTR(
const void),
51 const typename WType::Scalar tolTighten = 1.e-1
56 typedef typename WType::Scalar Scalar ;
57 const std::ptrdiff_t n = W.rowsOfBlocks() ;
59 SOCLaw< Dimension, Scalar, true > coulombLaw ( n, mu ) ;
60 SOCLaw< Dimension, Scalar, false > socLaw ( n, mu ) ;
62 Eigen::Map< Eigen::VectorXd > r_map ( r, W.rows() ) ;
63 Eigen::Map< const Eigen::VectorXd > b_map ( b, W.rows() ) ;
65 Eigen::VectorXd s( W.rows() ) ;
68 const Scalar tol = minimizer.tol() ;
71 s = W * r_map + b_map ;
72 res = minimizer.eval( coulombLaw, s, r_map ) ;
73 if( callback ) callback->trigger( 0, res ) ;
75 for(
unsigned cdxIter = 0 ; cdxIter < cadouxIterations ; ++cdxIter )
77 minimizer.setTol( tolTighten * std::max( tol, std::min( res, 1. ) ) ) ;
79 minimizer.dualityCOV( coulombLaw, s, s ) ;
82 minimizer.solve( socLaw, s, r_map ) ;
85 s = W * r_map + b_map ;
86 res = minimizer.eval( coulombLaw, s, r_map ) ;
88 if( callback ) callback->trigger( cdxIter+1, res ) ;
89 if( res < tol ) break ;
93 minimizer.setTol( tol ) ;
100 template<
unsigned Dimension,
typename WType,
typename Method,
typename MatrixT >
101 static double solveCadouxVel(
103 const typename WType::Scalar* b,
const typename WType::Scalar* mu,
104 ConstrainedSolverBase< Method, MatrixT > &minimizer,
105 typename WType::Scalar* u,
const unsigned cadouxIterations,
106 const Signal<unsigned, typename WType::Scalar> *callback = BOGUS_NULL_PTR(
const void),
107 const typename WType::Scalar tolTighten = 1.e-1
114 typedef typename WType::Scalar Scalar ;
115 const std::ptrdiff_t n = W.rowsOfBlocks() ;
117 SOCLaw< Dimension, Scalar, false > socLaw ( n, mu ) ;
119 Eigen::Map< Eigen::VectorXd > u_map ( u, W.rows() ) ;
120 Eigen::Map< const Eigen::VectorXd > b_map ( b, W.rows() ) ;
122 Eigen::VectorXd s( W.rows() ), Wsb( W.rows() ), ustar( u_map ), r( W.rows() ) ;
125 const double tol = minimizer.tol() ;
127 #ifndef BOGUS_DONT_PARALLELIZE
128 #pragma omp parallel for
130 for( std::ptrdiff_t i = 0 ; i < n ; ++i )
132 s[ Dimension*i ] = u_map.segment< Dimension-1 >( Dimension*i+1 ).norm() * std::max(0., 1./mu[i]) ;
133 s.segment< Dimension-1 >( Dimension*i+1 ).setZero() ;
138 r = W * u_map + b_map ;
139 res = minimizer.eval( socLaw, r, ustar ) ;
140 if( callback ) callback->trigger( 0, res ) ;
142 for(
unsigned cdxIter = 0 ; cdxIter < cadouxIterations ; ++cdxIter )
144 minimizer.setTol( tolTighten * std::max( tol, std::min( res, 1. ) ) ) ;
146 Wsb = b_map - W * s ;
148 minimizer.solve( socLaw, Wsb, ustar ) ;
152 #ifndef BOGUS_DONT_PARALLELIZE
153 #pragma omp parallel for
155 for( std::ptrdiff_t i = 0 ; i < n ; ++i )
157 s[ Dimension*i ] = ustar.segment< Dimension-1 >( Dimension*i+1 ).norm() * std::max(0., 1./mu[i]) ;
158 s.segment< Dimension-1 >( Dimension*i+1 ).setZero() ;
164 r = W * u_map + b_map ;
165 res = minimizer.eval( socLaw, r, ustar ) ;
167 if( callback ) callback->trigger( cdxIter+1, res ) ;
168 if( cdxIter > 0 && res < tol ) break ;
172 minimizer.setTol( tol ) ;