Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/issue 123 complex numbers with vars #789

Closed
wants to merge 141 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
788edbc
Failing test for issue 123
Mar 6, 2018
0695ca1
Updated test to use AVAR macro
Mar 6, 2018
a271bdc
Complex numbers rough first attempt
Mar 7, 2018
41f9d0b
Fixed accidental reversal of tests
Mar 7, 2018
ed33827
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Mar 7, 2018
e65748b
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Mar 7, 2018
ab66802
Changed restriction on stan::math::internal::complex converting ctor …
Mar 8, 2018
6fd81ba
[Jenkins] auto-formatting by clang-format version 5.0.1-svn319952-1~e…
stan-buildbot Mar 8, 2018
99bd2f0
Added std::complex<fvar<T>>
Mar 9, 2018
523cbe1
Changes to enable computation with Eigen
Mar 22, 2018
4a15c4c
Adding complex double times var
Mar 27, 2018
accf844
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Mar 27, 2018
941595d
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Mar 30, 2018
a978a08
fixes for fullPivLu() test case
Apr 13, 2018
67f0b73
switched to output std::complex, added hessian test, added static ass…
ChrisChiasson May 19, 2018
59df90d
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 19, 2018
9ed85e6
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 19, 2018
9fd648d
removed inline from type trait value convenience booleans
ChrisChiasson May 21, 2018
51e9381
tried to address cpplint issues
ChrisChiasson May 21, 2018
eb7a775
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 21, 2018
6616c0a
removed dead code and obviated comments
ChrisChiasson May 21, 2018
c6cca98
changed forward declaration keyword for complex to match struct decla…
ChrisChiasson May 22, 2018
ea3a2b8
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 22, 2018
73bdbda
Trying to change the number of template parameters specified by stan'…
ChrisChiasson May 22, 2018
09cf3c9
remove leftover diff output from merge
ChrisChiasson May 22, 2018
5fb41d0
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 22, 2018
3ef68c5
removed compatibility attempt, added include
ChrisChiasson May 22, 2018
f86a6a5
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 22, 2018
9cbdc14
removed constexpr from _v template using declarations due to old GCC …
ChrisChiasson May 23, 2018
59fbd80
reintroduced equality and inequality
ChrisChiasson May 23, 2018
cbc12fd
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot May 23, 2018
5778b3d
moved enable_if into function parameter list... not sure why this fix…
ChrisChiasson May 24, 2018
1805f7f
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 24, 2018
2bd02fe
removed value template variables because gcc 4.9 doesn't support them…
ChrisChiasson May 25, 2018
83adf5a
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 25, 2018
d371f2d
override clang's complex division, and modify fvar enable_if ctor to …
ChrisChiasson May 27, 2018
dc1870f
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 27, 2018
b433c27
cpplint
ChrisChiasson May 27, 2018
ebf8ac1
doxygen complaint, headers complaint
ChrisChiasson May 27, 2018
da6876f
duplicate symbol complaint
ChrisChiasson May 27, 2018
27a45b7
trying to put code in a state where others can help
ChrisChiasson May 29, 2018
98087fb
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 29, 2018
23b454f
switched back to clang 5 and ported my tests backs to regular cpp files
ChrisChiasson May 31, 2018
dbd4faa
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot May 31, 2018
99081b8
trying to use full (explicit) function template specialization to ove…
ChrisChiasson Jun 3, 2018
b6419ee
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 3, 2018
9a9d404
variable ctor restrictions
ChrisChiasson Jun 4, 2018
e78930e
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot Jun 4, 2018
c8121ba
moved some operators and classes to their own namespace and tightened…
ChrisChiasson Jun 5, 2018
c6bffc7
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Jun 5, 2018
8239d09
cpplint, stronger types for division override
ChrisChiasson Jun 5, 2018
fe010fd
thought I removed these static_asserts earlier
ChrisChiasson Jun 6, 2018
ca32ef3
may have found a method that actually allows the overload... plus mor…
ChrisChiasson Jun 6, 2018
62dd118
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Jun 6, 2018
73d2074
reduce derivative operations in denominator & make it squared
ChrisChiasson Jun 6, 2018
fa8d852
Initial attempt to make complex fit stan's structure and pull in upda…
ChrisChiasson Jun 15, 2018
68cf52e
Properly hooked into the new non-deducible template argument only ver…
ChrisChiasson Jun 18, 2018
00a1bfa
val enable_if_t to make two ambiguous cases exclusive; is_arith_like …
ChrisChiasson Jun 19, 2018
ab0ad61
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 19, 2018
85c2d42
trying to get val recursion scheme correct
ChrisChiasson Jun 19, 2018
d7df296
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Jun 19, 2018
efb2721
fixup tests
ChrisChiasson Jun 19, 2018
99035c1
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 19, 2018
4ca9f02
trying to fix doxygen complaint
ChrisChiasson Jun 20, 2018
72dbc12
made test use double
ChrisChiasson Jun 20, 2018
f7baf67
bring std::sqrt into scope
ChrisChiasson Jun 20, 2018
f68d54f
bringing std::sqrt into scope
ChrisChiasson Jun 20, 2018
6ea194d
hopefully making this a regular comment will make doxygen happy
ChrisChiasson Jun 20, 2018
c3be260
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 20, 2018
b7c4600
go home Doxygen, you're drunk
ChrisChiasson Jun 20, 2018
35675ef
rm_zeroing doxygen, probably unrelated to Jenkins doxygen error in ot…
ChrisChiasson Jun 20, 2018
30e243a
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 20, 2018
9dc41a9
using a different doxygen ignore command; it is possible stan doesn't…
ChrisChiasson Jun 20, 2018
13e30a2
opened up copysign template some more
ChrisChiasson Jun 24, 2018
1d6c004
added GPU checks
rok-cesnovar Jun 4, 2018
fde62be
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 5, 2018
519ede2
Fix docs
SteveBronder Jun 5, 2018
023a700
update docs
SteveBronder Jun 5, 2018
f3bd995
Adds <code>matrix_gpu<\code> to the docs and moved around the flags a…
SteveBronder Jun 5, 2018
26f4558
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 5, 2018
31b9347
remove 0 by 0 being accepted info from docs
SteveBronder Jun 6, 2018
42b1912
cpplint error
SteveBronder Jun 6, 2018
1a98267
added quotation to BOOST_LIB_ABS
rok-cesnovar Jun 8, 2018
5cfefd9
split gpu checks in to separate files, fixed the header guards, added…
rok-cesnovar Jun 19, 2018
acaf423
change kernel names to is_*
rok-cesnovar Jun 19, 2018
e7150d4
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 19, 2018
90d9965
add exp() test
bgoodri Jun 22, 2018
8277554
add abs() test
bgoodri Jun 22, 2018
15240fc
add arg() test
bgoodri Jun 22, 2018
768c843
add a bunch of tests
bgoodri Jun 22, 2018
35e439a
fix acosh_test.cpp
bgoodri Jun 25, 2018
ba17f31
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 25, 2018
cc4e47e
trying to improve complex subfunctions and bring in more flexibility …
ChrisChiasson Jun 26, 2018
3cd4345
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Jun 26, 2018
f3e098b
forgot to add new files to scal.hpp
ChrisChiasson Jun 26, 2018
4d1f473
trying to find a definition of pow that will work on libc++
ChrisChiasson Jun 26, 2018
258ae51
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot Jun 26, 2018
fe12a30
add pseudo_eigendecomposition_test.cpp
bgoodri Jun 27, 2018
67b0dc2
fix frechet_lccdf test
ChrisChiasson Jun 27, 2018
5094cc2
trying to fix polar and pow... not having a very good time
ChrisChiasson Jun 27, 2018
dc5f2c2
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot Jun 27, 2018
36a58ab
use std::pow in frechet_lpdf
bgoodri Jun 28, 2018
0908396
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot Jun 28, 2018
57c6d9b
use std::pow in frechet_lcdf
bgoodri Jun 28, 2018
3384667
use std::pow in frechet_cdf
bgoodri Jun 28, 2018
1370b5f
use std::pow in weibull_lpdf
bgoodri Jun 28, 2018
912d8b3
use std::pow in weibull_cdf
bgoodri Jun 28, 2018
e82360f
use std::pow in weibull_lcdf
bgoodri Jun 28, 2018
52805bc
use std::pow in weibull_lccdf
bgoodri Jun 28, 2018
1317c09
use std::pow in pareto_type_2_cdf
bgoodri Jun 28, 2018
be5b3c0
use std::pow in pareto_type_2_lcdf
bgoodri Jun 28, 2018
7ac48a5
also test imaginary parts are zero
bgoodri Jun 28, 2018
e69fa68
remove old var ctors taking complex, and remove the complex header, w…
ChrisChiasson Jun 29, 2018
ee59e70
added more description to zeroing, and removed single level upcast th…
ChrisChiasson Jun 29, 2018
e2d1162
removed the tests added in PR #643 regarding var(std::complex<T>&) us…
ChrisChiasson Jun 29, 2018
dfc52ff
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jun 29, 2018
f5ac5f5
removing test that invokes gcc 4.9's complex bug
ChrisChiasson Jul 3, 2018
8c9c261
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot Jul 3, 2018
eb70e6d
Disable complex exp test on gcc < 5 due to compiler bug. See comments…
ChrisChiasson Jul 3, 2018
aea814d
fix pow() and exp() on g++-4.9
bgoodri Jul 3, 2018
319bf6d
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jul 3, 2018
814c8f4
fix doxygen error
bgoodri Jul 4, 2018
c24546a
attempt at abs overloads
ChrisChiasson Jul 5, 2018
7aa5315
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Jul 6, 2018
09f9019
fix return type on abs functions (whoops)
Jul 9, 2018
ee002ff
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Jul 9, 2018
5322bfa
changes to instantiation -- honestly forgot it *wasn't* being done th…
ChrisChiasson Jul 11, 2018
ab9278d
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jul 12, 2018
5fd2b1c
attempt at fixing proj on gcc
Jul 12, 2018
c6415b6
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jul 12, 2018
ca6c740
attempt to feed pow the right type in operator_division
Jul 12, 2018
4d88872
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tag…
stan-buildbot Jul 12, 2018
cfc82ad
trying a different approach for operator division... I think I attemp…
Jul 12, 2018
f4de40a
[Jenkins] auto-formatting by clang-format version 5.0.1 (tags/RELEASE…
stan-buildbot Jul 12, 2018
56797be
just a hunch about the mac push back issue
ChrisChiasson Jul 13, 2018
e65c975
undoing change to fvar on previous commit -- which is not technically…
Jul 13, 2018
0f10cea
the special tightly scoped abs(complex) overloads to get around buggy…
ChrisChiasson Jul 25, 2018
152ec31
in rev/core.hpp, std_numeric_limits appears after std_is_inf, but wit…
ChrisChiasson Jul 25, 2018
12a09bf
increase tolerance per discussion in PR #789 about this test
ChrisChiasson Jul 26, 2018
7f3d34c
increase tolerance because of test failure, similar to the pseudo eig…
ChrisChiasson Jul 26, 2018
07ffd6c
add using std::pow to normal_sufficient_lpdf.hpp
ChrisChiasson Jul 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions make/libraries
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ $(BOOST_LIB)/mpi.so: $(BOOST)/user-config.jam
$(BOOST_LIB)/libboost_serialization.so: $(BOOST_LIB)/mpi.so

$(BOOST_LIB)/libboost_serialization.dylib: $(BOOST_LIB)/mpi.so
install_name_tool -add_rpath "$(BOOST_LIB_ABS)" "$(BOOST_LIB)/libboost_serialization.dylib"
install_name_tool -id @rpath/libboost_serialization.dylib "$(BOOST_LIB)/libboost_serialization.dylib"
install_name_tool -add_rpath "$(BOOST_LIB_ABS)" $(BOOST_LIB)/libboost_serialization.dylib
install_name_tool -id @rpath/libboost_serialization.dylib $(BOOST_LIB)/libboost_serialization.dylib

$(BOOST_LIB)/libboost_mpi.so: $(BOOST_LIB)/mpi.so

Expand Down
11 changes: 4 additions & 7 deletions stan/math/fwd/core/fvar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include <stan/math/prim/scal/meta/likely.hpp>
#include <stan/math/prim/scal/fun/is_nan.hpp>
#include <stan/math/fwd/scal/meta/ad_promotable.hpp>
#include <boost/utility/enable_if.hpp>
#include <ostream>
#include <type_traits>

namespace stan {
namespace math {
Expand Down Expand Up @@ -97,13 +97,10 @@ struct fvar {
* @tparam V type of value (must be assignable to the value and
* tangent type T)
* @param[in] v value
* @param[in] dummy value given by default with enable-if
* metaprogramming
*/
template <typename V>
fvar(const V& v,
typename boost::enable_if_c<ad_promotable<V, T>::value>::type* dummy = 0)
: val_(v), d_(0.0) {
template <typename V,
typename std::enable_if_t<ad_promotable<V, T>::value>* = nullptr>
fvar(const V& v) : val_(v), d_(0.0) { // NOLINT(runtime/explicit)
if (unlikely(is_nan(v)))
d_ = v;
}
Expand Down
1 change: 1 addition & 0 deletions stan/math/fwd/core/operator_division.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ inline fvar<T> operator/(double x1, const fvar<T>& x2) {
// TODO(carpenter): store x1 / x2.val_ and reuse
return fvar<T>(x1 / x2.val_, -x1 * x2.d_ / (x2.val_ * x2.val_));
}

} // namespace math
} // namespace stan
#endif
7 changes: 7 additions & 0 deletions stan/math/fwd/cplx.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef STAN_MATH_FWD_CPLX_HPP
#define STAN_MATH_FWD_CPLX_HPP

#include <stan/math/fwd/cplx/fvar.hpp>
#include <stan/math/fwd/cplx/operator_division.hpp>

#endif
21 changes: 21 additions & 0 deletions stan/math/fwd/cplx/fvar.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef STAN_MATH_FWD_CPLX_FVAR_HPP
#define STAN_MATH_FWD_CPLX_FVAR_HPP

#include <stan/math/fwd/scal/meta/ad_promotable.hpp>
#include <stan/math/fwd/scal/meta/is_fvar.hpp>
#include <stan/math/fwd/core/fvar.hpp>
#include <stan/math/prim/cplx/complex.hpp>

namespace std {

/**
* std::complex<fvar> inherits from stan::math::complex. Details
* are provided there.
*/
template <class T>
struct complex<stan::math::fvar<T>> : stan::math::complex<stan::math::fvar<T>> {
using stan::math::complex<stan::math::fvar<T>>::complex;
};

} // namespace std
#endif
29 changes: 29 additions & 0 deletions stan/math/fwd/cplx/operator_division.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef STAN_MATH_FWD_CPLX_OPERATOR_DIVISION_HPP
#define STAN_MATH_FWD_CPLX_OPERATOR_DIVISION_HPP

#include <stan/math/fwd/cplx/fvar.hpp>
#include <stan/math/fwd/scal/fun/pow.hpp>
#include <stan/math/prim/cplx/operator_division.hpp>

namespace stan {
namespace math {

/**
* Return the result of dividing the first argument by the second.
* This overload exists because libc++ uses logb and scalbn for
* complex division, which aren't defined for fvars.
*
* @tparam T type of complex fvar value and tangent
* @param t first argument
* @param u second argument
* @return first argument divided by second argument
*/
template <class T>
inline std::complex<fvar<T>> operator/(std::complex<fvar<T>> const& t,
std::complex<fvar<T>> const& u) {
return stan::math::operator_division(t, u); // no recursion
}

} // namespace math
} // namespace stan
#endif
2 changes: 1 addition & 1 deletion stan/math/fwd/mat/vectorize/apply_scalar_unary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace math {
* autodiff variable.
*/
template <typename F, typename T>
struct apply_scalar_unary<F, fvar<T> > {
struct apply_scalar_unary<F, fvar<T>> {
/**
* Function return type, which is same as the argument type for
* the function, <code>fvar&lt;T&gt;</code>.
Expand Down
3 changes: 3 additions & 0 deletions stan/math/fwd/scal.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef STAN_MATH_FWD_SCAL_HPP
#define STAN_MATH_FWD_SCAL_HPP

#include <stan/math/fwd/cplx.hpp>

#include <stan/math/fwd/core.hpp>
#include <stan/math/fwd/scal/meta/ad_promotable.hpp>
#include <stan/math/fwd/scal/meta/is_fvar.hpp>
Expand Down Expand Up @@ -79,6 +81,7 @@
#include <stan/math/fwd/scal/fun/Phi_approx.hpp>
#include <stan/math/fwd/scal/fun/pow.hpp>
#include <stan/math/fwd/scal/fun/primitive_value.hpp>
#include <stan/math/fwd/scal/fun/proj.hpp>
#include <stan/math/fwd/scal/fun/rising_factorial.hpp>
#include <stan/math/fwd/scal/fun/round.hpp>
#include <stan/math/fwd/scal/fun/sin.hpp>
Expand Down
10 changes: 10 additions & 0 deletions stan/math/fwd/scal/fun/abs.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#ifndef STAN_MATH_FWD_SCAL_FUN_ABS_HPP
#define STAN_MATH_FWD_SCAL_FUN_ABS_HPP

#include <stan/math/fwd/cplx.hpp>
#include <stan/math/fwd/core.hpp>
#include <stan/math/fwd/scal/fun/hypot.hpp>
#include <stan/math/fwd/scal/fun/value_of.hpp>
#include <stan/math/prim/scal/fun/constants.hpp>
#include <stan/math/prim/scal/fun/abs.hpp>
Expand All @@ -25,4 +27,12 @@ inline fvar<T> abs(const fvar<T>& x) {

} // namespace math
} // namespace stan

namespace std {
// constrained complex overload to forward zeroing fvar to std::abs
template <class T>
inline stan::math::fvar<T> abs(std::complex<stan::math::fvar<T>> const& t) {
return abs(std::complex<stan::math::zeroing<stan::math::fvar<T>>>(t));
}
} // namespace std
#endif
6 changes: 6 additions & 0 deletions stan/math/fwd/scal/fun/is_inf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ inline int is_inf(const fvar<T>& x) {
return is_inf(x.val());
}

// forwarding for ADL
template <class T>
inline auto isinf(const fvar<T>& a) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of questions:

  1. why is this function here? (this is isinf and not is_inf)
  2. why is it declared and defined multiple times? (in other files too)
  3. why is isinf in the stan::math namespace? I'm guessing you need it in the std namespace?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see how we've handled it elsewhere. Is there a reason we can't do the same here? By that, I mean specialize isnan and isinf for stan::math::fvar<T> and include it in its own header file called stan/math/fwd/core/std_isnan.hpp and std_isinf?
See:
stan/math/fwd/core/std_numeric_limits.hpp
stan/math/rev/core/std_isnan.hpp
stan/math/rev/core/std_numeric_limits.hpp
stan/math/rev/core/std_isinf.hpp

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify? What other packages? I didn't see anywhere in this pull request that this is meant to work with other packages.

(I just found a stackoverflow post on isnan outside of any namespace; is this something you've run into or is this hypothetical?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're way past that; std::complex for our types are unspecified. We should do what we can verify is correct, is maintainable, and makes sense.

return is_inf(a);
}

} // namespace math
} // namespace stan
#endif
6 changes: 6 additions & 0 deletions stan/math/fwd/scal/fun/is_nan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ inline int is_nan(const fvar<T>& x) {
return is_nan(x.val());
}

// forwarding for ADL
template <class T>
inline auto isnan(const fvar<T>& a) {
return is_nan(a);
}

} // namespace math
} // namespace stan
#endif
28 changes: 28 additions & 0 deletions stan/math/fwd/scal/fun/proj.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef STAN_MATH_FWD_SCAL_FUN_PROJ_HPP
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just following our (not very good) convention, can you rename this file std_proj.hpp?

#define STAN_MATH_FWD_SCAL_FUN_PROJ_HPP

#include <stan/math/fwd/cplx.hpp>
#include <stan/math/fwd/scal/fun/is_inf.hpp>
#include <stan/math/prim/scal/fun/proj.hpp>

namespace std {

/**
* Return a projection of a complex number onto
* the Riemann sphere.
*
* This overloads an erroneous definition in
* libstdc++ for general types.
*
* @tparam T auto diff variable type
* @param[in] t Variable input.
* @return projection onto Riemann sphere
*/
template <class T>
inline std::complex<stan::math::fvar<T>> proj(
std::complex<stan::math::fvar<T>> const& t) {
return stan::math::proj(t);
}

} // namespace std
#endif
11 changes: 11 additions & 0 deletions stan/math/prim/cplx.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef STAN_MATH_PRIM_CPLX_HPP
#define STAN_MATH_PRIM_CPLX_HPP

#include <stan/math/prim/cplx/complex.hpp>
#include <stan/math/prim/cplx/operator_addition.hpp>
#include <stan/math/prim/cplx/operator_division.hpp>
#include <stan/math/prim/cplx/operator_multiplication.hpp>
#include <stan/math/prim/cplx/operator_subtraction.hpp>
#include <stan/math/prim/cplx/zeroing.hpp>

#endif
57 changes: 57 additions & 0 deletions stan/math/prim/cplx/complex.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef STAN_MATH_PRIM_CPLX_COMPLEX_HPP
#define STAN_MATH_PRIM_CPLX_COMPLEX_HPP

#include <stan/math/prim/cplx/zeroing.hpp>
#include <complex>

namespace stan {
namespace math {

/**
* Complex class that forwards the interface of std::complex, brining
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is meant here? I still don't understand what "forwards" means in the way it's used here.

* stan::math's namespace into ADL for functions called on data types
* that inherit from this class, as well as allowing template
* specializations of std::complex to indirectly work with different
* underlying data types. For example, std::complex<var> specializes
* the std::complex<T> template to inherit from
* stan::math::complex<T>, which in turn inherits from
* std::complex<zeroing<T>>. This causes stan::math to be pulled into
* ADL on operations involving std::complex<var>, to handle, e.g.
* division operations that the base std::complex doesn't have
* defined usably for var, and, since stan::math::zeroing<var> zero
* initializes itself, will also correctly work with the remaining
* algorithms in std::complex<T> that require the expression T() to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification? The algorithms expect T() to initialize a variable to 0?

* be 0.
*/
template <class T>
struct complex : std::complex<zeroing<T>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the motivation for having stan::math::complex<T>? Shouldn't we just be using std::complex<T>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we did that, we would create an inheritance loop. The way we force things to work is by making a template specialization for std::complex<var> inherit from stan::math::complex<var>, which in turn inherits from std::complex<zeroing<var>>. We wouldn't be able to do this if the starting and ending classes were the same.

using std::complex<zeroing<T>>::complex;
// NOLINTNEXTLINE(runtime/explicit)
complex(const std::complex<zeroing<T>>& t)
: std::complex<zeroing<T>>(t) {} ///< allow promotion
/**
* Without this converting ctor, copy initialization of
* std::complex<zeroing<(f)var>>> from an (f)var fails, because the
* default implementation in the std::complex template requires the
* argument type to match the template type. This is the same reason
* why std::complex<double> can't be multiplied by an int.
*
* tparam R type of real argument. Won't fire on non-arithmetic types.
* tparam I type of imaginary argument.
* param[in] real, the pure real component of the complex number.
* param[in] imag, the pure imaginary component of the complex number
*/
template <class R = double, class I = R,
std::enable_if_t<is_arith_like<R>::value>* = nullptr>
// NOLINTNEXTLINE(runtime/explicit)
complex(R const& real = 0, I const& imag = 0)
: std::complex<zeroing<T>>(zeroing<T>(real), zeroing<T>(imag)) {}
// downcast
operator std::complex<T>() const {
return *static_cast<std::complex<T> const*>(this);
}
};

} // namespace math
} // namespace stan
#endif
50 changes: 50 additions & 0 deletions stan/math/prim/cplx/operator_addition.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef STAN_MATH_PRIM_CPLX_OPERATOR_ADDITION_HPP
#define STAN_MATH_PRIM_CPLX_OPERATOR_ADDITION_HPP

#include <stan/math/prim/scal/fun/copysign.hpp>
#include <stan/math/prim/scal/fun/complex_promote.hpp>
#include <stan/math/prim/scal/fun/isfinite.hpp>
#include <stan/math/prim/scal/meta/is_arith_like.hpp>
#include <stan/math/prim/scal/meta/is_complex.hpp>
#include <stan/math/prim/scal/meta/is_fr_var.hpp>
#include <complex>

namespace stan {
namespace math {

/**
* Return the sum of the specified arguments
*
* @tparam T type of complex first argument
* @tparam U type of second argument
* @param t complex first argument
* @param u second argument
* @return sum
*/
template <class T, class U,
std::enable_if_t<is_fr_var<T, U>::value
&& (is_complex<U>::value
|| is_arith_like<U>::value)>* = nullptr>
inline auto operator+(std::complex<T> const& t, U const& u) {
return complex_promote<U>(t) += u;
}

/**
* Return the sum of the specified arguments
*
* @tparam T type of first argument
* @tparam U type of complex second argument
* @param t first argument
* @param u complex second argument
* @return sum
*/
template <class T, class U,
std::enable_if_t<is_fr_var<T, U>::value
&& is_arith_like<T>::value>* = nullptr>
inline auto operator+(T const& t, std::complex<U> const& u) {
return complex_promote<U>(t) += u;
}

} // namespace math
} // namespace stan
#endif
Loading