Beispiel #1
0
def lmdif(fcn, x0, xmin, xmax, ftol=EPSILON, xtol=EPSILON, gtol=EPSILON,
          maxfev=None, epsfcn=EPSILON, factor=100.0, verbose=0):

    def par_at_boundary( low, val, high, tol ):
        for par_min, par_val, par_max in izip( low, val, high ):
            if sao_fcmp( par_val, par_min, tol ) == 0:
                return True
            if sao_fcmp( par_val, par_max, tol ) == 0:
                return True
        return False

    x, xmin, xmax = _check_args(x0, xmin, xmax)
    
    if maxfev is None:
       maxfev = 256 * len(x)

    def stat_cb0( pars ):
        return fcn( pars )[ 0 ]
    def stat_cb1( pars ):
        return fcn( pars )[ 1 ]

    m = numpy.asanyarray(stat_cb1(x)).size
    
    orig_fcn = stat_cb1
    error = []

    def stat_cb1(x_new, iflag):
        fvec = None
        try:
##             if _outside_limits(x_new, xmin, xmax) or _my_is_nan(x_new):
##                 fvec = numpy.empty((m,), x_new.dtype, numpy.isfortran(x_new))
##                 fvec[:] = numpy.sqrt(FUNC_MAX / m)
##             else:
            fvec = orig_fcn(x_new)
        except:
            error.append(sys.exc_info()[1])
            fvec = numpy.zeros((m,), x_new.dtype, numpy.isfortran(x_new))
            iflag = -1

        return fvec, iflag

    info, nfev, fval, covarerr = _minpack.mylmdif(stat_cb1, m, x, ftol, xtol, gtol, maxfev, epsfcn, factor, verbose, xmin, xmax)

    if par_at_boundary( xmin, x, xmax, xtol ):
        nm_result = neldermead( fcn, x, xmin, xmax, ftol=numpy.sqrt(ftol), maxfev=maxfev-nfev, finalsimplex=2, iquad=0, verbose=0 )
        nfev += nm_result[ 4 ][ 'nfev' ]
        x = nm_result[ 1 ]
        fval = nm_result[ 2 ]
##        if nm_result[ 2 ] < fval:
##            x = nm_result[ 1 ]
##            fval = nm_result[ 2 ]
##            info, mynfev, fval, covarerr = _minpack.mylmdif(stat_cb1, m, x, ftol, xtol, gtol, maxfev-nfev, epsfcn, factor, verbose, xmin, xmax)
 ##           nfev += mynfev
        
    if error:
        raise error.pop()

    key = {
        0: (False, 'improper input parameters'),
        1: (True,
            ('both actual and predicted relative reductions in the sum ' +
             'of squares are at most ftol=%g') % ftol),
        2: (True,
            ('relative error between two consecutive iterates is at ' +
             'most xtol=%g') % xtol),
        4: (True,
            ('the cosine of the angle between fvec and any column of ' +
             'the jacobian is at most gtol=%g in absolute value') % gtol),
        5: (False,
            ('number of calls to function has reached or exceeded '+
             'maxfev=%d') % maxfev),
        6: (False,
            ('ftol=%g is too small; no further reduction in the sum of ' +
             'squares is possible') % ftol),
        7: (False,
            ('xtol=%g is too small; no further improvement in the ' +
             'approximate solution is possible') % xtol),
        8: (False,
            ('gtol=%g is too small; fvec is orthogonal to the columns ' +
             'of the jacobian to machine precision') % gtol),
        }
    key[3] = (True, key[1][1] + ' and ' + key[2][1])
    status, msg = key.get(info, (False, 'unknown status flag (%d)' % info))

    if 0 == info:
        info = 1
    elif info >= 1 or info <= 4:
        info = 0
    else:
        info = 3
    status, msg = _get_saofit_msg( maxfev, info )
      
    rv = (status, x, fval)
    print_covar_err = False
    if print_covar_err:
        rv += (msg, {'info': info, 'nfev': nfev, 'covarerr': covarerr})
    else:
        rv += (msg, {'info': info, 'nfev': nfev})

    return rv
