コード例 #1
0
ファイル: ipPD.py プロジェクト: edwintye/pygotools
def _solveKKTAndUpdatePD(x, func, grad, fx, g, gOrig, Haug, z, G, h, y, A, b, t):
    p = len(x)
    step = 1.0
    deltaX = None
    deltaZ = None
    deltaY = None

    # standard log barrier, \nabla f(x) / -f(x)
    if G is not None:
        s = h - G.dot(x)
        Gs = G/s
        zs = z/s
        # now find the matrix/vector of our qp
        Haug += numpy.einsum('ji,ik->jk', G.T, G*zs)
        Dphi = Gs.sum(axis=0).reshape(p, 1)
        g += Dphi / t

    # find the solution to a Newton step to get the descent direction
    if A is not None:
        bTemp = _rPriFunc(x, A, b)
        g += A.T.dot(y)
        # print "here"
        LHS = scipy.sparse.bmat([
                [Haug, A.T],
                [A, None]
                ],'csc')
        RHS = numpy.append(g, bTemp, axis=0)
        # print LHS
        # print RHS
        # if the total number of elements (in sparse format) is
        # more than half total possible elements, it is a dense matrix
        if LHS.size>= (LHS.shape[0] * LHS.shape[1])/2:
            deltaTemp = scipy.linalg.solve(LHS.todense(), -RHS).reshape(len(RHS), 1)
        else:
            deltaTemp = scipy.linalg.solve(LHS.todense(), -RHS).reshape(len(RHS), 1)
        # print deltaTemp
        deltaX = deltaTemp[:p]
        deltaY = deltaTemp[p::]
    else:
        deltaX = scipy.linalg.solve(Haug, -g).reshape(p, 1)

    # store the information for the next iteration
    oldFx = fx
    oldGrad = gOrig.copy()

    if G is None:
        maxStep = 1
        barrierFunc = _logBarrier(x, func, t, G, h)
        lineFunc = lineSearch(maxStep, x, deltaX, barrierFunc)
        searchScale = deltaX.ravel().dot(g.ravel())
    else:
        maxStep = _maxStepSizePD(z, x, deltaX, t, G, h)
        lineFunc = _residualLineSearchPD(maxStep, x, deltaX,
                                      grad, t,
                                      z, _deltaZFunc, G, h,
                                      y, deltaY, A, b)

        searchScale = -lineFunc(0.0)

    # perform a line search.  Because the minimization routine
    # in scipy can sometimes be a bit weird, we assume that the
    # exact line search can sometimes fail, so we do a
    # back tracking line search if that is the case
    step, fx = exactLineSearch2(maxStep, lineFunc, searchScale, oldFx)

    # step, fx =  exactLineSearch(maxStep, lineFunc)
    # if fx >= oldFx or step <=0:
    #     step, fx =  backTrackingLineSearch(maxStep, lineFunc, searchScale)

    # found one iteration, now update the information
    if z is not None:
        z += step * _deltaZFunc(x, deltaX, t, z, G, h)
    if y is not None:
        y += step * deltaY

    x += step * deltaX

    return x, y, z, fx, step, oldFx, oldGrad, deltaX
コード例 #2
0
ファイル: ipPDC.py プロジェクト: edwintye/pygotools
def _solveKKTAndUpdatePDC(x, func, grad, fx, g, gOrig, Haug, z, G, h, y, A, b, t):
    p = len(x)
    step = 1
    deltaX = None
    deltaZ = None
    deltaY = None

    rDual = _rDualFunc(x, grad, z, G, y, A)
    RHS = rDual
    if G is not None:
        s = h - G.dot(x)
        Gs = G/s
        zs = z/s

        # now find the matrix/vector of our qp
        rCent = _rCentFunc(z, s, t)
        RHS = numpy.append(RHS, rCent, axis=0)

    ## solving the QP to get the descent direction
    if A is not None:
        bTemp = b - A.dot(x)
        g += A.T.dot(y)

        rPri = _rPriFunc(x, A, b)
        RHS = numpy.append(RHS, rPri, axis=0)

        if G is not None:
            LHS = scipy.sparse.bmat([
                    [Haug, G.T, A.T],
                    [G*-z, scipy.sparse.diags(s.ravel(),0), None],
                    [A, None, None]
                    ],'csc')
            if LHS.size>= (LHS.shape[0] * LHS.shape[1])/2:
                deltaTemp = scipy.sparse.linalg.spsolve(LHS, -RHS).reshape(len(RHS), 1)
            else:
                deltaTemp = scipy.linalg.solve(LHS.todense(), -RHS).reshape(len(RHS), 1)
                deltaX = deltaTemp[:p]
                deltaZ = deltaTemp[p:-len(A)]
                deltaY = deltaTemp[-len(A):]
        else: # G is None
            LHS = scipy.sparse.bmat([
                    [Haug, A.T],
                    [A, None]
                    ],'csc')
            if LHS.size>= (LHS.shape[0] * LHS.shape[1])/2:
                deltaTemp = scipy.sparse.linalg.spsolve(LHS, -RHS).reshape(len(RHS), 1)
            else:
                deltaTemp = scipy.linalg.solve(LHS.todense(), -RHS).reshape(len(RHS),1)
                deltaX = deltaTemp[:p]
                deltaY = deltaTemp[p::]
    else: # A is None
        if G is not None:
            LHS = scipy.sparse.bmat([
                    [Haug, G.T],
                    [G*-z, scipy.sparse.diags(s.ravel(),0)],
                    ],'csc')
            deltaTemp = scipy.sparse.linalg.spsolve(LHS, -RHS).reshape(len(RHS), 1)
            deltaX = deltaTemp[:p]
            deltaZ = deltaTemp[p::]
        else:
            deltaX = scipy.linalg.solve(Haug, -RHS).reshape(len(RHS), 1)

    # store the information for the next iteration
    oldFx = fx
    oldGrad = gOrig.copy()

    if G is None:
        # print "obj"
        maxStep = 1
        barrierFunc = _logBarrier(x, func, t, G, h)
        lineFunc = lineSearch(maxStep, x, deltaX, barrierFunc)
        searchScale = deltaX.ravel().dot(g.ravel())
    else:
        maxStep = _maxStepSizePDC(z, deltaZ, x, deltaX, G, h)
        lineFunc = _residualLineSearchPDC(step, x, deltaX,
                                       grad, t,
                                       z, deltaZ, G, h,
                                       y, deltaY, A, b)
        searchScale = -lineFunc(0.0)

    # perform a line search.  Because the minimization routine
    # in scipy can sometimes be a bit weird, we assume that the
    # exact line search can sometimes fail, so we do a
    # back tracking line search if that is the case
    step, fx = exactLineSearch2(maxStep, lineFunc, searchScale, oldFx)
    # step, fx =  exactLineSearch(maxStep, lineFunc)
    # if fx >= oldFx or step <= 0 or step>=maxStep:
    #     step, fx =  backTrackingLineSearch(maxStep, lineFunc, searchScale, oldFx)

    if z is not None:
        z += step * deltaZ
    if y is not None:
        y += step * deltaY
        
    x += step * deltaX

    return x, y, z, fx, step, oldFx, oldGrad, deltaX
コード例 #3
0
def _solveKKTAndUpdatePDC(x, func, grad, fx, g, gOrig, Haug, z, G, h, y, A, b,
                          t):
    p = len(x)
    step = 1
    deltaX = None
    deltaZ = None
    deltaY = None

    rDual = _rDualFunc(x, grad, z, G, y, A)
    RHS = rDual
    if G is not None:
        s = h - G.dot(x)
        Gs = G / s
        zs = z / s

        # now find the matrix/vector of our qp
        rCent = _rCentFunc(z, s, t)
        RHS = numpy.append(RHS, rCent, axis=0)

    ## solving the QP to get the descent direction
    if A is not None:
        bTemp = b - A.dot(x)
        g += A.T.dot(y)

        rPri = _rPriFunc(x, A, b)
        RHS = numpy.append(RHS, rPri, axis=0)

        if G is not None:
            LHS = scipy.sparse.bmat(
                [[Haug, G.T, A.T],
                 [G * -z, scipy.sparse.diags(s.ravel(), 0), None],
                 [A, None, None]], 'csc')
            if LHS.size >= (LHS.shape[0] * LHS.shape[1]) / 2:
                deltaTemp = scipy.sparse.linalg.spsolve(LHS, -RHS).reshape(
                    len(RHS), 1)
            else:
                deltaTemp = scipy.linalg.solve(LHS.todense(),
                                               -RHS).reshape(len(RHS), 1)
                deltaX = deltaTemp[:p]
                deltaZ = deltaTemp[p:-len(A)]
                deltaY = deltaTemp[-len(A):]
        else:  # G is None
            LHS = scipy.sparse.bmat([[Haug, A.T], [A, None]], 'csc')
            if LHS.size >= (LHS.shape[0] * LHS.shape[1]) / 2:
                deltaTemp = scipy.sparse.linalg.spsolve(LHS, -RHS).reshape(
                    len(RHS), 1)
            else:
                deltaTemp = scipy.linalg.solve(LHS.todense(),
                                               -RHS).reshape(len(RHS), 1)
                deltaX = deltaTemp[:p]
                deltaY = deltaTemp[p::]
    else:  # A is None
        if G is not None:
            LHS = scipy.sparse.bmat([
                [Haug, G.T],
                [G * -z, scipy.sparse.diags(s.ravel(), 0)],
            ], 'csc')
            deltaTemp = scipy.sparse.linalg.spsolve(LHS,
                                                    -RHS).reshape(len(RHS), 1)
            deltaX = deltaTemp[:p]
            deltaZ = deltaTemp[p::]
        else:
            deltaX = scipy.linalg.solve(Haug, -RHS).reshape(len(RHS), 1)

    # store the information for the next iteration
    oldFx = fx
    oldGrad = gOrig.copy()

    if G is None:
        # print "obj"
        maxStep = 1
        barrierFunc = _logBarrier(x, func, t, G, h)
        lineFunc = lineSearch(maxStep, x, deltaX, barrierFunc)
        searchScale = deltaX.ravel().dot(g.ravel())
    else:
        maxStep = _maxStepSizePDC(z, deltaZ, x, deltaX, G, h)
        lineFunc = _residualLineSearchPDC(step, x, deltaX, grad, t, z, deltaZ,
                                          G, h, y, deltaY, A, b)
        searchScale = -lineFunc(0.0)

    # perform a line search.  Because the minimization routine
    # in scipy can sometimes be a bit weird, we assume that the
    # exact line search can sometimes fail, so we do a
    # back tracking line search if that is the case
    step, fx = exactLineSearch2(maxStep, lineFunc, searchScale, oldFx)
    # step, fx =  exactLineSearch(maxStep, lineFunc)
    # if fx >= oldFx or step <= 0 or step>=maxStep:
    #     step, fx =  backTrackingLineSearch(maxStep, lineFunc, searchScale, oldFx)

    if z is not None:
        z += step * deltaZ
    if y is not None:
        y += step * deltaY

    x += step * deltaX

    return x, y, z, fx, step, oldFx, oldGrad, deltaX
