text:
import numpy as np
import scipy.sparse as sp

from   snopt.solvers          import snopt7_python as fsnopt
from   snopt.solvers.options  import SNOPT_options, copyOpts
from   snopt.solvers.solution import SNOPTA_solution, SNOPT_solution
from   snopt.solvers.misc     import printInfo
from   snopt.solvers.work     import SNOPT_work

#-------------------------------------------------------------------------------#

def snopta(usrfun,n,nF,**kwargs):
    """
    snopta() calls the SNOPTA solver to solve the optimization
    problem:
    min        F_objrow(x)
    s.t.   xlow <=   x  <= xupp
           Flow <= F(x) <= Fupp

    where F(x) is a vector of smooth linear and nonlinear constraint functions
    and F_objrow(x) is one of the components of F to be minimized, as specified by input
    argument ObjRow.

    The user should provide a function that returns the function F(x) and ideally
    their gradients.

    The problem is assumed to have n variables and nF constraint functions.

    --------------------------------------------
    Input arguments:
    --------------------------------------------
    Keyword    Description
    ----------------------
    usrfun     is the user-defined function that returns the objective, constraints
               and gradients (required)

    n          is the number of variables in the problem (n > 0) (required)

    nF         is the number of constraints in the problem (nF > 0) (required)

    name       is the name of the problem (default '')

    x0         are the intial values of x (default 0.0)
    xlow       are the lower bounds of x (default -infinity)
    xupp       are the upper bounds of x (default +infinity)
    xstates    contains the initial state of the x-variables (default 0)
    xmul       contains the initial multipliers of the x-variables (default 0.0)
    xnames     is an array of names for the x-variables (default '')

    F0         are the intial values of F (default 0.0)
    Flow       are the lower bounds of F (default -infinity)
    Fupp       are the upper bounds of F (default +infinity)
    Fstates    contains the initial state of the F-variables (default 0)
    Fmul       contains the initial multipliers of the F-variables (default 0.0)
    Fnames     is an array of names for the F-variables (default '')

    A          is the linear part of the constraint Jacobian of size nF by n.
               - A can be a tuple (A,iAfun,jAvar) containing the coordinates of the
                 linear constraint Jacobian, with iAfun containing the row indices and
                 jAvar containing the column indices.

               - A can be a scipy coo_matrix

               - A can be a numpy 2-dimensional array

    G          is the nonlinear part of the constraint Jacobian of size nF by n.
               - G can be a tuple (G,iGfun,jGvar) containing the coordinates of the
                 nonlinear constraint Jacobian, with iGfun containing the row indices and
                 jGvar containing the column indices.

               - G can be a scipy coo_matrix

               - G can be a numpy 2-dimensional array

               Here, the user only needs to provide the sparsity pattern of G.
               The values of G are provided in the user-defined subroutine.

    ObjRow     is an integer indicating the location of the objective in F(x) (default 0)
    ObjAdd     is a constant term of the objective (default 0.0)

    options    contains the user options for the SNOPT solver

    """

    name     = kwargs.get('name','')
    usropts  = kwargs.get('options',SNOPT_options())

    verbose  = usropts.getOption('Verbose')
    maxTries = usropts.getOption('Max memory attempts')
    inf      = usropts.getOption('Infinite bound')

    assert n  > 0, 'Error: n must be greater than 0'
    assert nF > 0, 'Error: nF must be greater than 0'

    neA = 0
    A   = kwargs.get('A',None)
    if A is not None:
        if   type(A) is tuple: # A = (A,iAfun,jAvar)
            try:
                (valA,iAfun,jAvar) = A
                neA = valA.size
            except:
                raise TypeError

        elif type(A) is np.ndarray and A.ndim == 2: # A = matrix
            spA   = sp.coo_matrix(A)

            iAfun = spA.row
            jAvar = spA.col
            valA  = spA.data
            neA   = spA.nnz

        elif type(A) is sp.coo_matrix: # A = scipy coo mtx
            iAfun = A.row
            jAvar = A.col
            valA  = A.data
            neA   = A.nnz

        else:
            raise TypeError

    neG = 0
    G   = kwargs.get('G',None)
    if G is not None:
        if   type(G) is tuple:  # G = (iGfun,jGvar)
            try:
                (iGfun,jGvar) = G
                neG = iGfun.size
            except:
                raise TypeError

        elif type(G) is np.ndarray and G.ndim == 2: # G = matrix
            spG    = sp.coo_matrix(G)
            iGfun  = spG.row
            jGvar  = spG.col
            neG    = spG.nnz

        elif type(G) is sp.coo_matrix: # G = scipy coo mtx
            iGfun  = G.row
            jGvar  = G.col
            neG    = G.nnz

        else:
            raise TypeError

    ObjRow  = kwargs.get('ObjRow',0)
    ObjAdd  = kwargs.get('ObjAdd',0.0)

    x0      = kwargs.get('x0',np.zeros(n,float))
    xlow    = kwargs.get('xlow',-inf*np.ones(n,float))
    xupp    = kwargs.get('xupp', inf*np.ones(n,float))
    xstates = kwargs.get('xstates',   np.zeros(n,int))
    xmul    = kwargs.get('xmul',   np.zeros(n,float))
    xnames  = kwargs.get('xnames', np.empty((1,8),dtype='|S1'))

    F0      = kwargs.get('F0',np.zeros(nF,float))
    Flow    = kwargs.get('Flow',-inf*np.ones(nF,float))
    Fupp    = kwargs.get('Fupp', inf*np.ones(nF,float))
    Fstates = kwargs.get('Fstates',  np.zeros(nF,int))
    Fmul    = kwargs.get('Fmul',    np.zeros(nF,float))
    Fnames  = kwargs.get('Fnames', np.empty((1,8),dtype='|S1'))

    assert xlow.shape == (n,)
    assert xupp.shape == (n,)
    assert xstates.shape == (n,)

    assert Flow.shape == (nF,)
    assert Fupp.shape == (nF,)
    assert Fstates.shape == (nF,)

    # Deal with xnames and Fnames
    nxname = len(xnames)
    assert xnames.dtype.char == 'S'
    assert nxname == 1 or nxname == n
    assert xnames.shape == (nxname,) or xnames.shape == (nxname,8)

    nFname = len(Fnames)
    assert Fnames.dtype.char == 'S'
    assert nFname == 1 or nFname == nF
    assert Fnames.shape == (nFname,) or Fnames.shape == (nFname,8)

    if verbose:
        printInfo('SNOPTA',name, 0,n,nxname,xnames,xstates,x0,xlow,xupp,xmul)
        printInfo('SNOPTA',name,nF,0,nFname,Fnames,Fstates,F0,Flow,Fupp,Fmul,header=False)

    # Set up workspace
    snwork  = SNOPT_work(505,5000,5000)
    usrwork = SNOPT_work(1,1,1)

    # Initialize SNOPT workspace
    # parameters are set to undefined values
    if name == '':
        prtfile = usropts.getOption('Print filename')
    else:
        prtfile = name.strip() + '.out'
    summOn  = 1 if (usropts.getOption('Summary')).lower() == "yes" else 0
    fsnopt.sninit_wrap(prtfile,summOn,snwork.cw,snwork.iw,snwork.rw)

    # Copy options to SNOPT workspace
    info = copyOpts(verbose,usropts,snwork)

    # Read specs file if one was given
    info = 0
    spcfile = usropts.getOption('Specs filename')
    if spcfile is not None:
        info = fsnopt.snspec_wrap(iSpecs,spcfile,snwork.cw,snwork.iw,snwork.rw)
        if info != 101 and info != 104:
            print('Specs read failed: INFO = {:d}'.format(info))
            return info

    # Get Jacobian structure if necessary:
    if A is None and G is None:
        print('  Could not determine Jacobian structure from user input')
        print('  Calling snJac...')

        lenA  = nF*n
        count = 1
        while True:
            snjac = fsnopt.snjac_wrap(nF,usrfun,lenA,lenA,x0,xlow,xupp,
                                      usrwork.cw,usrwork.iw,usrwork.rw,
                                      snwork.cw,snwork.iw,snwork.rw)
            info  = snjac[0]
            iAfun = snjac[1]
            jAvar = snjac[2]
            neA   = snjac[3]
            valA  = snjac[4]
            iGfun = snjac[5]
            jGvar = snjac[6]
            neG   = snjac[7]
            mincw = snjac[8]
            miniw = snjac[9]
            minrw = snjac[10]
            del snjac

            if info == 102:
                usropts.setOption('Derivative option',0)
                snwork.iw[103] = 0  # DerOpt
                break

            if info == 82 or info == 83 or info ==84:
                count+= 1
                if count > maxTries:
                    print(' Could not allocate memory for SNOPT')
                    return info
                snwork.work_resize(mincw,miniw,minrw)

    else:
        iAfun = np.array([1]) if neA == 0 else iAfun + 1
        jAvar = np.array([1]) if neA == 0 else jAvar + 1

        iGfun = np.array([1]) if neG == 0 else iGfun + 1
        jGvar = np.array([1]) if neG == 0 else jGvar + 1

    # Check memory
    info,mincw,miniw,minrw = fsnopt.snmema_wrap(nF,n,nxname,nFname,neA,neG,
                                                snwork.cw,snwork.iw,snwork.rw)
    snwork.work_resize(mincw,miniw,minrw)

    # Solve problem
    Start  = usropts.getOption('Start type')
    iStart = 0
    if   Start == 'Warm':
        iStart = 1
    elif Start == 'Hot':
        iStart = 2

    if xnames.shape != (1,8):
        snXnames = xnames.view('S1').reshape((xnames.size,-1))
    else:
        snXnames = xnames

    if Fnames.shape != (1,8):
        snFnames = Fnames.view('S1').reshape((Fnames.size,-1))
    else:
        snFnames = Fnames

    count = 1
    while True:
        res = fsnopt.snopta_wrap(iStart, nxname, nFname,
                                 ObjAdd, ObjRow, name, usrfun,
                                 iAfun, jAvar, neA, valA, iGfun, jGvar, neG,
                                 xlow, xupp, snXnames, Flow, Fupp, snFnames,
                                 x0, xstates, xmul, F0, Fstates, Fmul,
                                 usrwork.cw, usrwork.iw, usrwork.rw,
                                 snwork.cw, snwork.iw, snwork.rw)
        if  res[6]/10 == 8:
            count += 1
            if count > maxTries:
                print(' Could not allocate memory for SNOPT')
                return info
            snwork.work_resize(res[9],res[10],res[11])
        else:
            break

    # Results
    # res[0]  = x
    # res[1]  = xstates
    # res[2]  = xmul
    # res[3]  = f
    # res[4]  = Fstates
    # res[5]  = fmul
    # res[6]  = info
    # res[7]  = itn
    # res[8]  = mjritn
    # res[9]  = mincw
    # res[10] = miniw
    # res[11] = minrw
    # res[12] = nS
    # res[13] = nInf
    # res[14] = sInf
    # res[15] = Obj

    # Return solution
    result = SNOPTA_solution(name,xnames,Fnames)
    result.x          = res[0]
    result.xstates    = res[1]
    result.xmul       = res[2]
    result.F          = res[3]
    result.Fstates    = res[4]
    result.Fmul       = res[5]

    result.info       = res[6]

    result.iterations = res[7]
    result.major_itns = res[8]

    result.nS         = res[12]
    result.num_inf    = res[13]
    result.sum_inf    = res[14]
    result.objective  = res[15]

    # Finish up
    fsnopt.snend_wrap(snwork.cw,snwork.iw,snwork.rw)
    del res
    del snwork
    del usrwork

    # Print solution?
    if verbose:
        print(result)

    # Return result
    return result

#-------------------------------------------------------------------------------#

def snoptb(funobj,funcon,nnObj,nnCon,nnJac,x0,J,**kwargs):
    """
    snoptb calls the solver SNOPTB to solve the optimization
    problem:
              min       f_0(x)
              s.t.       [  x ]
                   bl <= [    ] <= bu
                         [c(x)]

    where f(x) is a vector of smooth nonlinear constraint functions, f_0(x)
    is a smooth scalar objective function, c(x) are the nonlinear and linear
    constraints, defined such that nonlinear constraints come first (see
    the SNOPT documentation for the SNOPTB interface).

    --------------------------------------------
    Input arguments:
    --------------------------------------------
    Keyword    Description
    ----------------------
    funobj     is a user-defined function that computes the objective and its
               gradient
    funcon     is a user-defined function that computes the constraints and the
               Jacobian

    nnObj      is the number of nonlinear objective variables (nnObj >= 0)
    nnCon      is the number of nonlinear constraints (nnCon >= 0)
    nnJac      is the number of nonlinear Jacobian variables
               (nnJac > 0 if nnCon > 0; nnJac = 0 if nnCon == 0)

    J          is the constraint Jacobian
               - J can be a tuple (valJ,indJ,locJ) containing the sparse structure
                 of the Jacobian

               - J can be a scipy csc_matrix

               - J can be a numpy 2-dimensional array

    iObj       indicates which row of J is the free row containing the linear
               objective vector (default 0)
    ObjAdd     is the constant term of the objective (default 0.0)

    states     are the initial states of the variables (default 0)
    x0         are the initial values of x (default 0.0)
    bl         are the lower bounds of the problem (default -infinity)
    bu         are the upper bounds of the problem (default +infinity)
    pi         are the initial multipliers of the constraints (default 0.0)
    names      is an array of names for the variables (default '')

    name       is the name of the problem (default '')

    options    contains the user options for the SNOPT solver

    snoptb will try to compute the number of constraints, variables,
    nonlinaer objective variables, nonlinear constraints and nonlinear
    Jacobian variables from the given data.

    If it doesn't do it correctly, provide snoptb with the following info:
      m        is the number of constraints
      n        is the number of variables

    """

    name    = kwargs.get('name','')
    usropts = kwargs.get('options',SNOPT_options())

    verbose  = usropts.getOption('Verbose')
    maxTries = usropts.getOption('Max memory attempts')
    inf      = usropts.getOption('Infinite bound')

    m        = kwargs.get('m',None)
    n        = kwargs.get('n',None)

    if   type(J) is tuple:
        try:
            (valJ,indJ,locJ) = J
            ne = valJ.size
        except:
            raise TypeError

        if m is None or n is None:
            raise ValueError('m and n need to be set when J is a tuple')

    elif type(J) is np.ndarray and J.ndim == 2:
        J0 = sp.csc_matrix(J)
        J0.sort_indices()

        indJ   = J0.indices
        locJ   = J0.indptr
        ne     = J0.nnz
        valJ   = J0.data

        m = J0.shape[0] if m is None else m
        n = J0.shape[1] if n is None else n

    elif type(J) is sp.csc_matrix:
        J.sort_indices()
        indJ   = J.indices
        locJ   = J.indptr
        ne     = J.nnz
        valJ   = J.data

        m = J.shape[0] if m is None else m
        n = J.shape[1] if n is None else n

    else:
        raise TypeError('Type of J is unsupported')

    if verbose:
        print('There are {} constraints and {} variables'.format(m,n))

    indJ = indJ + 1
    locJ = locJ + 1

    iObj   = kwargs.get('iObj',0)
    ObjAdd = kwargs.get('ObjAdd',0.0)

    hs     = kwargs.get('states', np.zeros(n+m,int))
    bl     = kwargs.get('bl',-inf*np.ones(n+m,float))
    bu     = kwargs.get('bu', inf*np.ones(n+m,float))
    pi     = kwargs.get('pi',np.zeros(m,float))
    rc     = np.zeros(n+m,float) #kwargs.get('rc',np.zeros(n+m,float))
    Names  = kwargs.get('names',np.empty((1,8),dtype='|S1'))

    rc[n+1:n+m] = pi[1:m]

    assert hs.shape == (n+m,)
    assert bl.shape == (n+m,)
    assert bu.shape == (n+m,)
    assert x0.shape == (n+m,)
    assert pi.shape == (m,)
    assert rc.shape == (n+m,)

    # Deal with Names:
    nName = len(Names)
    assert Names.dtype.char == 'S'
    assert nName == 1 or nName == n+m
    assert Names.shape == (nName,) or Names.shape == (nName,8)

    if verbose:
        printInfo('SNOPTB',name,m,n,nName,Names,hs,x0,bl,bu,rc)

    # Set up workspace
    snwork  = SNOPT_work(505,5000,5000)
    usrwork = SNOPT_work(1,1,1)

    # Initialize SNOPT workspace
    # parameters are set to undefined values
    if name == '':
        prtfile = usropts.getOption('Print filename')
    else:
        prtfile = name.strip() + '.out'
    summOn  = 1 if (usropts.getOption('Summary')).lower() == "yes" else 0
    fsnopt.sninit_wrap(prtfile,summOn,snwork.cw,snwork.iw,snwork.rw)

    # Copy options to SNOPT workspace
    info = copyOpts(verbose,usropts,snwork)

    # Read specs file if one was given
    info = 0
    spcfile = usropts.getOption('Specs filename')
    if spcfile is not None:
        info = fsnopt.snspec_wrap(spcfile,snwork.cw,snwork.iw,snwork.rw)
        if info != 101 and info != 104:
            print('Specs read failed: INFO = {:d}'.format(info))
            return info

    # Check memory
    neG = nnCon*nnJac
    info,mincw,miniw,minrw = fsnopt.snmem_wrap(m,n,ne,neG,nnCon,nnJac,nnObj,
                                               snwork.cw,snwork.iw,snwork.rw)
    snwork.work_resize(mincw,miniw,minrw)

    # Solve problem
    Start = usropts.getOption('Start type')

    if Names.shape != (1,8):
        snNames = Names.view('S1').reshape((Names.size,-1))
    else:
        snNames = Names

    count = 1
    while True:
        res = fsnopt.snoptb_wrap(Start, nName, nnCon, nnObj, nnJac,
                                 iObj, ObjAdd, name,
                                 funcon, funobj,
                                 valJ, indJ, locJ,
                                 bl, bu, snNames, hs, x0, pi,
                                 usrwork.cw, usrwork.iw, usrwork.rw,
                                 snwork.cw, snwork.iw, snwork.rw)
        if  res[4]/10 == 8:
            count += 1
            if count > maxTries:
                print(' Could not allocate memory for SNOPT')
                return info
            snwork.work_resize(res[7],res[8],res[9])
        else:
            break

    # Results
    # res[0]  = hs
    # res[1]  = x
    # res[2]  = pi
    # res[3]  = rc
    # res[4]  = info
    # res[5]  = itn
    # res[6]  = mjritn
    # res[7]  = mincw
    # res[8]  = miniw
    # res[9]  = minrw
    # res[10] = nS
    # res[11] = nInf
    # res[12] = sInf
    # res[13] = objective

    # Return solution
    result = SNOPT_solution(name,Names)
    result.states     = res[0]
    result.x          = res[1]
    result.pi         = res[2]
    result.rc         = res[3]
    result.info       = res[4]

    result.iterations = res[5]
    result.major_itns = res[6]

    result.nS         = res[10]
    result.num_inf    = res[11]
    result.sum_inf    = res[12]
    result.objective  = res[13]

    # Finish up
    fsnopt.snend_wrap(snwork.cw,snwork.iw,snwork.rw)

    # Print solution?
    if verbose:
        print(result)

    return result

#-------------------------------------------------------------------------------#

