Skip to content
Open
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
2 changes: 1 addition & 1 deletion docs/api/math/arcosh.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

.. xfunction:: datatable.math.arcosh
:src: src/core/expr/funary/hyperbolic.cc resolve_op_arcosh
:src: src/core/expr/funary/hyperbolic.cc pyfn_arcosh
:cvar: doc_math_arcosh
:signature: arcosh(x)

Expand Down
2 changes: 1 addition & 1 deletion docs/api/math/arsinh.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

.. xfunction:: datatable.math.arsinh
:src: src/core/expr/funary/hyperbolic.cc resolve_op_arsinh
:src: src/core/expr/funary/hyperbolic.cc pyfn_arsinh
:cvar: doc_math_arsinh
:signature: arsinh(x)

Expand Down
2 changes: 1 addition & 1 deletion docs/api/math/artanh.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

.. xfunction:: datatable.math.artanh
:src: src/core/expr/funary/hyperbolic.cc resolve_op_artanh
:src: src/core/expr/funary/hyperbolic.cc pyfn_artanh
:cvar: doc_math_artanh
:signature: artanh(x)

Expand Down
2 changes: 1 addition & 1 deletion docs/api/math/cosh.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

.. xfunction:: datatable.math.cosh
:src: src/core/expr/funary/hyperbolic.cc resolve_op_cosh
:src: src/core/expr/funary/hyperbolic.cc pyfn_cosh
:cvar: doc_math_cosh
:signature: cosh(x)

Expand Down
2 changes: 1 addition & 1 deletion docs/api/math/sinh.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

.. xfunction:: datatable.math.sinh
:src: src/core/expr/funary/hyperbolic.cc resolve_op_sinh
:src: src/core/expr/funary/hyperbolic.cc pyfn_sinh
:cvar: doc_math_sinh
:signature: sinh(x)

Expand Down
2 changes: 1 addition & 1 deletion docs/api/math/tanh.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

.. xfunction:: datatable.math.tanh
:src: src/core/expr/funary/hyperbolic.cc resolve_op_tanh
:src: src/core/expr/funary/hyperbolic.cc pyfn_tanh
:cvar: doc_math_tanh
:signature: tanh(x)

