Пример #1
0
    def __init__(self, **kw):

        self.ncols       = kw.get('ncols', None)
        self.nthreads    = kw.get('nthreads', 1)
        self.random_seed = kw.get('rngseed',  None)
        self.objf_choice = kw.get('objf choice', 'random')
        self.sol_type    = kw.get('solution type', 'interior')
        self.add_noise   = kw.get('add noise', False)

        ran_set_seed(self.random_seed)

        self.lp = lpsolve('make_lp', 0, self.ncols)
        #lpsolve('set_bounds_tighter', self.lp, True) # important so that we don't loosen tight bounds

        self.ineqs = []

        self.eq_count  = 0
        self.leq_count = 0
        self.geq_count = 0
        self.bnd_count  = 0

        self.iteration   = 0
        self.prev_sol    = None
        self.sum_ln_k    = 0
        self.curr_sol    = None
        self.n_solutions = 0
Пример #2
0
    def __init__(self, **kw):

        ncols = kw.get('ncols', None)
        nthreads = kw.get('nthreads', 1)
        rngseed = kw.get('rngseed', 0)
        self.objf_choice = kw.get('objf choice', 'random')
        self.sol_type = kw.get('solution type', 'interior')
        self.noise = kw.get('add noise', 1e-6)
        self.reset = kw.get('reset', False)

        Log("Samplex created")
        Log("    ncols = %i" % ncols)
        if ncols is not None:
            self.nVars = ncols
            self.nRight = self.nVars

        ran_set_seed(rngseed)
        self.random_seed = rngseed

        self.nthreads = nthreads
        Samplex.pivot = lambda s: csamplex.pivot(s)

        self.data = None
        self.dcopy = []

        self.n_equations = 0
        self.lhv = []
        self.rhv = []
        self.nVars = None  # Number of variables + 1(constant column) [N]
        self.nLeft = 0  # Number of left hand variables            [L]
        self.nSlack = 0  # Number of slack variables                [S]
        self.nTemp = 0  # Number of temporary variables            [Z]
        self.nRight = 0  # Number of right hand variables           [R]
        self.eq_count = 0
        self.leq_count = 0
        self.geq_count = 0

        self.eq_list = []

        self.iteration = 0
        self.moca = None
        self.sum_ln_k = 0
        self.curr_sol = None
        self.n_solutions = 0

        self.forbidden_variables = []
Пример #3
0
    def __init__(self, **kw):

        ncols    = kw.get('ncols', None)
        nthreads = kw.get('nthreads', 1)
        rngseed  = kw.get('rngseed',  0)
        self.objf_choice = kw.get('objf choice', 'random')
        self.sol_type  = kw.get('solution type', 'interior')
        self.noise   = kw.get('add noise', 1e-6)
        self.reset   = kw.get('reset', False)

        Log( "Samplex created" )
        Log( "    ncols = %i" % ncols )
        if ncols is not None:
            self.nVars = ncols
            self.nRight = self.nVars

        ran_set_seed(rngseed)
        self.random_seed = rngseed

        self.nthreads = nthreads
        Samplex.pivot = lambda s: csamplex.pivot(s)

        self.data = None
        self.dcopy = []

        self.n_equations = 0
        self.lhv = []
        self.rhv = []
        self.nVars = None            # Number of variables + 1(constant column) [N]
        self.nLeft = 0               # Number of left hand variables            [L]
        self.nSlack = 0              # Number of slack variables                [S]
        self.nTemp = 0               # Number of temporary variables            [Z]
        self.nRight = 0              # Number of right hand variables           [R]
        self.eq_count = 0
        self.leq_count = 0
        self.geq_count = 0

        self.eq_list = []

        self.iteration = 0
        self.moca = None
        self.sum_ln_k = 0
        self.curr_sol = None
        self.n_solutions = 0

        self.forbidden_variables = []
