Example #1
0
def SL0_approx_dai(A,
                   x,
                   eps,
                   sigma_min,
                   sigma_decrease_factor=0.5,
                   mu_0=2,
                   L=3,
                   A_pinv=None,
                   true_s=None):

    if A_pinv is None:
        A_pinv = numpy.linalg.pinv(A)

    if true_s is not None:
        ShowProgress = True
    else:
        ShowProgress = False

    # Initialization
    #s = A\x;
    s = numpy.dot(A_pinv, x)
    sigma = 2.0 * numpy.abs(s).max()

    # Main Loop
    while sigma > sigma_min:
        for i in numpy.arange(L):
            delta = OurDelta(s, sigma)
            s = s - mu_0 * delta
            # At this point, s no longer exactly satisfies x = A*s
            # The original SL0 algorithm projects s onto {s | x = As} with
            # s = s - numpy.dot(A_pinv,(numpy.dot(A,s)-x))   # Projection
            # We want to project s onto {s | |x-As| < eps}
            # We move onto the direction -A_pinv*(A*s-x), but only with a
            # smaller step:
            direction = numpy.dot(A_pinv, (numpy.dot(A, s) - x))
            if (numpy.linalg.norm(numpy.dot(A, direction)) >= eps):
                #s = s - (1.0 - eps/numpy.linalg.norm(numpy.dot(A,direction))) * direction
                try:
                    s = EllipseProj.ellipse_proj_dai(A, x, s, eps)
                except Exception, e:
                    #raise EllipseProj.EllipseProjDaiError(e)
                    raise EllipseProj.EllipseProjDaiError()

            #assert(numpy.linalg.norm(x - numpy.dot(A,s)) < eps + 1e-6)

        if ShowProgress:
            #fprintf('     sigma=#f, SNR=#f\n',sigma,estimate_SNR(s,true_s))
            string = '     sigma=%f, SNR=%f\n' % sigma, estimate_SNR(s, true_s)
            print string

        sigma = sigma * sigma_decrease_factor
Example #2
0
def SL0_approx_analysis_dai(Aeps,
                            Aexact,
                            x,
                            eps,
                            sigma_min,
                            sigma_decrease_factor=0.5,
                            mu_0=2,
                            L=3,
                            Aeps_pinv=None,
                            Aexact_pinv=None,
                            true_s=None):

    if Aeps_pinv is None:
        Aeps_pinv = numpy.linalg.pinv(Aeps)
    if Aexact_pinv is None:
        Aexact_pinv = numpy.linalg.pinv(Aexact)

    if true_s is not None:
        ShowProgress = True
    else:
        ShowProgress = False

    # Initialization
    #s = A\x;
    s = numpy.dot(Aeps_pinv, x)
    sigma = 2.0 * numpy.abs(s).max()

    # Main Loop
    while sigma > sigma_min:
        for i in numpy.arange(L):
            delta = OurDelta(s, sigma)
            s = s - mu_0 * delta
            # At this point, s no longer exactly satisfies x = A*s
            # The original SL0 algorithm projects s onto {s | x = As} with
            # s = s - numpy.dot(A_pinv,(numpy.dot(A,s)-x))   # Projection
            #
            # We want to project s onto {s | |x-AEPS*s|<eps AND |Aexact*s|=0}
            # First:   make s orthogonal to Aexact (|Aexact*s|=0)
            # Second:  move onto the direction -A_pinv*(A*s-x), but only with a smaller step:
            # This separation assumes that the rows of Aexact are orthogonal to the rows of Aeps
            #
            # 1. Make s orthogonal to Aexact:
            #     s = s - Aexact_pinv * Aexact * s
            s = s - numpy.dot(Aexact_pinv, (numpy.dot(Aexact, s)))
            # 2. Move onto the direction -A_pinv*(A*s-x), but only with a smaller step:
            direction = numpy.dot(Aeps_pinv, (numpy.dot(Aeps, s) - x))
            # Nic 10.04.2012: Why numpy.dot(Aeps,direction) and not just 'direction'?
            # Nic 10.04.2012: because 'direction' is of size(s), but I'm interested in it's projection on Aeps
            if (numpy.linalg.norm(numpy.dot(Aeps, direction)) >= eps):
                #  s = s - (1.0 - eps/numpy.linalg.norm(numpy.dot(Aeps,direction))) * direction
                try:
                    s = EllipseProj.ellipse_proj_dai(Aeps, x, s, eps)
                except Exception, e:
                    #raise EllipseProj.EllipseProjDaiError(e)
                    raise EllipseProj.EllipseProjDaiError()

            #assert(numpy.linalg.norm(x - numpy.dot(A,s)) < eps + 1e-6)

        if ShowProgress:
            #fprintf('     sigma=#f, SNR=#f\n',sigma,estimate_SNR(s,true_s))
            string = '     sigma=%f, SNR=%f\n' % sigma, estimate_SNR(s, true_s)
            print string

        sigma = sigma * sigma_decrease_factor