Skip to content

Commit

Permalink
Add trigonometric and hyperbolic scalar functions
Browse files Browse the repository at this point in the history
  • Loading branch information
krippner committed Aug 19, 2024
1 parent 82ec9b8 commit 89e1597
Show file tree
Hide file tree
Showing 20 changed files with 497 additions and 6 deletions.
12 changes: 6 additions & 6 deletions docs/modules/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ x + 3; // right-hand side literal
The following operations are currently supported:

- `+`, `-`, `*`, `/`: Arithmetic operations.
- `pow`: Power function.
- `sin`: Sine function.
- `cos`: Cosine function.
- `sin`, `cos`, `tan`, `cot`: Trigonometric functions.
- `asin`, `acos`, `atan`, `acot`: Inverse trigonometric functions.
- `sinh`, `cosh`, `tanh`: Hyperbolic functions.
- `exp`: Exponential function.
- `log`: Natural logarithm.
- `sqrt`: Square root.
- `pow`: Power function.
- `square`: Square function.
- `min`: Minimum of a scalar expression and zero.
- `max`: Maximum of a scalar expression and zero.
- `sqrt`: Square root.
- `min`, `max`: Minimum, maximum of a scalar expression and zero.
44 changes: 44 additions & 0 deletions include/AutoDiff/src/Basic/ops/ArcCos.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_ARC_COS_HPP
#define AUTODIFF_SRC_BASIC_OPS_ARC_COS_HPP

namespace AutoDiff::Basic {

template <typename X>
class ArcCos : public UnaryOperation<ArcCos<X>, X> {
public:
using Base = UnaryOperation<ArcCos<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return std::acos(Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
auto const& x = Base::xValue();
return -std::pow(1 - x * x, -0.5) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
auto const& x = Base::xValue();
Base::xPullBack(derivative * (-std::pow(1 - x * x, -0.5)));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(acos, Basic::ArcCos)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_ARC_COS_HPP
44 changes: 44 additions & 0 deletions include/AutoDiff/src/Basic/ops/ArcCot.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_ARC_COT_HPP
#define AUTODIFF_SRC_BASIC_OPS_ARC_COT_HPP

namespace AutoDiff::Basic {

template <typename X>
class ArcCot : public UnaryOperation<ArcCot<X>, X> {
public:
using Base = UnaryOperation<ArcCot<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return std::atan(1 / Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
auto const& x = Base::xValue();
return -1 / (1 + x * x) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
auto const& x = Base::xValue();
Base::xPullBack(derivative / -(1 + x * x));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(acot, Basic::ArcCot)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_ARC_COT_HPP
44 changes: 44 additions & 0 deletions include/AutoDiff/src/Basic/ops/ArcSin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_ARC_SIN_HPP
#define AUTODIFF_SRC_BASIC_OPS_ARC_SIN_HPP

namespace AutoDiff::Basic {

template <typename X>
class ArcSin : public UnaryOperation<ArcSin<X>, X> {
public:
using Base = UnaryOperation<ArcSin<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return std::asin(Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
auto const& x = Base::xValue();
return std::pow(1 - x * x, -0.5) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
auto const& x = Base::xValue();
Base::xPullBack(derivative * std::pow(1 - x * x, -0.5));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(asin, Basic::ArcSin)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_ARC_SIN_HPP
44 changes: 44 additions & 0 deletions include/AutoDiff/src/Basic/ops/ArcTan.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_ARC_TAN_HPP
#define AUTODIFF_SRC_BASIC_OPS_ARC_TAN_HPP

namespace AutoDiff::Basic {

template <typename X>
class ArcTan : public UnaryOperation<ArcTan<X>, X> {
public:
using Base = UnaryOperation<ArcTan<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return std::atan(Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
auto const& x = Base::xValue();
return 1 / (1 + x * x) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
auto const& x = Base::xValue();
Base::xPullBack(derivative / (1 + x * x));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(atan, Basic::ArcTan)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_ARC_TAN_HPP
42 changes: 42 additions & 0 deletions include/AutoDiff/src/Basic/ops/Cosh.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_COSH_HPP
#define AUTODIFF_SRC_BASIC_OPS_COSH_HPP

namespace AutoDiff::Basic {

template <typename X>
class Cosh : public UnaryOperation<Cosh<X>, X> {
public:
using Base = UnaryOperation<Cosh<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return std::cosh(Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
return std::sinh(Base::xValue()) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
Base::xPullBack(derivative * std::sinh(Base::xValue()));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(cosh, Basic::Cosh)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_COSH_HPP
44 changes: 44 additions & 0 deletions include/AutoDiff/src/Basic/ops/Cot.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_COT_HPP
#define AUTODIFF_SRC_BASIC_OPS_COT_HPP

namespace AutoDiff::Basic {

template <typename X>
class Cot : public UnaryOperation<Cot<X>, X> {
public:
using Base = UnaryOperation<Cot<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return 1 / std::tan(Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
auto const& tan_x = std::tan(Base::xValue());
return (-1 - 1 / (tan_x * tan_x)) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
auto const& tan_x = std::tan(Base::xValue());
Base::xPullBack(derivative * (-1 - 1 / (tan_x * tan_x)));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(cot, Basic::Cot)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_COT_HPP
42 changes: 42 additions & 0 deletions include/AutoDiff/src/Basic/ops/Sinh.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_SINH_HPP
#define AUTODIFF_SRC_BASIC_OPS_SINH_HPP

namespace AutoDiff::Basic {

template <typename X>
class Sinh : public UnaryOperation<Sinh<X>, X> {
public:
using Base = UnaryOperation<Sinh<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return std::sinh(Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
return std::cosh(Base::xValue()) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
Base::xPullBack(derivative * std::cosh(Base::xValue()));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(sinh, Basic::Sinh)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_SINH_HPP
44 changes: 44 additions & 0 deletions include/AutoDiff/src/Basic/ops/Tan.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024 Matthias Krippner
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#ifndef AUTODIFF_SRC_BASIC_OPS_TAN_HPP
#define AUTODIFF_SRC_BASIC_OPS_TAN_HPP

namespace AutoDiff::Basic {

template <typename X>
class Tan : public UnaryOperation<Tan<X>, X> {
public:
using Base = UnaryOperation<Tan<X>, X>;
using Base::Base;

[[nodiscard]] auto _valueImpl() -> decltype(auto)
{
return std::tan(Base::xValue());
}

[[nodiscard]] auto _pushForwardImpl() -> decltype(auto)
{
auto const& tan_x = std::tan(Base::xValue());
return (1 + tan_x * tan_x) * Base::xPushForward();
}

template <typename Derivative>
void _pullBackImpl(Derivative const& derivative)
{
auto const& tan_x = std::tan(Base::xValue());
Base::xPullBack(derivative * (1 + tan_x * tan_x));
}
};

} // namespace AutoDiff::Basic

namespace AutoDiff {

AUTODIFF_MAKE_BASIC_UNARY_OP(tan, Basic::Tan)

} // namespace AutoDiff

#endif // AUTODIFF_SRC_BASIC_OPS_TAN_HPP
Loading

0 comments on commit 89e1597

Please sign in to comment.