예제 #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
예제 #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
예제 #3
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
예제 #4
0
def SL0_approx_proj(A, x, eps, sigma_min, sigma_decrease_factor=0.5, mu_0=2, L=3, L2=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()
  
  u,singvals,v  = numpy.linalg.svd(A, full_matrices=0)
  
  # 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:
          s_orig = s

          # Reference
          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
            s_cvxpy = EllipseProj.ellipse_proj_cvxpy(A,x,s,eps)       
            
          # Starting point
          direction = numpy.dot(A_pinv,(numpy.dot(A,s)-x))
          if (numpy.linalg.norm(numpy.dot(A,direction)) >= eps):
            s_first = s - (1.0 - eps/numpy.linalg.norm(numpy.dot(A,direction))) * direction

          #steps = 1
          ##steps = math.floor(math.log2(numpy.lingl.norm(s)/eps))
          #step = math.pow(numpy.linalg.norm(s)/eps, 1.0/steps)
          #eps = eps * step**(steps-1)
          #for k in range(steps):
            
          direction = numpy.dot(A_pinv,(numpy.dot(A,s)-x))
          if (numpy.linalg.norm(numpy.dot(A,direction)) >= eps):
            s = EllipseProj.ellipse_proj_proj(A,x,s,eps,L2)
            
            #eps = eps/step
      
      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
  
  return s
예제 #5
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
예제 #6
0
def SL0_approx_proj(A,
                    x,
                    eps,
                    sigma_min,
                    sigma_decrease_factor=0.5,
                    mu_0=2,
                    L=3,
                    L2=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()

    u, singvals, v = numpy.linalg.svd(A, full_matrices=0)

    # 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:
            s_orig = s

            # Reference
            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
                s_cvxpy = EllipseProj.ellipse_proj_cvxpy(A, x, s, eps)

            # Starting point
            direction = numpy.dot(A_pinv, (numpy.dot(A, s) - x))
            if (numpy.linalg.norm(numpy.dot(A, direction)) >= eps):
                s_first = s - (1.0 - eps / numpy.linalg.norm(
                    numpy.dot(A, direction))) * direction

            #steps = 1
            ##steps = math.floor(math.log2(numpy.lingl.norm(s)/eps))
            #step = math.pow(numpy.linalg.norm(s)/eps, 1.0/steps)
            #eps = eps * step**(steps-1)
            #for k in range(steps):

            direction = numpy.dot(A_pinv, (numpy.dot(A, s) - x))
            if (numpy.linalg.norm(numpy.dot(A, direction)) >= eps):
                s = EllipseProj.ellipse_proj_proj(A, x, s, eps, L2)

                #eps = eps/step

        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

    return s