Advertisement
Dmitrey15

OpenOpt least norms routine

Jul 16th, 2012
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.87 KB | None | 0 0
  1. # OpenOpt routine to solve min {alpha1*||A1 x - b1||_1 + alpha2*||A2 x - b2||^2 + beta1 * ||x||_1 + beta2 * ||x||^2}
  2. # optionally: with specifiable accuracy fTol > 0 (by gsubg and maybe amsg2p, latter requires known good enough fOpt estimation)
  3.  
  4. # made by Dmitrey
  5.  
  6. def leastNorms(alpha1 = 0, A1 = None, b1 = None, alpha2 = 0, A2 = None, b2 = None, beta1 = 0, beta2 = 0, x0 = None, fTol = None,  solver = 'gsubg'):
  7.     # solves min alpha1*||A1 x - b1||_1 + alpha2*||A2 x - b2||^2 + beta1 * ||x||_1 + beta2 * ||x||^2 -> min
  8.     # with specifiable accuracy fTol
  9.    
  10.     assert (alpha1 != 0 and A1 is not None and b1 is not None) or (alpha2 != 0 and A2 is not None and b2 is not None), \
  11.     'at least one of sets (alpha1, A1, b1), (alpha2, A2, b2) must be provided'
  12.    
  13.     if alpha1 != 0:
  14.         n = A1.shape[1]
  15.     else:
  16.         n = A2.shape[1]
  17.    
  18.     from openopt import oosolver, NSP
  19.     if type(solver) == str:
  20.         solver = oosolver(solver)
  21.     if solver.__name__ == 'gsubg':
  22.         assert fTol is not None, 'for solver gsubg non-default fTol value must be provided'
  23.    
  24.     import numpy as np
  25.     try:
  26.         import scipy.sparse as sp
  27.         from scipy.sparse import isspmatrix
  28.     except ImportError:
  29.         isspmatrix = lambda *args: False
  30.         sp = None
  31.        
  32.    
  33.     matMultVec =  lambda x, y: np.dot(x, y) if not isspmatrix(x) else x._mul_sparse_matrix(sp.csr_matrix(y.reshape((y.size, 1)))).A.flatten()
  34.    
  35.     if isspmatrix(A1):
  36.         A1 = A1.tocsc()
  37.         A1T = A1.T.tocsc()
  38.     else:
  39.         A1T = A1.T
  40.     if isspmatrix(A2):
  41.         A2 = A2.tocsc()
  42.         A2T = A2.T.tocsc()
  43.     else:
  44.         A2T = A2.T
  45.    
  46.     if isspmatrix(b1):
  47.         b1 = b1.A.flatten()
  48.     if isspmatrix(b2):
  49.         b2 = b2.A.flatten()
  50.    
  51.    
  52.     def f(x):
  53.         r = 0.0
  54.        
  55.         # I don't want to use np.linalg norm for better compatibility with PyPy
  56.         if alpha1 != 0:
  57.             tmp = np.abs(matMultVec(A1, x) - b1)
  58.             assert tmp.ndim == 1, 'bug in leastNorms, probably due to incorrect input'
  59.             r += alpha1 * np.sum(tmp)
  60.         if alpha2 != 0:
  61.             tmp = (matMultVec(A2, x) - b2)**2
  62.             assert tmp.ndim == 1, 'bug in leastNorms, probably due to incorrect input'
  63.             r += alpha2 * np.sum(tmp)
  64.        
  65.         if beta1 != 0:
  66.             r += beta1 * np.sum(np.abs(x))
  67.         if beta2 != 0:
  68.             r += beta2 * np.sqrt(np.sum(x**2))
  69.        
  70.         return r
  71.        
  72.     def df(x):
  73.         r = np.zeros(x.size)
  74.        
  75.         if alpha1 != 0:
  76.             r += alpha1 * matMultVec(A1T, np.sign(matMultVec(A1, x) - b1))
  77.         if alpha2 != 0:
  78.             r += 2 * alpha2 * matMultVec(A2T, matMultVec(A2,x)  - b2)
  79.        
  80.         if beta1 != 0:
  81.             r += beta1 * np.sign(x)
  82.         if beta2 != 0:
  83.             r += 2 * beta2 * x
  84.        
  85.         return r        
  86.    
  87.     p = NSP(x0 = np.zeros(n) if x0 is None else x0, f = f, df = df, fTol = fTol)
  88.     #p.checkdf()
  89.     r = p.minimize(solver)
  90.     return r
  91.  
  92. if __name__ == '__main__':
  93.     n = 10000 # unknowns
  94.     m = 50
  95.     import scipy.sparse as sp
  96.    
  97.     X = sp.rand(n, 1, density=0.8)
  98.    
  99.     # Let A1 be matrix of shape (m, n)
  100.     alpha1 = 0.015
  101.     A1 = sp.rand(m, n, density=5.0/n) # in average 5 nonzero elements per each of m columns
  102.     b1 = A1._mul_sparse_matrix(X) + 0.015* sp.rand(m, 1, density=0.8)
  103.  
  104.     # Let A2 be matrix of shape (m+10, n)    
  105.     alpha2 = 0.015
  106.     A2 = sp.rand(m+10, n, density=5.0/n)
  107.     b2 = A2._mul_sparse_matrix(X) + 0.015* sp.rand(m+10, 1, density=0.8)
  108.    
  109.     beta1 = 0.0005
  110.     beta2 = 0.001
  111.    
  112.     fTol = 0.01
  113.     x0 = None
  114.    
  115.     from openopt import oosolver
  116.     # ralg is suitable for medium-scaled problems with nVars (=n) ~ 1000, see http://openopt.org/ralg for details
  117. #    solver = oosolver('ralg', iprint=10)
  118. #    r = leastNorms(alpha1, A1, b1, alpha2, A2, b2, beta1, beta2, x0, fTol, solver)
  119.     # gsubg is suitable for large-scaled problems, see http://openopt.org/gsubg for details
  120.     solver = oosolver('gsubg', iprint=10, maxShoots = 20)
  121.     r = leastNorms(alpha1, A1, b1, alpha2, A2, b2, beta1, beta2, x0, fTol, solver)
  122.     # alternatively you can use leastNorms(alpha2 = alpha2, b1 = b1, alpha1 = alpha1 ...)
  123. '''
  124. Output (may differ due to random variables involved in initial data creation)
  125. ------------------------- OpenOpt 0.39 -------------------------
  126. solver: gsubg   problem: unnamed    type: NSP   goal: minimum
  127. iter   objFunVal  
  128.    0  2.018e+00
  129.   10  1.123e-01
  130.   20  9.871e-02
  131.   30  9.267e-02
  132.   40  9.063e-02
  133.   50  8.691e-02
  134.   60  8.544e-02
  135.   70  8.341e-02
  136.   80  8.249e-02
  137.   90  8.216e-02
  138.  100  8.200e-02
  139. Terminated (singular KKT matrix).
  140.  104  8.142e-02
  141. istop: 16 (optimal solution wrt required fTol has been obtained)
  142. Solver:   Time Elapsed = 90.28  CPU Time Elapsed = 85.07
  143. objFunValue: 0.081420241
  144. '''
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement