Skip to content

Commit

Permalink
Add radians, degrees, and dstack (#300)
Browse files Browse the repository at this point in the history
* add Pi constants

* add radians & degrees

* add dstack & column_stack

* update tests

* fix gcc werror
  • Loading branch information
alifahrri authored Oct 12, 2024
1 parent 2b5577f commit e4ecebc
Show file tree
Hide file tree
Showing 34 changed files with 1,861 additions and 32 deletions.
24 changes: 24 additions & 0 deletions include/nmtools/array/array/column_stack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef NMTOOLS_ARRAY_ARRAY_COLUMN_STACK_HPP
#define NMTOOLS_ARRAY_ARRAY_COLUMN_STACK_HPP

#include "nmtools/array/view/column_stack.hpp"
#include "nmtools/array/eval.hpp"

namespace nmtools::array
{
template <typename output_t=none_t, typename context_t=none_t, typename resolver_t=eval_result_t<>
, typename a_t, typename b_t>
constexpr auto column_stack(const a_t& a, const b_t& b
, context_t&& context=context_t{}, output_t&& output=output_t{},meta::as_value<resolver_t> resolver=meta::as_value_v<resolver_t>)
{
auto array = view::column_stack(a,b);
return eval(
array
, nmtools::forward<context_t>(context)
, nmtools::forward<output_t>(output)
, resolver
);
}
} // nmtools::array

#endif // NMTOOLS_ARRAY_ARRAY_COLUMN_STACK_HPP
24 changes: 24 additions & 0 deletions include/nmtools/array/array/dstack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef NMTOOLS_ARRAY_ARRAY_DSTACK_HPP
#define NMTOOLS_ARRAY_ARRAY_DSTACK_HPP

#include "nmtools/array/view/dstack.hpp"
#include "nmtools/array/eval.hpp"

namespace nmtools::array
{
template <typename output_t=none_t, typename context_t=none_t, typename resolver_t=eval_result_t<>
, typename a_t, typename b_t>
constexpr auto dstack(const a_t& a, const b_t& b
, context_t&& context=context_t{}, output_t&& output=output_t{},meta::as_value<resolver_t> resolver=meta::as_value_v<resolver_t>)
{
auto array = view::dstack(a,b);
return eval(
array
, nmtools::forward<context_t>(context)
, nmtools::forward<output_t>(output)
, resolver
);
}
} // nmtools::array

#endif // NMTOOLS_ARRAY_ARRAY_DSTACK_HPP
24 changes: 24 additions & 0 deletions include/nmtools/array/array/ufuncs/deg2rad.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef NMTOOLS_ARRAY_ARRAY_UFUNCS_DEG2RAD_HPP
#define NMTOOLS_ARRAY_ARRAY_UFUNCS_DEG2RAD_HPP

#include "nmtools/array/view/ufuncs/deg2rad.hpp"
#include "nmtools/array/eval.hpp"

namespace nmtools::array
{
template <typename output_t=none_t, typename context_t=none_t, typename resolver_t=eval_result_t<>
, typename array_t>
constexpr auto deg2rad(const array_t& array
, context_t&& context=context_t{}, output_t&& output=output_t{},meta::as_value<resolver_t> resolver=meta::as_value_v<resolver_t>)
{
auto a = view::deg2rad(array);
return eval(
a
, nmtools::forward<context_t>(context)
, nmtools::forward<output_t>(output)
, resolver
);
}
} // nmtools::array

#endif // NMTOOLS_ARRAY_ARRAY_UFUNCS_DEG2RAD_HPP
24 changes: 24 additions & 0 deletions include/nmtools/array/array/ufuncs/degrees.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef NMTOOLS_ARRAY_ARRAY_UFUNCS_DEGREES_HPP
#define NMTOOLS_ARRAY_ARRAY_UFUNCS_DEGREES_HPP

#include "nmtools/array/view/ufuncs/degrees.hpp"
#include "nmtools/array/eval.hpp"

namespace nmtools::array
{
template <typename output_t=none_t, typename context_t=none_t, typename resolver_t=eval_result_t<>
, typename array_t>
constexpr auto degrees(const array_t& array
, context_t&& context=context_t{}, output_t&& output=output_t{},meta::as_value<resolver_t> resolver=meta::as_value_v<resolver_t>)
{
auto a = view::degrees(array);
return eval(
a
, nmtools::forward<context_t>(context)
, nmtools::forward<output_t>(output)
, resolver
);
}
} // nmtools::array

#endif // NMTOOLS_ARRAY_ARRAY_UFUNCS_DEGREES_HPP
24 changes: 24 additions & 0 deletions include/nmtools/array/array/ufuncs/rad2deg.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef NMTOOLS_ARRAY_UFUNCS_RAD2DEG_HPP
#define NMTOOLS_ARRAY_UFUNCS_RAD2DEG_HPP

#include "nmtools/array/view/ufuncs/rad2deg.hpp"
#include "nmtools/array/eval.hpp"

namespace nmtools::array
{
template <typename output_t=none_t, typename context_t=none_t, typename resolver_t=eval_result_t<>
, typename array_t>
constexpr auto rad2deg(const array_t& array
, context_t&& context=context_t{}, output_t&& output=output_t{},meta::as_value<resolver_t> resolver=meta::as_value_v<resolver_t>)
{
auto a = view::rad2deg(array);
return eval(
a
, nmtools::forward<context_t>(context)
, nmtools::forward<output_t>(output)
, resolver
);
}
} // nmtools::array

#endif // NMTOOLS_ARRAY_UFUNCS_RAD2DEG_HPP
24 changes: 24 additions & 0 deletions include/nmtools/array/array/ufuncs/radians.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef NMTOOLS_ARRAY_ARRAY_UFUNCS_RADIANS_HPP
#define NMTOOLS_ARRAY_ARRAY_UFUNCS_RADIANS_HPP

#include "nmtools/array/view/ufuncs/radians.hpp"
#include "nmtools/array/eval.hpp"

namespace nmtools::array
{
template <typename output_t=none_t, typename context_t=none_t, typename resolver_t=eval_result_t<>
, typename array_t>
constexpr auto radians(const array_t& array
, context_t&& context=context_t{}, output_t&& output=output_t{},meta::as_value<resolver_t> resolver=meta::as_value_v<resolver_t>)
{
auto a = view::radians(array);
return eval(
a
, nmtools::forward<context_t>(context)
, nmtools::forward<output_t>(output)
, resolver
);
}
} // nmtools::array

#endif // NMTOOLS_ARRAY_ARRAY_UFUNCS_RADIANS_HPP
115 changes: 115 additions & 0 deletions include/nmtools/array/view/column_stack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#ifndef NMTOOLS_ARRAY_VIEW_COLUMN_STACK_HPP
#define NMTOOLS_ARRAY_VIEW_COLUMN_STACK_HPP

#include "nmtools/array/shape.hpp"
#include "nmtools/meta.hpp"

namespace nmtools::index
{
struct column_stack_reshape_t {};

template <typename src_shape_t>
constexpr auto column_stack_reshape(const src_shape_t& src_shape)
{
using result_t = meta::resolve_optype_t<column_stack_reshape_t,src_shape_t>;

auto result = result_t {};

if constexpr (!meta::is_fail_v<result_t>
&& !meta::is_constant_index_array_v<result_t>)
{
auto src_dim = len(src_shape);
[[maybe_unused]]
auto dst_dim = src_dim == 1 ? 2 : src_dim;

if constexpr (meta::is_resizable_v<result_t>) {
result.resize(dst_dim);
}

if (src_dim == 1) {
at(result,meta::ct_v<0>) = at(src_shape,meta::ct_v<0>);
at(result,meta::ct_v<1>) = 1;
} else {
for (nm_size_t i=0; i<(nm_size_t)src_dim; i++) {
at(result,i) = at(src_shape,i);
}
}
}

return result;
}
} // nmtools::index

namespace nmtools::meta
{
namespace error
{
template <typename...>
struct COLUMN_STACK_RESHAPE_UNSUPPORTED : detail::fail_t {};
}

template <typename src_shape_t>
struct resolve_optype<
void, index::column_stack_reshape_t, src_shape_t
> {
static constexpr auto vtype = [](){
if constexpr (!is_index_array_v<src_shape_t>) {
using type = error::COLUMN_STACK_RESHAPE_UNSUPPORTED<src_shape_t>;
return as_value_v<type>;
} else if constexpr (is_constant_index_array_v<src_shape_t>) {
constexpr auto src_shape = to_value_v<src_shape_t>;
constexpr auto result = index::column_stack_reshape(src_shape);
using nmtools::at, nmtools::len;
return template_reduce<len(result)>([&](auto init, auto I){
using init_t = type_t<decltype(init)>;
using type = append_type_t<init_t,ct<at(result,I)>>;
return as_value_v<type>;
}, as_value_v<nmtools_tuple<>>);
} else {
[[maybe_unused]]
constexpr auto B_DIM = bounded_size_v<src_shape_t>;
constexpr auto DIM = len_v<src_shape_t>;
if constexpr (DIM > 0) {
using type = nmtools_array<nm_size_t,DIM == 1 ? 2 : DIM>;
return as_value_v<type>;
} else if constexpr (!is_fail_v<decltype(B_DIM)>) {
using type = nmtools_static_vector<nm_size_t,B_DIM == 1 ? 2 : B_DIM>;
return as_value_v<type>;
} else {
// TODO: support small vector
using type = nmtools_list<nm_size_t>;
return as_value_v<type>;
}
}
}();
using type = type_t<decltype(vtype)>;
}; // index::colum_stack_reshape_t
} // nmtools::meta

/********************************************************************************/

#include "nmtools/array/view/alias.hpp"
#include "nmtools/array/view/reshape.hpp"
#include "nmtools/array/view/concatenate.hpp"

namespace nmtools::view
{
template <typename a_t, typename b_t>
constexpr auto column_stack(const a_t& a, const b_t& b)
{
auto aliased = view::aliased(a,b);
auto a_src_shape = shape<true>(a);
auto a_dst_shape = index::column_stack_reshape(a_src_shape);
auto b_src_shape = shape<true>(b);
auto b_dst_shape = index::column_stack_reshape(b_src_shape);

auto a_reshaped = view::reshape(nmtools::get<0>(aliased),a_dst_shape);
auto b_reshaped = view::reshape(nmtools::get<1>(aliased),b_dst_shape);

auto axis = meta::ct_v<1>;

return view::concatenate(a_reshaped,b_reshaped,axis);
}
} // namespace nmtools::view

#endif // NMTOOLS_ARRAY_VIEW_COLUMN_STACK_HPP
119 changes: 119 additions & 0 deletions include/nmtools/array/view/dstack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#ifndef NMTOOLS_ARRAY_VIEW_DSTACK_HPP
#define NMTOOLS_ARRAY_VIEW_DSTACK_HPP

#include "nmtools/meta.hpp"
#include "nmtools/array/shape.hpp"

namespace nmtools::index
{
struct dstack_reshape_t {};

template <typename src_shape_t>
constexpr auto dstack_reshape(const src_shape_t& src_shape)
{
using result_t = meta::resolve_optype_t<dstack_reshape_t,src_shape_t>;

auto result = result_t {};

if constexpr (!meta::is_fail_v<result_t>
&& !meta::is_constant_index_array_v<result_t>)
{
auto src_dim = len(src_shape);

[[maybe_unused]]
auto dst_dim = src_dim < 3 ? 3 : src_dim;

if constexpr (meta::is_resizable_v<result_t>) {
result.resize(dst_dim);
}

if (src_dim == 1) {
at(result,meta::ct_v<0>) = 1;
at(result,meta::ct_v<1>) = at(src_shape,meta::ct_v<0>);
at(result,meta::ct_v<2>) = 1;
} else if (src_dim == 2) {
at(result,meta::ct_v<0>) = at(src_shape,meta::ct_v<0>);
at(result,meta::ct_v<1>) = at(src_shape,1); // avoid triggering static_assert
at(result,meta::ct_v<2>) = 1;
} else {
for (nm_size_t i=0; i<(nm_size_t)src_dim; i++) {
at(result,i) = at(src_shape,i);
}
}
}

return result;
}
} // nmtools::index

namespace nmtools::meta
{
namespace error
{
template <typename...>
struct DSTACK_RESHAPE_UNSUPPORTED : detail::fail_t {};
}

template <typename src_shape_t>
struct resolve_optype<
void, index::dstack_reshape_t, src_shape_t
> {
static constexpr auto vtype = [](){
if constexpr (!is_index_array_v<src_shape_t>) {
using type = error::DSTACK_RESHAPE_UNSUPPORTED<src_shape_t>;
return as_value_v<type>;
} else if constexpr (is_constant_index_array_v<src_shape_t>) {
constexpr auto src_shape = to_value_v<src_shape_t>;
constexpr auto result = index::dstack_reshape(src_shape);
using nmtools::at, nmtools::len;
return template_reduce<len(result)>([&](auto init, auto I){
using init_t = type_t<decltype(init)>;
using type = append_type_t<init_t,ct<at(result,I)>>;
return as_value_v<type>;
}, as_value_v<nmtools_tuple<>>);
} else {
[[maybe_unused]]
constexpr auto B_DIM = bounded_size_v<src_shape_t>;
constexpr auto DIM = len_v<src_shape_t>;
if constexpr (DIM > 0) {
using type = nmtools_array<nm_size_t,(DIM < 3 ? 3 : DIM)>;
return as_value_v<type>;
} else if constexpr (!is_fail_v<decltype(B_DIM)>) {
using type = nmtools_static_vector<nm_size_t,(B_DIM < 3 ? 3 : B_DIM)>;
return as_value_v<type>;
} else {
// TODO: support small vector
using type = nmtools_list<nm_size_t>;
return as_value_v<type>;
}
}
}();
using type = type_t<decltype(vtype)>;
}; // index::dstack_reshape_t
} // nmtools::meta

#include "nmtools/array/view/alias.hpp"
#include "nmtools/array/view/reshape.hpp"
#include "nmtools/array/view/concatenate.hpp"

namespace nmtools::view
{
template <typename a_t, typename b_t>
constexpr auto dstack(const a_t& a, const b_t& b)
{
auto aliased = view::aliased(a,b);
auto a_src_shape = shape<true>(a);
auto a_dst_shape = index::dstack_reshape(a_src_shape);
auto b_src_shape = shape<true>(b);
auto b_dst_shape = index::dstack_reshape(b_src_shape);

auto a_reshaped = view::reshape(nmtools::get<0>(aliased),a_dst_shape);
auto b_reshaped = view::reshape(nmtools::get<1>(aliased),b_dst_shape);

auto axis = meta::ct_v<2>;

return view::concatenate(a_reshaped,b_reshaped,axis);
}
} // nmtools::view

#endif // NMTOOLS_ARRAY_VIEW_DSTACK_HPP
Loading

0 comments on commit e4ecebc

Please sign in to comment.