Быстрые решатели CVX в Matlab

Мне интересно, какой самый быстрый выпуклый оптимизатор в Matlab или есть ли способ ускорить текущие решатели? Я использую CVX, но на решение проблемы оптимизации у меня уходит вечность. Оптимизация, которую я должен решить

minimize norm(Ax-b, 2)
subject to
x >= 0
and x d <= delta

где размеры А и В очень велики.

Есть ли способ, которым я могу решить это с помощью решателя наименьших квадратов, а затем перенести его в версию ограничения, чтобы сделать это быстрее?

1 ответ

Я не уверен что x.d <= delta значит, но я просто предположу, что это должно быть x <= delta,

Вы можете решить эту проблему, используя метод проецируемого градиента или метод ускоренного проецируемого градиента (который является лишь небольшой модификацией метода проецируемого градиента, который "волшебным образом" сходится гораздо быстрее). Вот код Python, который показывает, как минимизировать.5|| Ax - b ||^2 при условии ограничения 0 <= x <= delta с использованием FISTA, который является методом ускоренного проецируемого градиента. Более подробную информацию о методе прогнозируемого градиента и FISTA можно найти, например, в рукописи Бойда о проксимальных алгоритмах.

import numpy as np
import matplotlib.pyplot as plt

def fista(gradf,proxg,evalf,evalg,x0,params):
    # This code does FISTA with line search

    maxIter = params['maxIter']
    t = params['stepSize'] # Initial step size
    showTrigger = params['showTrigger']

    increaseFactor = 1.25
    decreaseFactor = .5

    costs = np.zeros((maxIter,1))

    xkm1 = np.copy(x0)
    vkm1 = np.copy(x0)

    for k in np.arange(1,maxIter+1,dtype = np.double):

        costs[k-1] = evalf(xkm1) + evalg(xkm1)
        if k % showTrigger == 0:
            print "Iteration: " + str(k) + "    cost: " + str(costs[k-1])

        t = increaseFactor*t

        acceptFlag = False
        while acceptFlag == False:
            if k == 1:
                theta = 1
            else:
                a = tkm1
                b = t*(thetakm1**2)
                c = -t*(thetakm1**2)
                theta = (-b + np.sqrt(b**2 - 4*a*c))/(2*a)

            y = (1 - theta)*xkm1 + theta*vkm1
            (gradf_y,fy) = gradf(y)
            x = proxg(y - t*gradf_y,t)
            fx = evalf(x)
            if fx <= fy + np.vdot(gradf_y,x - y) + (.5/t)*np.sum((x - y)**2):
                acceptFlag = True
            else:
                t = decreaseFactor*t

        tkm1 = t
        thetakm1 = theta
        vkm1 = xkm1 + (1/theta)*(x - xkm1)
        xkm1 = x

    return (xkm1,costs)


if __name__ == '__main__':

    delta = 5.0
    numRows = 300
    numCols = 50
    A = np.random.randn(numRows,numCols)
    ATrans = np.transpose(A)
    xTrue = delta*np.random.rand(numCols,1)
    b = np.dot(A,xTrue)
    noise = .1*np.random.randn(numRows,1)
    b = b + noise

    def evalf(x):
        AxMinusb = np.dot(A, x) - b
        val = .5 * np.sum(AxMinusb ** 2)
        return val

    def gradf(x):
        AxMinusb = np.dot(A, x) - b
        grad = np.dot(ATrans, AxMinusb)
        val = .5 * np.sum(AxMinusb ** 2)
        return (grad, val)

    def evalg(x):
        return 0.0

    def proxg(x,t):
        return np.maximum(np.minimum(x,delta),0.0)

    x0 = np.zeros((numCols,1))
    params = {'maxIter': 500, 'stepSize': 1.0, 'showTrigger': 5}
    (x,costs) = fista(gradf,proxg,evalf,evalg,x0,params)

    plt.figure()
    plt.plot(x)
    plt.plot(xTrue)

    plt.figure()
    plt.semilogy(costs)
Другие вопросы по тегам