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

Added "append_array" function to address Issue 481 #550

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Added "append_array" function to address Issue 481
  • Loading branch information
bbbales2 committed May 6, 2017
commit b1ec2b23b75b90dedbe785ca39949404ac2aac4d
1 change: 1 addition & 0 deletions stan/math/prim/arr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <stan/math/prim/arr/err/check_nonzero_size.hpp>
#include <stan/math/prim/arr/err/check_ordered.hpp>

#include <stan/math/prim/arr/fun/append_array.hpp>
#include <stan/math/prim/arr/fun/array_builder.hpp>
#include <stan/math/prim/arr/fun/common_type.hpp>
#include <stan/math/prim/arr/fun/dot.hpp>
Expand Down
31 changes: 31 additions & 0 deletions stan/math/prim/arr/fun/append_array.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef STAN_MATH_PRIM_ARR_FUN_APPEND_ARRAY_HPP
#define STAN_MATH_PRIM_ARR_FUN_APPEND_ARRAY_HPP

#include <boost/math/tools/promotion.hpp>
#include <vector>

namespace stan {
namespace math {

/**
* Return the concatenation of two specified vectors in the order of
* the arguments
*
* @tparam T1 Scalar type of first vector.
* @tparam T2 Scalar Type of second vector.
* @param x First vector.
* @param y Second vector.
* @return A vector of x and y concatenated together (in that order).
*/
template <typename T1, typename T2>
std::vector<typename boost::math::tools::promote_args<T1, T2>::type>
append_array(const std::vector<T1>& x, const std::vector<T2>& y) {
std::vector<typename boost::math::tools::promote_args<T1, T2>::type> z;
z.reserve(x.size() + y.size());
z.insert(z.end(), x.begin(), x.end());
z.insert(z.end(), y.begin(), y.end());
return z;
}
}
}
#endif
322 changes: 322 additions & 0 deletions test/unit/math/fwd/arr/fun/append_array_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
#include <stan/math/fwd/arr.hpp>
#include <gtest/gtest.h>

TEST(AgradFwd, append_array_double_fvar) {
std::vector<double> x(3);
std::vector<stan::math::fvar<double> > y(2), result;

x[0] = 1.0;
x[1] = 2.0;
x[2] = 3.0;
y[0] = 0.5;
y[0].d_ = 5.0;
y[1] = 4.0;
y[1].d_ = 6.0;

EXPECT_NO_THROW(result = stan::math::append_array(x, y));
EXPECT_EQ(5, result.size());

EXPECT_FLOAT_EQ(1.0, result[0].val());
EXPECT_FLOAT_EQ(2.0, result[1].val());
EXPECT_FLOAT_EQ(3.0, result[2].val());
EXPECT_FLOAT_EQ(0.5, result[3].val());
EXPECT_FLOAT_EQ(4.0, result[4].val());

EXPECT_FLOAT_EQ(0.0, result[0].tangent());
EXPECT_FLOAT_EQ(0.0, result[1].tangent());
EXPECT_FLOAT_EQ(0.0, result[2].tangent());
EXPECT_FLOAT_EQ(5.0, result[3].tangent());
EXPECT_FLOAT_EQ(6.0, result[4].tangent());
}

TEST(AgradFwd, append_array_fvar_double) {
std::vector<double> x(2);
std::vector<stan::math::fvar<double> > y(3), result;

x[0] = 1.0;
x[1] = 2.0;
y[0] = 5.0;
y[0].d_ = 1.5;
y[1] = 6.0;
y[1].d_ = 2.5;
y[2] = 7.0;
y[2].d_ = 3.5;

EXPECT_NO_THROW(result = stan::math::append_array(y, x));
EXPECT_EQ(5, result.size());
EXPECT_FLOAT_EQ(5.0, result[0].val());
EXPECT_FLOAT_EQ(6.0, result[1].val());
EXPECT_FLOAT_EQ(7.0, result[2].val());
EXPECT_FLOAT_EQ(1.0, result[3].val());
EXPECT_FLOAT_EQ(2.0, result[4].val());

EXPECT_FLOAT_EQ(1.5, result[0].tangent());
EXPECT_FLOAT_EQ(2.5, result[1].tangent());
EXPECT_FLOAT_EQ(3.5, result[2].tangent());
EXPECT_FLOAT_EQ(0.0, result[3].tangent());
EXPECT_FLOAT_EQ(0.0, result[4].tangent());
}