Пример #4
0
    def next(self, nsolutions=None):

        Log( '=' * 80 )
        Log( 'Simplex Random Walk' )
        Log( '=' * 80 )

        Log( "    %i equations" % len(self.eq_list) )

        Log( "%6s %6s %6s\n%6i %6i %6i" 
            % (">=", "<=", "=", self.geq_count, self.leq_count, self.eq_count) )


        if nsolutions == 0: return

        assert nsolutions is not None

        dim = self.nVars
        dof = dim - self.eq_count

        burnin_len  = max(10, int(self.burnin_factor * dof))
        redo        = max(100,  int((dof ** self.redo_exp) * self.redo_factor))

        nmodels = nsolutions
        nthreads = self.nthreads

        self.stride = int(dim+1)

        n_stored = 0
        self.dim = dim
        self.dof = dof
        self.redo = redo

        self.burnin_len = burnin_len

        accept_rate     = self.accept_rate
        accept_rate_tol = self.accept_rate_tol

        store = np.zeros((dim, 1+burnin_len), order='Fortran', dtype=np.float64)
        newp = np.zeros(dim, order='C', dtype=np.float64)
        eval  = np.zeros(dim, order='C', dtype=np.float64)
        evec  = np.zeros((dim,dim), order='F', dtype=np.float64)

        self.eqs = np.zeros((self.eqn_count+dim,dim+1), order='C', dtype=np.float64)
        for i,[c,e] in enumerate(self.eq_list):
            self.eqs[i,:] = e
        for i in xrange(dim):
            self.eqs[self.eqn_count+i,1+i] = 1

        self.dist_eqs = np.zeros((self.eqn_count-self.eq_count,dim+1), order='C', dtype=np.float64)
        i=0
        for c,e in self.eq_list:
            if c == 'eq':
                continue
            elif c == 'leq':
                p = e
            elif c == 'geq':
                p = -e
            self.dist_eqs[i,:] = p
            i += 1

        Log( 'Using lpsolve %s' % lpsolve('lp_solve_version') )
        Log( "random seed = %s" % self.random_seed )
        Log( "threads = %s" % self.nthreads )
        Log( "acceptence rate = %s" % self.accept_rate )
        Log( "acceptence rate tolerance = %s" % self.accept_rate_tol )
        Log( "dof = %s" % self.dof)
        Log( "sample distance = max(100,%s * %s^%s) = %s" % (self.redo_factor, self.dof, self.redo_exp, redo) )
        Log( "starting twiddle = %s" % self.twiddle )
        Log( "burn-in length = %s" % burnin_len )

        time_begin_next = time.clock()

        #-----------------------------------------------------------------------
        # Create pseudo inverse matrix to reproject samples back into the
        # solution space.
        #-----------------------------------------------------------------------
        P = np.eye(dim) 
        if self.eq_count > 0:
            self.A = np.zeros((self.eq_count, dim), order='C', dtype=np.float64)
            self.b = np.zeros(self.eq_count, order='C', dtype=np.float64)
            for i,[c,e] in enumerate(self.eq_list[:self.eq_count]):
                self.A[i] = e[1:]
                self.b[i] = e[0]
            self.Apinv = pinv(self.A)
            P -= np.dot(self.Apinv, self.A)
        else:
            self.A = None
            self.B = None
            self.Apinv = None

        ev, evec = eigh(P)
        #-----------------------------------------------------------------------


        #-----------------------------------------------------------------------
        # Find a point that is completely inside the simplex
        #-----------------------------------------------------------------------
        Log('Finding first inner point')
        time_begin_inner_point = time.clock()
        self.inner_point(newp)
        time_end_inner_point = time.clock()
        ok,fail_count = self.in_simplex(newp, eq_tol=1e-12, tol=0, verbose=1)
        assert ok

        self.avg0 = newp

#       eqs  = self.eqs.copy('A')
#       eqs[:,1:] = np.dot(self.eqs[:,1:], evec)

#       print newp

#       S = zeros(self.eqs.shape[0])
#       newp[:] = np.dot(evec.T, newp)
#       newp0 = newp.copy()
#       steps = newp.copy()
#       for q in range(100):
#           csamplex.refine_center(self, eqs, newp, ev, S, steps)
#           d = newp - newp0
#           #print d
#           print norm(d)
#           #print
#           newp0 = newp.copy()