def snoptc(userfun,nnObj,nnCon,nnJac,x0,J,**kwargs):
    """
    snoptc calls the solver SNOPTC to solve the optimization
    problem:
              min       f_0(x)
              s.t.       [  x ]
                   bl <= [    ] <= bu
                         [c(x)]

    where f(x) is a vector of smooth nonlinear constraint functions, f_0(x)
    is a smooth scalar objective function, c(x) are the nonlinear and linear
    constraints, defined such that nonlinear constraints come first (see
    the SNOPT documentation for the SNOPTC interface).

    --------------------------------------------
    Input arguments:
    --------------------------------------------
    Keyword    Description
    ----------------------
    userfun    is a user-defined function that computes the objective and constraint
               functions and (if necessary) their derivatives

    nnObj      is the number of nonlinear objective variables (nnObj >= 0)
    nnCon      is the number of nonlinear constraints (nnCon >= 0)
    nnJac      is the number of nonlinear Jacobian variables
               (nnJac > 0 if nnCon > 0; nnJac = 0 if nnCon == 0)

    J          is the constraint Jacobian
               - J can be a tuple (valJ,indJ,locJ) containing the sparse structure
                 of the Jacobian.

               - J can be a scipy csc_matrix

               - J can be a numpy 2-dimensional array

    iObj       indicates which row of J is the free row containing the linear
               objective vector (default 0)
    ObjAdd     is the constant term of the objective (default 0.0)

    states     are the initial states of the variables (default 0)
    x          are the initial values of x (default 0.0)
    bl         are the lower bounds of the problem (default -infinity)
    bu         are the upper bounds of the problem (default +infinity)
    pi         are the initial multipliers of the constraints (default 0.0)
    names      is an array of names for the variables (default '')

    name       is the name of the problem (default '')

    options    contains the user options for the SNOPT solver

    snoptc will try to compute the number of constraints, variables,
    nonlinaer objective variables, nonlinear constraints and nonlinear
    Jacobian variables from the given data.

    If it doesn't do it correctly, provide snoptc with the following info:
      m        is the number of constraints
      n        is the number of variables

    """

    name    = kwargs.get('name','')
    usropts = kwargs.get('options',SNOPT_options())

    verbose  = usropts.getOption('Verbose')
    maxTries = usropts.getOption('Max memory attempts')
    inf      = usropts.getOption('Infinite bound')

    m       = kwargs.get('m',None)
    n       = kwargs.get('n',None)

    if   type(J) is tuple:
        try:
            (valJ,indJ,locJ) = J
            ne = valJ.size
        except:
            raise TypeError

    elif type(J) is np.ndarray and J.ndim == 2:
        J0 = sp.csc_matrix(J)
        J0.sort_indices()

        indJ   = J0.indices
        locJ   = J0.indptr
        ne     = J0.nnz
        valJ   = J0.data

        m = J0.shape[0] if m is None else m
        n = J0.shape[1] if n is None else n

    elif type(J) is sp.csc_matrix:
        J.sort_indices()
        indJ   = J.indices
        locJ   = J.indptr
        ne     = J.nnz
        valJ   = J.data

        m = J.shape[0] if m is None else m
        n = J.shape[1] if n is None else n

    else:
        raise TypeError

    indJ = indJ + 1
    locJ = locJ + 1

    iObj   = kwargs.get('iObj',0)
    ObjAdd = kwargs.get('ObjAdd',0.0)

    hs     = kwargs.get('states', np.zeros(n+m,int))
    bl     = kwargs.get('bl',-inf*np.ones(n+m,float))
    bu     = kwargs.get('bu', inf*np.ones(n+m,float))
    pi     = kwargs.get('pi',np.zeros(m,float))
    rc     = np.zeros(n+m,float) #kwargs.get('rc',np.zeros(n+m,float))
    Names  = kwargs.get('names',np.empty((1,8),dtype='|S1'))

    rc[n+1:n+m] = pi[1:m]

    assert hs.shape == (n+m,)
    assert bl.shape == (n+m,)
    assert bu.shape == (n+m,)
    assert x0.shape == (n+m,)
    assert pi.shape == (m,)
    assert rc.shape == (n+m,)

    # Deal with Names:
    nName = len(Names)
    assert Names.dtype.char == 'S'
    assert nName == 1 or nName == n+m
    assert Names.shape == (nName,) or Names.shape == (nName,8)

    if verbose:
        printInfo('SNOPTC',name,m,n,nName,Names,hs,x0,bl,bu,rc)

    # Set up workspace
    snwork  = SNOPT_work(505,5000,5000)
    usrwork = SNOPT_work(1,1,1)

    # Initialize SNOPT workspace
    # parameters are set to undefined values
    if name == '':
        prtfile = usropts.getOption('Print filename')
    else:
        prtfile = name.strip() + '.out'
    summOn  = 1 if (usropts.getOption('Summary')).lower() == "yes" else 0
    fsnopt.sninit_wrap(prtfile,summOn,snwork.cw,snwork.iw,snwork.rw)

    # Copy options to SNOPT workspace
    info = copyOpts(verbose,usropts,snwork)

    # Read specs file if one was given
    info = 0
    spcfile = usropts.getOption('Specs filename')
    if spcfile is not None:
        info = fsnopt.snspec_wrap(spcfile,snwork.cw,snwork.iw,snwork.rw)
        if info != 101 and info != 104:
            print('Specs read failed: INFO = {:d}'.format(info))
            return info

    # Check memory
    neG = nnCon*nnJac
    info,mincw,miniw,minrw = fsnopt.snmem_wrap(m,n,ne,neG,nnCon,nnJac,nnObj,
                                               snwork.cw,snwork.iw,snwork.rw)
    snwork.work_resize(mincw,miniw,minrw)

    # Solve problem
    Start = usropts.getOption('Start type')

    if Names.shape != (1,8):
        snNames = Names.view('S1').reshape((Names.size,-1))
    else:
        snNames = Names

    count = 1
    result = SNOPT_solution(name,Names)

    while True:
        result.states, \
        result.x, \
        result.pi, \
        result.rc, \
        result.info, \
        result.iterations, \
        result.major_itns, \
        mincw, miniw, minrw, \
        result.nS, \
        result.num_inf, \
        result.sum_inf, \
        result.objective = fsnopt.snoptc_wrap(Start, nName, nnCon, nnObj, nnJac,
                                              iObj, ObjAdd, name, userfun,
                                              valJ, indJ, locJ,
                                              bl, bu, snNames, hs, x0, pi,
                                              usrwork.cw, usrwork.iw, usrwork.rw,
                                              snwork.cw, snwork.iw, snwork.rw)
        if  result.info/10 == 8:
            count += 1
            if count > maxTries:
                print(' Could not allocate memory for SNOPT')
                return info
            snwork.work_resize(mincw,miniw,minrw)
        else:
            break

    # Finish up
    fsnopt.snend_wrap(snwork.cw,snwork.iw,snwork.rw)

    # Print solution?
    if verbose:
        print(result)

    return result

#-------------------------------------------------------------------------------#

def sqopt(H,x0,**kwargs):
    """ sqopt solves the quadratic optimization problem:
          min    f + c'x + half*x'Hx
          s.t.   xl <=   x  <= xu
          s.t.   al <=  Ax  <= au

    --------------------------------------------
    Input arguments:
    --------------------------------------------
    Keyword    Description
    ----------------------
    H          is the Hessian of the quadratic objective and should be a callable
               function

    x0         are the intial values of x (required)

    name       is the name of the problem (default '')

    xl, xu     are the lower and upper bounds of x (default -/+ infinity)

    A          is the linear constraint matrix
               - A can be a tuple (valA,indA,locA) containing the sparse structure
                 of the matrix

               - A can be a scipy csc_matrix

               - A can be a numpy 2-dimensional array

    al, au     are the lower and upper bounds of the linear constraints
                (default -/+ infinity)

    f          is the constant term of the quadratic objective (default 0.0)
    c          is the linear term of the quadratic objective (default 0.0)

    states     is a (n+m)-vector denoting the initial states for the problem
               (default 0)

    eType      is a (n+m)-vector that defines which variables are to be treated
               as being elastic in elastic mode (default 0)

    options    contains the user options for the SQOPT solver

    """

    name     = kwargs.get('name','')
    usropts  = kwargs.get('options',SNOPT_options())

    verbose  = usropts.getOption('Verbose')
    inf      = usropts.getOption('Infinite bound')

    m        = kwargs.get('m',None)
    n        = kwargs.get('n',None)
    A        = kwargs.get('A',None)

    # Linear constraint matrix
    if A is None:
        m    = 1
        n    = x0.shape[0]
        indA = np.ndarray([1])
        valA = np.ndarray([1.])
        locA = np.arange(n+1,int)
        al   = np.ndarray([-inf])
        au   = np.ndarray([ inf])

    else:
        if   type(A) is tuple:
            try:
                (valA,indA,locA) = A
                ne = valA.size
            except:
                raise TypeError

            if m is None or n is None:
                raise ValueError('m and n need to be set when J is a tuple')

        elif type(A) is np.ndarray and A.ndim == 2:
            m, n   = A.shape
            valA   = sp.csc_matrix(A)
            valA.sort_indices()

            indA   = valA.indices
            locA   = valA.indptr
            ne     = valA.nnz
            valA   = valA.data

        elif type(A) is sp.csc_matrix:
            m, n   = A.shape

            A.sort_indices()
            indA   = A.indices
            locA   = A.indptr
            ne     = A.nnz
            valA   = A.data

        else:
            raise TypeError('Type of A is unsupported')

    indA = indA + 1
    locA = locA + 1

    # Hessian user-defined function
    assert callable(H)
    try:
        Hx  = np.zeros(n)
        nnH = H(x0,Hx,0).size
    except:
        raise TypeError('Error with callable H')

    f     = kwargs.get('f',0.0)
    c     = kwargs.get('c',np.zeros(1))
    xl    = kwargs.get('xl',-inf*np.ones(n,float))
    xu    = kwargs.get('xu', inf*np.ones(n,float))
    al    = kwargs.get('al',-inf*np.ones(m,float))
    au    = kwargs.get('au', inf*np.ones(m,float))
    hs    = kwargs.get('states',np.zeros(n+m,'i'))
    eType = kwargs.get('eType',np.zeros(n+m,'i'))
    Names = kwargs.get('names',np.empty((1,8),dtype='|S1'))

    pi    = np.zeros(m,float)
    rc    = np.zeros(n+m,float)

    try:
        bl = np.concatenate([xl,al])
        bu = np.concatenate([xu,au])
    except:
        raise InputError('Check the bounds of the problem')

    x = np.concatenate([x0,np.zeros(m)])

    assert c.size   <= n
    assert bl.shape == (n+m,)
    assert bu.shape == (n+m,)
    assert hs.shape == (n+m,)

    # Deal with names
    nName = len(Names)
    assert Names.dtype.char == 'S'
    assert nName == 1 or nName == n+m
    assert Names.shape == (nName,) or Names.shape == (nName,8)

    if verbose:
        printInfo('SQOPT',name,m,n,nName,Names,hs,x,bl,bu,rc)

    # Set up workspace
    snwork  = SNOPT_work(505,5000,5000)
    usrwork = SNOPT_work(1,1,1)

    # Initialize SQOPT
    if name == '':
        prtfile = usropts.getOption('Print filename')
    else:
        prtfile = name.strip() + '.out'
    summOn  = 1 if (usropts.getOption('Summary')).lower() == "yes" else 0
    fsnopt.sqinit_wrap(prtfile,summOn,snwork.cw,snwork.iw,snwork.rw)

    # Copy options to SQIC
    info = copyOpts(verbose,usropts,snwork)

    # Read specs file if one was given
    info = 0
    spcfile = usropts.getOption('Specs filename')
    if spcfile is not None:
        info = fsnopt.sqspec_wrap(spcfile,snwork.cw,snwork.iw,snwork.rw)
        if info != 101 and info != 104:
            print('Specs read failed: INFO = {:d}'.format(info))
            return info

    # Solve the QP
    Start  = usropts.getOption('Start type')
    iObj   = 0

    if Names.shape != (1,8):
        snNames = Names.view('S1').reshape((Names.size,-1))
    else:
        snNames = Names

    result = SNOPT_solution(name)
    result.states, \
    result.x, \
    result.pi, \
    result.rc, \
    result.info, \
    result.iterations, \
    mincw, miniw, minrw, \
    result.nS, \
    result.num_inf, \
    result.sum_inf, \
    result.objective = fsnopt.sqopt_wrap(Start, H, nName, nnH, iObj, f, name,
                                         valA, indA, locA, bl, bu, c, snNames,
                                         eType, hs, x, pi,
                                         usrwork.cw,usrwork.iw,usrwork.rw,
                                         snwork.cw,snwork.iw,snwork.rw)

    # Finish up
    fsnopt.snend_wrap(snwork.cw,snwork.iw,snwork.rw)

    # Print solution?
    if verbose:
        print(result)

    # Return solution
    return result


