Beispiel #1
0
def newton_solver(f,
                  x0,
                  lb=None,
                  ub=None,
                  infos=False,
                  verbose=False,
                  maxit=50,
                  tol=1e-8,
                  eps=1e-5,
                  numdiff=False):
    '''Solves many independent systems f(x)=0 simultaneously using a simple gradient descent.
    :param f: objective function to be solved with values p x N . The second output argument represents the derivative with
    values in (p x p x N)
    :param x0: initial value ( p x N )
    :return: solution x such that f(x) = 0
    '''

    precision = x0.dtype  # default tolerance should depend on precision

    from dolo.numeric.serial_operations import serial_multiplication as stv, serial_solve
    err = 1

    it = 0
    while err > tol and it <= maxit:
        if not numdiff:
            [res, dres] = f(x0)
        else:
            res = f(x0)
            dres = numpy.zeros((res.shape[0], x0.shape[0], x0.shape[1]),
                               dtype=precision)
            for i in range(x0.shape[0]):
                xi = x0.copy()
                xi[i, :] += eps
                resi = f(xi)
                dres[:, i, :] = (resi - res) / eps

        try:
            dx = -serial_solve(dres, res)
        except:
            dx = -serial_solve(dres, res, debug=True)
        x = x0 + dx

        err = abs(res).max()

        x0 = x
        it += 1

    if not infos:
        return x
    else:
        return [x, it]
Beispiel #2
0
def newton_solver(f, x0, lb=None, ub=None, infos=False, verbose=False, maxit=50, tol=1e-8, eps=1e-5, numdiff=False):
    '''Solves many independent systems f(x)=0 simultaneously using a simple gradient descent.
    :param f: objective function to be solved with values p x N . The second output argument represents the derivative with
    values in (p x p x N)
    :param x0: initial value ( p x N )
    :return: solution x such that f(x) = 0
    '''

    precision = x0.dtype   # default tolerance should depend on precision

    from dolo.numeric.serial_operations import serial_multiplication as stv, serial_solve
    err = 1

    it = 0
    while err > tol and it <= maxit:
        if not numdiff:
            [res,dres] = f(x0)
        else:
            res = f(x0)
            dres = numpy.zeros( (res.shape[0], x0.shape[0], x0.shape[1]), dtype=precision )
            for i in range(x0.shape[0]):
                xi = x0.copy()
                xi[i,:] += eps
                resi = f(xi)
                dres[:,i,:] = (resi - res)/eps

        try:
            dx = - serial_solve(dres,res)
        except:
            dx = - serial_solve(dres,res, debug=True)
        x = x0 + dx

        err = abs(res).max()

        x0 = x
        it += 1

    if not infos:
        return x
    else:
        return [x, it]
Beispiel #3
0
def newton_solver(f, x0, lb=None, ub=None, infos=False, backsteps=10, maxit=10):
    '''Solves many independent systems f(x)=0 simultaneously using a simple gradient descent.
    :param f: objective function to be solved with values p x N . The second output argument represents the derivative with
    values in (p x p x N)
    :param x0: initial value ( p x N )
    :return: solution x such that f(x) = 0
    '''

    from dolo.numeric.serial_operations import serial_multiplication as stv, serial_solve
    err = 1
    tol = 1e-8
    it = 0
    while err > tol and it <= maxit:
        [res,dres] = f(x0)
#	res = f(x0)
#        dres = df(x0)
        fnorm = abs(res).max()  # suboptimal

        dx = - serial_solve(dres,res)

#        x = x0 + dx

        for i in range(backsteps):
            xx = x0 + dx/(2**i)
            if not ub==None:
                xx = numpy.maximum(xx, lb)
                xx = numpy.minimum(xx, ub)
            new_res = f(xx)[0]
            new_fnorm = abs(new_res).max()
            if numpy.isfinite(new_fnorm) and new_fnorm < fnorm: # all right proceed to next iteration
                x = xx
                break
            if i == backsteps -1:
                if numpy.isfinite(new_fnorm):
                    x = xx
                else:
                    raise Exception('Non finite value found')

        err = abs(dx).max()

        x0 = x
        it += 1