TEST(AgradFwd, append_array_double_fvar_fvar) {
std::vector<double> x(3);
std::vector<stan::math::fvar<stan::math::fvar<double> > > y(2), result;

x[0] = 1.0;
x[1] = 2.0;
x[2] = 3.0;
y[0] = 0.5;
y[0].val_.d_ = 1.5;
y[0].d_ = 5.0;
y[0].d_.d_ = 2.5;
y[1] = 4.0;
y[1].val_.d_ = 3.5;
y[1].d_ = 6.0;
y[1].d_.d_ = 4.5;

EXPECT_NO_THROW(result = stan::math::append_array(x, y));
EXPECT_EQ(5, result.size());

EXPECT_FLOAT_EQ(1.0, result[0].val().val());
EXPECT_FLOAT_EQ(2.0, result[1].val().val());
EXPECT_FLOAT_EQ(3.0, result[2].val().val());
EXPECT_FLOAT_EQ(0.5, result[3].val().val());
EXPECT_FLOAT_EQ(4.0, result[4].val().val());

EXPECT_FLOAT_EQ(0.0, result[0].val().tangent());
EXPECT_FLOAT_EQ(0.0, result[1].val().tangent());
EXPECT_FLOAT_EQ(0.0, result[2].val().tangent());
EXPECT_FLOAT_EQ(1.5, result[3].val().tangent());
EXPECT_FLOAT_EQ(3.5, result[4].val().tangent());

EXPECT_FLOAT_EQ(0.0, result[0].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[1].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[2].tangent().val());
EXPECT_FLOAT_EQ(5.0, result[3].tangent().val());
EXPECT_FLOAT_EQ(6.0, result[4].tangent().val());

EXPECT_FLOAT_EQ(0.0, result[0].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[1].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[2].tangent().tangent());
EXPECT_FLOAT_EQ(2.5, result[3].tangent().tangent());
EXPECT_FLOAT_EQ(4.5, result[4].tangent().tangent());
}

TEST(AgradFwd, append_array_fvar_fvar_double) {
std::vector<double> x(2);
std::vector<stan::math::fvar<stan::math::fvar<double> > > y(3), result;

x[0] = 1.0;
x[1] = 2.0;
y[0] = 5.0;
y[0].val_.d_ = 11.0;
y[0].d_ = 1.5;
y[0].d_.d_ = 15.0;
y[1] = 6.0;
y[1].val_.d_ = 12.0;
y[1].d_ = 2.5;
y[1].d_.d_ = 16.0;
y[2] = 7.0;
y[2].val_.d_ = 13.0;
y[2].d_ = 3.5;
y[2].d_.d_ = 17.0;

EXPECT_NO_THROW(result = stan::math::append_array(y, x));
EXPECT_EQ(5, result.size());
EXPECT_FLOAT_EQ(5.0, result[0].val().val());
EXPECT_FLOAT_EQ(6.0, result[1].val().val());
EXPECT_FLOAT_EQ(7.0, result[2].val().val());
EXPECT_FLOAT_EQ(1.0, result[3].val().val());
EXPECT_FLOAT_EQ(2.0, result[4].val().val());

EXPECT_FLOAT_EQ(11.0, result[0].val().tangent());
EXPECT_FLOAT_EQ(12.0, result[1].val().tangent());
EXPECT_FLOAT_EQ(13.0, result[2].val().tangent());
EXPECT_FLOAT_EQ(0.0, result[3].val().tangent());
EXPECT_FLOAT_EQ(0.0, result[4].val().tangent());

EXPECT_FLOAT_EQ(1.5, result[0].tangent().val());
EXPECT_FLOAT_EQ(2.5, result[1].tangent().val());
EXPECT_FLOAT_EQ(3.5, result[2].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[3].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[4].tangent().val());

EXPECT_FLOAT_EQ(15.0, result[0].tangent().tangent());
EXPECT_FLOAT_EQ(16.0, result[1].tangent().tangent());
EXPECT_FLOAT_EQ(17.0, result[2].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[3].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[4].tangent().tangent());
}