#       #assert 0
#       newp[:] = np.dot(evec, newp)


        store[:,0] = newp
        n_stored = 1

        q = MP.Queue()

        #-----------------------------------------------------------------------
        # Estimate the eigenvectors of the simplex
        #-----------------------------------------------------------------------
        Log('Estimating eigenvectors')
        time_begin_est_eigenvectors = time.clock()
        self.measured_ev(newp, ev, eval, evec)
        time_end_est_eigenvectors = time.clock()

        #-----------------------------------------------------------------------
        # Now we can start the random walk
        #-----------------------------------------------------------------------

        Log( "Getting solutions" )

        ran_set_seed(self.random_seed)
        seeds = np.random.choice(1000000*nthreads, nthreads, replace=False)

        #-----------------------------------------------------------------------
        # Launch the threads
        #-----------------------------------------------------------------------
        threads = []
        models_per_thread = nmodels // nthreads
        models_under      = nmodels - nthreads*models_per_thread
        id,N = 0,0
        while id < nthreads and N < nmodels:
            n = models_per_thread
            if id < models_under:
                n += 1
            assert n > 0
            Log( 'Thread %i gets %i' % (id,n) )
            cmdq = MP.Queue()
            ackq = MP.Queue()

            thr = MP.Process(target=rwalk_burnin, 
                             args=(id, n, int(np.ceil(burnin_len/nthreads)), self, q, cmdq, ackq, newp, self.twiddle, eval.copy('A'), evec.copy('A'), seeds[id]))
            threads.append([thr,cmdq,ackq])
            N += n
            id += 1

        assert N == nmodels

        for thr,cmdq,_ in threads:
            thr.daemon=True
            thr.start()
            cmdq.put(['CONT'])

        def drainq(q):
            try:
                while True:
                    q.get(block=False)
            except QueueEmpty:
                pass

        def pause_threads(threads):
            for _,cmdq,ackq in threads:
                cmdq.put(['WAIT'])
                assert ackq.get() == 'OK'

        def adjust_threads(i, cont_cmd):
            pause_threads(threads)
            drainq(q)
            Log( 'Computing eigenvalues... [%i/%i]' % (i, burnin_len) )
            self.compute_eval_evec(store, eval, evec, n_stored)

            # new twiddle <-- average twiddle
            t = 0
            for _,cmdq,ackq in threads:
                cmdq.put(['REQ TWIDDLE'])
                t += ackq.get()
            t /= len(threads)

            Log( 'New twiddle %f' % t )
            for _,cmdq,_ in threads:
                cmdq.put(['NEW DATA', [eval.copy('A'), evec.copy('A'), t]])
                cmdq.put([cont_cmd])

        #-----------------------------------------------------------------------
        # Burn-in
        #-----------------------------------------------------------------------
        time_begin_burnin = time.clock()
        compute_eval_window = 2 * self.dof
        j = 0
        k = -1
        while n_stored < burnin_len+1:
            #for i in xrange(burnin_len):
            k,vecs,phase = q.get()

            #print 'Received ', len(vecs), ' from ', k
            for vec in vecs:
                j += 1
                store[:, n_stored] = vec
                n_stored += 1
                if n_stored == burnin_len+1: break

                if j == compute_eval_window:
                    j = 0
                    adjust_threads(i+1,'CONT')
                    compute_eval_window = int(0.1*burnin_len + 1)
                    break

            if j != 0 and len(threads) < compute_eval_window:
                threads[k][1].put(['CONT'])

        time_end_burnin = time.clock()

        #-----------------------------------------------------------------------
        # Actual random walk
        #-----------------------------------------------------------------------
        time_begin_get_models = time.clock()
        adjust_threads(burnin_len, 'RWALK')
        i=0
        while i < nmodels:
            k,vec,phase = q.get()
            if phase != 'RWALK': continue
            t = np.zeros(dim+1, order='Fortran', dtype=np.float64)
            t[1:] = vec
            i += 1
            Log( '%i models left to generate' % (nmodels-i), overwritable=True)
            yield t

        time_end_get_models = time.clock()

        #-----------------------------------------------------------------------
        # Stop the threads and get their running times.
        #-----------------------------------------------------------------------
        time_threads = []
        for thr,cmdq,ackq in threads:
            cmdq.put(['STOP'])
            m,t = ackq.get()
            assert m == 'TIME'
            time_threads.append(t)
            #thr.terminate()

        time_end_next = time.clock()

        max_time_threads = np.amax(time_threads) if time_threads else 0
        avg_time_threads = np.mean(time_threads) if time_threads else 0

        Log( '-'*80 )
        Log( 'SAMPLEX TIMINGS' )
        Log( '-'*80 )
        Log( 'Initial inner point    %.2fs' % (time_end_inner_point - time_begin_inner_point) )
        Log( 'Estimate eigenvectors  %.2fs' % (time_end_est_eigenvectors - time_begin_est_eigenvectors) )
        Log( 'Burn-in                %.2fs' % (time_end_burnin - time_begin_burnin) )
        Log( 'Modeling               %.2fs' % (time_end_get_models - time_begin_get_models) )
        Log( 'Max/Avg thread time    %.2fs %.2fs' % (max_time_threads, avg_time_threads) )
        Log( 'Total wall-clock time  %.2fs' % (time_end_next - time_begin_next) )
        Log( '-'*80 )