#    print (it <=maxit)
#    print(err)
    if not infos:
        return x
    else:
        return [x, it]
Beispiel #4
0
def ncpsolve(f, a, b, x, tol=None, infos=False, verbose=False, serial=False):
    '''
    don't ask what ncpsolve can do for you...
    :param f:
    :param a:
    :param b:
    :param x:
    :param tol:
    :param serial:
    :return:
    '''

    maxit = 100

    if tol is None:
        tol = sqrt(finfo(float64).eps)

    maxsteps = 10
    showiters = True

    it = 0
    if verbose:
        headline = '|{0:^5} | {1:^12} | {2:^12} |'.format(
            'k', ' backsteps', '||f(x)||')
        stars = '-' * len(headline)
        print(stars)
        print(headline)
        print(stars)

    while it < maxit:

        it += 1

        [fval, fjac] = f(x)
        [ftmp, fjac] = smooth(x, a, b, fval, fjac, serial=serial)

        fnorm = norm(ftmp, ord=inf)

        if fnorm < tol:
            if verbose:
                print(stars)
            if infos:
                return [x, it]
            else:
                return x

        if serial:
            from dolo.numeric.serial_operations import serial_solve
            dx = -serial_solve(fjac, ftmp)
        else:
            dx = -solve(fjac, ftmp)

        fnormold = inf

        for backsteps in range(maxsteps):

            xnew = x + dx
            fnew = f(xnew)[0]  # TODO: don't ask for derivatives
            fnew = smooth(xnew, a, b, fnew, serial=serial)
            fnormnew = norm(fnew, ord=inf)

            if fnormnew < fnorm:
                break
            if fnormold < fnormnew:
                dx = 2 * dx
                break

            fnormold = fnormnew
            dx = dx / 2

        x = x + dx

        if verbose:
            print('|{0:5} | {2:12.3e} | {2:12.3e} |'.format(
                it, backsteps, fnormnew))

    if verbose:
        print(stars)

    warnings.Warning('Failure to converge in ncpsolve')

    fval = f(x)

    return [x, fval]
Beispiel #5
0
def ncpsolve(f, a, b, x, tol=None, infos=False, verbose=False, serial=False):
    '''
    don't ask what ncpsolve can do for you...
    :param f:
    :param a:
    :param b:
    :param x:
    :param tol:
    :param serial:
    :return:
    '''

    maxit = 100

    if tol is None:
        tol = sqrt( finfo( float64 ).eps )

    maxsteps = 10
    showiters = True


    it = 0
    if verbose:
        headline = '|{0:^5} | {1:^12} | {2:^12} |'.format( 'k',' backsteps', '||f(x)||' )
        stars = '-'*len(headline)
        print(stars)
        print(headline)
        print(stars)

    while it < maxit:

        it += 1

        [fval, fjac] = f(x)
        [ftmp, fjac] = smooth(x, a, b, fval, fjac, serial=serial)

        fnorm = norm( ftmp, ord=inf)

        if fnorm < tol:
            if verbose:
                print(stars)
            if infos:
                return [x, it]
            else:
                return x

        if serial:
            from dolo.numeric.serial_operations import serial_solve
            dx = - serial_solve( fjac, ftmp )
        else:
            dx = - solve( fjac, ftmp)

        fnormold = inf

        for backsteps in range(maxsteps):

            xnew = x + dx
            fnew = f(xnew)[0] # TODO: don't ask for derivatives
            fnew = smooth( xnew, a, b, fnew, serial=serial)
            fnormnew = norm(fnew, ord=inf)

            if fnormnew < fnorm:
                break
            if fnormold < fnormnew:
                dx = 2*dx
                break

            fnormold = fnormnew
            dx = dx/2

        x = x + dx

        if verbose:
            print('|{0:5} | {2:12.3e} | {2:12.3e} |'.format( it, backsteps, fnormnew) )


    if verbose:
        print(stars)

    warnings.Warning('Failure to converge in ncpsolve')

    fval = f(x)

    return [x,fval]