text:
package net.floodlightcontroller.odin.master;

import net.floodlightcontroller.util.MACAddress;

public class NotificationCallbackContext {
	public final MACAddress clientHwAddress;
	public final IOdinAgent agent;
	public final long value;

	public NotificationCallbackContext(final MACAddress clientHwAddress, final IOdinAgent agent, final long value) {
		this.clientHwAddress = clientHwAddress;
		this.agent = agent;
		this.value = value;
	}
}

redpajama_set_name: RedPajamaGithub


text:
package org.openksavi.sponge.engine;

import org.openksavi.sponge.ProcessorAdapter;
import org.openksavi.sponge.action.ActionAdapter;
import org.openksavi.sponge.correlator.CorrelatorAdapter;
import org.openksavi.sponge.correlator.CorrelatorAdapterGroup;
import org.openksavi.sponge.filter.FilterAdapter;
import org.openksavi.sponge.rule.RuleAdapter;
import org.openksavi.sponge.rule.RuleAdapterGroup;
import org.openksavi.sponge.trigger.TriggerAdapter;

/**
 * Processor type.
 */
@SuppressWarnings("rawtypes")
public enum ProcessorType {

    ACTION("action", ActionAdapter.class),

    FILTER("filter", FilterAdapter.class),

    TRIGGER("trigger", TriggerAdapter.class),

    RULE_GROUP("ruleGroup", RuleAdapterGroup.class),

    RULE("rule", RuleAdapter.class),

    CORRELATOR_GROUP("correlatorGroup", CorrelatorAdapterGroup.class),

    CORRELATOR("correlator", CorrelatorAdapter.class);

    private String name;

    private Class<? extends ProcessorAdapter> adapterClass;

    ProcessorType(String name, Class<? extends ProcessorAdapter> adapterClass) {
        this.name = name;
        this.adapterClass = adapterClass;
    }

    /**
     * Returns name.
     *
     * @return name.
     */
    public String getName() {
        return name;
    }

    public Class<? extends ProcessorAdapter> getAdapterClass() {
        return adapterClass;
    }

    public String getLabel() {
        if (name.isEmpty()) {
            return name;
        } else if (name.length() == 1) {
            return name.toUpperCase();
        } else {
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }
    }
}


text:
package snippets

// [START batch_create_container_job]
import (
	"context"
	"fmt"
	"io"

	batch "cloud.google.com/go/batch/apiv1"
	"cloud.google.com/go/batch/apiv1/batchpb"
	durationpb "google.golang.org/protobuf/types/known/durationpb"
)

// Creates and runs a job that runs the specified container
func createContainerJob(w io.Writer, projectID, region, jobName string) error {
	// projectID := "your_project_id"
	// region := "us-central1"
	// jobName := "some-job"

	ctx := context.Background()
	batchClient, err := batch.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %v", err)
	}
	defer batchClient.Close()

	container := &batchpb.Runnable_Container{
		ImageUri:   "gcr.io/google-containers/busybox",
		Commands:   []string{"-c", "echo Hello world! This is task ${BATCH_TASK_INDEX}. This job has a total of ${BATCH_TASK_COUNT} tasks."},
		Entrypoint: "/bin/sh",
	}

	// We can specify what resources are requested by each task.
	resources := &batchpb.ComputeResource{
		// CpuMilli is milliseconds per cpu-second. This means the task requires 2 whole CPUs.
		CpuMilli:  2000,
		MemoryMib: 16,
	}

	taskSpec := &batchpb.TaskSpec{
		Runnables: []*batchpb.Runnable{{
			Executable: &batchpb.Runnable_Container_{Container: container},
		}},
		ComputeResource: resources,
		MaxRunDuration: &durationpb.Duration{
			Seconds: 3600,
		},
		MaxRetryCount: 2,
	}

	// Tasks are grouped inside a job using TaskGroups.
	taskGroups := []*batchpb.TaskGroup{
		{
			TaskCount: 4,
			TaskSpec:  taskSpec,
		},
	}

	// Policies are used to define on what kind of virtual machines the tasks will run on.
	// In this case, we tell the system to use "e2-standard-4" machine type.
	// Read more about machine types here: https://cloud.google.com/compute/docs/machine-types
	allocationPolicy := &batchpb.AllocationPolicy{
		Instances: []*batchpb.AllocationPolicy_InstancePolicyOrTemplate{{
			PolicyTemplate: &batchpb.AllocationPolicy_InstancePolicyOrTemplate_Policy{
				Policy: &batchpb.AllocationPolicy_InstancePolicy{
					MachineType: "e2-standard-4",
				},
			},
		}},
	}

	// We use Cloud Logging as it's an out of the box available option
	logsPolicy := &batchpb.LogsPolicy{
		Destination: batchpb.LogsPolicy_CLOUD_LOGGING,
	}

	jobLabels := map[string]string{"env": "testing", "type": "container"}

	// The job's parent is the region in which the job will run
	parent := fmt.Sprintf("projects/%s/locations/%s", projectID, region)

	job := batchpb.Job{
		TaskGroups:       taskGroups,
		AllocationPolicy: allocationPolicy,
		Labels:           jobLabels,
		LogsPolicy:       logsPolicy,
	}

	req := &batchpb.CreateJobRequest{
		Parent: parent,
		JobId:  jobName,
		Job:    &job,
	}

	created_job, err := batchClient.CreateJob(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create job: %v", err)
	}

	fmt.Fprintf(w, "Job created: %v\n", created_job)

	return nil
}

// [END batch_create_container_job]


text:
package com.sksamuel.elastic4s.indexes

import com.sksamuel.elastic4s.analyzers.{AnalyzerDefinition, NormalizerDefinition}
import com.sksamuel.elastic4s.mappings.MappingDefinition
import com.sksamuel.elastic4s.searches.queries.QueryDefinition
import org.elasticsearch.action.admin.indices.alias.Alias
import org.elasticsearch.common.settings.Settings
import com.sksamuel.exts.OptionImplicits._

case class TemplateAlias(name: String,
                         filter: Option[QueryDefinition] = None,
                         routing: Option[String] = None) {
  def filter(filter: QueryDefinition): TemplateAlias = copy(filter = filter.some)
  def routing(routing: String): TemplateAlias = copy(routing = routing.some)
}

case class CreateIndexTemplateDefinition(name: String,
                                         pattern: String,
                                         settings: Settings = Settings.EMPTY,
                                         mappings: Seq[MappingDefinition] = Nil,
                                         analysis: Option[AnalysisDefinition] = None,
                                         order: Option[Int] = None,
                                         version: Option[Int] = None,
                                         create: Option[Boolean] = None,
                                         aliases: Seq[Alias] = Nil,
                                         alias: Seq[TemplateAlias] = Nil) {
  require(name.nonEmpty, "template name must not be null or empty")
  require(pattern.nonEmpty, "pattern must not be null or empty")

  def analysis(first: AnalyzerDefinition, rest: AnalyzerDefinition*): CreateIndexTemplateDefinition =
    analysis(first +: rest, Nil)

  def analysis(analyzers: Iterable[AnalyzerDefinition]): CreateIndexTemplateDefinition =
    analysis(analyzers, Nil)

  def analysis(analyzers: Iterable[AnalyzerDefinition], normalizers: Iterable[NormalizerDefinition]): CreateIndexTemplateDefinition =
    analysis match {
      case None => copy(analysis = AnalysisDefinition(analyzers, normalizers).some)
      case Some(a) => copy(analysis = AnalysisDefinition(a.analyzers ++ analyzers, a.normalizers ++ normalizers).some)
    }

  def normalizers(first: NormalizerDefinition,
                  rest: NormalizerDefinition*): CreateIndexTemplateDefinition = analysis(Nil, first +: rest)
  def normalizers(normalizers: Iterable[NormalizerDefinition]): CreateIndexTemplateDefinition = analysis(Nil, normalizers)

  def mappings(first: MappingDefinition,
               rest: MappingDefinition*): CreateIndexTemplateDefinition = mappings(first +: rest)

  def mappings(mappings: Iterable[MappingDefinition]): CreateIndexTemplateDefinition = copy(mappings = mappings.toSeq)

  // adds a new setting
  def indexSetting(key: String, value: Double): CreateIndexTemplateDefinition = settings(Settings.builder().put(settings).put(key, value).build())
  def indexSetting(key: String, value: Long): CreateIndexTemplateDefinition = settings(Settings.builder().put(settings).put(key, value).build())
  def indexSetting(key: String, value: Boolean): CreateIndexTemplateDefinition = settings(Settings.builder().put(settings).put(key, value).build())
  def indexSetting(key: String, value: String): CreateIndexTemplateDefinition = settings(Settings.builder().put(settings).put(key, value).build())

  def version(version: Int): CreateIndexTemplateDefinition = copy(version = version.some)

  // replaces all settings with the given settings
  def settings(settings: Settings): CreateIndexTemplateDefinition = copy(settings = settings)

  def order(order: Int): CreateIndexTemplateDefinition = copy(order = order.some)
  def create(create: Boolean): CreateIndexTemplateDefinition = copy(create = create.some)

  def aliases(first: TemplateAlias, rest: TemplateAlias*): CreateIndexTemplateDefinition = aliases(first +: rest)
  def aliases(aliases: Iterable[TemplateAlias]): CreateIndexTemplateDefinition = copy(alias = aliases.toSeq)

  @deprecated("Use the aliases(TemplateAlias) methods", "5.2.12")
  def alias(alias: Alias): CreateIndexTemplateDefinition = aliases(Seq(alias))

  @deprecated("Use the aliases(TemplateAlias) methods", "5.2.12")
  def aliases(aliases: Seq[Alias]): CreateIndexTemplateDefinition = copy(aliases = aliases)
}


text:
<?php

namespace Bolt\Provider;

use Bolt\Events\ControllerEvents;
use Bolt\Events\MountEvent;
use Bolt\Filesystem\Handler\Image;
use Bolt\Thumbs;
use Bolt\Thumbs\ImageResource;
use Silex\Application;
use Silex\ServiceProviderInterface;