Пример #5
0
    def next(self, nsolutions=None):

        Log( '=' * 80 )
        Log( 'Simplex Random Walk' )
        Log( '=' * 80 )

        Log( "    %i equations" % len(self.eq_list) )

        Log( "%6s %6s %6s\n%6i %6i %6i" 
            % (">=", "<=", "=", self.geq_count, self.leq_count, self.eq_count) )


        if nsolutions == 0: return

        assert nsolutions is not None

        dim = self.nVars
        dof = dim - self.eq_count

        burnin_len  = max(10, int(self.burnin_factor * dof))
        redo        = max(100,  int((dof ** self.redo_exp) * self.redo_factor))

        nmodels = nsolutions
        nthreads = self.nthreads

        self.stride = int(dim+1)

        n_stored = 0
        self.dim = dim
        self.dof = dof
        self.redo = redo

        self.burnin_len = burnin_len

        accept_rate     = self.accept_rate
        accept_rate_tol = self.accept_rate_tol

        store = np.zeros((dim, 1+burnin_len), order='Fortran', dtype=np.float64)
        newp = np.zeros(dim, order='C', dtype=np.float64)
        eval  = np.zeros(dim, order='C', dtype=np.float64)
        evec  = np.zeros((dim,dim), order='F', dtype=np.float64)

        self.eqs = np.zeros((self.eqn_count+dim,dim+1), order='C', dtype=np.float64)
        for i,[c,e] in enumerate(self.eq_list):
            self.eqs[i,:] = e
        for i in xrange(dim):
            self.eqs[self.eqn_count+i,1+i] = 1

        self.dist_eqs = np.zeros((self.eqn_count-self.eq_count,dim+1), order='C', dtype=np.float64)
        i=0
        for c,e in self.eq_list:
            if c == 'eq':
                continue
            elif c == 'leq':
                p = e
            elif c == 'geq':
                p = -e
            self.dist_eqs[i,:] = p
            i += 1

        Log( 'Using lpsolve %s' % lpsolve('lp_solve_version') )
        Log( "random seed = %s" % self.random_seed )
        Log( "threads = %s" % self.nthreads )
        Log( "acceptence rate = %s" % self.accept_rate )
        Log( "acceptence rate tolerance = %s" % self.accept_rate_tol )
        Log( "dof = %s" % self.dof)
        Log( "sample distance = max(100,%s * %s^%s) = %s" % (self.redo_factor, self.dof, self.redo_exp, redo) )
        Log( "starting twiddle = %s" % self.twiddle )
        Log( "burn-in length = %s" % burnin_len )

        time_begin_next = time.clock()

        #-----------------------------------------------------------------------
        # Create pseudo inverse matrix to reproject samples back into the
        # solution space.
        #-----------------------------------------------------------------------
        P = np.eye(dim) 
        if self.eq_count > 0:
            self.A = np.zeros((self.eq_count, dim), order='C', dtype=np.float64)
            self.b = np.zeros(self.eq_count, order='C', dtype=np.float64)
            for i,[c,e] in enumerate(self.eq_list[:self.eq_count]):
                self.A[i] = e[1:]
                self.b[i] = e[0]
            self.Apinv = pinv(self.A)
            P -= np.dot(self.Apinv, self.A)
        else:
            self.A = None
            self.B = None
            self.Apinv = None

        ev, evec = eigh(P)
        #-----------------------------------------------------------------------


        #-----------------------------------------------------------------------
        # Find a point that is completely inside the simplex
        #-----------------------------------------------------------------------
        Log('Finding first inner point')
        time_begin_inner_point = time.clock()
        self.inner_point(newp)
        time_end_inner_point = time.clock()
        ok,fail_count = self.in_simplex(newp, eq_tol=1e-12, tol=0, verbose=1)
        assert ok

        self.avg0 = newp

#       eqs  = self.eqs.copy('A')
#       eqs[:,1:] = np.dot(self.eqs[:,1:], evec)

#       print newp

#       S = zeros(self.eqs.shape[0])
#       newp[:] = np.dot(evec.T, newp)
#       newp0 = newp.copy()
#       steps = newp.copy()
#       for q in range(100):
#           csamplex.refine_center(self, eqs, newp, ev, S, steps)
#           d = newp - newp0
#           #print d
#           print norm(d)
#           #print
#           newp0 = newp.copy()