TEST(AgradFwd, append_array_fvar_fvar) {
std::vector<stan::math::fvar<double> > x(3), y(2), result;

x[0] = 5.0;
x[0].d_ = 1.5;
x[1] = 6.0;
x[1].d_ = 0.5;
x[2] = 7.0;
x[2].d_ = -1.5;
y[0] = 0.5;
y[0].d_ = 2.5;
y[1] = 4.0;
y[1].d_ = -5.0;

EXPECT_NO_THROW(result = stan::math::append_array(x, y));
EXPECT_EQ(5, result.size());
EXPECT_FLOAT_EQ(5.0, result[0].val());
EXPECT_FLOAT_EQ(6.0, result[1].val());
EXPECT_FLOAT_EQ(7.0, result[2].val());
EXPECT_FLOAT_EQ(0.5, result[3].val());
EXPECT_FLOAT_EQ(4.0, result[4].val());

EXPECT_FLOAT_EQ(1.5, result[0].tangent());
EXPECT_FLOAT_EQ(0.5, result[1].tangent());
EXPECT_FLOAT_EQ(-1.5, result[2].tangent());
EXPECT_FLOAT_EQ(2.5, result[3].tangent());
EXPECT_FLOAT_EQ(-5.0, result[4].tangent());
}

TEST(AgradFwd, append_array_fvar_fvar_fvar1) {
std::vector<stan::math::fvar<double> > x(3);
std::vector<stan::math::fvar<stan::math::fvar<double> > > y(2), result;

x[0] = 5.0;
x[0].d_ = 1.5;
x[1] = 6.0;
x[1].d_ = 0.5;
x[2] = 7.0;
x[2].d_ = -1.5;
y[0] = 0.5;
y[0].val_.d_ = 11.0;
y[0].d_ = 2.5;
y[0].d_.d_ = 15.0;
y[1] = 4.0;
y[1].val_.d_ = 12.0;
y[1].d_ = -5.0;
y[1].d_.d_ = 16.0;

EXPECT_NO_THROW(result = stan::math::append_array(x, y));
EXPECT_EQ(5, result.size());
EXPECT_FLOAT_EQ(5.0, result[0].val().val());
EXPECT_FLOAT_EQ(6.0, result[1].val().val());
EXPECT_FLOAT_EQ(7.0, result[2].val().val());
EXPECT_FLOAT_EQ(0.5, result[3].val().val());
EXPECT_FLOAT_EQ(4.0, result[4].val().val());

EXPECT_FLOAT_EQ(1.5, result[0].val().tangent());
EXPECT_FLOAT_EQ(0.5, result[1].val().tangent());
EXPECT_FLOAT_EQ(-1.5, result[2].val().tangent());
EXPECT_FLOAT_EQ(11.0, result[3].val().tangent());
EXPECT_FLOAT_EQ(12.0, result[4].val().tangent());

EXPECT_FLOAT_EQ(0.0, result[0].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[1].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[2].tangent().val());
EXPECT_FLOAT_EQ(2.5, result[3].tangent().val());
EXPECT_FLOAT_EQ(-5.0, result[4].tangent().val());

EXPECT_FLOAT_EQ(0.0, result[0].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[1].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[2].tangent().tangent());
EXPECT_FLOAT_EQ(15.0, result[3].tangent().tangent());
EXPECT_FLOAT_EQ(16.0, result[4].tangent().tangent());
}

