1. 24 Nov, 2017 1 commit
    • Jason Rhinelander's avatar
      New right/tolerance argument syntax; remove domain_t deduction · 6a75e5f5
      Jason Rhinelander authored
      This changes the `right` and `tolerance` argument into more complex
      objects that allow both a literal, or special objects returned by
      `search_right()`, `absolute_tolerance(.001)`, or
      This allows the much more descriptive syntax:
          constrained_maximum_search(f, 0, search_right(), relative_tolerance(.001))
      This also reintroduces the ability to specify an absolute tolerance
      level, which was there once (as a separate argument) but got lost along
      the way.
      This commit also changes the `domain_t` argument to be no longer
      deduced.  Previously it was deduced from `left`, which would have made
      the above example rather broken: `domain_t` would have been `int` (from
      the 0) rather than `double` (which would require 0.0).  Overriding
      `domain_t` now requires an explicitly template parameter:
          constrained_maximum_search<float>(f, 0, search_right(), relative_tolerance(.001))
  2. 13 Nov, 2017 1 commit
    • Jason Rhinelander's avatar
      constrained_maximum_search fixes · 642f7423
      Jason Rhinelander authored
      - Specifying NaN for automatic `right` selection resulted in an infinite
        loop when `left` was 0.  Changed to start searching at 1.0 when that
      - The `constrained_minimum_search` didn't implement automatic `right`
        selection; fixed.
      - Minor tweaks to calculation to avoid promotion to double; the main
        change was introducing a `half()` function to handle division by 2
        without resorting to actual division for floating points while still
        working for non-floating point domain types.
      - Fixed a typo in the static_assert for a `bool` return type in
  3. 31 Oct, 2017 2 commits
    • Jason Rhinelander's avatar
      single_peak_search - better argument type handling · 779a7ae2
      Jason Rhinelander authored
      The previous change to single_peak_search which deduced the domain type
      from the arguments was pretty undesirable: if you specified both left
      and right as integers, you'd get a search over the integer domain.
      This removes the type deduction, instead using an optional template
      parameter which defaults to double and isn't deduced, thus allowing
      custom types to be used, but falling back to double if not specified.
      This also fixes the test code to remove the tests that specified both
      relative and absolute tolerances (the latter was removed).
    • Jason Rhinelander's avatar
      De-prefix eris_id_t and eris_time_t · 4d881c7e
      Jason Rhinelander authored
      This lets external code use `eris::id_t` and `eris::time_t` which is
      far nicer than `eris::eris_id_t`.
      The existing `eris_id_t` and `eris_time_t` are kept as deprecated
      aliases for the new ones.
  4. 21 Aug, 2017 1 commit
    • Jason Rhinelander's avatar
      Allow `constrained_maximum_search` to find `right` · 83b09164
      Jason Rhinelander authored
      This adds support for automatically finding `right` based on `left`: if
      `right` is given as NaN, a search starts at `2*left` (if `left`
      positive) or `-left` (if `left` negative) and continuously doubles the
      potential `right` value until a constraint-violating value is found;
      this then forms the RHS limit.
  5. 06 Aug, 2017 2 commits
    • Jason Rhinelander's avatar
      algorithms: add a constrained_{max,min}imum_search · 33e11b3a
      Jason Rhinelander authored
      This lets you numerically find the largest or smallest value satisfying
      some condition.
      For example, to determine the highest price that has at least `x` sales:
          auto quantity_demanded = [](double p) { return (int)(99 - 2*p); };
          int x = 10;
          double min = 0.0, max = 100.0;
          auto r = eris::constrained_maximum_search(
              [&](double p) { return quantity_demanded(p) >= x; },
              min, max, 0 /* maximum precision */);
          std::cout << std::setprecision(16) << "p = " << r.arg << "\n";
          // p = 44.5
      With less precision for `tol_rel` (e.g. the default, 1e-10) you'll
      generally get some number slightly smaller than 44.5.
    • Jason Rhinelander's avatar
      Make single_peak_search templated; remove abs_tol · 2bf6d8d3
      Jason Rhinelander authored
      This makes single_peak_search templated (so that it doesn't have to be
      implemented with double).  It also updates the return type struct with
      templated types, a constructor, and an iterator counter.
  6. 23 May, 2017 1 commit
    • Jason Rhinelander's avatar
      C++14 simplifications · 4badfac1
      Jason Rhinelander authored
      Replace `typename std::enable_if<...>::type` with
      Replace various `typename = enable_if_t<...>` with `enable_if_t<..., int> = 0`
      which allows for better overloading.
  7. 04 Oct, 2016 1 commit
    • Jason Rhinelander's avatar
      single_peak_search: return struct · f3ccc293
      Jason Rhinelander authored
      Returning just the argmax is sort of inconvenient when the max is always
      wanted: this returns a struct that has both .max and .arg elements.  It
      should retain backwards compatibility in most cases by making the struct
      implicitly convertible to a double, yielding the `.arg` value, the same
      as before.
  8. 17 Sep, 2016 1 commit
    • Jason Rhinelander's avatar
      Added eris/utils.hpp · 12677ad6
      Jason Rhinelander authored
      This class is for programming utility functions, as opposed to
      algorithm which is for C++ implementations of various algorithms.
      It contains a new C++14-compatible index_sequence; it also takes the
      range() function from algorithms.hpp, since it's really about C++
      programming, not an algorithm.
  9. 03 Nov, 2015 2 commits
    • Jason Rhinelander's avatar
      Merge src/eris, include/eris -> eris/ · 020cee1d
      Jason Rhinelander authored
      The src/include split is more of a nuissance than anything helpful:
      this commit gets rid of it, moving everything into "eris" in the
      top-level directory.
    • Jason Rhinelander's avatar
      Remove hack needed for g++-4.8 · 90ade58b
      Jason Rhinelander authored
      g++-4.8 isn't supported now by the code (except via patches for
      ubuntu-trusty), so removing this other hack that was been around for
      g++-4.8 to give all_combinations a much nicer interface.
  10. 26 Aug, 2015 1 commit
    • Jason Rhinelander's avatar
      Applied include-what-you-use updates · 58b4711b
      Jason Rhinelander authored
      This also adds eris.imp to handle implicit imports and various compiler
      fixups for libstdc++, boost, and Eigen, and to avoid needing to include
      <eris/types.hpp> everywhere, for example.
  11. 23 Jul, 2015 1 commit
  12. 12 Jan, 2015 1 commit
  13. 09 May, 2014 1 commit
    • Jason Rhinelander's avatar
      Improvements to single_peak_search · 8551a20a
      Jason Rhinelander authored
      - Added tol_abs parameter which defaults to 1e-20.
      - renamed existing tolerance parameter to tol_rel
      - Unrolled the recursion into a loop
      - Added check and fix for midleft > midright, which can happen when the
        optimum is close to 0.
      - Added check for numerical precision limit: if the calculated midpoint
        is not distinguishable from the endpoint, we're as good as it's going
        to get.  (This, combined with the previous problem, could cause an
        infinite loop for an optimum at 0).
  14. 01 May, 2014 1 commit
  15. 29 Apr, 2014 1 commit
    • Jason Rhinelander's avatar
      Added single_peak_search code in eris/algorithms · 7aa8b705
      Jason Rhinelander authored
      This uses a golden ratio section search to efficiently search a domain
      for a function max.  Obviously it only works when the function is
      single-peaked and has no perfectly-flat sections.
      This also includes a test script.
  16. 04 Apr, 2014 1 commit
  17. 20 Feb, 2014 1 commit
    • Jason Rhinelander's avatar
      QMarket optimization overhaul; Stepper oscillation · 51816949
      Jason Rhinelander authored
      - pricing retries now has a "first" tries and a regular retries.  The
        first one typically needs more iterations because the initial value
        is arbitrary, while later ones have a decent first guess in the
        previous period's value.
      - Removed obsolete 'optimizer' variable (made obsolete when
        optimization moved into QMarket itself in the eris optimizer design
      - The Stepper used for adjusting the price is now public, so that its
        properties can be changed by the QMarket creator.
      - The default Stepper now has a minimum step size of 1/65536.  The
        previous minimum of machine epsilon was rediculously small (and
        required a lot of steps to get away from).
      - Stepper now has a variable for checking whether the steps are
        oscillating back and forth at the minimum step size.
      - QMarket uses oscillation detecting to detect that the price is close
        enough to the optimum and thus more price adjustments aren't needed.
      - Various previously-const public attributes of Stepper are now
        non-const so that Stepper users can change the Stepper behaviour.
        This makes Stepper-using classes (like QMarket) easier: they can just
        expose the Stepper instead of needing to pass through a bunch of
        construction-time Stepper parameters.
  18. 31 Jan, 2014 1 commit
    • 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.
  19. 23 Aug, 2013 1 commit
    • Jason Rhinelander's avatar
      Fixed for gcc compilation · e8a1a550
      Jason Rhinelander authored
      gcc doesn't seem to like my class member struct arguments being out of
      order, so fixed that.
      The bigger problem is the hack (adding what should be an unneeded
      template type) to all_combinations, because gcc doesn't seem to be
      handling typename It::value_type properly.
  20. 20 Aug, 2013 1 commit
    • Jason Rhinelander's avatar
      Stepper: add absolute steps · 7c9beb0b
      Jason Rhinelander authored
      Using Stepper for positioning won't work with relative steps, since
      there is no reason a step should be smaller for current positions closer
      to 0.  Added a parameter (defaulting to the relative) so that steps can
      instead be absolute values.
  21. 25 Jul, 2013 1 commit
  22. 19 Jul, 2013 2 commits
  23. 19 Jun, 2013 1 commit
    • Jason Rhinelander's avatar
      algorithms.hpp: range(pair) for range iteration · 6d266d3e
      Jason Rhinelander authored
      C++11 doesn't allow: for (auto v : multimap.equal_range(key)) { ... }
      because equal_range gives back a pair, which isn't iterable.  Added a
      wrapper class and eris::range() function that wraps this pair into an
      iterable class, so that I can at least do:
          for (auto v : eris::range(multimap.equal_range(key))) { ... }
      This appears to be something that was supported in early C++11 drafts,
      but removed
      without the suggested solution of having equal_range returning something
      iterable actually being implemented.
  24. 31 May, 2013 1 commit