Beispiel #2
0
def lmdif(fcn, x0, xmin, xmax, ftol=EPSILON, xtol=EPSILON, gtol=EPSILON,
          maxfev=None, epsfcn=EPSILON, factor=100.0, verbose=0):

    x, xmin, xmax = _check_args(x0, xmin, xmax)

    if maxfev is None:
        maxfev = 256 * len(x)

    def stat_cb0( pars ):
        return fcn( pars )[ 0 ]
    def stat_cb1( pars ):
        return fcn( pars )[ 1 ]

    m = numpy.asanyarray(stat_cb1(x)).size
    
    orig_fcn = stat_cb1
    error = []

    def stat_cb1(x_new, iflag):
        fvec = None
        try:
##             if _outside_limits(x_new, xmin, xmax) or _my_is_nan(x_new):
##                 fvec = numpy.empty((m,), x_new.dtype, numpy.isfortran(x_new))
##                 fvec[:] = numpy.sqrt(FUNC_MAX / m)
##             else:
            fvec = orig_fcn(x_new)
        except:
            error.append(sys.exc_info()[1])
            fvec = numpy.zeros((m,), x_new.dtype, numpy.isfortran(x_new))
            iflag = -1

        return fvec, iflag

    def myfdjac( myx, myfvec, myfjac, myxmax, myiflag, myepsfcn ):

        eps = numpy.sqrt( max( [ EPSILON, myepsfcn ] ) )
        n = len( myx )

        def fdjac( xxx, origxxx, fvec, upbound, iflag, epsilon ):
            myn = len( xxx )
            diffs = []
            for jj in xrange( myn ):
                temp = xxx[ jj ]
                h = epsilon * abs( xxx[ jj ] )
                if 0.0 == h:
                    h = eps
                if xxx[ jj ] + h > upbound[ jj ]:
                    h = - h
                xxx[ jj ] = temp + h
                wa, iflag = fcn( origxxx, iflag )
                xxx[ jj ] = temp
                diff = ( wa - fvec ) / h
                diff = numpy.append( diff, iflag )
                diffs.append( diff )
            return diffs

        diffs = divide_run_parallel( fdjac, myx, myx, myfvec, myxmax, myiflag, eps )

        for jj in range( n ):
            myfjac[ 0:, jj ] = diffs[ jj ][:-1].copy()
            if diffs[ jj ][ -1 ] < 0:
                myiflag = diffs[ jj ][ -1 ]
        return myiflag, myfjac

    multicore = 0
    info, nfev, fval, covarerr = _minpack.mylmdif(stat_cb1, m, x, ftol, xtol, gtol, maxfev, epsfcn, factor, verbose, xmin, xmax, multicore, myfdjac)

    if error:
        raise error.pop()

    key = {
        0: (False, 'improper input parameters'),
        1: (True,
            ('both actual and predicted relative reductions in the sum ' +
             'of squares are at most ftol=%g') % ftol),
        2: (True,
            ('relative error between two consecutive iterates is at ' +
             'most xtol=%g') % xtol),
        4: (True,
            ('the cosine of the angle between fvec and any column of ' +
             'the jacobian is at most gtol=%g in absolute value') % gtol),
        5: (False,
            ('number of calls to function has reached or exceeded '+
             'maxfev=%d') % maxfev),
        6: (False,
            ('ftol=%g is too small; no further reduction in the sum of ' +
             'squares is possible') % ftol),
        7: (False,
            ('xtol=%g is too small; no further improvement in the ' +
             'approximate solution is possible') % xtol),
        8: (False,
            ('gtol=%g is too small; fvec is orthogonal to the columns ' +
             'of the jacobian to machine precision') % gtol),
        }
    key[3] = (True, key[1][1] + ' and ' + key[2][1])
    status, msg = key.get(info, (False, 'unknown status flag (%d)' % info))

    if 0 == info:
        info = 1
    elif info >= 1 or info <= 4:
        info = 0
    else:
        info = 3
    status, msg = _get_saofit_msg( maxfev, info )
      
    rv = (status, x, fval)
    print_covar_err = False
    if print_covar_err:
        rv += (msg, {'info': info, 'nfev': nfev, 'covarerr': covarerr})
    else:
        rv += (msg, {'info': info, 'nfev': nfev})

    return rv
