Example #1
0
def run(y, A):
    """
    Run the specified SL0 reconstruction algorithm.

    The available SL0 reconstruction algorithms are the original SL0 and the
    modified SL0. Which of the available SL0 reconstruction algorithms is used,
    is specified as a configuration option.

    Parameters
    ----------
    y : ndarray
        The m x 1 measurement vector.
    A : ndarray
        The m x n matrix which is the product of the measurement matrix and the
        dictionary matrix.

    Returns
    -------
    alpha : ndarray
        The n x 1 reconstructed coefficient vector.

    See Also
    --------
    magni.cs.reconstruction.sl0.config : Configuration options.
    magni.cs.reconstruction.sl0._original.run : The original SL0 reconstruction
        algorithm.
    magni.cs.reconstruction.sl0._modified.run : The modified SL0 reconstruction
        algorithm.

    Examples
    --------
    See the individual run functions in the implementations of the original and
    modified SL0 reconstruction algorithms.

    """

    _validate_run(y, A)

    algorithm = _config.get('algorithm')

    if algorithm == 'std':
        x = _original.run(y, A)
    elif algorithm == 'mod':
        x = _modified.run(y, A)

    return x
Example #2
0
def _run_proj(y, A):
    """
    Run the original *projection* SL0 reconstruction algorithm.

    This function implements the algorithm with an unconstrained gradient step
    followed by a projection back onto the feasible set.

    Parameters
    ----------
    y : ndarray
        The m x 1 measurement vector.
    A : ndarray
        The m x n matrix which is the product of the measurement matrix and the
        dictionary matrix.

    Returns
    -------
    alpha : ndarray
        The n x 1 reconstructed coefficient vector.

    """

    param = _config.get()
    sigma_min = param['sigma_min']
    L = int(np.round(param['L']))
    mu = param['mu']
    sigma_update = param['sigma_update']

    Q, R = scipy.linalg.qr(A.T, mode='economic')
    A_pinv = Q.dot(scipy.linalg.inv(R.T))
    x = A_pinv.dot(y)
    sigma = param['precision_float'](2) * np.abs(x).max()

    while sigma > sigma_min:
        for j in range(L):
            d = x * np.exp(-x ** 2 / (2 * sigma ** 2))
            x = x - mu * d
            x = x - A_pinv.dot(A.dot(x) - y)  # Projection

        sigma = sigma * sigma_update

    return x
Example #3
0
def _run_feas(y, A):
    """
    Run the original *feasibility* SL0 reconstruction algorithm.

    This function implements the algorithm with a search on the feasible set.

    Parameters
    ----------
    y : ndarray
        The m x 1 measurement vector.
    A : ndarray
        The m x n matrix which is the product of the measurement matrix and the
        dictionary matrix.

    Returns
    -------
    alpha : ndarray
        The n x 1 reconstructed coefficient vector.

    """

    param = _config.get()
    sigma_min = param['sigma_min']
    L = int(np.round(param['L']))
    mu = param['mu']
    sigma_update = param['sigma_update']

    Q, R = scipy.linalg.qr(A.T, mode='economic')
    IP = np.eye(A.shape[1]) - Q.dot(Q.T)
    x = Q.dot(scipy.linalg.solve_triangular(R, y, trans='T'))
    sigma = param['precision_float'](2) * np.abs(x).max()

    while sigma > sigma_min:
        for j in range(L):
            d = np.exp(-x ** 2 / (2 * sigma ** 2)) * x
            x = x - mu * IP.dot(d)  # Search on feasible set

        sigma = sigma * sigma_update

    return x
Example #4
0
def _run_proj(y, A):
    """
    Run the original *projection* SL0 reconstruction algorithm.

    This function implements the algorithm with an unconstrained gradient step
    followed by a projection back onto the feasible set.

    Parameters
    ----------
    y : ndarray
        The m x 1 measurement vector.
    A : ndarray
        The m x n matrix which is the product of the measurement matrix and the
        dictionary matrix.

    Returns
    -------
    alpha : ndarray
        The n x 1 reconstructed coefficient vector.

    """

    param = _config.get()

    sigma_update = param['sigma_update']
    sigma_min = param['sigma_min']

    L = param['L']
    L_update = param['L_update']

    mu_start = param['mu_start']
    mu_end = param['mu_end']

    epsilon = param['epsilon']

    Q, R = scipy.linalg.qr(A.T, mode='economic')
    A_pinv = Q.dot(scipy.linalg.inv(R.T))
    x = A_pinv.dot(y)

    mult = _calc_sigma_start(A.shape[0] / A.shape[1])
    sigma = mult * np.abs(x).max()

    x_zeros = np.zeros(x.shape)
    i = 0

    while sigma > sigma_min:
        if i < 4 or mult * sigma_update**i > 0.75:
            if A.shape[0] / A.shape[1] <= 0.5:
                mu = 50 * mu_start
            else:
                mu = mu_start
        else:
            mu = mu_end

        x_prev = x_zeros
        j = 0

        while scipy.linalg.norm(x - x_prev) > sigma * epsilon and j <= L:
            x_prev = x.copy()

            d = np.exp(-(x ** 2) / (2 * sigma ** 2)) * x
            x = x - mu * d
            x = x - A_pinv.dot(A.dot(x) - y)  # Projection

            j = j + 1

        sigma = sigma * sigma_update
        L = L * L_update
        i = i + 1

    return x
Example #5
0
def _run_feas(y, A):
    """
    Run the modified *feasibility* SL0 reconstruction algorithm.

    This function implements the algorithm with a search on the feasible set.

    Parameters
    ----------
    y : ndarray
        The m x 1 measurement vector.
    A : ndarray
        The m x n matrix which is the product of the measurement matrix and the
        dictionary matrix.

    Returns
    -------
    alpha : ndarray
        The n x 1 reconstructed coefficient vector.

    """

    param = _config.get()

    sigma_update = param['sigma_update']
    sigma_min = param['sigma_min']

    L = param['L']
    L_update = param['L_update']

    mu_start = param['mu_start']
    mu_end = param['mu_end']

    epsilon = param['epsilon']

    Q, R = scipy.linalg.qr(A.T)
    Q1 = Q[:, :A.shape[0]]
    Q2 = Q[:, A.shape[0]:]
    R = R[:R.shape[1], :]
    x = Q1.dot(scipy.linalg.solve_triangular(R, y, trans='T'))

    mult = _calc_sigma_start(A.shape[0] / A.shape[1])
    sigma = mult * np.abs(x).max()

    x_zeros = np.zeros(x.shape)
    i = 0

    while sigma > sigma_min:
        if i < 4 or mult * sigma_update**i > 0.75:
            if A.shape[0] / A.shape[1] <= 0.5:
                mu = 50 * mu_start
            else:
                mu = mu_start
        else:
            mu = mu_end

        x_prev = x_zeros
        j = 0

        while scipy.linalg.norm(x - x_prev) > sigma * epsilon and j <= L:
            x_prev = x.copy()

            d = np.exp(-(x ** 2) / (2 * sigma ** 2)) * x
            nabla = Q2.T.dot(d)
            x = x - Q2.dot(mu * nabla)  # Search on feasible set

            j = j + 1

        sigma = sigma * sigma_update
        L = L * L_update
        i = i + 1

    return x