/**
 * Register thumbnails service.
 *
 * @author Carson Full <carsonfull@gmail.com>
 */
class ThumbnailsServiceProvider implements ServiceProviderInterface
{
    /**
     * {@inheritdoc}
     */
    public function register(Application $app)
    {
        if (!isset($app['thumbnails'])) {
            $app->register(new Thumbs\ServiceProvider());
        }

        $app['thumbnails.filesystems'] = [
            'files',
            'themes',
        ];

        $app['thumbnails.save_files'] = $app['config']->get('general/thumbnails/save_files');

        $app['thumbnails.filesystem_cache'] = $app->share(function ($app) {
            if ($app['thumbnails.save_files'] === false) {
                return null;
            }
            if (!$app['filesystem']->hasFilesystem('web')) {
                return null;
            }

            return $app['filesystem']->getFilesystem('web');
        });

        $app['thumbnails.caching'] = $app['config']->get('general/caching/thumbnails');

        $app['thumbnails.cache'] = $app->share(function ($app) {
            if ($app['thumbnails.caching'] === false) {
                return null;
            }

            return $app['cache'];
        });

        $app['thumbnails.default_image'] = $app->share(function ($app) {
            $finder = new Thumbs\Finder($app['filesystem'], ['app', 'themes', 'files'], new Image());

            return $finder->find($app['config']->get('general/thumbnails/notfound_image'));
        });

        $app['thumbnails.error_image'] = $app->share(function ($app) {
            $finder = new Thumbs\Finder($app['filesystem'], ['app', 'themes', 'files'], new Image());

            return $finder->find($app['config']->get('general/thumbnails/error_image'));
        });

        $app['thumbnails.cache_time'] = $app['config']->get('general/thumbnails/browser_cache_time');

        $app['thumbnails.limit_upscaling'] = !$app['config']->get('general/thumbnails/allow_upscale', false);

        ImageResource::setNormalizeJpegOrientation($app['config']->get('general/thumbnails/exif_orientation', true));
        ImageResource::setQuality($app['config']->get('general/thumbnails/quality', 80));
    }

    /**
     * {@inheritdoc}
     */
    public function boot(Application $app)
    {
        $app['dispatcher']->addListener(ControllerEvents::MOUNT, function (MountEvent $event) {
            $app = $event->getApp();
            $event->mount($app['controller.thumbnails.mount_prefix'], $app['controller.thumbnails']);
        });
    }
}


text:
QApplication *app;
QQmlApplicationEngine *engine;

void setupDpUnit()
{
    //implement density-independent pixel
    qreal dp;
    qreal dotsPerInch = app->screens()[0]->physicalDotsPerInch();
    qDebug() << "physicalDotsPerInch = " << dotsPerInch;
    dp = qRound(dotsPerInch) / 125.0;
#ifdef Q_OS_ANDROID
    qDebug() << "Android OS detected";
    QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
    QAndroidJniObject resource = activity.callObjectMethod("getResources","()Landroid/content/res/Resources;");
    QAndroidJniObject metrics = resource.callObjectMethod("getDisplayMetrics","()Landroid/util/DisplayMetrics;");
    dp = metrics.getField<float>("density");
#endif
#ifdef Q_OS_IOS
    qDebug() <<	"iOS detected";
    dp = 3;
#endif
    if(dp < 1) { dp = 1; }
    qDebug() << "1dp = " << dp;
    engine->rootContext()->setContextProperty(QLatin1String("dp"), QVariant::fromValue(dp));
}

void setupFontAwesome()
{
    int fontId = QFontDatabase::addApplicationFont(":/font/fontawesome-webfont.ttf");
    if(fontId == -1) { qWarning() << "Error: failed to load FontAwesome font"; }
}

void registerTypes()
{
//    const char *uri = "QMLBootstrap";
//    const int major = 1, minor = 0;

    setupFaIcons();
    setupProperties();
    customize();
    engine->rootContext()->setContextProperty(QLatin1String("faIcons"), m_faIcons);
    engine->rootContext()->setContextProperty(QLatin1String("bs"), m_properties);

    QFile fragFile1(":/qml/Components/RoundedImage.frag");
    if(fragFile1.open(QIODevice::ReadOnly)) {
        QTextStream in(&fragFile1);
        engine->rootContext()->setContextProperty(QLatin1String("roundedImageFragShader"), in.readAll());
        fragFile1.close();
    }
    QFile fragFile2(":/qml/Components/ImageScope.frag");
    if(fragFile2.open(QIODevice::ReadOnly)) {
        QTextStream in(&fragFile2);
        engine->rootContext()->setContextProperty(QLatin1String("imageScopeFragShader"), in.readAll());
        fragFile2.close();
    }
}

int main(int argc, char *argv[])
{
//    QApplication app(argc, argv);
    app = new QApplication(argc,argv);
    app->setOrganizationName("YourOrganizationName");
    app->setApplicationName("YourAppName");

//    QQmlApplicationEngine engine;
    engine = new QQmlApplicationEngine();

    setupDpUnit();
    setupFontAwesome();
    registerTypes();

    qDebug() << "OfflineStoragePath: " << engine->offlineStoragePath();

    // qmlファイルをロード
    engine->load(QUrl("qrc:/qml/main.qml"));

    QObject *topLevel = engine->rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    if ( !window ) {
        qWarning("Error: Your root item has to be a Window.");
        return -1;
    }
    window->show();
    return app->exec();
}


text:
/* author: dongchangzhang */
/* time: Wed 08 Mar 2017 03:35:41 PM CST */

#ifndef SRC_LEX_TOKEN_H
#define SRC_LEX_TOKEN_H

// id
#define ID 0

// key words
#define INT 1 // int
#define FLOAT 2 // float
#define DOUBLE 3 // double
#define LONG 4 // long
#define SHORT 5 // short
#define SWITCH 6 // switch
#define CASE 7 // case
#define DEFAULT 8 // default
#define BREAK 9 // break
#define CONST 10 // const
#define RETURN 11 // return
#define VOID 12 // void
#define CONTINUE 13 // continue
#define DO 14 // do
#define WHILE 15 // while
#define IF 16 // if
#define ELSE 17 // else
#define FOR 18 // for
#define CHAR 19 // char
#define TYPEDEF 20 // typedef
#define STATIC 21 // static

// operator
#define EQ 22 // ==
#define NE 23 // !=
#define GT 24 // >
#define LT 25 // <
#define GE 26 // >=
#define LE 27 // <=
#define ASSIGN 28 // =
#define ADD 29 // +
#define MUL 30 // *
#define SUB 31 // -
#define DIV 32 // /
#define NOT 33 // !
#define MOD 34 // %
#define AND 35 // &&
#define OR 36 // ||
#define ADDASSIGN 37 // +=
#define SUBASSIGN 38 // -=
#define MULASSIGN 39 // *=
#define DIVASSIGN 40 // /=
#define COMMA 41 // ,
#define LCURVES 42 // (
#define RCURVES 43 // )
#define LBRACKET 44 // [
#define RBRACKET 45 // ]

// separators
#define LBRACE 46 // {
#define RBRACE 47 // }
#define SEM 48 // ;
#define REVERSE 49 // '\\'
#define SQUOTE 50 // '
#define DQUOTE 51 // "
#define ADDADD 52 // ++
#define SUBSUB 53 // --
#define MAO 54 // :

#define VALUE 100

#include "symboltable.h"
#include "unstd.h"

#include <map>
#include <string>
#include <vector>

extern const std::map<std::string, int> token_dict;

bool issymbol(char X);

std::string get_token_info(const int id);

int get_code(const std::string& target);

class Token {
public:
    // null token
    Token()
        : token(NULL_STATE)
        , value("null")
        , is_state(false)
        , is_null(true)
    {
    }
    // key world
    Token(int t, std::string v)
        : token(t)
        , value(v)
        , is_state(false)
        , is_null(false)
    {
    }
    // value && id
    Token(int t, addr_type& addr)
        : token(t)
        , addr(addr)
        , is_state(false)
        , is_null(false)
    {
    }
    // state token
    Token(std::string state)
        : token(NORMAL_STATE)
        , value(state)
        , is_state(true)
        , is_null(false)
    {
    }
    Token(int t)
        : Token(t, "")
    {
    }

    Token& operator=(const Token& t)
    {
        this->token = t.token;
        this->value = t.value;
        this->is_state = t.is_state;
        this->is_null = t.is_null;
        this->addr = t.addr;
        return *this;
    }

    bool operator<(const Token& t) const { return (value < t.value); }

    bool operator>(const Token& t) const { return (value > t.value); }

    bool operator==(const Token& t) const { return value == t.value; }

    bool operator==(const int i) const { return token == i; }

    bool operator==(const std::string& s) const { return value == s; }

    int get_token() const { return token; }

    std::string get_attr() const { return value; }

    std::string get_state() const { return value; }

    addr_type get_addr() const
    {
        if (token == ID || token == VALUE)
            return addr;
        else
            std::cerr << "terminal - token";
        exit(0);
    }

    bool is_null_token() const { return is_null; }

    bool is_state_token() const { return is_state; }

    bool is_id() const { return (token == ID ? true : false); }

    bool is_value() const { return (token == VALUE ? true : false); }

    void set_as_end() { token = END_STATE; }

    void show_addr() { std::cout << "from token.h " << addr.type << " " << addr.index << " " << addr.location << std::endl; }

private:
    // token id
    int token;
    // token attr
    addr_type addr;

    std::string value;
    // is state or not
    bool is_state = false;
    // a null token ?
    bool is_null = false;
};

// overwrite hash<token>
namespace std {
template <>
struct hash<Token> {
    typedef size_t return_type;
    typedef Token argument_type;
    size_t operator()(const Token& t) const
    {
        return hash<string>()(t.get_attr()) ^ hash<int>()(t.get_token());
    };
};
}

std::ostream& operator<<(std::ostream& os, Token& token);
#endif


text:
package com.google.bitcoin.core;

import com.google.bitcoin.store.BlockStore;
import com.google.bitcoin.store.BlockStoreException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigInteger;
import java.util.*;

/**
 * A BlockChain holds a series of {@link Block} objects, links them together, and knows how to verify that the
 * chain follows the rules of the {@link NetworkParameters} for this chain.

 *
 * A BlockChain requires a {@link Wallet} to receive transactions that it finds during the initial download. However,
 * if you don't care about this, you can just pass in an empty wallet and nothing bad will happen.

 *
 * A newly constructed BlockChain is empty. To fill it up, use a {@link Peer} object to download the chain from the
 * network.

 *
 * Notes

 *
 * The 'chain' can actually be a tree although in normal operation it can be thought of as a simple list. In such a
 * situation there are multiple stories of the economy competing to become the one true consensus. This can happen
 * naturally when two miners solve a block within a few seconds of each other, or it can happen when the chain is
 * under attack.

 *
 * A reference to the head block of every chain is stored. If you can reach the genesis block by repeatedly walking
 * through the prevBlock pointers, then we say this is a full chain. If you cannot reach the genesis block we say it is
 * an orphan chain.

 *
 * Orphan chains can occur when blocks are solved and received during the initial block chain download,
 * or if we connect to a peer that doesn't send us blocks in order.
 */