Expand Down
269 changes: 158 additions & 111 deletions src/core/expr/funary/hyperbolic.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------
// Copyright 2019-2020 H2O.ai
// Copyright 2023 H2O.ai
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
Expand All @@ -20,130 +20,177 @@
// IN THE SOFTWARE.
//------------------------------------------------------------------------------
#include <cmath>
#include "column/const.h"
#include "column/func_unary.h"
#include "documentation.h"
#include "expr/funary/pyfn.h"
#include "expr/funary/umaker.h"
#include "expr/funary/umaker_impl.h"
#include "ltype.h"
#include "expr/fexpr_func_unary.h"
#include "python/xargs.h"
#include "stype.h"
namespace dt {
namespace expr {


using func32_t = float(*)(float);
using func64_t = double(*)(double);

/**
* All standard hyperbolic functions have the same signature:
*
* VOID -> VOID
* {BOOL, INT*, FLOAT64} -> FLOAT64
* FLOAT32 -> FLOAT32
*
*/
static umaker_ptr _resolve_hyp(SType stype, const char* name,
func32_t fn32, func64_t fn64)
{
if (stype == SType::VOID) {
return umaker_ptr(new umaker_copy());
}
if (stype == SType::FLOAT64) {
return umaker1<double, double>::make(fn64, SType::AUTO, SType::FLOAT64);
}
if (stype == SType::FLOAT32) {
return umaker1<float, float>::make(fn32, SType::AUTO, SType::FLOAT32);
}
if (stype == SType::BOOL || stype_to_ltype(stype) == LType::INT) {
return umaker1<double, double>::make(fn64, SType::FLOAT64, SType::FLOAT64);
}
throw TypeError() << "Function `" << name << "` cannot be applied to a "
"column of type `" << stype << "`";
template<size_t POS>
class FExpr_Hyperbolic : public FExpr_FuncUnary {
public:
using FExpr_FuncUnary::FExpr_FuncUnary;

static std::string function_name() {
switch (POS) {
case 1:
return "sinh";
case 2:
return "cosh";
case 3:
return "tanh";
case 4:
return "arsinh";
case 5:
return "arcosh";
case 6:
return "artanh";
}

}


std::string name() const override {
return function_name();
}

/**
* All standard hyperbolic functions have the same signature:
*
* VOID -> VOID
* {BOOL, INT*, FLOAT64} -> FLOAT64
* FLOAT32 -> FLOAT32
*
*/
template <typename T, size_t POSN>
static inline T op_hyperbolic(T x) {
switch (POSN) {
case 1:
return sinh(x);
case 2:
return cosh(x);
case 3:
return tanh(x);
case 4:
return asinh(x);
case 5:
return acosh(x);
case 6:
return atanh(x);
}
}


Column evaluate1(Column&& col) const override{
SType stype = col.stype();

switch (stype) {
case SType::VOID:
return Column(new ConstNa_ColumnImpl(col.nrows(), SType::VOID));
case SType::BOOL:
case SType::INT8:
case SType::INT16:
case SType::INT32:
case SType::INT64:
col.cast_inplace(SType::FLOAT64);
return make<double, POS>(std::move(col));
case SType::FLOAT32:
return make<float, POS>(std::move(col));
case SType::FLOAT64:
return make<double, POS>(std::move(col));
default:
std::string func_name = function_name();
throw TypeError() << "Function `" << func_name << "` cannot be applied to a "
"column of type `" << stype << "`";
}
}

private:
template <typename T, size_t POSS>
static Column make(Column&& col) {
xassert(compatible_type<T>(col.stype()));
return Column(new FuncUnary1_ColumnImpl<T, T>(
std::move(col), op_hyperbolic<T, POSS>,
col.nrows(), col.stype()
));
}

};

static py::oobj pyfn_sinh(const py::XArgs &args) {
auto arg = args[0].to_oobj();
return PyFExpr::make(new FExpr_Hyperbolic<1>(as_fexpr(arg)));
}




//------------------------------------------------------------------------------
// Op::SINH
//------------------------------------------------------------------------------

py::PKArgs args_sinh(1, 0, 0, false, false, {"x"}, "sinh", dt::doc_math_sinh);


umaker_ptr resolve_op_sinh(SType stype) {
return _resolve_hyp(stype, "sinh", &std::sinh, &std::sinh);
static py::oobj pyfn_cosh(const py::XArgs &args) {
auto arg = args[0].to_oobj();
return PyFExpr::make(new FExpr_Hyperbolic<2>(as_fexpr(arg)));
}




//------------------------------------------------------------------------------
// Op::COSH
//------------------------------------------------------------------------------

py::PKArgs args_cosh(1, 0, 0, false, false, {"x"}, "cosh", dt::doc_math_cosh);


umaker_ptr resolve_op_cosh(SType stype) {
return _resolve_hyp(stype, "cosh", &std::cosh, &std::cosh);
static py::oobj pyfn_tanh(const py::XArgs &args) {
auto arg = args[0].to_oobj();
return PyFExpr::make(new FExpr_Hyperbolic<3>(as_fexpr(arg)));
}




//------------------------------------------------------------------------------
// Op::TANH
//------------------------------------------------------------------------------

py::PKArgs args_tanh(1, 0, 0, false, false, {"x"}, "tanh", dt::doc_math_tanh);


umaker_ptr resolve_op_tanh(SType stype) {
return _resolve_hyp(stype, "tanh", &std::tanh, &std::tanh);
static py::oobj pyfn_arsinh(const py::XArgs &args) {
auto arg = args[0].to_oobj();
return PyFExpr::make(new FExpr_Hyperbolic<4>(as_fexpr(arg)));
}




//------------------------------------------------------------------------------
// Op::ARSINH
//------------------------------------------------------------------------------

py::PKArgs args_arsinh(1, 0, 0, false, false, {"x"}, "arsinh", dt::doc_math_arsinh);


umaker_ptr resolve_op_arsinh(SType stype) {
return _resolve_hyp(stype, "arsinh", &std::asinh, &std::asinh);
}




//------------------------------------------------------------------------------
// Op::ARCOSH
//------------------------------------------------------------------------------

py::PKArgs args_arcosh(1, 0, 0, false, false, {"x"}, "arcosh", dt::doc_math_arcosh);


umaker_ptr resolve_op_arcosh(SType stype) {
return _resolve_hyp(stype, "arcosh", &std::acosh, &std::acosh);
static py::oobj pyfn_arcosh(const py::XArgs &args) {
auto arg = args[0].to_oobj();
return PyFExpr::make(new FExpr_Hyperbolic<5>(as_fexpr(arg)));
}




//------------------------------------------------------------------------------
// Op::ARTANH
//------------------------------------------------------------------------------

py::PKArgs args_artanh(1, 0, 0, false, false, {"x"}, "artanh", dt::doc_math_artanh);


umaker_ptr resolve_op_artanh(SType stype) {
return _resolve_hyp(stype, "artanh", &std::atanh, &std::atanh);
static py::oobj pyfn_artanh(const py::XArgs &args) {
auto arg = args[0].to_oobj();
return PyFExpr::make(new FExpr_Hyperbolic<6>(as_fexpr(arg)));
}




}} // namespace dt::expr
DECLARE_PYFN(&pyfn_sinh)
->name("sinh")
->docs(doc_math_sinh)
->arg_names({"cols"})
->n_positional_args(1)
->n_required_args(1);

DECLARE_PYFN(&pyfn_cosh)
->name("cosh")
->docs(doc_math_cosh)
->arg_names({"cols"})
->n_positional_args(1)
->n_required_args(1);

DECLARE_PYFN(&pyfn_tanh)
->name("tanh")
->docs(doc_math_tanh)
->arg_names({"cols"})
->n_positional_args(1)
->n_required_args(1);

DECLARE_PYFN(&pyfn_arsinh)
->name("arsinh")
->docs(doc_math_arsinh)
->arg_names({"cols"})
->n_positional_args(1)
->n_required_args(1);

DECLARE_PYFN(&pyfn_arcosh)
->name("arcosh")
->docs(doc_math_arcosh)
->arg_names({"cols"})
->n_positional_args(1)
->n_required_args(1);

DECLARE_PYFN(&pyfn_artanh)
->name("artanh")
->docs(doc_math_artanh)
->arg_names({"cols"})
->n_positional_args(1)
->n_required_args(1);

}} // dt::expr
8 changes: 0 additions & 8 deletions src/core/expr/funary/pyfn.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,6 @@ void py::DatatableModule::init_funary()
FUNARY(args_deg2rad, Op::DEG2RAD);
FUNARY(args_rad2deg, Op::RAD2DEG);

// Hyperbolic
FUNARY(args_sinh, Op::SINH);
FUNARY(args_cosh, Op::COSH);
FUNARY(args_tanh, Op::TANH);
FUNARY(args_arsinh, Op::ARSINH);
FUNARY(args_arcosh, Op::ARCOSH);
FUNARY(args_artanh, Op::ARTANH);

// Exponential/power
FUNARY(args_cbrt, Op::CBRT);
FUNARY(args_exp, Op::EXP);
Expand Down
8 changes: 0 additions & 8 deletions src/core/expr/funary/pyfn.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@ extern py::PKArgs args_arctan;
extern py::PKArgs args_deg2rad;
extern py::PKArgs args_rad2deg;

// Hyperbolic
extern py::PKArgs args_sinh;
extern py::PKArgs args_cosh;
extern py::PKArgs args_tanh;
extern py::PKArgs args_arsinh;
extern py::PKArgs args_arcosh;
extern py::PKArgs args_artanh;

// Exponential/power
extern py::PKArgs args_cbrt;
extern py::PKArgs args_exp;
Expand Down
8 changes: 0 additions & 8 deletions src/core/expr/funary/umaker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,6 @@ umaker_ptr resolve_op(Op opcode, SType stype)
case Op::DEG2RAD: return resolve_op_deg2rad(stype);
case Op::RAD2DEG: return resolve_op_rad2deg(stype);

// Math: hyperbolic
case Op::SINH: return resolve_op_sinh(stype);
case Op::COSH: return resolve_op_cosh(stype);
case Op::TANH: return resolve_op_tanh(stype);
case Op::ARSINH: return resolve_op_arsinh(stype);
case Op::ARCOSH: return resolve_op_arcosh(stype);
case Op::ARTANH: return resolve_op_artanh(stype);

// Math: exponential/power
case Op::CBRT: return resolve_op_cbrt(stype);
case Op::EXP: return resolve_op_exp(stype);
Expand Down
Loading