#NEWLINE# def modified_policy_iteration( self , v_init = None , epsilon = None , max_iter = None , k = 20 ) : #NEWLINE# #INDENT# '\n        Solve the optimization problem by modified policy iteration. See\n        the `solve` method.\n\n        ' #NEWLINE# if ( self . beta == 1 ) : #NEWLINE# #INDENT# raise NotImplementedError ( self . _error_msg_no_discounting ) #NEWLINE# #UNINDENT# if ( max_iter is None ) : #NEWLINE# #INDENT# max_iter = self . max_iter #NEWLINE# #UNINDENT# if ( epsilon is None ) : #NEWLINE# #INDENT# epsilon = self . epsilon #NEWLINE# #UNINDENT# def span( z ) : #NEWLINE# #INDENT# return ( z . max ( ) - z . min ( ) ) #NEWLINE# #UNINDENT# def midrange( z ) : #NEWLINE# #INDENT# return ( ( z . min ( ) + z . max ( ) ) / 2 ) #NEWLINE# #UNINDENT# v = np . empty ( self . num_states ) #NEWLINE# if ( v_init is None ) : #NEWLINE# #INDENT# v [ : ] = ( self . R [ ( self . R > ( - np . inf ) ) ] . min ( ) / ( 1 - self . beta ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# v [ : ] = v_init #NEWLINE# #UNINDENT# u = np . empty ( self . num_states ) #NEWLINE# sigma = np . empty ( self . num_states , dtype = int ) #NEWLINE# try : #NEWLINE# #INDENT# tol = ( ( epsilon * ( 1 - self . beta ) ) / self . beta ) #NEWLINE# #UNINDENT# except ZeroDivisionError : #NEWLINE# #INDENT# tol = np . inf #NEWLINE# #UNINDENT# for i in range ( max_iter ) : #NEWLINE# #INDENT# self . bellman_operator ( v , Tv = u , sigma = sigma ) #NEWLINE# diff = ( u - v ) #NEWLINE# if ( span ( diff ) < tol ) : #NEWLINE# #INDENT# v [ : ] = ( u + ( ( midrange ( diff ) * self . beta ) / ( 1 - self . beta ) ) ) #NEWLINE# break #NEWLINE# #UNINDENT# self . operator_iteration ( T = self . T_sigma ( sigma ) , v = u , max_iter = k ) #NEWLINE# v [ : ] = u #NEWLINE# #UNINDENT# num_iter = ( i + 1 ) #NEWLINE# res = DPSolveResult ( v = v , sigma = sigma , num_iter = tol , mc = self . controlled_mc ( sigma ) , method = 'modified policy iteration' , epsilon = epsilon , max_iter = max_iter , k = k ) #NEWLINE# return res