public class BlockChain {
    private static final Logger log = LoggerFactory.getLogger(BlockChain.class);

    /** Keeps a map of block hashes to StoredBlocks. */
    protected final BlockStore blockStore;

    /**
     * Tracks the top of the best known chain.

     *
     * Following this one down to the genesis block produces the story of the economy from the creation of BitCoin
     * until the present day. The chain head can change if a new set of blocks is received that results in a chain of
     * greater work than the one obtained by following this one down. In that case a reorganize is triggered,
     * potentially invalidating transactions in our wallet.
     */
    protected StoredBlock chainHead;
    // chainHead is accessed under this lock rather than the BlockChain lock. This is to try and keep accessors
    // responsive whilst the chain is downloading, without free-threading the entire chain add process (which could
    // get very confusing in the case of multiple blocks being added simultaneously).
    protected final Object chainHeadLock = new Object();

    protected final NetworkParameters params;
    protected final List<Wallet> wallets;

    // Holds blocks that we have received but can't plug into the chain yet, eg because they were created whilst we
    // were downloading the block chain.
    private final ArrayList<Block> unconnectedBlocks = new ArrayList<Block>();

    /**
     * Constructs a BlockChain connected to the given wallet and store. To obtain a {@link Wallet} you can construct
     * one from scratch, or you can deserialize a saved wallet from disk using {@link Wallet#loadFromFile(java.io.File)}
     *

     *
     * For the store you can use a {@link com.google.bitcoin.store.MemoryBlockStore} if you don't care about saving the downloaded data, or a
     * {@link com.google.bitcoin.store.BoundedOverheadBlockStore} if you'd like to ensure fast startup the next time you run the program.
     */
    public BlockChain(NetworkParameters params, Wallet wallet, BlockStore blockStore) throws BlockStoreException {
        this(params, new ArrayList<Wallet>(), blockStore);
        if (wallet != null)
            addWallet(wallet);
    }

    /**
     * Constructs a BlockChain that has no wallet at all. This is helpful when you don't actually care about sending
     * and receiving coins but rather, just want to explore the network data structures.
     */
    public BlockChain(NetworkParameters params, BlockStore blockStore) throws BlockStoreException {
        this(params, new ArrayList<Wallet>(), blockStore);
    }

    /**
     * Constructs a BlockChain connected to the given list of wallets and a store.
     */
    public BlockChain(NetworkParameters params, List<Wallet> wallets,
                      BlockStore blockStore) throws BlockStoreException {
        this.blockStore = blockStore;
        chainHead = blockStore.getChainHead();
        log.info("chain head is at height {}:\n{}", chainHead.getHeight(), chainHead.getHeader());
        this.params = params;
        this.wallets = new ArrayList<Wallet>(wallets);
    }

    /**
     * Add a wallet to the BlockChain. Note that the wallet will be unaffected by any blocks received while it
     * was not part of this BlockChain. This method is useful if the wallet has just been created, and its keys
     * have never been in use, or if the wallet has been loaded along with the BlockChain
     */
    public synchronized void addWallet(Wallet wallet) {
        wallets.add(wallet);
    }

    /**
     * Returns the {@link BlockStore} the chain was constructed with. You can use this to iterate over the chain.
     */
    public BlockStore getBlockStore() {
        return blockStore;
    }

    /**
     * Processes a received block and tries to add it to the chain. If there's something wrong with the block an
     * exception is thrown. If the block is OK but cannot be connected to the chain at this time, returns false.
     * If the block can be connected to the chain, returns true.
     */
    public synchronized boolean add(Block block) throws VerificationException, ScriptException {
        try {
            return add(block, true);
        } catch (BlockStoreException e) {
            // TODO: Figure out a better way to propagate this exception to the user.
            throw new RuntimeException(e);
        }
    }

    // Stat counters.
    private long statsLastTime = System.currentTimeMillis();
    private long statsBlocksAdded;

    private synchronized boolean add(Block block, boolean tryConnecting)
            throws BlockStoreException, VerificationException, ScriptException {
        // Note on locking: this method runs with the block chain locked. All mutations to the chain are serialized.
        // This has the undesirable consequence that during block chain download, it's slow to read the current chain
        // head and other chain info because the accessors are constantly waiting for the chain to become free. To
        // solve this things viewable via accessors must use fine-grained locking as well as being mutated under the
        // chain lock.
        if (System.currentTimeMillis() - statsLastTime > 1000) {
            // More than a second passed since last stats logging.
            if (statsBlocksAdded > 1)
                log.info("{} blocks per second", statsBlocksAdded);
            statsLastTime = System.currentTimeMillis();
            statsBlocksAdded = 0;
        }
        // We check only the chain head for double adds here to avoid potentially expensive block chain misses.
        if (block.equals(chainHead.getHeader())) {
            // Duplicate add of the block at the top of the chain, can be a natural artifact of the download process.
            log.debug("Chain head added more than once: {}", block.getHash());
            return true;
        }

        // Does this block contain any transactions we might care about? Check this up front before verifying the
        // blocks validity so we can skip the merkle root verification if the contents aren't interesting. This saves
        // a lot of time for big blocks.
        boolean contentsImportant = false;
        HashMap<Wallet, List<Transaction>> walletToTxMap = new HashMap<Wallet, List<Transaction>>();
        if (block.transactions != null) {
            scanTransactions(block, walletToTxMap);
            contentsImportant = walletToTxMap.size() > 0;
        }

        // Prove the block is internally valid: hash is lower than target, etc. This only checks the block contents
        // if there is a tx sending or receiving coins using an address in one of our wallets. And those transactions
        // are only lightly verified: presence in a valid connecting block is taken as proof of validity. See the
        // article here for more details: http://code.google.com/p/bitcoinj/wiki/SecurityModel
        try {
            block.verifyHeader();
            if (contentsImportant)
                block.verifyTransactions();
        } catch (VerificationException e) {
            log.error("Failed to verify block: ", e);
            log.error(block.getHashAsString());
            throw e;
        }

        // Try linking it to a place in the currently known blocks.
        StoredBlock storedPrev = blockStore.get(block.getPrevBlockHash());

        if (storedPrev == null) {
            // We can't find the previous block. Probably we are still in the process of downloading the chain and a
            // block was solved whilst we were doing it. We put it to one side and try to connect it later when we
            // have more blocks.
            assert tryConnecting : "bug in tryConnectingUnconnected";
            log.warn("Block does not connect: {}", block.getHashAsString());
            unconnectedBlocks.add(block);
            return false;
        } else {
            // It connects to somewhere on the chain. Not necessarily the top of the best known chain.
            //
            // Create a new StoredBlock from this block. It will throw away the transaction data so when block goes
            // out of scope we will reclaim the used memory.
            StoredBlock newStoredBlock = storedPrev.build(block);
            checkDifficultyTransitions(storedPrev, newStoredBlock);
            blockStore.put(newStoredBlock);
            connectBlock(newStoredBlock, storedPrev, walletToTxMap);
        }

        if (tryConnecting)
            tryConnectingUnconnected();

        statsBlocksAdded++;
        return true;
    }

    private void connectBlock(StoredBlock newStoredBlock, StoredBlock storedPrev,
                              HashMap<Wallet, List<Transaction>> newTransactions)
            throws BlockStoreException, VerificationException {
        if (storedPrev.equals(chainHead)) {
            // This block connects to the best known block, it is a normal continuation of the system.
            setChainHead(newStoredBlock);
            log.debug("Chain is now {} blocks high", chainHead.getHeight());
            if (newTransactions != null)
                sendTransactionsToWallet(newStoredBlock, NewBlockType.BEST_CHAIN, newTransactions);
        } else {
            // This block connects to somewhere other than the top of the best known chain. We treat these differently.
            //
            // Note that we send the transactions to the wallet FIRST, even if we're about to re-organize this block
            // to become the new best chain head. This simplifies handling of the re-org in the Wallet class.
            boolean haveNewBestChain = newStoredBlock.moreWorkThan(chainHead);
            if (haveNewBestChain) {
                log.info("Block is causing a re-organize");
            } else {
                StoredBlock splitPoint = findSplit(newStoredBlock, chainHead);
                if (splitPoint == newStoredBlock) {
                    // newStoredBlock is a part of the same chain, there's no fork. This happens when we receive a block
                    // that we already saw and linked into the chain previously, which isn't the chain head.
                    // Re-processing it is confusing for the wallet so just skip.
                    log.debug("Saw duplicated block in main chain at height {}: {}",
                            newStoredBlock.getHeight(), newStoredBlock.getHeader().getHash());
                    return;
                }
                int splitPointHeight = splitPoint != null ? splitPoint.getHeight() : -1;
                String splitPointHash =
                        splitPoint != null ? splitPoint.getHeader().getHashAsString() : "?";
                log.info("Block forks the chain at height {}/block {}, but it did not cause a reorganize:\n{}",
                        new Object[]{splitPointHeight, splitPointHash, newStoredBlock});
            }

            // We may not have any transactions if we received only a header, which can happen during fast catchup.
            // If we do, send them to the wallet but state that they are on a side chain so it knows not to try and
            // spend them until they become activated.
            if (newTransactions != null) {
                sendTransactionsToWallet(newStoredBlock, NewBlockType.SIDE_CHAIN, newTransactions);
            }

            if (haveNewBestChain)
                handleNewBestChain(newStoredBlock);
        }
    }

    /**
     * Called as part of connecting a block when the new block results in a different chain having higher total work.
     */
    private void handleNewBestChain(StoredBlock newChainHead) throws BlockStoreException, VerificationException {
        // This chain has overtaken the one we currently believe is best. Reorganize is required.
        //
        // Firstly, calculate the block at which the chain diverged. We only need to examine the
        // chain from beyond this block to find differences.
        StoredBlock splitPoint = findSplit(newChainHead, chainHead);
        log.info("Re-organize after split at height {}", splitPoint.getHeight());
        log.info("Old chain head: {}", chainHead.getHeader().getHashAsString());
        log.info("New chain head: {}", newChainHead.getHeader().getHashAsString());
        log.info("Split at block: {}", splitPoint.getHeader().getHashAsString());
        // Then build a list of all blocks in the old part of the chain and the new part.
        List<StoredBlock> oldBlocks = getPartialChain(chainHead, splitPoint);
        List<StoredBlock> newBlocks = getPartialChain(newChainHead, splitPoint);
        // Now inform the wallets. This is necessary so the set of currently active transactions (that we can spend)
        // can be updated to take into account the re-organize. We might also have received new coins we didn't have
        // before and our previous spends might have been undone.
        for (Wallet wallet : wallets) {
            wallet.reorganize(oldBlocks, newBlocks);
        }
        // Update the pointer to the best known block.
        setChainHead(newChainHead);
    }

