def beziereven_sum ( func , N , xmin , xmax , **kwargs ) : """Make a function/histiogram representation in terms of Bezier sum (sum of Bernstein Polynomials) >>> func = lambda x : x * x >>> fsum = beziereven_sum ( func , 2 , -1 , 1 ) >>> print fsum >>> x = ... >>> print 'FUN(%s) = %s ' % ( x , fsum ( x ) ) """ assert is_integer ( N ) and 0 <= N , "beziereven_sum: invalid N %s " % N xmin,xmax = _get_xminmax_ ( func , xmin , xmax , 'beziereven_sum' ) ## result bsum = Ostap.Math.BernsteinEven ( N , xmin , xmax ) npars = bsum.bernstein().npars() ## constants b_i = npars *[0.0] xmid = 0.5 * ( xmin + xmax ) ## symmetric function: f(xmid-x)=f(xmid+x) def _sym_func_ ( x ) : x1 = x x2 = xmid - x y1 = float ( func ( x1 ) ) y2 = float ( func ( x2 ) ) return 0.5 * ( y1 + y2 ) from ostap.math.integral import integral as _integral args = {} for i in range ( len ( b_i ) ) : index = 2 * N + 1 , i if not index in _bernstein_dual_basis_ : ## create the dual basic function _DUAL = Ostap.Math.BernsteinDualBasis _dual = _DUAL ( *index ) _bernstein_dual_basis_ [ index ] = _dual ## get the dual basic function dual = _bernstein_dual_basis_[ index ] ## get the integration function fun_i = lambda x : _sym_func_ ( x ) * dual ( bsum.t( x ) ) ## use integration if kwargs : args = deepcopy ( kwargs ) c_i = _integral ( fun_i , xmin , xmax , **args ) / ( xmax - xmin ) b_i[i] = c_i ## fill result with symmetrized coefficients last = npars - 1 for i in bsum : bsum.setPar( i , 0.5 * ( b_i[ i ] + b_i [ last - i ] ) ) return bsum
def _diff2_(fun1, fun2, xmin, xmax): _fun1_ = lambda x: float(fun1(x))**2 _fun2_ = lambda x: float(fun2(x))**2 _fund_ = lambda x: (float(fun1(x)) - float(fun2(x)))**2 from ostap.math.integral import integral as _integral import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") d1 = _integral(_fun1_, xmin, xmax) d2 = _integral(_fun2_, xmin, xmax) dd = _integral(_fund_, xmin, xmax) import math return "%.4e" % math.sqrt(dd / (d1 * d2))
def sp_integrate_1D(func, xmin, xmax, *args, **kwargs): """Make 1D numerical integration >>> func = ... >>> print func.sp_integrate ( -10 , 10 ) """ from ostap.math.integral import integral as _integral return _integral(func, xmin, xmax, *args, **kwargs)
def bezier_sum ( func , N , xmin , xmax , **kwargs ) : """Make a function/histiogram representation in terms of Bezier sum (sum of Bernstein Polynomials) >>> func = lambda x : x * x >>> fsum = bezier_sum ( func , 4 , 0 , 1 ) >>> print fsum >>> x = ... >>> print 'FUN(%s) = %s ' % ( x , fsum ( x ) ) """ if not isinstance ( N , (int,long) ) or 0 > N : raise AttributeError( "bezier_sum: invalid N %s " % N ) xmin,xmax = _get_xminmax_ ( func , xmin , xmax , 'bezier_sum' ) ## result bsum = Ostap.Math.Bernstein ( N , xmin , xmax ) ## from scipy import integrate from ostap.math.integral import integral as _integral args = {} for i in range ( 0 , N + 1 ) : index = N,i if not _bernstein_dual_basis_.has_key ( index ) : ## create the dual basic function _DUAL = Ostap.Math.BernsteinDualBasis _dual = _DUAL ( *index ) _bernstein_dual_basis_ [ index ] = _dual ## get the dual basic function dual = _bernstein_dual_basis_[ index ] ## get the integration function fun_i = lambda x : float ( func ( x ) ) * dual ( bsum.t( x ) ) ## use scipy for integration if kwargs : args = deepcopy ( kwargs ) c_i = _integral ( fun_i , xmin , xmax , **args ) / ( xmax - xmin ) bsum.setPar( i , c_i ) return bsum
def legendre_sum ( func , N , xmin , xmax , **kwargs ) : """ Make a function representation in terms of Legendre polynomials [It is not very CPU efficient (scipy is used for integration), but stable enough...] >>> func = lambda x : x * x >>> fsum = legendre_sum ( func , 4 , -1 , 1 ) >>> print fsum >>> x = ... >>> print 'FUN(%s) = %s ' % ( x , fsum ( x ) ) see Gaudi::Math::LegendreSum """ from copy import deepcopy if not isinstance ( N , (int,long) ) or 0 > N : raise AttributeError( "legendre_sum: invalid N %s " % N ) xmin,xmax = _get_xminmax_ ( func , xmin , xmax , 'legendre_sum' ) ## prepare the result lsum = Ostap.Math.LegendreSum ( N , xmin , xmax ) ## the type for the basic legendre polynomials, used for integration L_ = Ostap.Math.Legendre ## transform x to local variable -1<t<1 tx = lambda x : lsum.t ( x ) idx = 1.0 / ( xmax - xmin ) ## scale factor from ostap.math.integral import integral as _integral args = {} for n in range ( N + 1 ) : li = L_ ( n ) fun_n = lambda x : func ( x ) * li ( tx ( x ) ) if kwargs : args = deepcopy ( kwargs ) c_n = _integral ( fun_n , xmin , xmax , **args ) * ( 2 * n + 1 ) * idx lsum.setPar ( n , c_n ) return lsum