#       #assert 0
#       newp[:] = np.dot(evec, newp)


        store[:,0] = newp
        n_stored = 1


        #-----------------------------------------------------------------------
        # Estimate the eigenvectors of the simplex
        #-----------------------------------------------------------------------
        Log('Estimating eigenvectors')
        time_begin_est_eigenvectors = time.clock()
        self.measured_ev(newp, ev, eval, evec)
        time_end_est_eigenvectors = time.clock()

        #-----------------------------------------------------------------------
        # Now we can start the random walk
        #-----------------------------------------------------------------------

        Log( "Getting solutions" )

        q = MP.Queue()

        ran_set_seed(self.random_seed)
        seeds = np.random.choice(1000000*nthreads, nthreads, replace=False)

        #-----------------------------------------------------------------------
        # Launch the threads
        #-----------------------------------------------------------------------
        threads = []
        models_per_thread = nmodels // nthreads
        models_under      = nmodels - nthreads*models_per_thread
        id,N = 0,0
        while id < nthreads and N < nmodels:
            n = models_per_thread
            if id < models_under:
                n += 1
            assert n > 0
            Log( 'Thread %i gets %i' % (id,n) )
            cmdq = MP.Queue()
            ackq = MP.Queue()
            thr = MP.Process(target=rwalk_burnin, 
                             args=(id, n, int(np.ceil(burnin_len/nthreads)), self, q, cmdq, ackq, newp, self.twiddle, eval.copy('A'), evec.copy('A'), seeds[id]))
            threads.append([thr,cmdq,ackq])
            N += n
            id += 1

        assert N == nmodels

        for thr,cmdq,_ in threads:
            thr.daemon=True
            thr.start()
            cmdq.put(['CONT'])

        def drainq(q):
            try:
                while True:
                    q.get(block=False)
            except QueueEmpty:
                pass

        def pause_threads(threads):
            for _,cmdq,ackq in threads:
                cmdq.put(['WAIT'])
                assert ackq.get() == 'OK'

        def adjust_threads(i, cont_cmd):
            pause_threads(threads)
            drainq(q)
            Log( 'Computing eigenvalues... [%i/%i]' % (i, burnin_len) )
            self.compute_eval_evec(store, eval, evec, n_stored)

            # new twiddle <-- average twiddle
            t = 0
            for _,cmdq,ackq in threads:
                cmdq.put(['REQ TWIDDLE'])
                t += ackq.get()
            t /= len(threads)

            Log( 'New twiddle %f' % t )
            for _,cmdq,_ in threads:
                cmdq.put(['NEW DATA', [eval.copy('A'), evec.copy('A'), t]])
                cmdq.put([cont_cmd])

        #-----------------------------------------------------------------------
        # Burn-in
        #-----------------------------------------------------------------------
        time_begin_burnin = time.clock()
        compute_eval_window = 2 * self.dof
        j = 0
        for i in xrange(burnin_len):
            j += 1
            k,vec = q.get()

            store[:, n_stored] = vec
            n_stored += 1

            if j == compute_eval_window:
                j = 0
                adjust_threads(i+1,'CONT')
                compute_eval_window = int(0.1*burnin_len + 1)
            elif len(threads) < compute_eval_window:
                threads[k][1].put(['CONT'])
        time_end_burnin = time.clock()

        #-----------------------------------------------------------------------
        # Actual random walk
        #-----------------------------------------------------------------------
        time_begin_get_models = time.clock()
        adjust_threads(burnin_len, 'RWALK')
        i=0
        while i < nmodels:
            k,vec = q.get()
            t = np.zeros(dim+1, order='Fortran', dtype=np.float64)
            t[1:] = vec
            i += 1
            Log( '%i models left to generate' % (nmodels-i), overwritable=True)
            yield t

        time_end_get_models = time.clock()

        #-----------------------------------------------------------------------
        # Stop the threads and get their running times.
        #-----------------------------------------------------------------------
        time_threads = []
        for thr,cmdq,ackq in threads:
            cmdq.put(['STOP'])
            m,t = ackq.get()
            assert m == 'TIME'
            time_threads.append(t)
            #thr.terminate()

        time_end_next = time.clock()

        max_time_threads = np.amax(time_threads) if time_threads else 0
        avg_time_threads = np.mean(time_threads) if time_threads else 0

        Log( '-'*80 )
        Log( 'SAMPLEX TIMINGS' )
        Log( '-'*80 )
        Log( 'Initial inner point    %.2fs' % (time_end_inner_point - time_begin_inner_point) )
        Log( 'Estimate eigenvectors  %.2fs' % (time_end_est_eigenvectors - time_begin_est_eigenvectors) )
        Log( 'Burn-in                %.2fs' % (time_end_burnin - time_begin_burnin) )
        Log( 'Modeling               %.2fs' % (time_end_get_models - time_begin_get_models) )
        Log( 'Max/Avg thread time    %.2fs %.2fs' % (max_time_threads, avg_time_threads) )
        Log( 'Total wall-clock time  %.2fs' % (time_end_next - time_begin_next) )
        Log( '-'*80 )