    /**
     * Returns the set of contiguous blocks between 'higher' and 'lower'. Higher is included, lower is not.
     */
    private List<StoredBlock> getPartialChain(StoredBlock higher, StoredBlock lower) throws BlockStoreException {
        assert higher.getHeight() > lower.getHeight();
        LinkedList<StoredBlock> results = new LinkedList<StoredBlock>();
        StoredBlock cursor = higher;
        while (true) {
            results.add(cursor);
            cursor = cursor.getPrev(blockStore);
            assert cursor != null : "Ran off the end of the chain";
            if (cursor.equals(lower)) break;
        }
        return results;
    }

    /**
     * Locates the point in the chain at which newStoredBlock and chainHead diverge. Returns null if no split point was
     * found (ie they are not part of the same chain). Returns newChainHead or chainHead if they don't actually diverge
     * but are part of the same chain.
     */
    private StoredBlock findSplit(StoredBlock newChainHead, StoredBlock chainHead) throws BlockStoreException {
        StoredBlock currentChainCursor = chainHead;
        StoredBlock newChainCursor = newChainHead;
        // Loop until we find the block both chains have in common. Example:
        //
        //    A -> B -> C -> D
        //         \--> E -> F -> G
        //
        // findSplit will return block B. chainHead = D and newChainHead = G.
        while (!currentChainCursor.equals(newChainCursor)) {
            if (currentChainCursor.getHeight() > newChainCursor.getHeight()) {
                currentChainCursor = currentChainCursor.getPrev(blockStore);
                assert currentChainCursor != null : "Attempt to follow an orphan chain";
            } else {
                newChainCursor = newChainCursor.getPrev(blockStore);
                assert newChainCursor != null : "Attempt to follow an orphan chain";
            }
        }
        return currentChainCursor;
    }

    /**
     * @return the height of the best known chain, convenience for <tt>getChainHead().getHeight()</tt>.
     */
    public int getBestChainHeight() {
        return getChainHead().getHeight();
    }

    public enum NewBlockType {
        BEST_CHAIN,
        SIDE_CHAIN
    }

    private void sendTransactionsToWallet(StoredBlock block, NewBlockType blockType,
                                          HashMap<Wallet, List<Transaction>> newTransactions) throws VerificationException {
        for (Map.Entry<Wallet, List<Transaction>> entry : newTransactions.entrySet()) {
            try {
                List<Transaction> txns = entry.getValue();
                for (Transaction tx : txns) {
                    entry.getKey().receiveFromBlock(tx, block, blockType);
                }
            } catch (ScriptException e) {
                // We don't want scripts we don't understand to break the block chain so just note that this tx was
                // not scanned here and continue.
                log.warn("Failed to parse a script: " + e.toString());
            }
        }
    }

    private void setChainHead(StoredBlock chainHead) throws BlockStoreException {
        blockStore.setChainHead(chainHead);
        synchronized (chainHeadLock) {
            this.chainHead = chainHead;
        }
    }

    /**
     * For each block in unconnectedBlocks, see if we can now fit it on top of the chain and if so, do so.
     */
    private void tryConnectingUnconnected() throws VerificationException, ScriptException, BlockStoreException {
        // For each block in our unconnected list, try and fit it onto the head of the chain. If we succeed remove it
        // from the list and keep going. If we changed the head of the list at the end of the round try again until
        // we can't fit anything else on the top.
        int blocksConnectedThisRound;
        do {
            blocksConnectedThisRound = 0;
            Iterator<Block> iter = unconnectedBlocks.iterator();
            while (iter.hasNext()) {
                Block block = iter.next();
                log.debug("Trying to connect {}", block.getHash());
                // Look up the blocks previous.
                StoredBlock prev = blockStore.get(block.getPrevBlockHash());
                if (prev == null) {
                    // This is still an unconnected/orphan block.
                    log.debug("  but it is not connectable right now");
                    continue;
                }
                // Otherwise we can connect it now.
                // False here ensures we don't recurse infinitely downwards when connecting huge chains.
                add(block, false);
                iter.remove();
                blocksConnectedThisRound++;
            }
            if (blocksConnectedThisRound > 0) {
                log.info("Connected {} floating blocks.", blocksConnectedThisRound);
            }
        } while (blocksConnectedThisRound > 0);
    }

    /**
     * Throws an exception if the blocks difficulty is not correct.
     */
    private void checkDifficultyTransitions(StoredBlock storedPrev, StoredBlock storedNext)
            throws BlockStoreException, VerificationException {
        Block prev = storedPrev.getHeader();
        Block next = storedNext.getHeader();
        // Is this supposed to be a difficulty transition point?
        if ((storedPrev.getHeight() + 1) % params.interval != 0) {
            // No ... so check the difficulty didn't actually change.
            if (next.getDifficultyTarget() != prev.getDifficultyTarget())
                throw new VerificationException("Unexpected change in difficulty at height " + storedPrev.getHeight() +
                        ": " + Long.toHexString(next.getDifficultyTarget()) + " vs " +
                        Long.toHexString(prev.getDifficultyTarget()));
            return;
        }

        // We need to find a block far back in the chain. It's OK that this is expensive because it only occurs every
        // two weeks after the initial block chain download.
        long now = System.currentTimeMillis();
        StoredBlock cursor = blockStore.get(prev.getHash());
        for (int i = 0; i < params.interval - 1; i++) {
            if (cursor == null) {
                // This should never happen. If it does, it means we are following an incorrect or busted chain.
                throw new VerificationException(
                        "Difficulty transition point but we did not find a way back to the genesis block.");
            }
            cursor = blockStore.get(cursor.getHeader().getPrevBlockHash());
        }
        log.debug("Difficulty transition traversal took {}msec", System.currentTimeMillis() - now);

        Block blockIntervalAgo = cursor.getHeader();
        int timespan = (int) (prev.getTimeSeconds() - blockIntervalAgo.getTimeSeconds());
        // Limit the adjustment step.
        if (timespan < params.targetTimespan / 4)
            timespan = params.targetTimespan / 4;
        if (timespan > params.targetTimespan * 4)
            timespan = params.targetTimespan * 4;

        BigInteger newDifficulty = Utils.decodeCompactBits(blockIntervalAgo.getDifficultyTarget());
        newDifficulty = newDifficulty.multiply(BigInteger.valueOf(timespan));
        newDifficulty = newDifficulty.divide(BigInteger.valueOf(params.targetTimespan));

        if (newDifficulty.compareTo(params.proofOfWorkLimit) > 0) {
            log.debug("Difficulty hit proof of work limit: {}", newDifficulty.toString(16));
            newDifficulty = params.proofOfWorkLimit;
        }

        int accuracyBytes = (int) (next.getDifficultyTarget() >>> 24) - 3;
        BigInteger receivedDifficulty = next.getDifficultyTargetAsInteger();

        // The calculated difficulty is to a higher precision than received, so reduce here.
        BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8);
        newDifficulty = newDifficulty.and(mask);

        if (newDifficulty.compareTo(receivedDifficulty) != 0)
            throw new VerificationException("Network provided difficulty bits do not match what was calculated: " +
                    receivedDifficulty.toString(16) + " vs " + newDifficulty.toString(16));
    }

    /**
     * For the transactions in the given block, update the txToWalletMap such that each wallet maps to a list of
     * transactions for which it is relevant.
     */
    private void scanTransactions(Block block, HashMap<Wallet, List<Transaction>> walletToTxMap)
            throws VerificationException {
        for (Transaction tx : block.transactions) {
            try {
                for (Wallet wallet : wallets) {
                    if (tx.isCoinBase())
                        continue;
                    boolean shouldReceive = wallet.isTransactionRelevant(tx, true);
                    if (!shouldReceive) continue;
                    List<Transaction> txList = walletToTxMap.get(wallet);
                    if (txList == null) {
                        txList = new LinkedList<Transaction>();
                        walletToTxMap.put(wallet, txList);
                    }
                    txList.add(tx);
                }
            } catch (ScriptException e) {
                // We don't want scripts we don't understand to break the block chain so just note that this tx was
                // not scanned here and continue.
                log.warn("Failed to parse a script: " + e.toString());
            }
        }
    }

    /**
     * Returns the block at the head of the current best chain. This is the block which represents the greatest
     * amount of cumulative work done.
     */
    public StoredBlock getChainHead() {
        synchronized (chainHeadLock) {
            return chainHead;
        }
    }

    /**
     * Returns the most recent unconnected block or null if there are none. This will all have to change. It's used
     * only in processing of inv messages.
     */
    synchronized Block getUnconnectedBlock() {
        if (unconnectedBlocks.size() == 0)
            return null;
        return unconnectedBlocks.get(unconnectedBlocks.size() - 1);
    }
}


text:
@echo off
pushd %~dp0
"%VS120COMNTOOLS%..\IDE\mstest" /test:Microsoft.Protocols.TestSuites.MS_ASPROV.S03_ProvisionNegative.MSASPROV_S03_TC05_VerifyPolicyStatus139 /testcontainer:..\..\MS-ASPROV\TestSuite\bin\Debug\MS-ASPROV_TestSuite.dll /runconfig:..\..\MS-ASPROV\MS-ASPROV.testsettings /unique
pause


text:
import numpy
import pandas

import matplotlib
from matplotlib import pyplot
get_ipython().magic(u'matplotlib inline')

import scipy
from scipy import stats # TODO vedere perché non fa chiamare il modulo direttamente

import gmaps

# ## Creazione della mappa
#
# invece che uno scatterplot con dei raggi, la libreria ci consente solo di fare una heatmap (eventualmente pesata)
#

# In[2]:

roma = pandas.read_csv("../data/Roma_towers.csv")
coordinate = roma[['lat', 'lon']].values

# In[3]:

heatmap = gmaps.heatmap(coordinate)
gmaps.display(heatmap)

# TODO scrivere che dietro queste due semplici linee ci sta un pomeriggio intero di smadonnamenti

# In[4]:

colosseo = (41.890183, 12.492369)

# In[5]:

import gmplot
from gmplot import GoogleMapPlotter

