Last active
February 14, 2024 15:09
-
-
Save WardBrian/85ca3a4bfb3a23f55ef40604987c04eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Demonstration of `scalar_type_t`, `base_type_t`, and `value_type_t`, for | |
* examples where they do the same thing and examples where they differ. | |
* | |
* Place in math repo directory and compile with: | |
make -f make/standalone test_types | |
*/ | |
#include <stan/math/prim.hpp> | |
#include <stan/math/prim/fun/typedefs.hpp> | |
#include <stan/math/rev/meta.hpp> | |
#include <stan/math/mix.hpp> | |
#include <complex> | |
#include <vector> | |
#include <iostream> | |
/* Code to print a type de-mangled, from | |
* https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c | |
*/ | |
#include <type_traits> | |
#include <cxxabi.h> | |
#include <memory> | |
#include <string> | |
#include <cstdlib> | |
template <class T> | |
std::string type_name() { | |
typedef typename std::remove_reference<T>::type TR; | |
std::unique_ptr<char, void (*)(void*)> own( | |
abi::__cxa_demangle(typeid(TR).name(), nullptr, nullptr, nullptr), | |
std::free); | |
std::string r = own != nullptr ? own.get() : typeid(TR).name(); | |
return r; | |
} | |
template <typename T> | |
void print_for_type(int number) { | |
std::cout << "Test type " << number << ":\t" << type_name<T>() << '\n'; | |
std::cout << "Base type:\t" << type_name<stan::base_type_t<T>>() << '\n'; | |
std::cout << "Scalar type:\t" << type_name<stan::scalar_type_t<T>>() << '\n'; | |
std::cout << "Value type:\t" << type_name<stan::value_type_t<T>>() << '\n'; | |
std::cout << "Partial type:\t" << type_name<stan::partials_return_t<T>>() << '\n'; | |
std::cout << "Return type:\t" << type_name<stan::return_type_t<T>>() << '\n'; | |
std::cout << "------------------------------" << '\n'; | |
} | |
int main() { | |
using v_t = stan::math::var; | |
using fv_t = stan::math::fvar<v_t>; | |
using ffv_t = stan::math::fvar<fv_t>; | |
using cffv_t = std::complex<ffv_t>; | |
print_for_type<cffv_t>(-1); | |
using test_type0 = Eigen::Matrix<v_t, -1, -1>; | |
print_for_type<test_type0>(0); | |
using test_type1 = std::vector<cffv_t>; | |
print_for_type<test_type1>(1); | |
using test_type2 = std::vector<test_type1>; | |
print_for_type<test_type2>(2); | |
using test_type3 = Eigen::Matrix<std::complex<v_t>, -1, -1>; | |
print_for_type<test_type3>(3); | |
using test_type4 = std::vector<test_type3>; | |
print_for_type<test_type4>(4); | |
using test_type5 = stan::math::var_value<Eigen::MatrixXd>; | |
print_for_type<test_type5>(5); | |
using test_type6 = v_t; | |
print_for_type<test_type6>(6); | |
using test_type7 = Eigen::Matrix<fv_t, -1, -1>; | |
print_for_type<test_type7>(7); | |
print_for_type<int>(8); | |
std::cout << "Summary: Base type and Scalar type only differ when dealing " | |
"with complex numbers, which base type strips but scalar " | |
"type does not. Value Type only removes one layer of the onion, " | |
"which leads to different behavior for var<matrix> types" | |
<< '\n'; | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Test type -1: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Base type: stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > | |
Scalar type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Value type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Partial type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Return type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
------------------------------ | |
Test type 0: Eigen::Matrix<stan::math::var_value<double, void>, -1, -1, 0, -1, -1> | |
Base type: stan::math::var_value<double, void> | |
Scalar type: stan::math::var_value<double, void> | |
Value type: stan::math::var_value<double, void> | |
Partial type: double | |
Return type: stan::math::var_value<double, void> | |
------------------------------ | |
Test type 1: std::vector<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > >, std::allocator<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > > > | |
Base type: stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > | |
Scalar type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Value type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Partial type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Return type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
------------------------------ | |
Test type 2: std::vector<std::vector<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > >, std::allocator<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > > >, std::allocator<std::vector<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > >, std::allocator<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > > > > > | |
Base type: stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > | |
Scalar type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Value type: std::vector<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > >, std::allocator<std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > > > | |
Partial type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
Return type: std::complex<stan::math::fvar<stan::math::fvar<stan::math::var_value<double, void> > > > | |
------------------------------ | |
Test type 3: Eigen::Matrix<std::complex<stan::math::var_value<double, void> >, -1, -1, 0, -1, -1> | |
Base type: stan::math::var_value<double, void> | |
Scalar type: std::complex<stan::math::var_value<double, void> > | |
Value type: std::complex<stan::math::var_value<double, void> > | |
Partial type: std::complex<stan::math::var_value<double, void> > | |
Return type: std::complex<stan::math::var_value<double, void> > | |
------------------------------ | |
Test type 4: std::vector<Eigen::Matrix<std::complex<stan::math::var_value<double, void> >, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<std::complex<stan::math::var_value<double, void> >, -1, -1, 0, -1, -1> > > | |
Base type: stan::math::var_value<double, void> | |
Scalar type: std::complex<stan::math::var_value<double, void> > | |
Value type: Eigen::Matrix<std::complex<stan::math::var_value<double, void> >, -1, -1, 0, -1, -1> | |
Partial type: std::complex<stan::math::var_value<double, void> > | |
Return type: std::complex<stan::math::var_value<double, void> > | |
------------------------------ | |
Test type 5: stan::math::var_value<Eigen::Matrix<double, -1, -1, 0, -1, -1>, void> | |
Base type: stan::math::var_value<Eigen::Matrix<double, -1, -1, 0, -1, -1>, void> | |
Scalar type: stan::math::var_value<double, void> | |
Value type: Eigen::Matrix<double, -1, -1, 0, -1, -1> | |
Partial type: double | |
Return type: stan::math::var_value<double, void> | |
------------------------------ | |
Test type 6: stan::math::var_value<double, void> | |
Base type: stan::math::var_value<double, void> | |
Scalar type: stan::math::var_value<double, void> | |
Value type: double | |
Partial type: double | |
Return type: stan::math::var_value<double, void> | |
------------------------------ | |
Test type 7: Eigen::Matrix<stan::math::fvar<stan::math::var_value<double, void> >, -1, -1, 0, -1, -1> | |
Base type: stan::math::fvar<stan::math::var_value<double, void> > | |
Scalar type: stan::math::fvar<stan::math::var_value<double, void> > | |
Value type: stan::math::fvar<stan::math::var_value<double, void> > | |
Partial type: stan::math::var_value<double, void> | |
Return type: stan::math::fvar<stan::math::var_value<double, void> > | |
------------------------------ | |
Test type 8: int | |
Base type: int | |
Scalar type: int | |
Value type: int | |
Partial type: double | |
Return type: double | |
------------------------------ | |
Summary: Base type and Scalar type only differ when dealing with complex numbers, which base type strips but scalar type does not. Value Type only removes one layer of the onion, which leads to different behavior for var<matrix> types |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment