39 #ifndef __INCLUDE_MIST_MINIMIZATION__
40 #define __INCLUDE_MIST_MINIMIZATION__
43 #ifndef __INCLUDE_MIST_CONF_H__
48 #ifndef __INCLUDE_MIST_MATRIX__
53 #ifndef __INCLUDE_MIST_LIMITS__
67 namespace __minimization_utility__
69 template <
class T,
class Allocator,
class Functor >
70 struct __convert_to_vector_functor__
72 typedef typename matrix< T, Allocator >::size_type size_type;
73 const matrix< T, Allocator > &ori_;
74 const matrix< T, Allocator > &dir_;
75 matrix< T, Allocator > &tmp_;
78 __convert_to_vector_functor__(
const matrix< T, Allocator > &ori,
const matrix< T, Allocator > &dir, matrix< T, Allocator > &tmp, Functor &f ) : ori_( ori ), dir_( dir ), tmp_( tmp ), f_( f ){ }
80 double operator ()(
double x )
82 for( size_type i = 0 ; i < ori_.size( ) ; i++ )
84 tmp_[ i ] = ori_[ i ] + dir_[ i ] * x;
91 template <
class Functor >
92 struct __no_copy_constructor_functor__
95 __no_copy_constructor_functor__( Functor &f ) : f_( f ){ }
97 template <
class PARAMETER >
98 double operator ()(
const PARAMETER &x )
103 template <
class PARAMETER >
104 double operator ()(
const PARAMETER &x )
const
109 template <
class PARAMETER >
110 double operator ()(
const PARAMETER &x,
size_t index )
112 return( f_( x, index ) );
115 template <
class PARAMETER >
116 double operator ()(
const PARAMETER &x,
size_t index )
const
118 return( f_( x, index ) );
123 template <
class T,
class Allocator,
class Functor >
124 struct __gradient_vector_functor__
126 typedef typename matrix< T, Allocator >::size_type size_type;
127 typedef matrix< T, Allocator > matrix_type;
131 __gradient_vector_functor__( Functor &f,
double d ) : f_( f ), d_( d ){ }
133 const matrix_type operator ()(
const matrix_type &v )
const
135 matrix_type dir( v.size( ), 1 ), tmp( v );
136 double len = 0.0, v1, v2;
139 for( i = 0 ; i < dir.size( ) ; i++ )
141 tmp[ i ] = v[ i ] + d_;
144 tmp[ i ] = v[ i ] - d_;
150 len += dir[ i ] * dir[ i ];
156 len = std::sqrt( len );
157 for( i = 0 ; i < dir.size( ) ; i++ )
167 template <
class T,
class Allocator >
168 inline bool clipping( matrix< T, Allocator > &p1, matrix< T, Allocator > &p2,
const double d1,
const double d2,
const double d )
170 typedef matrix< T, Allocator > matrix_type;
172 bool c1 = d + d1 >= 0;
173 bool c2 = d + d2 >= 0;
179 else if( !c1 && !c2 )
188 p1 = v2 + ( v1 - v2 ) * ( ( d + d2 ) / ( d2 - d1 ) );
192 p2 = v1 + ( v2 - v1 ) * ( ( d + d1 ) / ( d1 - d2 ) );
198 template <
class T,
class Allocator >
199 inline bool clipping( matrix< T, Allocator > &p1, matrix< T, Allocator > &p2,
const matrix< T, Allocator > &p,
const matrix< T, Allocator > &dir,
const matrix< T, Allocator > &box )
201 typedef matrix< T, Allocator > matrix_type;
202 typedef typename matrix_type::value_type value_type;
203 typedef typename matrix_type::size_type size_type;
205 double infinity = 0.0;
208 matrix_type offset( p.size( ), 1 );
211 for( r = 0 ; r < box.rows( ) ; r++ )
213 double l = ( box( r, 0 ) - box( r, 1 ) );
215 offset[ r ] = ( box( r, 0 ) + box( r, 1 ) ) / 2.0;
218 infinity = std::sqrt( infinity );
221 p1 = p - dir * infinity - offset;
222 p2 = p + dir * infinity - offset;
226 for( r = 0 ; r < box.rows( ) ; r++ )
229 flag = flag && clipping( p1, p2, p1[ r ], p2[ r ], std::abs( box( r, 0 ) - offset[ r ] ) );
232 flag = flag && clipping( p1, p2, -p1[ r ], -p2[ r ], std::abs( box( r, 1 ) - offset[ r ] ) );
241 template <
class T,
class Allocator >
242 inline bool clipping_length(
double &l1,
double &l2,
const matrix< T, Allocator > &p,
const matrix< T, Allocator > &dir,
const matrix< T, Allocator > &box )
244 typedef matrix< T, Allocator > matrix_type;
245 typedef typename matrix_type::value_type value_type;
246 typedef typename matrix_type::size_type size_type;
250 if( !clipping( p1, p2, p, dir, box ) )
258 for( size_type r = 0 ; r < p1.size( ) ; r++ )
260 l1 += ( p[ r ] - p1[ r ] ) * ( p[ r ] - p1[ r ] );
261 l2 += ( p[ r ] - p2[ r ] ) * ( p[ r ] - p2[ r ] );
265 l1 = - std::sqrt( l1 ) + 0.000000000001;
266 l2 = + std::sqrt( l2 ) - 0.000000000001;
272 return( l1 < 0.0 || l2 > 0.0 );
307 template <
class Functor >
308 bool enclose(
double &a,
double &b,
double &c,
double &fa,
double &fb,
double &fc, Functor f,
size_t max_iterations = 100 )
310 const double gold = ( 3.0 - std::sqrt( 5.0 ) ) / 2.0;
311 const double _1_gold = 1.0 / gold;
313 const double limit = 100.0;
335 c = a + _1_gold * ( b - a );
339 if( fa == fb && fb == fc )
347 while( fb > fc && ite++ < max_iterations )
352 double fcb = fc - fb;
353 double fba = fb - fa;
356 double l1 = 2.0 * ( cb * fba - ba * fcb );
357 double l2 = std::abs( l1 );
358 double x = b + ( ba * ba * fcb + cb * cb * fba ) / ( l1 / l2 * ( l2 + dust ) );
360 if( ( c - x ) * ( x - b ) > 0 )
382 else if( ( b + limit * cb - x ) * ( x - c ) > 0 )
397 c = a + _1_gold * ( b - a );
418 c = a + _1_gold * ( b - a );
425 return( ite < max_iterations );
451 template <
class Functor >
452 double minimization(
double a,
double b,
double &x, Functor f,
double tolerance,
size_t &iterations,
size_t max_iterations,
bool use_enclose =
true )
455 const double gold = ( 3.0 - std::sqrt( 5.0 ) ) / 2.0;
461 if( !
enclose( a, p, b, fa, fp, fb, f ) )
478 if( std::abs( p - a ) > std::abs( p - b ) )
497 p = a + gold * ( b - a );
498 q = b - gold * ( b - a );
505 for( ; std::abs( a - b ) > tolerance * ( std::abs( p ) + std::abs( q ) ) && ite < max_iterations ; ite++ )
512 q = p + gold * ( b - p );
521 p = q - gold * ( q - a );
560 template <
class Functor >
561 double minimization(
double a,
double b,
double &x, Functor f,
double tolerance,
size_t max_iterations = 1000,
bool use_enclose =
true )
563 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
565 return(
minimization( a, b, x, __no_copy_constructor_functor__( f ), tolerance, itenum, max_iterations, use_enclose ) );
593 template <
class Functor >
594 double minimization(
double a,
double b,
double &x, Functor f,
double tolerance,
size_t &iterations,
size_t max_iterations,
bool use_enclose =
true )
596 double u, v, w, fu, fv, fw, fx, e = 0.0, d = 0.0;
597 const double c = ( 3.0 - std::sqrt( 5.0 ) ) / 2.0;
603 if( !
enclose( a, x, b, fa, fx, fb, f ) )
636 v = w = x = a + c * ( b - a );
637 fv = fw = fx = f( x );
641 for( ite = 1 ; ite <= max_iterations ; ite++ )
643 double m = ( a + b ) * 0.5;
644 double tol = 1.0e-12 * std::abs( x ) + tolerance;
645 double t2 = 2.0 * tol;
648 if( std::abs( x - m ) <= t2 - 0.5 * ( b - a ) )
653 double p = 0.0, q = 0.0, r = 0.0;
655 if( std::abs( e ) > tol )
658 r = ( x - w ) * ( fx - fv );
659 q = ( x - v ) * ( fx - fw );
660 p = ( x - v ) * q - ( x - w ) * r;
676 if( std::abs( p ) < std::abs( 0.5 * q * r ) && p > q * ( a - x ) && p < q * ( b - x ) )
683 if( u - a < t2 || b - u < t2 )
685 d = x < m ? tol : -tol;
692 e = ( x < m ? b : a ) - x;
696 u = x + ( std::abs( d ) >= tol ? d : ( d > 0 ? tol : -tol ) );
734 if( fu <= fw || w == x )
741 else if( fu <= fv || v == x || v == w )
773 template <
class Functor >
774 double minimization(
double a,
double b,
double &x, Functor f,
double tolerance,
size_t max_iterations = 1000,
bool use_enclose =
true )
776 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
778 return(
minimization( a, b, x, __no_copy_constructor_functor__( f ), tolerance, itenum, max_iterations, use_enclose ) );
785 template <
class T,
class Allocator>
789 for (
size_t i = 0 ; i < a.
size() ; i++ )
796 template <
class T,
class Allocator>
800 for (
size_t i = 0 ; i < a.
size() ; i++ )
802 res += a[i].r * b[i].r;
803 res += a[i].g * b[i].g;
804 res += a[i].b * b[i].b;
822 template <
class T,
class Allocator,
class Functor,
class T2 >
823 double minimization(
array2< T, Allocator > &p, Functor f,
const array2< T, Allocator > &grad,
const array2< T, Allocator > &d,T2 &data,
const double rho = 0.7,
const double c = 0.1,
const size_t max_iterations = 10)
826 double value = f( p, data );
828 double fd = mul( grad, d );
835 if ( i == max_iterations )
846 for(
size_t k = 0 ; k < p.
size() ; k++ )
848 p[k] = start[k] + alpha * d[k];
855 }
while( err > value + c * alpha * fd );
873 template <
class T,
class Allocator,
class Functor>
877 double value = f( p );
879 double fd = mul( grad, d );
886 if ( i == max_iterations )
897 for(
size_t k = 0 ; k < p.
size() ; k++ )
899 p[k] = start[k] + alpha * d[k];
906 }
while( err > value + c * alpha * fd );
913 namespace gradient_with_vector
928 template <
class T,
class Allocator,
class Functor1,
class Functor2 >
936 matrix_type dir( p.
size( ), 1 ), tmp( p.
size( ), 1 );
937 double x, err, old_err = f( p );
940 __minimization_utility__::__convert_to_vector_functor__< T, Allocator, Functor1 > functor( p, dir, tmp, f );
943 for( ite = 1 ; ite <= max_iterations ; ite++ )
947 for( i = 0 ; i < dir.size( ) ; i++ )
950 dir[ i ] = g( p[ i ], i );
951 len += dir[ i ] * dir[ i ];
957 len = std::sqrt( len );
958 for( i = 0 ; i < dir.size( ) ; i++ )
974 if( 2.0 * std::abs( err - old_err ) <= tolerance * ( std::abs( err ) + std::abs( old_err ) ) || old_err <= err )
1012 template <
class T,
class Allocator,
class Functor1,
class Functor2 >
1020 matrix_type dir( p.
size( ), 1 ), tmp( p.
size( ), 1 );
1021 double x, err, old_err = f( p );
1024 __minimization_utility__::__convert_to_vector_functor__< T, Allocator, Functor1 > functor( p, dir, tmp, f );
1027 for( ite = 1 ; ite <= max_iterations ; ite++ )
1031 for( i = 0 ; i < dir.size( ) ; i++ )
1034 dir[ i ] = g( p[ i ], i );
1035 len += dir[ i ] * dir[ i ];
1041 len = std::sqrt( len );
1042 for( i = 0 ; i < dir.size( ) ; i++ )
1054 if( __minimization_utility__::clipping_length( l1, l2, p, dir, bound ) )
1064 if( 2.0 * std::abs( err - old_err ) <= tolerance * ( std::abs( err ) + std::abs( old_err ) ) || old_err <= err )
1101 template <
class T,
class Allocator,
class Functor1,
class Functor2 >
1104 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor1 > __no_copy_constructor_functor1__;
1105 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor2 > __no_copy_constructor_functor2__;
1107 return(
minimization( p, bound, __no_copy_constructor_functor1__( f ), __no_copy_constructor_functor2__( g ), tolerance, itenum, max_iterations ) );
1123 template <
class T,
class Allocator,
class Functor1,
class Functor2 >
1126 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor1 > __no_copy_constructor_functor1__;
1127 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor2 > __no_copy_constructor_functor2__;
1129 return(
minimization( p, __no_copy_constructor_functor1__( f ), __no_copy_constructor_functor2__( g ), tolerance, itenum, max_iterations ) );
1151 template <
class T,
class Allocator,
class Functor >
1159 matrix_type dir( p.
size( ), 1 ), tmp = p;
1160 double x, v1, v2, err = 1.0e100, old_err = f( p );
1164 __minimization_utility__::__convert_to_vector_functor__< T, Allocator, Functor > functor( p, dir, tmp, f );
1167 for( ite = 1 ; ite <= max_iterations ; )
1171 for( i = 0 ; i < dir.size( ) ; i++ )
1173 tmp[ i ] = p[ i ] + distance;
1176 tmp[ i ] = p[ i ] - distance;
1183 len += dir[ i ] * dir[ i ];
1189 len = std::sqrt( len );
1190 for( i = 0 ; i < dir.size( ) ; i++ )
1208 if( ite > max_iterations || 2.0 * std::abs( old_err - err ) < tolerance * ( std::abs( old_err ) + std::abs( err ) ) || err >= old_err )
1245 template <
class T,
class Allocator,
class Functor >
1253 matrix_type dir( p.
size( ), 1 ), tmp = p;
1254 double x = 0.0, v1, v2, err = 1.0e100, old_err = f( p );
1258 __minimization_utility__::__convert_to_vector_functor__< T, Allocator, Functor > functor( p, dir, tmp, f );
1261 for( ite = 1 ; ite <= max_iterations ; )
1265 for( i = 0 ; i < dir.size( ) ; i++ )
1267 tmp[ i ] = p[ i ] + distance;
1270 tmp[ i ] = p[ i ] - distance;
1277 len += dir[ i ] * dir[ i ];
1283 len = std::sqrt( len );
1284 for( i = 0 ; i < dir.size( ) ; i++ )
1295 double l1 = 0.0, l2 = 0.0;
1296 if( __minimization_utility__::clipping_length( l1, l2, p, dir, bound ) )
1306 if( ite > max_iterations || 2.0 * std::abs( old_err - err ) < tolerance * ( std::abs( old_err ) + std::abs( err ) ) )
1345 template <
class T,
class Allocator,
class Functor1,
class Functor2,
class T2 >
1346 double minimization(
array2< T, Allocator > &p, Functor1 f, Functor2 g,
const T2 &data,
double tolerance,
size_t &iterations,
const size_t max_iterations = 12,
const double armijo_rho = 0.7,
const double armijo_c = 0.1,
const size_t armijo_max_iteration = 10 )
1349 double err = 0.0, old_err = f( p, data );
1354 for( ite = 1 ; ite <= max_iterations ; ite++ )
1361 err =
Armijo::minimization( p, f, grad, -grad, data, armijo_rho, armijo_c, armijo_max_iteration );
1364 if( 2.0 * std::abs( err - old_err ) <= tolerance * ( std::abs( err ) + std::abs( old_err ) ) || old_err <= err )
1370 std::cout << ite <<
" : Energy : " << err << std::endl;
1392 template <
class T,
class Allocator,
class Functor1,
class Functor2 >
1393 double minimization(
array2< T, Allocator > &p, Functor1 f, Functor2 g,
double tolerance,
size_t &iterations,
const size_t max_iterations = 12,
const double armijo_rho = 0.7,
const double armijo_c = 0.1,
const size_t armijo_max_iteration = 10 )
1396 double err = 0.0, old_err = f( p );
1401 for( ite = 1 ; ite <= max_iterations ; ite++ )
1411 if( 2.0 * std::abs( err - old_err ) <= tolerance * ( std::abs( err ) + std::abs( old_err ) ) || old_err <= err )
1417 std::cout << ite <<
" : Energy : " << err << std::endl;
1434 template <
class T,
class Allocator,
class Functor >
1437 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
1439 return(
minimization( p, __no_copy_constructor_functor__( f ), tolerance, distance, itenum, max_iterations ) );
1456 template <
class T,
class Allocator,
class Functor >
1459 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
1461 return(
minimization( p, bound, __no_copy_constructor_functor__( f ), tolerance, distance, itenum, max_iterations ) );
1467 namespace conjugate_gradient
1470 template <
class T,
class Allocator >
1474 for(
size_t i = 0 ; i < a.
size() ; i++ )
1481 template <
class T,
class Allocator >
1485 for(
size_t i = 0 ; i < a.
size() ; i++ )
1487 res += a[i].r * a[i].r;
1488 res += a[i].g * a[i].g;
1489 res += a[i].b * a[i].b;
1493 template <
class T,
class Allocator>
1497 for (
size_t i = 0 ; i < a.
size() ; i++ )
1504 template <
class T,
class Allocator>
1508 for (
size_t i = 0 ; i < a.
size() ; i++ )
1510 res += a[i].r * b[i].r;
1511 res += a[i].g * b[i].g;
1512 res += a[i].b * b[i].b;
1525 template <
class T >
1528 return mul( g1, g1 - g0 ) / pow( norm( g0 ), 2 );
1538 template <
class T >
1541 return norm( g1 ) / norm( g0 );
1561 template <
class T,
class Allocator,
class Functor1,
class Functor2>
1562 double minimization(
array2< T, Allocator > &p, Functor1 f, Functor2 g,
double tolerance,
size_t &iterations,
const size_t max_iterations = 12,
const double armijo_rho = 0.7,
const double armijo_c = 0.1,
const size_t armijo_max_iteration = 10 )
1565 double err = 0.0, old_err = f( p );
1571 for( ite = 1 ; ite <= max_iterations ; ite++ )
1578 if( ite % p.
width() == 1 )
1589 for(
size_t i = 0 ; i < d.size() ; i++ )
1591 d[i] = -grad1[i] + beta * d[i];
1599 if( 2.0 * std::abs( err - old_err ) <= tolerance * ( std::abs( err ) + std::abs( old_err ) ) || old_err <= err )
1606 std::cout << ite <<
" : Energy : " << err <<
" : β -> " << beta << std::endl;
1629 template <
class T,
class Allocator,
class Functor1,
class Functor2,
class T2 >
1630 double minimization(
array2< T, Allocator > &p, Functor1 f, Functor2 g,
const T2 &data,
double tolerance,
size_t &iterations,
const size_t max_iterations = 12,
const double armijo_rho = 0.7,
const double armijo_c = 0.1,
const size_t armijo_max_iteration = 10 )
1633 double err = 0.0, old_err = f( p, data );
1639 for( ite = 1 ; ite <= max_iterations ; ite++ )
1642 g( p, grad1, data );
1646 if( ite % p.
width() == 1 )
1657 for(
size_t i = 0 ; i < d.size() ; i++ )
1659 d[i] = -grad1[i] + beta * d[i];
1664 err =
Armijo::minimization( p, f, grad1, d, data, armijo_rho, armijo_c, armijo_max_iteration );
1667 if( 2.0 * std::abs( err - old_err ) <= tolerance * ( std::abs( err ) + std::abs( old_err ) ) || old_err <= err )
1674 std::cout << ite <<
" : Energy : " << err <<
" : β -> " << beta << std::endl;
1697 template <
class T,
class Allocator,
class Functor >
1705 matrix_type odirs( dirs ), dir( p.
size( ), 1 ), tmp( p.
size( ), 1 ), p0( p ), pn( p );
1706 double x, fp = f( p ), fp0 = fp, delta;
1709 __minimization_utility__::__convert_to_vector_functor__< T, Allocator, Functor > functor( p, dir, tmp, f );
1713 for( ite = 0 ; ite < max_iterations ; ite++ )
1718 size_type index = 0;
1720 for( c = 0 ; c < dirs.
cols( ) ; c++ )
1723 for( r = 0 ; r < dirs.
rows( ) ; r++ )
1725 dir[ r ] = dirs( r, c );
1733 for( r = 0 ; r < p.
size( ) ; r++ )
1735 p[ r ] += dir[ r ] * x;
1738 double d = std::abs( fp - old_fp );
1747 if( 2.0 * std::abs( fp - fp0 ) <= tolerance * ( std::abs( fp ) + std::abs( fp0 ) ) || fp0 <= fp )
1753 if( ite < max_iterations )
1756 for( r = 0 ; r < p.
size( ) ; r++ )
1758 dir[ r ] = p[ r ] - p0[ r ];
1759 pn[ r ] = 2.0 * p[ r ] - p0[ r ];
1762 double fe = f( pn );
1767 double tmp = fp0 - fp - delta;
1768 double ttt = 2.0 * ( fp0 - 2.0 * fp + fe ) * tmp * tmp - delta * ( fp0 - fe ) * ( fp0 - fe );
1775 for( r = 0 ; r < p.
size( ) ; r++ )
1777 p[ r ] += dir[ r ] * x;
1781 if( index < dirs.
rows( ) - 1 )
1783 for( r = 0 ; r < dirs.
rows( ) ; r++ )
1785 dirs( r, index ) = dirs( r, dirs.
rows( ) - 1 );
1786 dirs( r, dirs.
rows( ) - 1 ) = dir[ r ];
1791 for( r = 0 ; r < dirs.
rows( ) ; r++ )
1793 dirs( r, index ) = dir[ r ];
1800 for( r = 0 ; r < p.
size( ) ; r++ )
1827 template <
class T,
class Allocator,
class Functor >
1835 matrix_type dir( p.
size( ), 1 ), tmp( p.
size( ), 1 ), p0( p ), pn( p );
1836 double x = 0.0, fp0 = 1.0e100, fp = f( p ), delta;
1837 double l1 = 0.0, l2 = 0.0;
1840 __minimization_utility__::__convert_to_vector_functor__< T, Allocator, Functor > functor( p, dir, tmp, f );
1844 for( ite = 1 ; ite <= max_iterations ; ite++ )
1849 size_type index = 0;
1851 for( c = 0 ; c < dirs.
cols( ) ; c++ )
1854 for( r = 0 ; r < dirs.
rows( ) ; r++ )
1856 dir[ r ] = dirs( r, c );
1862 if( __minimization_utility__::clipping_length( l1, l2, p, dir, bound ) )
1872 for( r = 0 ; r < p.
size( ) ; r++ )
1874 p[ r ] += dir[ r ] * x;
1877 double d = std::abs( fp - old_fp );
1888 if( 2.0 * std::abs( fp - fp0 ) <= tolerance * ( std::abs( fp ) + std::abs( fp0 ) ) )
1894 if( ite <= max_iterations )
1897 for( r = 0 ; r < p.
size( ) ; r++ )
1899 dir[ r ] = p[ r ] - p0[ r ];
1900 pn[ r ] = 2.0 * p[ r ] - p0[ r ];
1903 double fe = f( pn );
1908 double tmp = fp0 - fp - delta;
1909 double ttt = 2.0 * ( fp0 - 2.0 * fp + fe ) * tmp * tmp - delta * ( fp0 - fe ) * ( fp0 - fe );
1912 if( __minimization_utility__::clipping_length( l1, l2, p, dir, bound ) )
1921 for( r = 0 ; r < p.
size( ) ; r++ )
1923 p[ r ] += dir[ r ] * x;
1929 if( index < dirs.
rows( ) - 1 )
1931 for( r = 0 ; r < dirs.
rows( ) ; r++ )
1933 dirs( r, index ) = dirs( r, dirs.
rows( ) - 1 );
1934 dirs( r, dirs.
rows( ) - 1 ) = dir[ r ];
1939 for( r = 0 ; r < dirs.
rows( ) ; r++ )
1941 dirs( r, index ) = dir[ r ];
1948 for( r = 0 ; r < p.
size( ) ; r++ )
1972 template <
class T,
class Allocator,
class Functor >
1975 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
1977 return(
minimization( p, dirs, __no_copy_constructor_functor__( f ), tolerance, itenum, max_iterations ) );
1993 template <
class T,
class Allocator,
class Functor >
1996 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
1998 return(
minimization( p, dirs, bound, __no_copy_constructor_functor__( f ), tolerance, itenum, max_iterations ) );
2006 template <
class Functor >
2007 inline double expantion_step(
double alpha,
double alpha_max,
double delta,
double gamma,
double fp0, Functor f )
2011 if( alpha >= alpha_max )
2013 return( alpha_max );
2017 double a = alpha / delta;
2018 if( f( a ) > fp0 - gamma * a * a )
2042 template <
class T,
class Allocator,
class Functor >
2050 matrix_type dir( p.
size( ), 1 ), tmp( p.
size( ), 1 ), p0( p ), a( p.
size( ), 1 );
2051 double fp0 = 1.0e100, fp = f( p );
2054 __minimization_utility__::__convert_to_vector_functor__< T, Allocator, Functor > functor( p, dir, tmp, f );
2056 const double __alpha__ = 0.5;
2057 const double theta = 0.5;
2058 const double gamma = 1.0e-6;
2059 const double delta = 0.25;
2065 for( r = 0 ; r < a.size( ) ; r++ )
2070 for( ite = 1 ; ite <= max_iterations ; ite++ )
2075 size_type alpha_count = 0;
2077 for( c = 0 ; c < dirs.
cols( ) ; c++ )
2079 double alpha = a[ c ];
2082 for( r = 0 ; r < dirs.
rows( ) ; r++ )
2084 dir[ r ] = dirs( r, c );
2089 double gaa = gamma * alpha * alpha;
2090 if( functor( alpha ) <= fp0 - gaa )
2092 a[ c ] = alpha = expantion_step( alpha, infinity, delta, gamma, fp0, functor );
2095 for( r = 0 ; r < p.
size( ) ; r++ )
2097 p[ r ] += dir[ r ] * alpha;
2100 else if( functor( -alpha ) <= fp0 - gaa )
2103 for( r = 0 ; r < dirs.
rows( ) ; r++ )
2105 dir[ r ] = dirs( r, c ) = -dir[ r ];
2108 a[ c ] = alpha = expantion_step( alpha, infinity, delta, gamma, fp0, functor );
2111 for( r = 0 ; r < p.
size( ) ; r++ )
2113 p[ r ] += dir[ r ] * alpha;
2118 a[ c ] = theta * alpha;
2125 a[ c ] = theta * alpha;
2133 if( alpha_count < dirs.
cols( ) )
2136 if( 2.0 * std::abs( fp - fp0 ) <= tolerance * ( std::abs( fp ) + std::abs( fp0 ) ) )
2161 template <
class T,
class Allocator,
class Functor >
2164 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
2166 return(
minimization( p, dirs, __no_copy_constructor_functor__( f ), tolerance, itenum, max_iterations ) );
2181 namespace __condor_utility__
2183 inline double minimum(
double v1,
double v2 )
2185 return( v1 < v2 ? v1 : v2 );
2188 inline double maximum(
double v1,
double v2 )
2190 return( v1 > v2 ? v1 : v2 );
2193 inline double minimum(
double v1,
double v2,
double v3 )
2216 inline double minimum(
double v1,
double v2,
double v3,
double v4 )
2218 return( minimum( minimum( v1, v2 ), minimum( v3, v4 ) ) );
2221 inline double maximum(
double v1,
double v2,
double v3 )
2244 inline double maximum(
double v1,
double v2,
double v3,
double v4 )
2246 return( maximum( maximum( v1, v2 ), maximum( v3, v4 ) ) );
2249 template <
class Matrix >
2250 inline double frobenius_norm(
const Matrix &H )
2252 typedef Matrix matrix_type;
2253 typedef typename matrix_type::size_type size_type;
2256 for( size_type r = 0 ; r < H.size( ) ; r++ )
2258 val += H[ r ] * H[ r ];
2261 return( std::sqrt( val ) );
2264 template <
class Matrix >
2265 inline double infinitum_norm(
const Matrix &H )
2267 typedef Matrix matrix_type;
2268 typedef typename matrix_type::size_type size_type;
2271 for( size_type c = 0 ; c < H.cols( ) ; c++ )
2274 for( size_type r = 0 ; r < H.rows( ) ; r++ )
2276 val += std::abs( H( r, c ) );
2288 template <
class Matrix >
2289 inline double inner_product(
const Matrix &m1,
const Matrix &m2 )
2291 typedef Matrix matrix_type;
2292 typedef typename matrix_type::value_type value_type;
2293 typedef typename matrix_type::size_type size_type;
2294 typedef typename matrix_type::difference_type difference_type;
2297 for( size_type i = 0 ; i < m1.size( ) ; i++ )
2299 sum += m1[ i ] * m2[ i ];
2305 template <
class Matrix >
2306 inline double inner_product(
const Matrix &m1,
const Matrix &H,
const Matrix &m2 )
2308 typedef Matrix matrix_type;
2309 typedef typename matrix_type::size_type size_type;
2312 for( size_type c = 0 ; c < H.cols( ) ; c++ )
2315 for( size_type r = 0 ; r < H.rows( ) ; r++ )
2317 val += m1[ r ] * H( r, c );
2320 sum += val * m2[ c ];
2325 template <
class Matrix >
2326 inline double inner_product(
const Matrix &m1,
const Matrix &H,
const Matrix &m2,
double lambda )
2328 typedef Matrix matrix_type;
2329 typedef typename matrix_type::size_type size_type;
2332 for( size_type c = 0 ; c < H.cols( ) ; c++ )
2334 double val = lambda * m1[ c ];
2335 for( size_type r = 0 ; r < H.rows( ) ; r++ )
2337 val += m1[ r ] * H( r, c );
2340 sum += val * m2[ c ];
2345 struct __index_value_pair__
2350 __index_value_pair__(
size_t indx,
double val ) : index( indx ), value( val ){ }
2352 bool operator <(
const __index_value_pair__ &v )
const
2355 return( value > v.value );
2359 template <
class Matrix >
2360 inline void solve(
const Matrix &A, Matrix &b )
2362 typedef Matrix matrix_type;
2363 typedef typename matrix_type::size_type size_type;
2364 typedef typename matrix_type::difference_type difference_type;
2366 for( size_type r = 0 ; r < A.rows( ) ; r++ )
2368 double sum = b[ r ];
2369 for( difference_type c = r - 1 ; c >= 0 ; c-- )
2371 sum -= A( r, c ) * b[ c ];
2374 b[ r ] = sum / A( r, r );
2378 template <
class Matrix >
2379 inline void solve_(
const Matrix &A, Matrix &b )
2381 typedef Matrix matrix_type;
2382 typedef typename matrix_type::size_type size_type;
2383 typedef typename matrix_type::difference_type difference_type;
2385 for( difference_type c = A.cols( ) - 1 ; c >= 0 ; c-- )
2387 double sum = b[ c ];
2388 for( size_type r = c + 1 ; r < A.rows( ) ; r++ )
2390 sum -= A( r, c ) * b[ r ];
2393 b[ c ] = sum / A( c, c );
2398 template <
class Matrix >
2399 inline bool cholesky_factorization(
const Matrix &H, Matrix &L,
double lambda,
double &lambda_modified )
2401 typedef Matrix matrix_type;
2402 typedef typename matrix_type::value_type value_type;
2403 typedef typename matrix_type::size_type size_type;
2404 typedef typename matrix_type::difference_type difference_type;
2407 for( size_type r = 0 ; r < H.rows( ) ; r++ )
2409 double scale = H( r, r ) + lambda;
2411 for( size_type c = 0 ; c < r ; c++ )
2413 scale -= L( r, c ) * L( r, c );
2420 matrix_type v( L.rows( ), 1 );
2422 for( difference_type j = r - 1 ; j >= 0 ; j-- )
2425 for( size_type i = j + 1 ; i <= r ; i++ )
2427 sum += L( i, j ) * v[ i ];
2429 v[ j ] = - sum / L( j, j );
2432 lambda_modified = - scale / frobenius_norm( v );
2437 scale = std::sqrt( scale );
2440 for( size_type c = r + 1 ; c < H.cols( ) ; c++ )
2442 double val = H( r, c );
2443 for( size_type l = 0 ; l < r ; l++ )
2445 val -= L( c, l ) * L( r, l );
2448 L( c, r ) = val / scale;
2455 template <
class Matrix >
2456 inline bool cholesky_factorization(
const Matrix &H, Matrix &L,
double lambda )
2459 return( cholesky_factorization( H, L, lambda, dmy ) );
2462 template <
class Matrix >
2463 inline bool compute_eigen_vector(
const Matrix &L, Matrix &w,
double lambda )
2465 typedef Matrix matrix_type;
2466 typedef typename matrix_type::value_type value_type;
2467 typedef typename matrix_type::size_type size_type;
2468 typedef typename matrix_type::difference_type difference_type;
2470 w.resize( L.rows( ), 1 );
2471 for( size_type r = 0 ; r < L.rows( ) ; r++ )
2473 if( L( r, r ) >= 0.0 )
2484 w *= 1.0 / frobenius_norm( w );
2489 class polynomial :
public matrix< double >
2494 typedef matrix_type::value_type value_type;
2495 typedef matrix_type::size_type size_type;
2496 typedef matrix_type::difference_type difference_type;
2500 size_type dimension;
2503 imatrix_type alpha_;
2506 std::vector< double > r;
2509 polynomial( ) : dimension( 0 ), N( 1 )
2513 polynomial( size_type ndim ) : base( ( ndim + 1 ) * ( ndim + 2 ) / 2, 1 ), dimension( ndim ), N( ( ndim + 1 ) * ( ndim + 2 ) / 2 ), alpha( N, ndim ), alpha_( N, ndim ), tr( N, 1 ), tc( N, 1 ), r( ndim )
2516 compute_polynomial_indeces( );
2519 polynomial(
const polynomial &poly ) : base( poly ), dimension( poly.dimension ), N( poly.N ), alpha( poly.alpha ), alpha_( poly.alpha_ ), tr( poly.tr ), tc( poly.tc ), r( poly.r )
2523 void reinitialize_polynomial( size_type ndim )
2527 N = ( ndim + 1 ) * ( ndim + 2 ) / 2;
2528 alpha.resize( N, ndim );
2529 alpha_.resize( N, ndim );
2534 base::resize( N, 1 );
2537 compute_polynomial_indeces( );
2540 const polynomial & operator =(
const polynomial &poly )
2548 base::operator =( poly );
2551 dimension = poly.dimension;
2554 alpha_ = poly.alpha_;
2562 const polynomial & operator =(
const matrix_type &mat )
2565 base::operator =( mat );
2570 template <
class Matrix >
2571 double operator ()(
const Matrix &x )
2573 difference_type n = dimension;
2574 const matrix_type &c = *
this;
2576 double r0 = c[ tr[ 0 ] ];
2577 for( difference_type j = 0 ; j < n ; j++ )
2582 for( size_type i = 1 ; i < N ; i++ )
2584 difference_type k = tc[ i - 1 ];
2586 for( difference_type j = k ; j < n ; j++ )
2593 r[ k ] = x[ k ] * rsum;
2597 for( difference_type j = 0 ; j < n ; j++ )
2605 matrix_type compute_hessian_matrix( )
const
2607 matrix_type H( dimension, dimension );
2608 const matrix_type &coeff = *
this;
2610 size_type indx = dimension + 1;
2611 for( size_type r = 0 ; r < H.rows( ) ; r++ )
2613 H( r, r ) = coeff[ indx++ ] * 2.0;
2614 for( size_type c = r + 1 ; c < H.cols( ) ; c++ )
2616 H( r, c ) = H( c, r ) = coeff[ indx++ ];
2624 void translate(
const matrix_type &x )
2627 polynomial &c = *
this;
2628 matrix_type Hx = compute_hessian_matrix( ) * x;
2631 for( size_type r = 0 ; r < Hx.rows( ) ; r++ )
2633 c[ r + 1 ] += Hx[ r ];
2639 void compute_polynomial_indeces( )
2641 difference_type n = dimension;
2642 difference_type R = N;
2643 difference_type C = n;
2644 imatrix_type &lex = alpha_;
2645 imatrix_type ° = alpha;
2651 difference_type row = 1;
2652 for( difference_type c = 0 ; c < C ; c++ )
2658 difference_type col = 0;
2659 difference_type val = 2;
2660 for( ; row < R && col < C ; )
2665 deg( row, col ) =
static_cast< imatrix_type::value_type
>( val );
2671 for( difference_type c = 1 ; c < C - col ; c++ )
2673 deg( row, col ) =
static_cast< imatrix_type::value_type
>( val );;
2674 deg( row, col + c ) =
static_cast< imatrix_type::value_type
>( val );;
2690 difference_type col = 0;
2691 difference_type val = 2;
2692 for( difference_type row = 0 ; row < R - 1 ; )
2697 lex( row, col ) =
static_cast< imatrix_type::value_type
>( val );
2703 for( difference_type c = 1 ; c < C - col ; c++ )
2705 lex( row, col ) =
static_cast< imatrix_type::value_type
>( val );
2706 lex( row, col + c ) =
static_cast< imatrix_type::value_type
>( val );
2709 lex( row, col ) =
static_cast< imatrix_type::value_type
>( val );
2722 for( difference_type r = 0 ; r < R ; r++ )
2724 difference_type c = C - 1;
2725 for( ; c >= 0 ; c-- )
2727 if( lex( r, c ) != 0 )
2732 tc[ r ] =
static_cast< imatrix_type::value_type
>( c );
2736 for( difference_type r = 0 ; r < R ; r++ )
2738 difference_type indx = 0;
2739 for( ; indx < R ; indx++ )
2741 difference_type c = 0;
2742 for( ; c < C ; c++ )
2744 if( lex( r, c ) != deg( indx, c ) )
2758 tr[ r ] =
static_cast< imatrix_type::value_type
>( indx );
2775 template <
class Matrix,
class Functor >
2778 typedef Matrix matrix_type;
2779 typedef typename matrix_type::value_type value_type;
2780 typedef typename matrix_type::size_type size_type;
2781 typedef typename matrix_type::difference_type difference_type;
2783 difference_type n = xbase.rows( );
2784 difference_type N = ( n + 1 ) * ( n + 2 ) / 2;
2789 for( difference_type i = 0 ; i < N ; i++ )
2791 x[ i ].resize( n, 1 );
2795 f[ 0 ] = func( x[ 0 ] );
2797 for( difference_type j = 0 ; j < n ; j++ )
2799 size_type k = j + 1;
2802 f[ k ] = func( x[ k ] );
2805 matrix_type s( n, 1 );
2806 for( difference_type j = 0 ; j < n ; j++ )
2808 if( f[ j + 1 ] > f[ 0 ] )
2818 for( difference_type j = 0 ; j < n ; j++ )
2820 difference_type k = j + 1 + n;
2829 x[ k ][ j ] += rho + rho;
2831 f[ k ] = func( x[ k ] );
2834 difference_type k = 2 * n + 1;
2835 for( difference_type j = 0 ; j < n ; j++ )
2837 for( difference_type i = 0 ; i < j ; i++ )
2840 x[ k ][ i ] += rho * s[ i ];
2841 x[ k ][ j ] += rho * s[ j ];
2842 f[ k ] = func( x[ k ] );
2848 for( size_type i = 0 ; i < x.size( ) ; i++ )
2850 for( size_type j = 0 ; j < x.size( ) ; j++ )
2852 if( f[ i ] < f[ j ] )
2854 double tmp = f[ i ];
2857 x[ i ].swap( x[ j ] );
2874 template <
class Matrix >
2875 bool compute_polynomial_basis( std::vector< Matrix > &x, Matrix &f, std::vector< __condor_utility__::polynomial > &poly_bases, __condor_utility__::polynomial &poly )
2877 typedef Matrix matrix_type;
2878 typedef typename matrix_type::value_type value_type;
2879 typedef typename matrix_type::size_type size_type;
2880 typedef typename matrix_type::difference_type difference_type;
2881 typedef __condor_utility__::polynomial polynomial_type;
2883 if( x.size( ) != poly_bases.size( ) )
2889 size_type N = poly.size( );
2890 for( size_type k = 0 ; k < N ; k++ )
2892 polynomial_type &pk = poly_bases[ k ];
2896 size_type index = k;
2904 for( size_type i = k ; i < N ; i++ )
2906 double val = pk( x[ i ] );
2907 if( std::abs( val ) > std::abs( max ) )
2913 if( std::abs( max ) > 1.0 )
2924 x[ k ].swap( x[ index ] );
2926 double tmp = f[ k ];
2927 f[ k ] = f[ index ];
2934 for( size_type j = 0 ; j < N ; j++ )
2938 polynomial_type &pj = poly_bases[ j ];
2939 pj -= pj( x[ k ] ) * pk;
2947 for( size_type i = 0 ; i < poly_bases.size( ) ; i++ )
2949 poly += f[ i ] * poly_bases[ i ];
2961 template <
class Matrix >
2964 typedef Matrix matrix_type;
2965 typedef typename matrix_type::size_type size_type;
2967 double Hmin = H( 0, 0 );
2968 for( size_type i = 1 ; i < H.rows( ) ; i++ )
2970 if( Hmin > H( i, i ) )
2986 template <
class Matrix >
2989 typedef Matrix matrix_type;
2990 typedef typename matrix_type::size_type size_type;
2992 double max = -1.0e100;
2993 for( size_type i = 0 ; i < H.rows( ) ; i++ )
2995 double val = H( i, i ) * alpha;
2996 for( size_type j = 0 ; j < i ; j++ )
2998 val += std::abs( H( i, j ) );
3000 for( size_type j = i + 1 ; j < H.cols( ) ; j++ )
3002 val += std::abs( H( i, j ) );
3022 template <
class Matrix >
3027 double Hf = __condor_utility__::frobenius_norm( H );
3028 double Hi = __condor_utility__::infinitum_norm( H );
3030 return( __condor_utility__::maximum( 0, Hm, dg_delta - __condor_utility__::minimum( Hg, Hf, Hi ) ) );
3041 template <
class Matrix >
3045 double Hf = __condor_utility__::frobenius_norm( H );
3046 double Hi = __condor_utility__::infinitum_norm( H );
3048 return( __condor_utility__::maximum( 0, dg_delta + __condor_utility__::minimum( Hg, Hf, Hi ) ) );
3060 template <
class Matrix >
3061 void compute_trust_region_step(
const Matrix &xbest, Matrix &s, __condor_utility__::polynomial &poly,
double delta,
size_t max_loop = 1000 )
3063 typedef Matrix matrix_type;
3064 typedef typename matrix_type::value_type value_type;
3065 typedef typename matrix_type::size_type size_type;
3066 typedef typename matrix_type::difference_type difference_type;
3067 typedef __condor_utility__::polynomial polynomial_type;
3069 matrix_type H = poly.compute_hessian_matrix( );
3070 matrix_type g = H * xbest;
3071 for( size_type i = 0 ; i < g.rows( ) ; i++ )
3073 g[ i ] += poly[ i + 1 ];
3076 double gnorm = __condor_utility__::frobenius_norm( g );
3077 double lambda = gnorm / delta;
3082 lambda = __condor_utility__::maximum( lambdaL, __condor_utility__::minimum( lambda, lambdaU ) );
3084 bool cholesky_factorization_finished =
false;
3085 matrix_type L( H.rows( ), H.cols( ) ), w( g.rows( ), g.cols( ) );
3088 s.resize( g.rows( ), 1 );
3092 for( loop = 0 ; loop < max_loop ; loop++ )
3094 if( !cholesky_factorization_finished )
3096 double lambdaM = 0.0;
3097 if( !__condor_utility__::cholesky_factorization( H, L, lambda, lambdaM ) )
3099 lambdaL = __condor_utility__::maximum( lambdaL, lambda + lambdaM );
3100 lambda = __condor_utility__::maximum( std::sqrt( lambdaL * lambdaU ), lambdaL + 0.01 * ( lambdaU - lambdaL ) );
3106 cholesky_factorization_finished =
false;
3113 __condor_utility__::solve( L, s );
3114 __condor_utility__::solve_( L, s );
3115 double snorm = __condor_utility__::frobenius_norm( s );
3118 if( std::abs( snorm - delta ) < 0.01 * delta )
3124 else if( snorm < delta )
3132 lambdaU = __condor_utility__::minimum( lambdaU, lambda );
3134 #if defined( __CHECK_HARD_CASE__ ) && __CHECK_HARD_CASE__ != 0
3137 __condor_utility__::compute_eigen_vector( L, u, lambda );
3139 double uHu = __condor_utility__::inner_product( u, H, u, lambda );
3142 if( uHu <= 0.01 * ( uHu + lambda * delta * delta ) )
3146 double c = - delta * delta;
3147 for( size_type i = 0 ; i < u.rows( ) ; i++ )
3149 a += u[ i ] * u[ i ];
3150 b += s[ i ] * u[ i ];
3151 c += s[ i ] * s[ i ];
3155 double bac = std::sqrt( b * b - a * c );
3157 double alpha1 = ( -b - bac ) / a;
3158 double alpha2 = ( -b + bac ) / a;
3160 matrix_type s1( s ), s2( s ), x1( xbest ), x2( xbest );
3161 for( size_type r = 0 ; r < s.rows( ) ; r++ )
3163 s1[ r ] += alpha1 * u[ r ];
3164 s2[ r ] += alpha2 * u[ r ];
3169 double f1 = poly( x1 );
3170 double f2 = poly( x2 );
3190 lambdaL = __condor_utility__::maximum( lambdaL, lambda );
3194 __condor_utility__::solve( L, w );
3196 double wnorm = __condor_utility__::frobenius_norm( w );
3197 double lambdaN = lambdaL;
3200 if( wnorm > 1.0e-20 )
3202 lambdaN = lambda + ( ( snorm - delta ) / delta ) * ( ( snorm * snorm ) / ( wnorm * wnorm ) );
3203 lambdaN = __condor_utility__::maximum( lambdaL, __condor_utility__::minimum( lambdaN, lambdaU ) );
3207 lambdaN = __condor_utility__::maximum( lambdaL, lambdaU );
3211 if( __condor_utility__::cholesky_factorization( H, L, lambdaN ) )
3214 cholesky_factorization_finished =
true;
3218 lambdaL = __condor_utility__::maximum( lambdaL, lambdaN );
3219 lambda = __condor_utility__::maximum( std::sqrt( lambdaL * lambdaU ), lambdaL + 0.01 * ( lambdaU - lambdaL ) );
3245 template <
class T,
class Allocator,
class Functor >
3249 typedef typename matrix_type::value_type value_type;
3250 typedef typename matrix_type::size_type size_type;
3251 typedef typename matrix_type::difference_type difference_type;
3253 typedef __condor_utility__::polynomial polynomial_type;
3256 std::vector< matrix_type > x;
3258 difference_type n = p.
rows( );
3259 difference_type N = ( n + 1 ) * ( n + 2 ) / 2;
3268 matrix_type xbase = x[ best_index ];
3269 polynomial_type poly;
3270 std::vector< polynomial_type > poly_bases( N );
3271 poly.reinitialize_polynomial( n );
3273 for( difference_type i = 0 ; i < N ; i++ )
3275 poly_bases[ i ] = poly;
3277 for( difference_type i = 0 ; i < N ; i++ )
3279 poly_bases[ i ].fill( 0 );
3280 poly_bases[ i ][ i ] = 1.0;
3293 double Fold = f[ best_index ];
3294 double Fold_ = Fold;
3295 double Fnew = 1.0e100;
3296 bool is_function_evaluated =
false;
3297 size_type number_of_updateM = 0;
3302 while( iterations < max_iterations )
3304 Fold = __condor_utility__::minimum( Fnew, Fold );
3305 is_function_evaluated =
false;
3306 for( size_type loop = 0 ; iterations++ < max_iterations ; loop++ )
3308 double Fbest = f[ best_index ];
3309 const matrix_type &xbest = x[ best_index ];
3315 snorm = __condor_utility__::frobenius_norm( tstep );
3316 matrix_type xnew = xbest + tstep;
3321 if( snorm < rho * 0.5 && loop > 0 )
3329 double R = Fold - poly( xnew );
3334 double na = 0.0, nr = 0.0;
3335 double noise = 0.5 * __condor_utility__::maximum( na * ( 1.0 + nr ), nr * std::abs( Fbest ) );
3336 if( R < noise && loop > 0 )
3345 matrix_type ppp( xbase + xnew );
3347 is_function_evaluated =
true;
3352 double r = R != 0.0 ? ( Fold - Fnew ) / R : Fold - Fnew;
3358 delta = __condor_utility__::maximum( delta, snorm * 1.25, rho + snorm );
3362 delta = __condor_utility__::maximum( 0.5 * delta, snorm );
3366 delta = 0.5 * snorm;
3369 if( delta < 1.5 * rho )
3377 double model_step = 0.0;
3378 bool has_reduction = Fnew < Fbest;
3380 difference_type index = -1;
3381 double max = -1.0e100;
3385 for( difference_type i = 0 ; i < N ; i++ )
3387 double pnew = poly_bases[ i ]( xnew );
3388 double norm = __condor_utility__::frobenius_norm( x[ i ] - xnew ) / rho;
3389 double val = __condor_utility__::maximum( 1.0, norm * norm * norm ) * std::abs( pnew );
3401 for( difference_type i = 0 ; i < N ; i++ )
3403 if( i != best_index )
3405 double pnew = poly_bases[ i ]( xnew );
3406 double norm = __condor_utility__::frobenius_norm( x[ i ] - xbest ) / rho;
3407 double val = __condor_utility__::maximum( 1.0, norm * norm * norm ) * std::abs( pnew );
3419 if( index >= 0 && Pnew != 0.0 )
3422 model_step = __condor_utility__::frobenius_norm( x[ index ] - xnew );
3425 poly_bases[ index ] /= Pnew;
3426 for( difference_type i = 0 ; i < N ; i++ )
3430 poly_bases[ i ] -= poly_bases[ i ]( xnew ) * poly_bases[ index ];
3441 if( f[ best_index ] > Fnew )
3443 Fold = __condor_utility__::minimum( Fnew, Fold );
3449 for( size_type i = 0 ; i < poly_bases.size( ) ; i++ )
3451 poly += f[ i ] * poly_bases[ i ];
3460 for( size_type i = 0 ; i < poly_bases.size( ) ; i++ )
3462 double len = __condor_utility__::frobenius_norm( xnew - x[ i ] );
3463 sum += std::abs( poly_bases[ i ]( xnew ) ) * len * len * len;
3468 M = __condor_utility__::maximum( M, std::abs( poly( xnew ) - Fnew ) / sum );
3469 number_of_updateM++;
3475 if( model_step > 2.0 * rho || snorm > 2.0 * rho || has_reduction )
3484 if( iterations >= max_iterations )
3493 if( number_of_updateM < 10 )
3497 else if( snorm >= rho * 0.5 )
3505 matrix_type H = poly.compute_hessian_matrix( );
3506 matrix_type L( H.rows( ), H.cols( ) );
3508 double Hf = __condor_utility__::frobenius_norm( H );
3509 double Hi = __condor_utility__::infinitum_norm( H );
3511 double lambdaL = 0.0;
3512 double lambdaU = __condor_utility__::minimum( Hg, Hf, Hi );
3513 while( lambdaL < 0.99 * lambdaU )
3515 double lambda = ( lambdaL + lambdaU ) * 0.5;
3517 if( __condor_utility__::cholesky_factorization( H, L, -lambda ) )
3527 eps = 0.5 * rho * rho * ( lambdaL + lambdaU ) * 0.5;
3534 std::vector< __condor_utility__::__index_value_pair__ > J;
3536 for( difference_type i = 0 ; i < N ; i++ )
3538 if( i != best_index )
3540 double len = __condor_utility__::frobenius_norm( x[ i ] - x[ best_index ] );
3541 if( len > 2.0 * rho )
3543 J.push_back( __condor_utility__::__index_value_pair__( i, len ) );
3552 std::sort( J.begin( ), J.end( ) );
3554 size_type index = 0;
3556 for( ; index < J.size( ) ; index++ )
3558 __condor_utility__::__index_value_pair__ &ivpair = J[ index ];
3559 polynomial_type &p = poly_bases[ ivpair.index ];
3560 matrix_type H = p.compute_hessian_matrix( );
3561 matrix_type g = H * x[ best_index ];
3562 for( size_type i = 0 ; i < g.rows( ) ; i++ )
3564 g[ i ] += p[ i + 1 ];
3567 double gnorm = __condor_utility__::frobenius_norm( g );
3573 matrix_type w( H.rows( ), 1 );
3578 double max = -1.0e10;
3580 for( size_type c = 0 ; c < H.cols( ) ; c++ )
3583 for( size_type r = 0 ; r < H.rows( ) ; r++ )
3585 sum += H( r, c ) * H( r, c );
3595 for( size_type r = 0 ; r < H.rows( ) ; r++ )
3597 w[ r ] = H( r, col );
3602 matrix_type D = H * w;
3603 double DHD = __condor_utility__::inner_product( D, H, D );
3604 double VD = __condor_utility__::inner_product( V, D );
3605 double DD = __condor_utility__::inner_product( D, D );
3606 double VHD = __condor_utility__::inner_product( V, H, D );
3607 double VHV = __condor_utility__::inner_product( V, H, V );
3608 double VV = __condor_utility__::inner_product( V, V );
3611 double a = DHD * VD - DD * DD;
3612 double b = ( DHD * VV - DD * VD ) * 0.5;
3613 double c = DD * VV - VD * VD;
3614 double bac = std::sqrt( b * b - a * c );
3617 double r1 = ( -b - bac ) / a;
3618 double r2 = ( -b + bac ) / a;
3620 double f1 = ( r1 * r1 * DHD + 2.0 * r1 * VHD + VHV ) / ( VV + 2.0 * r1 * VD + r1 * r1 * DD );
3621 double f2 = ( r2 * r2 * DHD + 2.0 * r2 * VHD + VHV ) / ( VV + 2.0 * r2 * VD + r2 * r2 * DD );
3636 DD = __condor_utility__::inner_product( D, D );
3637 if( gnorm * DD + 2.0 * rho * std::abs( DHD ) < 0.5 )
3639 double GD = __condor_utility__::inner_product( g, D );
3640 double scale = rho / std::sqrt( DD );
3641 if( GD * DHD < 0.0 )
3655 matrix_type G = D / __condor_utility__::frobenius_norm( D );
3656 matrix_type V = g / gnorm;
3657 double VHG = __condor_utility__::inner_product( V, H, G );
3658 double VHV = __condor_utility__::inner_product( V, H, V );
3659 double GHG = __condor_utility__::inner_product( G, H, G );
3660 double theta = std::atan2( 2.0 * VHG, VHV - GHG ) * 0.5;
3663 double s_ = std::sin( theta );
3664 double c_ = std::cos( theta );
3665 matrix_type ut = c_ * G + s_ * V;
3666 matrix_type uh = -s_ * G + c_ * V;
3670 const double pai = 3.1415926535897932384626433832795;
3671 const double phi[ 4 ] = { 0.0, pai * 0.25, pai * 0.5, pai * 0.75 };
3674 d = ( std::cos( phi[ 0 ] ) * uh + std::sin( phi[ 0 ] ) * ut );
3675 d = rho * d / __condor_utility__::frobenius_norm( d );
3678 double max = std::abs( __condor_utility__::inner_product( g, d ) ) + 0.5 * std::abs( __condor_utility__::inner_product( d, H, d ) );
3679 for( size_type i = 1 ; i < 4 ; i++ )
3681 matrix_type tmp = ( std::cos( phi[ i ] ) * uh + std::sin( phi[ i ] ) * ut );
3682 tmp = rho * tmp / __condor_utility__::frobenius_norm( tmp );
3683 double val = std::abs( __condor_utility__::inner_product( g, tmp ) ) + 0.5 * std::abs( __condor_utility__::inner_product( tmp, H, tmp ) );
3691 double GD = __condor_utility__::inner_product( g, d );
3692 double DHD = __condor_utility__::inner_product( d, H, d );
3693 if( GD * DHD < 0.0 )
3700 double len = ivpair.value;
3701 double val = M * len * len * len * p( x[ best_index ] + d );
3711 if( index < J.size( ) )
3714 difference_type outindex = J[ index ].index;
3716 matrix_type xnew = x[ best_index ] + d;
3717 matrix_type ppp = xbase + xnew;
3718 double fnew = func( ppp );
3719 is_function_evaluated =
true;
3722 poly_bases[ outindex ] /= poly_bases[ outindex ]( xnew );
3723 for( difference_type i = 0 ; i < N ; i++ )
3727 poly_bases[ i ] -= poly_bases[ i ]( xnew ) * poly_bases[ outindex ];
3732 x[ outindex ] = xnew;
3733 f[ outindex ] = fnew;
3737 for( size_type i = 0 ; i < poly_bases.size( ) ; i++ )
3739 poly += f[ i ] * poly_bases[ i ];
3743 Fold = __condor_utility__::minimum( fnew, Fold );
3744 if( f[ best_index ] > fnew )
3746 best_index = outindex;
3752 for( size_type i = 0 ; i < poly_bases.size( ) ; i++ )
3754 double len = __condor_utility__::frobenius_norm( xnew - x[ i ] );
3755 sum += std::abs( poly_bases[ i ]( xnew ) ) * len * len * len;
3760 M = __condor_utility__::maximum( M, std::abs( poly( xnew ) - Fnew ) / sum );
3761 number_of_updateM++;
3779 if( rho <= rho_end || 2.0 * std::abs( Fold_ - Fold ) < tolerance * ( std::abs( Fold_ ) + std::abs( Fold ) ) )
3791 double rho_old = rho;
3792 if( rho <= 16.0 * rho_end )
3796 else if( rho <= 250.0 * rho_end )
3798 rho = std::sqrt( rho_end * rho );
3805 delta = __condor_utility__::maximum( rho_old * 0.5, rho );
3811 matrix_type shift = x[ best_index ];
3812 xbase += x[ best_index ];
3813 poly.translate( shift );
3814 for( difference_type i = 0 ; i < N ; i++ )
3816 poly_bases[ i ].translate( shift );
3817 if( i == best_index )
3833 matrix_type xnew = xbase + x[ best_index ] + tstep;
3836 if( !is_function_evaluated )
3838 Fnew = func( xnew );
3843 p = xbase + x[ best_index ];
3873 template <
class T,
class Allocator,
class Functor >
3876 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
3878 return(
minimization( p, __no_copy_constructor_functor__( f ), rho, rho_end, 0.0, itenum, max_iterations ) );
3899 template <
class T,
class Allocator,
class Functor >
3902 typedef __minimization_utility__::__no_copy_constructor_functor__< Functor > __no_copy_constructor_functor__;
3904 return(
minimization( p, __no_copy_constructor_functor__( f ), 1.0, 1.0e-8, tolerance, itenum, max_iterations ) );
3918 #endif // __INCLUDE_MIST_MINIMIZATION__