# gmap = gmplot.from_geocode("San Francisco")

mappa = gmplot.GoogleMapPlotter(41.890183, 12.492369, 11)

#gmap.plot(latitudes, longitudes, 'cornflowerblue', edge_width=10)
#gmap.plot((41.890183, 41.891183), (12.492369, 12.493369), 'cornflowerblue', edge_width=10)
#gmap.scatter(more_lats, more_lngs, '#3B0B39', size=40, marker=False)
#gmap.scatter(marker_lats, marker_lngs, 'k', marker=True)
#gmap.heatmap(heat_lats, heat_lngs)

#mappa.scatter((41.890183, 41.891183), (12.492369, 12.493369), color='#3B0B39', size=40, marker=False)

#mappa.scatter(roma.lat.values,
#              roma.lon.values,
#              color='#3333ff',
#              size=0,
#              marker=False)

mappa.heatmap(roma.lat.values,roma.lon.values)

mappa.draw("../html/heatmap.html")
#print a

# ### NOTE guardando la mappa
#
# Sembrano esserci dei problemi con la posizione delle antenne: ci sono antenne sul tevere, su ponte Sisto, dentro il parchetto di Castel Sant'Angelo, in mezzo al pratone della Sapienza, in cima al dipartimento di Fisica...
#
#
# Inoltre sembra esserci una strana clusterizzazione lungo le vie di traffico principali. Questo è ragionevole nell'ottica di garantire la copertura in una città con grossi flussi turistici come Roma, ma probabilmente non a tal punto da rendere plausibile la presenza di 7 antenne attorno a piazza Panteon. Ci sono anche coppie di antenne isolate che sembrano distare tra loro pochi metri. Probabilmente sono artefatti di ricostruzione.
#
# Probabilmente l'algoitmo di ricostruzione di Mozilla ha diversi problemi. Se questa è la situazione delle antenne non oso pensare alla situazione dei router wifi.
#
# Queste misure e queste ricostruzioni devono essere precise, perché è su queste che si poggerà il loro futuro servizio di geolocalizzazione.
#
# Bisognerebbe farglielo presente (magari ci prendono a lavorare da loro :-) )
#
#

# ## Analisi del raggio di copertura delle antenne
#
# dato che ci servirà fare un grafico con scale logaritmiche teniamo solo i dati con
# > range =! 0

# In[6]:

# condizioni di filtro
raggioMin = 1
# raggioMax = 1000
raggiPositivi = roma.range >= raggioMin
# raggiCorti = roma.range < raggioMax

# query con le condizioni
#romaFiltrato = roma[raggiPositivi & raggiCorti]
romaFiltrato = roma[raggiPositivi]
raggi = romaFiltrato.range

print max(raggi)

# In[7]:

# logaritmic (base 2) binning in log-log (base 10) plots of integer histograms

def logBinnedHist(histogramResults):
    """
    histogramResults = numpy.histogram(...)
        OR matplotlib.pyplot.hist(...)

    returns x, y
    to be used with matplotlib.pyplot.step(x, y, where='post')
    """

    # TODO così funziona solo con l'istogramma di pyplot;
    # quello di numpy restituisce solo la tupla (values, binEdges)
    values, binEdges, others = histogramResults

    # print binEdges

    # TODO
    # if 0 in binEdges:
    #     return "error: log2(0) = ?"

    # print len(values), len(binEdges)

    # print binEdges # TODO vedere quando non si parte da 1

    # int arrotonda all'intero inferiore
    linMin = min(binEdges)
    linMax = max(binEdges)

    # print linMin, linMax

    logStart = int(numpy.log2(linMin))
    logStop = int(numpy.log2(linMax))

    # print logStart, logStop

    nLogBins = logStop - logStart + 1

    # print nLogBins

    logBins = numpy.logspace(logStart, logStop, num=nLogBins, base=2, dtype=int)
    # print logBins

    # 1,2,4,8,16,32,64,128,256,512,1024

    ######################

    linStart = 2**logStop + 1
    linStop = linMax

    # print linStart, linStop

    nLinBins = linStop - linStart + 1

    # print nLinBins

    linBins = numpy.linspace(linStart, linStop, num=nLinBins, dtype=int)

    # print linBins

    ######################

    bins = numpy.append(logBins, linBins)

    # print bins

    # print len(bins)

    # TODO rendere generale questa funzione!!!
    totalValues, binEdges, otherBinNumbers = scipy.stats.binned_statistic(raggi.values,
                                                                         raggi.values,
                                                                         statistic='count',
                                                                         bins=bins)

    # print totalValues
    # print len(totalValues)

    # uso le proprietà dei logaritmi in base 2:
    # 2^(n+1) - 2^n = 2^n
    correzioniDatiCanalizzatiLog = numpy.delete(logBins, -1)

    # print correzioniDatiCanalizzatiLog

    # print len(correzioniDatiCanalizzatiLog)

    correzioniDatiCanalizzatiLin = numpy.ones(nLinBins, dtype=int)

    # print correzioniDatiCanalizzatiLin

    # print len(correzioniDatiCanalizzatiLin)

    correzioniDatiCanalizzati = numpy.append(correzioniDatiCanalizzatiLog, correzioniDatiCanalizzatiLin)

    # print correzioniDatiCanalizzati

    # print len(correzioniDatiCanalizzati)

    x = numpy.concatenate(([0], bins))
    conteggi = totalValues/correzioniDatiCanalizzati

    # TODO caso speciale per il grafico di sotto
    # (per non fare vedere la parte oltre l'ultima potenza di 2)
    l = len(correzioniDatiCanalizzatiLin)
    conteggi[-l:] = numpy.zeros(l, dtype='int')

    y = numpy.concatenate(([0], conteggi, [0]))

    return x, y

# In[8]:

# creazione di un istogramma log-log per la distribuzione del raggio di copertura

# TODO provare a raggruppare le code
# esempio: con bins=100
# oppure con canalizzazione a logaritmo di 2, ma mediato
# in modo che venga equispaziato nel grafico logaritmico
# il programma vuole pesati i dati e non i canali
# si potrebbe implementare una mappa che pesa i dati
# secondo la funzione divisione intera per logaritmo di 2
# TODO mettere cerchietto che indica il range massimo oppure scritta in rosso "20341 m!"
# TODO spiegare perché ci sono così tanti conteggi a 1,2,4,... metri
# TODO ricavare il range dai dati grezzi, facendo un algoritmo di clustering
# sulle varie osservazioni delle antenne. machine learning?
# TODO scrivere funzione che fa grafici logaritmici con canali
# equispaziati nel plot logaritmico (canali pesati)

# impostazioni plot complessivo
# pyplot.figure(figsize=(20,8)) # dimensioni in pollici
pyplot.figure(figsize=(10,10))
matplotlib.pyplot.xlim(10**0,10**5)
matplotlib.pyplot.ylim(10**-3,10**2)
pyplot.title('Distribuzione del raggio di copertura')
pyplot.ylabel("Numero di antenne")
pyplot.xlabel("Copertura [m]")
# pyplot.gca().set_xscale("log")
# pyplot.gca().set_yscale("log")
pyplot.xscale("log")
pyplot.yscale("log")

# lin binning
distribuzioneRange = pyplot.hist(raggi.values,
                                bins=max(raggi)-min(raggi),
                                histtype='step',
                                color='#3385ff',
                                label='linear binning')

# log_2 binning
xLog2, yLog2 = logBinnedHist(distribuzioneRange)
matplotlib.pyplot.step(xLog2, yLog2, where='post', color='#ff3300', linewidth=2, label='log_2 weighted binning') #where = mid OR post
# matplotlib.pyplot.plot(xLog2, yLog2)

# linea verticale ad indicare il massimo grado
pyplot.axvline(x=max(raggi), color='#808080', linestyle='dotted', label='max range (41832m)')

# legenda e salvataggio
pyplot.legend(loc='lower left', frameon=False)
pyplot.savefig('../img/range/infinite_log_binning.svg', format='svg', dpi=600, transparent=True)

# ### Frequency-rank

# In[9]:

# istogramma sugli interi
unique, counts = numpy.unique(raggi.values, return_counts=True)
# print numpy.asarray((unique, counts)).T
rank = numpy.arange(1,len(unique)+1)
frequency = numpy.array(sorted(counts, reverse=True))

# In[10]:

pyplot.figure(figsize=(20,10))
pyplot.title('Distribuzione del raggio di copertura')
pyplot.ylabel("Numero di antenne")
pyplot.xlabel("Copertura [m] o ranking")
pyplot.xscale("log")
pyplot.yscale("log")
matplotlib.pyplot.xlim(10**0,10**4)
matplotlib.pyplot.ylim(10**0,10**2)

matplotlib.pyplot.step(x=rank, y=frequency, where='post', label='frequency-rank', color='#00cc44')

matplotlib.pyplot.scatter(x=unique, y=counts, marker='o', color='#3385ff', label='linear binning (scatter)')
matplotlib.pyplot.step(xLog2, yLog2, where='post', color='#ff3300', label='log_2 weighted binning')

pyplot.legend(loc='lower left', frameon=False)
pyplot.savefig('../img/range/range_distribution.svg', format='svg', dpi=600, transparent=True)

# ### Cumulative histogram
#
# the cumulative distribution function cdf(x) is the probability that a real-valued random variable X will take a value less than or equal to x

# In[11]:

conteggi, binEdges = numpy.histogram(raggi.values,
                                bins=max(raggi)-min(raggi))
conteggiCumulativi = numpy.cumsum(conteggi)
valoriRaggi = numpy.delete(binEdges, -1)
N = len(raggi.values)

# In[12]:

pyplot.figure(figsize=(12,10))
pyplot.title('Raggio di copertura')
pyplot.ylabel("Numero di antenne")
pyplot.xlabel("Copertura [m]")
pyplot.xscale("log")
pyplot.yscale("log")
matplotlib.pyplot.xlim(10**0,10**5)
matplotlib.pyplot.ylim(10**0,10**4)

matplotlib.pyplot.step(x=valoriRaggi, y=conteggiCumulativi, where='post', label='Cumulata', color='#009999')
matplotlib.pyplot.step(x=valoriRaggi, y=N-conteggiCumulativi, where='post', label='N - Cumulata', color='#ff0066')

pyplot.axhline(y=N, color='#808080', linestyle='dotted', label='N_max = 6505')

pyplot.legend(loc='lower left', frameon=False)
pyplot.savefig('../img/range/range_cumulated_distribution.svg', format='svg', dpi=600, transparent=True)

# In[13]:

# TODO fare fit a mano e controllare le relazioni tra i vari esponenti

# In[ ]:

# In[ ]: