GithubHelp home page GithubHelp logo

nomad's People

Contributors

betanalpha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nomad's Issues

Manual Draft

Finish up a first draft of the manual,

  • Automatic Differentiation
  • Implementation
  • Using Nomad
  • Nomad Reference Guide

Should we have a separate development team or just go with the Stan development team for attribution?

Templated Function Signatures and Vectorization

One of the nice things about the new autodiff system is that it incorporates operands and partials directly, which will make implementing functions and implementing distributions identical.

An immediate feature is the ability to construct all possible function signatures like Stan does for the distributions. For example, a binary function taking in two autodiff vars would be written as

template <short autodiff_order>
inline var<autodiff_order> binary_function(const var<autodiff_order>& v1,
                                           const var<autodiff_order>& v2) {

  const short partials_order = 3;
  const unsigned int n_inputs = 2;

  next_inputs_delta = n_inputs;
  next_partials_delta =
    var_body<autodiff_order, partials_order>::n_partials(n_inputs);

  new var_body<autodiff_order, partials_order>(n_inputs);

  double x = v1.first_val();
  double y = v2.first_val();

  push_dual_numbers<autodiff_order>(binary_function(x, y));

  push_inputs(v1.dual_numbers());
  push_inputs(v2.dual_numbers());

  if (autodiff_order >= 1) {
    push_partials(df_dx);
    push_partials(df_dy);
  }
  if (autodiff_order >= 2) {
    push_partials(df2_dx2);
    push_partials(df2_dxdy);
    push_partials(df2_dy2);
  }
  if (autodiff_order >= 3) {
    push_partials(df3_dx3);
    push_partials(df3_dx2dy);
    push_partials(df3_dxdy2);
    push_partials(df3_dy3);
  }
  return var<autodiff_order>(next_body_idx_ - 1);
}

and we'd have to add separate implementations for the (double, var) and (var, double) signatures. But we should be able to template the arguments out and do something like

template <short autodiff_order>
inline var<autodiff_order> binary_function(const T1& v1,
                                           const T2& v2) {

  const short partials_order = 3;
  const unsigned int n_inputs = T1.is_var() + T2.is_var();

  next_inputs_delta = n_inputs;
  next_partials_delta =
    var_body<autodiff_order, partials_order>::n_partials(n_inputs);

  new var_body<autodiff_order, partials_order>(n_inputs);

  double x = v1.first_val();
  double y = v2.first_val();

  push_dual_numbers<autodiff_order>(binary_function(x, y));

  push_inputs(v1.dual_numbers());
  push_inputs(v2.dual_numbers());

  if (autodiff_order >= 1) {
    if (T1.is_var()) push_partials(df_dx);
    if (T2.is_var()) push_partials(df_dy);
  }
  if (autodiff_order >= 2) {
    if (T1.is_var()) push_partials(df2_dx2);
    if (T1.is_var() && T2.is_var()) push_partials(df2_dxdy);
    if (T2.is_var()) push_partials(df2_dy2);
  }
  if (autodiff_order >= 3) {
    if (T1.is_var()) push_partials(df3_dx3);
    if (T1.is_var() && T2.is_var()) push_partials(df3_dx2dy);
    if (T1.is_var() && T2.is_var()) push_partials(df3_dxdy2);
    if (T2.is_var()) push_partials(df3_dy3);
  }
  return var<autodiff_order>(next_body_idx_ - 1);
}

Of course we'd have to be careful regarding some optimizations (especially if we want to use specialized var_body implementations).

Vectorization should work the same way, too, if we had a n_vars method in a template array wrapper.

Thoughts?

Discontinuous Functions

What should we do with functions without proper derivatives? Stan includes them and ignores the discontinuities, but this does lead to unintended problems when people try to autodiff through them.

http://www.cplusplus.com/reference/cmath/

  • ceil
  • floor
  • fmod
  • trunc
  • round
  • lround
  • llround
  • rint
  • lrint
  • llrint
  • nearbyint
  • remainder
  • remquo
  • fdim
  • fmax
  • fmin
  • fabs
  • abs
  • operator_equal_to
  • operator_greater_than_or_equal_to
  • operator_greater_than
  • operator_less_than_or_equal_to
  • operator_less_than
  • operator_not_equal_to
  • operator_unary_not

How To Test Equals Operators?

Comparison operators are very bad for autodiff because they admit the construction of discontinuous functions. Equals operators are particularly bad because they can't even be tested with finite differences, as the perturbations cause the comparison to fail. Not sure how these operators would be tested.

  • src/scalar/operators/nonsmooth_operators/operator_equal_to
  • src/scalar/operators/nonsmooth_operators/operator_not_equal_to
  • src/scalar/operators/nonsmooth_operators/operator_unary_not

Implement Eigen Operations

Right now we have an efficient matrix multiplication operation that admits expression template arguments but it only works for functions and not for operator overloading. Investigate this issue and see if we can have proper operator overloading.

Implement Remaining Operators

  • operator_multiplication_assignment
  • operator_multiplication
  • operator_subtraction_assignment
  • operator_subtraction
  • operator_unary_decrement
  • operator_unary_increment
  • operator_unary_plus

Domain Errors

What should we do with domain errors? The easiest solution would be to use std::nan() for the values and gradients, but then errors could not be traced back to their source. Alternatively, we can throw domain exceptions and be careful about wrapping the autodiff methods in try/catch blocks.

Functions with constrained domain:

  • src/scalar/functions/smooth_functions/acos.hpp
  • src/scalar/functions/smooth_functions/acosh.hpp
  • src/scalar/functions/smooth_functions/asin.hpp
  • src/scalar/functions/smooth_functions/atahn.hpp
  • src/scalar/functions/smooth_functions/inv_sqrt.hpp
  • src/scalar/functions/smooth_functions/log_diff_exp.hpp
  • src/scalar/functions/smooth_functions/log.hpp
  • src/scalar/functions/smooth_functions/log1p.hpp
  • src/scalar/functions/smooth_functions/log2.hpp
  • src/scalar/functions/smooth_functions/log10.hpp
  • src/scalar/functions/smooth_functions/multiply_log.hpp
  • src/scalar/functions/smooth_functions/pow.hpp
  • src/scalar/functions/smooth_functions/sqrt.hpp

To Do:

  • Select and implement error strategy.
  • Domain tests following finite difference functor pattern.

Implement Polygamma

Need the polygamma function in order to compute derivatives of the gamma function and its derivatives. Should be able to produce a reasonable implementation by leveraging the generic recursion relation to transform the domain to (0, 1) and expand the polygamma around 0. Bonus points for going the other way and using the asymptotic expansion for large arguments.

With a polygamma implementation we can then implement the last cmath functions,
http://www.cplusplus.com/reference/cmath/

  • tgamma
  • lgamma

Implement Special Functions

Miscellaneous special functions that have been implemented in Stan, some requiring the Boost libraries and some requiring the polygamma functions #3.

  • bessel_first_kind
  • bessel_second_king
  • falling_factorial
  • gamma_p
  • gamma_q
  • ibeta
  • lgamma
  • lmgamma
  • log1m_exp
  • log1m
  • modified_bessel_first_kind
  • modified_bessel_second_kind
  • owens_t
  • rising_factorial

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.