Beispiel #3
0
def lmdif(fcn, x0, xmin, xmax, ftol=EPSILON, xtol=EPSILON, gtol=EPSILON,
          maxfev=None, epsfcn=EPSILON, factor=100.0, verbose=0):

    def par_at_boundary( low, val, high, tol ):
        for par_min, par_val, par_max in izip( low, val, high ):
            if sao_fcmp( par_val, par_min, tol ) == 0:
                return True
            if sao_fcmp( par_val, par_max, tol ) == 0:
                return True
        return False

    x, xmin, xmax = _check_args(x0, xmin, xmax)

    if maxfev is None:
        maxfev = 256 * len(x)

    def stat_cb0( pars ):
        return fcn( pars )[ 0 ]
    def stat_cb1( pars ):
        return fcn( pars )[ 1 ]

    m = numpy.asanyarray(stat_cb1(x)).size

    orig_fcn = stat_cb1
    error = []

    def stat_cb1(x_new, iflag):
        fvec = None
        try:
##             if _outside_limits(x_new, xmin, xmax) or _my_is_nan(x_new):
##                 fvec = numpy.empty((m,), x_new.dtype, numpy.isfortran(x_new))
##                 fvec[:] = numpy.sqrt(FUNC_MAX / m)
##             else:
            fvec = orig_fcn(x_new)
        except:
            error.append(sys.exc_info()[1])
            fvec = numpy.zeros((m,), x_new.dtype, numpy.isfortran(x_new))
            iflag = -1

        return fvec, iflag

    info, nfev, fval, covarerr = _minpack.mylmdif(stat_cb1, m, x, ftol, xtol, gtol, maxfev, epsfcn, factor, verbose, xmin, xmax)

    if par_at_boundary( xmin, x, xmax, xtol ):
        nm_result = neldermead( fcn, x, xmin, xmax, ftol=numpy.sqrt(ftol), maxfev=maxfev-nfev, finalsimplex=2, iquad=0, verbose=0 )
        nfev += nm_result[ 4 ][ 'nfev' ]
        x = nm_result[ 1 ]
        fval = nm_result[ 2 ]
##        if nm_result[ 2 ] < fval:
##            x = nm_result[ 1 ]
##            fval = nm_result[ 2 ]
##            info, mynfev, fval, covarerr = _minpack.mylmdif(stat_cb1, m, x, ftol, xtol, gtol, maxfev-nfev, epsfcn, factor, verbose, xmin, xmax)
 ##           nfev += mynfev

    if error:
        raise error.pop()

    key = {
        0: (False, 'improper input parameters'),
        1: (True,
            ('both actual and predicted relative reductions in the sum ' +
             'of squares are at most ftol=%g') % ftol),
        2: (True,
            ('relative error between two consecutive iterates is at ' +
             'most xtol=%g') % xtol),
        4: (True,
            ('the cosine of the angle between fvec and any column of ' +
             'the jacobian is at most gtol=%g in absolute value') % gtol),
        5: (False,
            ('number of calls to function has reached or exceeded '+
             'maxfev=%d') % maxfev),
        6: (False,
            ('ftol=%g is too small; no further reduction in the sum of ' +
             'squares is possible') % ftol),
        7: (False,
            ('xtol=%g is too small; no further improvement in the ' +
             'approximate solution is possible') % xtol),
        8: (False,
            ('gtol=%g is too small; fvec is orthogonal to the columns ' +
             'of the jacobian to machine precision') % gtol),
        }
    key[3] = (True, key[1][1] + ' and ' + key[2][1])
    status, msg = key.get(info, (False, 'unknown status flag (%d)' % info))

    if 0 == info:
        info = 1
    elif info >= 1 or info <= 4:
        info = 0
    else:
        info = 3
    status, msg = _get_saofit_msg( maxfev, info )

    rv = (status, x, fval)
    print_covar_err = False
    if print_covar_err:
        rv += (msg, {'info': info, 'nfev': nfev, 'covarerr': covarerr})
    else:
        rv += (msg, {'info': info, 'nfev': nfev})

    return rv