1. 11 Feb, 2014 2 commits
  2. 03 Feb, 2014 11 commits
  3. 31 Jan, 2014 6 commits
    • Jason Rhinelander's avatar
      Comment/doc updates · fe082c11
      Jason Rhinelander authored
      fe082c11
    • Jason Rhinelander's avatar
      Stepper: added a max_step (defaulting for 0.5) · fbc89b70
      Jason Rhinelander authored
      The default max_step means whatever is being stepped increases by (at
      most) 50% and decreases by (at most) 33% in a single step.  Without
      this, initial conditions far off the equilibrium have a tendency to
      massively overshoot the equilibrium.
      fbc89b70
    • Jason Rhinelander's avatar
      Member::Lock: added member removal · cac1b218
      Jason Rhinelander authored
      Added the ability to remove a subset of members from a Lock.  This
      returns a new Lock consisting of the removed members--if the returned
      lock isn't used, it is released immediately, thus freeing the lock on
      the given members.
      
      This also involved converting Lock's internal vector implementation to a
      multiset, which required substantially reworking the locking code into
      using iterators on the multiset instead of indices.
      cac1b218
    • Jason Rhinelander's avatar
      Member::Lock: member lock addition, lock takeovers · b340e220
      Jason Rhinelander authored
      Added the ability to add a new member to a lock (which might require
      releasing the existing lock, if the new member can't be locked right
      away).
      
      Also added the ability to transfer one lock's members to another.  This
      requires no new locking attempts, but does require that the two locks
      have the same status (i.e. same read/write, and same locked/released
      status).
      b340e220
    • Jason Rhinelander's avatar
      MUPD: need to check feasibility *after* locking · 5ffc7e90
      Jason Rhinelander authored
      MUPD was causing a feasibility error because market feasibility was
      being checked before getting a market lock, which meant the market could
      be feasible, but after the lock might not be feasible anymore, in which
      case allocations failed with threads.  Moving the feasibility check to
      after the big market write lock fixes that.
      5ffc7e90
    • Jason Rhinelander's avatar
      f0c14f2f
  4. 07 Jan, 2014 1 commit
  5. 08 Dec, 2013 1 commit
  6. 07 Dec, 2013 1 commit
    • Jason Rhinelander's avatar
      Added CircularPosAgent: wrapping positional agent · 4fc7e970
      Jason Rhinelander authored
      New PositionalAgent subclass supports distance calculations, automatic
      wrapping when moving past a boundary, wrapping along just certain
      dimensions.
      
      - Explicitly added an initializer_list: the generic Container interface
        won't automatically match an initializer_list because the compiler
        can't deduce the type of initializer list accepted, and until it
        deduces that, it can't match the generic container.
      - Removed rvalue PositionalAgent constructor: it's wrong, since
        boundary1 and boundary2 are *not* the lower and upper boundaries:
        rather the min and max coordinates of each become lower and upper
        coordinates.
      - Removed the 1-, 2-, 3-, and 6-double-argument PositionalAgent
        constructors; by accepting Positions we already implicitly support
        initializer lists, so PositionalAgent({a,b}, {c,d}, {e,f}) works as
        expected: plus it's clearer than PositionalAgent(a,b,c,d,e,f).
      - Likewise for the 2- and 3-argument moveTo and moveBy methods.
      - Made the various boundary methods of PositionalAgent virtual because
        CircularPosAgent needs to override them (since wrapping boundaries
        aren't really boundaries).
      - Default lower_bound_ and upper_bound_ to zero vectors of the proper
        length (they get reset if boundaries apply, and are ignored if there
        are no boundaries).
      - Added pos-agent-test for testing various agent movement and wrapping
        methods.
      4fc7e970
  7. 06 Dec, 2013 2 commits
    • Jason Rhinelander's avatar
      Improved/expanded Position interface · e6c05957
      Jason Rhinelander authored
      Position's constructor can now take any sort of container, not just an
      initializer_list.
      
      Added Position(vector<double>&&) which takes over the vector rather than
      copying it.
      
      Moved Position(const size_t&) to static Position::zero(const size_t&) to
      avoid things like Position({3.0}) becoming ambiguous (either an
      initializer list or a downcast to size_t).
      
      Changed various loop ints to size_ts to avoid gcc warning
      
      Updated PositionalAgent for Position changes
      e6c05957
    • Jason Rhinelander's avatar
      Simplified template class for locking · 35f6bb90
      Jason Rhinelander authored
      35f6bb90
  8. 03 Dec, 2013 4 commits
  9. 25 Nov, 2013 2 commits
    • Jason Rhinelander's avatar
      Fixed accidentally undo of PA virtual methods · bd4775f7
      Jason Rhinelander authored
      Somehow I undid the PositionalAgent virtual method changes in the
      previous big commit.  This adds them back in.
      bd4775f7
    • Jason Rhinelander's avatar
      Eris interface overhaul · 7483175e
      Jason Rhinelander authored
      If eris had any releases yet, this would be a major version increment
      release.
      
      Optimization redesign
      =====================
      - Overhauled the way optimization works.  Now *any* member class can be
        an optimizer, and only implements the specific optimization methods
        that it wants, by inheriting from the appropriate interfaces in the
        new eris/Optimize.hpp header.
      - This means an Agent can have interopt code, intraopt code, or no
        optimization code in its class at all.
      - optimization methods are now prefixed with "inter" or "intra" since
        they are no longer contained with special optimization classes.  This
        also avoids a potential conflict between classes that want both intra
        and inter optimize() and/or apply() methods.
      - Goods and Markets can now have optimization code, too, by simplying
        inheriting from the appropriate interopt::* or intraopt::* interface
        class(es).
      - Got rid of InterOptimizer and IntraOptimizer base classes.
      - Eris now has optimizer lists for each type of optimization stage,
        determined when a Member (of any type) is added or removed; this
        speeds things up quite a bit, because we don't have to bother checking
        every InterOpt/IntraOpt/Agent member to call its RunStage method(s),
        especially since most of them are empty.
      - This also fixes the weird design of having Agent->advance(), but all
        the other interopt methods under InterOptimizer.
      - All interOpt and intraOpt-related methods are now gone.  A new set of
        "other" methods was added, so that non-agent/good/market objects, such
        as objects that only do optimization, can be added to the simulation.
      - Member is no longer abstract; while it was before a base class for the
        5 core types (Agent, Good, Market, InterOptimizer, IntraOptimizer),
        it's now a base for the first three, plus anything else; in
        particular, classes that are pure optimizers will now typically
        inherit from Member plus the optimization interfaces they need.
      - new insertOptimizers()/removeOptimizers() methods are called when
        adding or removing any sort of member; it figures out whether the
        member is castable to the various interopt::* and intraopt::* classes,
        and if so, records the member as an optimizer of the appropriate
        class.
      
      Threads changes
      ===============
      - Got rid of supporting different threading models; everything now works
        as the old Sequential model.  Preallocating had a very minimal
        performance benefit, at best, since the locking was replaced with an
        atomic queue index which works much faster.  The minimal performance
        increase (on the order of a couple percent in the voting simulation)
        isn't worth the code complication (needing to worry about per-thread
        queues, in particular).
      
      Interface changes
      =================
      - createAgent<A>(), createGood<G>(), etc. classes are gone now, replaced
        with a single create<T>() method.  This is a drop-in replacement for
        all of the above as it determines what the member category is by
        looking at T.
      - Likewise for clone*()
      - Likewise for remove*()
      - agentFilter, goodFilter, etc. are renamed to the much better choice
        agents(), goods(), etc., and now return a vector instead of the
        unordered_map.  This is nice: agents() is now a vector of all agents
        (agentFilter() already was that, but it wasn't obvious from the name),
        agents<Foo> is only Foo (and Foo-derived) agents, etc.
      - Member.writeLock() and .readLock() now take a variable number of
        SharedMember<T> arguments.  For example: foo->writeLock(other1,
        other2).  Previously you'd have to build a vector or list (or some
        other iterable object), add other1 and other2 to it, then call
        read/writeLock().
      - The versions of Member.writeLock() and .readLock() that took an
        iterable object of pairs (e.g. unordered_map) are now gone, since
        agents/goods/etc. now return vectors instead of the unordered_maps
        agentFilter/goodFilter/etc. used to return.
      
      Member changes
      ==============
      - WalrasianPricer is gone: its code is now in QMarket, which declares
        itself as the appropriate intraopt::* providers.  WalrasianPricer was
        so tightly tied to QMarket that it wasn't useful as an independent
        class anyway.
      - Agent is now a simpler class, *without* an assets Bundle.  The
        assets() Bundle is now provided by the eris::agent::AssetsAgent
        subclass instead.  This makes sense since the assets bundle was
        pointless for PositionalAgents, for example, which don't care about
        the assets clearing (and don't need the interopt::Advance optimizer
        just to clear assets).
      
      Other small changes
      ===================
      - SharedMember now has a < operator, so that SharedMembers can be added
        to ordered containers like std::set.
      - Discovered (and used) std::type_index for filter_cache_ keys instead
        of calling .hash_code() on the type_info object.
      - Simplified various bits of highly repetitive code with macros
      - Got rid of the unique_ptr<> hack from Simulation around agents_,
        goods_, etc.  It was needed because SharedMember<Agent> wasn't
        directly constructible, but that hasn't been true for a while.
      - Slightly optimized the thread signalling code to only signal the
        master from the last thread to finish the stage.
      - Moved RunStage from Simulation::RunStage to just RunStage in types.h
      7483175e
  10. 20 Nov, 2013 5 commits
  11. 19 Nov, 2013 2 commits
    • Jason Rhinelander's avatar
      New threading models · a355c35c
      Jason Rhinelander authored
      Reimplemented threading queuing with three new methods, controllable via
      simulation->threadModel(...)
      
      ThreadModel::Preallocate preallocates jobs across threads; threads then
      just do their own thing
      
      ThreadModel::Sequential does what we did before (each thread accesses
      the queue in parallel).  Changed this model to use an atomic_uint which
      is slightly faster than the previous big lock method, even though we are
      now back to copying eris_id_ts around
      
      ThreadModel::Hybrid calls new preallocate*() methods for each job (e.g.
      Agent::preallocateAdvance()): if they return true, the job gets put in
      one of the thread queues, otherwise it gets put in the shared queue.
      This should allow for a better mix when some jobs are slow and others
      are fast without the downside of prequeuing picking randomly suboptimal
      allocations.
      a355c35c
    • Jason Rhinelander's avatar
      Updated for new threading interface · 3a3fcea6
      Jason Rhinelander authored
      3a3fcea6
  12. 07 Nov, 2013 3 commits
    • Jason Rhinelander's avatar
      Merge remote-tracking branch 'origin/threaded' · 0a1a3c38
      Jason Rhinelander authored
      The threaded code now works and imposes only a miniscule performance
      penalty (especially when not activated, which is the default), so it's
      ready to come into the master branch.
      0a1a3c38
    • Jason Rhinelander's avatar
      Got rid of the run() argument · fd4b759b
      Jason Rhinelander authored
      This was added for code compatibility with the threaded branch, but the
      threaded branch no longer takes it (it got replaced with maxThreads(n)).
      fd4b759b
    • Jason Rhinelander's avatar
      Lock overhaul · 108049e1
      Jason Rhinelander authored
      Completely overhauled locking code: Member::ParallelLock is gone; there
      is just Member::Lock which handles any number (including 1) of parallel
      locks.  Also added lock manipulation (switching read <-> write, locking
      and releasing) to it.
      
      Thread running code is significant sped up by not using a queue, instead
      it just iterates through agents_/interopts_/intraopts_.
      
      Threading interface has changed: it's not set via
      simulation->maxThreads() instead of a run() argument.
      
      Threading can be avoided by setting maxThreads(0).  maxThreads(1) still
      uses threading (albeit with a single thread), and seems to imposes only
      a couple percent penalty (now that we aren't copying everything into a
      queue).
      108049e1