コード例 #4
0
def _solveKKTAndUpdatePD(x, func, grad, fx, g, gOrig, Haug, z, G, h, y, A, b,
                         t):
    p = len(x)
    step = 1.0
    deltaX = None
    deltaZ = None
    deltaY = None

    # standard log barrier, \nabla f(x) / -f(x)
    if G is not None:
        s = h - G.dot(x)
        Gs = G / s
        zs = z / s
        # now find the matrix/vector of our qp
        Haug += numpy.einsum('ji,ik->jk', G.T, G * zs)
        Dphi = Gs.sum(axis=0).reshape(p, 1)
        g += Dphi / t

    # find the solution to a Newton step to get the descent direction
    if A is not None:
        bTemp = _rPriFunc(x, A, b)
        g += A.T.dot(y)
        # print "here"
        LHS = scipy.sparse.bmat([[Haug, A.T], [A, None]], 'csc')
        RHS = numpy.append(g, bTemp, axis=0)
        # print LHS
        # print RHS
        # if the total number of elements (in sparse format) is
        # more than half total possible elements, it is a dense matrix
        if LHS.size >= (LHS.shape[0] * LHS.shape[1]) / 2:
            deltaTemp = scipy.linalg.solve(LHS.todense(),
                                           -RHS).reshape(len(RHS), 1)
        else:
            deltaTemp = scipy.linalg.solve(LHS.todense(),
                                           -RHS).reshape(len(RHS), 1)
        # print deltaTemp
        deltaX = deltaTemp[:p]
        deltaY = deltaTemp[p::]
    else:
        deltaX = scipy.linalg.solve(Haug, -g).reshape(p, 1)

    # store the information for the next iteration
    oldFx = fx
    oldGrad = gOrig.copy()

    if G is None:
        maxStep = 1
        barrierFunc = _logBarrier(x, func, t, G, h)
        lineFunc = lineSearch(maxStep, x, deltaX, barrierFunc)
        searchScale = deltaX.ravel().dot(g.ravel())
    else:
        maxStep = _maxStepSizePD(z, x, deltaX, t, G, h)
        lineFunc = _residualLineSearchPD(maxStep, x, deltaX, grad, t, z,
                                         _deltaZFunc, G, h, y, deltaY, A, b)

        searchScale = -lineFunc(0.0)

    # perform a line search.  Because the minimization routine
    # in scipy can sometimes be a bit weird, we assume that the
    # exact line search can sometimes fail, so we do a
    # back tracking line search if that is the case
    step, fx = exactLineSearch2(maxStep, lineFunc, searchScale, oldFx)

    # step, fx =  exactLineSearch(maxStep, lineFunc)
    # if fx >= oldFx or step <=0:
    #     step, fx =  backTrackingLineSearch(maxStep, lineFunc, searchScale)

    # found one iteration, now update the information
    if z is not None:
        z += step * _deltaZFunc(x, deltaX, t, z, G, h)
    if y is not None:
        y += step * deltaY

    x += step * deltaX

    return x, y, z, fx, step, oldFx, oldGrad, deltaX