TEST(AgradFwd, append_array_fvar_fvar_fvar2) {
std::vector<stan::math::fvar<double> > y(2);
std::vector<stan::math::fvar<stan::math::fvar<double> > > x(3), result;

x[0] = 5.0;
x[0].val_.d_ = 11.0;
x[0].d_ = 1.5;
x[0].d_.d_ = 15.0;
x[1] = 6.0;
x[1].val_.d_ = 12.0;
x[1].d_ = 0.5;
x[1].d_.d_ = 16.0;
x[2] = 7.0;
x[2].val_.d_ = 13.0;
x[2].d_ = -1.5;
x[2].d_.d_ = 17.0;
y[0] = 0.5;
y[0].d_ = 2.5;
y[1] = 4.0;
y[1].d_ = -5.0;

EXPECT_NO_THROW(result = stan::math::append_array(x, y));
EXPECT_EQ(5, result.size());
EXPECT_FLOAT_EQ(5.0, result[0].val().val());
EXPECT_FLOAT_EQ(6.0, result[1].val().val());
EXPECT_FLOAT_EQ(7.0, result[2].val().val());
EXPECT_FLOAT_EQ(0.5, result[3].val().val());
EXPECT_FLOAT_EQ(4.0, result[4].val().val());

EXPECT_FLOAT_EQ(11.0, result[0].val().tangent());
EXPECT_FLOAT_EQ(12.0, result[1].val().tangent());
EXPECT_FLOAT_EQ(13.0, result[2].val().tangent());
EXPECT_FLOAT_EQ(2.5, result[3].val().tangent());
EXPECT_FLOAT_EQ(-5.0, result[4].val().tangent());

EXPECT_FLOAT_EQ(1.5, result[0].tangent().val());
EXPECT_FLOAT_EQ(0.5, result[1].tangent().val());
EXPECT_FLOAT_EQ(-1.5, result[2].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[3].tangent().val());
EXPECT_FLOAT_EQ(0.0, result[4].tangent().val());

EXPECT_FLOAT_EQ(15.0, result[0].tangent().tangent());
EXPECT_FLOAT_EQ(16.0, result[1].tangent().tangent());
EXPECT_FLOAT_EQ(17.0, result[2].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[3].tangent().tangent());
EXPECT_FLOAT_EQ(0.0, result[4].tangent().tangent());
}

TEST(AgradFwd, append_array_fvar_fvar_fvar_fvar) {
std::vector<stan::math::fvar<stan::math::fvar<double> > > x(3), y(2), result;

x[0] = 5.0;
x[0].val_.d_ = 11.0;
x[0].d_ = 1.5;
x[0].d_.d_ = 16.0;
x[1] = 6.0;
x[1].val_.d_ = 12.0;
x[1].d_ = 0.5;
x[1].d_.d_ = 17.0;
x[2] = 7.0;
x[2].val_.d_ = 13.0;
x[2].d_ = -1.5;
x[2].d_.d_ = 18.0;
y[0] = 0.5;
y[0].val_.d_ = 14.0;
y[0].d_ = 2.5;
y[0].d_.d_ = 19.0;
y[1] = 4.0;
y[1].val_.d_ = 15.0;
y[1].d_ = -5.0;
y[1].d_.d_ = 20.0;

EXPECT_NO_THROW(result = stan::math::append_array(x, y));
EXPECT_EQ(5, result.size());
EXPECT_FLOAT_EQ(5.0, result[0].val().val());
EXPECT_FLOAT_EQ(6.0, result[1].val().val());
EXPECT_FLOAT_EQ(7.0, result[2].val().val());
EXPECT_FLOAT_EQ(0.5, result[3].val().val());
EXPECT_FLOAT_EQ(4.0, result[4].val().val());

EXPECT_FLOAT_EQ(1.5, result[0].tangent().val());
EXPECT_FLOAT_EQ(0.5, result[1].tangent().val());
EXPECT_FLOAT_EQ(-1.5, result[2].tangent().val());
EXPECT_FLOAT_EQ(2.5, result[3].tangent().val());
EXPECT_FLOAT_EQ(-5.0, result[4].tangent().val());

EXPECT_FLOAT_EQ(11.0, result[0].val().tangent());
EXPECT_FLOAT_EQ(12.0, result[1].val().tangent());
EXPECT_FLOAT_EQ(13.0, result[2].val().tangent());
EXPECT_FLOAT_EQ(14.0, result[3].val().tangent());
EXPECT_FLOAT_EQ(15.0, result[4].val().tangent());

EXPECT_FLOAT_EQ(16.0, result[0].tangent().tangent());
EXPECT_FLOAT_EQ(17.0, result[1].tangent().tangent());
EXPECT_FLOAT_EQ(18.0, result[2].tangent().tangent());
EXPECT_FLOAT_EQ(19.0, result[3].tangent().tangent());
EXPECT_FLOAT_EQ(20.0, result[4].tangent().tangent());
}
Loading