kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit e7cc84b8d8db5aef851704482931682ea42261e5
parent 4c4564758328532bdf5958e2c99834b2bbc3f870
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Thu,  4 Aug 2022 11:03:27 +0100

Move expressions handling to base

Diffstat:
Minclude/kfr/base.hpp | 2++
Ainclude/kfr/base/math_expressions.hpp | 655+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kfr/base/random.hpp | 1+
Ainclude/kfr/base/simd_expressions.hpp | 269+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kfr/base/univector.hpp | 2+-
Minclude/kfr/dft/impl/convolution-impl.cpp | 2++
Minclude/kfr/dft/impl/dft-impl.hpp | 2++
Minclude/kfr/dsp/fir.hpp | 1+
Minclude/kfr/dsp/iir_design.hpp | 4++--
Minclude/kfr/math/abs.hpp | 9---------
Minclude/kfr/math/asin_acos.hpp | 18------------------
Minclude/kfr/math/atan.hpp | 36------------------------------------
Minclude/kfr/math/clamp.hpp | 14--------------
Minclude/kfr/math/complex_math.hpp | 120-------------------------------------------------------------------------------
Minclude/kfr/math/gamma.hpp | 14--------------
Minclude/kfr/math/hyperbolic.hpp | 44--------------------------------------------
Minclude/kfr/math/log_exp.hpp | 99-------------------------------------------------------------------------------
Minclude/kfr/math/min_max.hpp | 36------------------------------------
Minclude/kfr/math/modzerobessel.hpp | 6------
Minclude/kfr/math/round.hpp | 55-------------------------------------------------------
Minclude/kfr/math/saturation.hpp | 14--------------
Minclude/kfr/math/select.hpp | 10----------
Minclude/kfr/math/sin_cos.hpp | 123-------------------------------------------------------------------------------
Minclude/kfr/math/sqrt.hpp | 9---------
Minclude/kfr/math/tan.hpp | 12------------
Minclude/kfr/simd/comparison.hpp | 36------------------------------------
Minclude/kfr/simd/complex.hpp | 81-------------------------------------------------------------------------------
Ainclude/kfr/simd/complex_type.hpp | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/kfr/simd/impl/basicoperators_complex.hpp | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kfr/simd/impl/function.hpp | 1-
Minclude/kfr/simd/impl/operators.hpp | 72++----------------------------------------------------------------------
Minclude/kfr/simd/operators.hpp | 165-------------------------------------------------------------------------------
Minclude/kfr/simd/read_write.hpp | 2+-
Msources.cmake | 10++++++++++
Mtests/unit/base/conversion.cpp | 1+
35 files changed, 1148 insertions(+), 976 deletions(-)

diff --git a/include/kfr/base.hpp b/include/kfr/base.hpp @@ -31,10 +31,12 @@ #include "base/fraction.hpp" #include "base/function_expressions.hpp" #include "base/generators.hpp" +#include "base/math_expressions.hpp" #include "base/memory.hpp" #include "base/pointer.hpp" #include "base/random.hpp" #include "base/reduce.hpp" +#include "base/simd_expressions.hpp" #include "base/small_buffer.hpp" #include "base/sort.hpp" #include "base/univector.hpp" diff --git a/include/kfr/base/math_expressions.hpp b/include/kfr/base/math_expressions.hpp @@ -0,0 +1,654 @@ +/** @addtogroup expressions + * @{ + */ +/* + Copyright (C) 2016 D Levin (https://www.kfrlib.com) + This file is part of KFR + + KFR is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + KFR is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with KFR. + + If GPL is not suitable for your project, you must purchase a commercial license to use KFR. + Buying a commercial license is mandatory as soon as you develop commercial activities without + disclosing the source code of your own applications. + See https://www.kfrlib.com for details. + */ +#pragma once + +#include "../math.hpp" +#include "basic_expressions.hpp" +#include "expression.hpp" + +namespace kfr +{ + +/** + * @brief Returns template expression that returns x if m is true, otherwise return y. Order of the arguments + * is same as in ternary operator. + */ +template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> +KFR_FUNCTION internal::expression_function<fn::select, E1, E2, E3> select(E1&& m, E2&& x, E3&& y) +{ + return { fn::select(), std::forward<E1>(m), std::forward<E2>(x), std::forward<E3>(y) }; +} + +/** + * @brief Returns template expression that returns the absolute value of x. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::abs, E1> abs(E1&& x) +{ + return { fn::abs(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the smaller of two values. Accepts and returns expressions. + */ +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::min, E1, E2> min(E1&& x, E2&& y) +{ + return { fn::min(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/** + * @brief Returns the greater of two values. Accepts and returns expressions. + */ +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::max, E1, E2> max(E1&& x, E2&& y) +{ + return { fn::max(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/** + * @brief Returns the smaller in magnitude of two values. Accepts and returns expressions. + */ +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::absmin, E1, E2> absmin(E1&& x, E2&& y) +{ + return { fn::absmin(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/** + * @brief Returns the greater in magnitude of two values. Accepts and returns expressions. + */ +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::absmax, E1, E2> absmax(E1&& x, E2&& y) +{ + return { fn::absmax(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/// @brief Returns the largest integer value not greater than x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::floor, E1> floor(E1&& x) +{ + return { fn::floor(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::ceil, E1> ceil(E1&& x) +{ + return { fn::ceil(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::round, E1> round(E1&& x) +{ + return { fn::round(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::trunc, E1> trunc(E1&& x) +{ + return { fn::trunc(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::fract, E1> fract(E1&& x) +{ + return { fn::fract(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::ifloor, E1> ifloor(E1&& x) +{ + return { fn::ifloor(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::iceil, E1> iceil(E1&& x) +{ + return { fn::iceil(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::iround, E1> iround(E1&& x) +{ + return { fn::iround(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::itrunc, E1> itrunc(E1&& x) +{ + return { fn::itrunc(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric sine of x. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sin, E1> sin(E1&& x) +{ + return { fn::sin(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric cosine of x. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cos, E1> cos(E1&& x) +{ + return { fn::cos(), std::forward<E1>(x) }; +} + +/** + * @brief Returns an approximation of the trigonometric sine of x. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::fastsin, E1> fastsin(E1&& x) +{ + return { fn::fastsin(), std::forward<E1>(x) }; +} + +/** + * @brief Returns an approximation of the trigonometric cosine of x. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::fastcos, E1> fastcos(E1&& x) +{ + return { fn::fastcos(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric sine of the even elements of the x and + * cosine of the odd elements. x must be a vector. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sincos, E1> sincos(E1&& x) +{ + return { fn::sincos(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric cosine of the even elements of the x and + * sine of the odd elements. x must be a vector. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cossin, E1> cossin(E1&& x) +{ + return { fn::cossin(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric sine of the x (expressed in degrees). Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sindeg, E1> sindeg(E1&& x) +{ + return { fn::sindeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric cosine of the x (expressed in degrees). Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cosdeg, E1> cosdeg(E1&& x) +{ + return { fn::cosdeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns an approximation of the trigonometric sine of the x + * (expressed in degrees). Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::fastsindeg, E1> fastsindeg(E1&& x) +{ + return { fn::fastsindeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns an approximation of the trigonometric cosine of the x + * (expressed in degrees). Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::fastcosdeg, E1> fastcosdeg(E1&& x) +{ + return { fn::fastcosdeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric sine of the even elements of the x and + * cosine of the odd elements. x must be expressed in degrees. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sincosdeg, E1> sincosdeg(E1&& x) +{ + return { fn::sincosdeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the trigonometric cosine of the even elements of the x and + * sine of the odd elements. x must be expressed in degrees. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cossindeg, E1> cossindeg(E1&& x) +{ + return { fn::cossindeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns the sinc function of x. Accepts and returns expressions. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sinc, E1> sinc(E1&& x) +{ + return { fn::sinc(), std::forward<E1>(x) }; +} + +/// @brief Creates an expression that returns the first argument clamped to a range [lo, hi] +template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> +KFR_FUNCTION internal::expression_function<fn::clamp, E1, E2, E3> clamp(E1&& x, E2&& lo, E3&& hi) +{ + return { fn::clamp(), std::forward<E1>(x), std::forward<E2>(lo), std::forward<E3>(hi) }; +} + +/// @brief Creates an expression that returns the first argument clamped to a range [0, hi] +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::clamp, E1, E2> clamp(E1&& x, E2&& hi) +{ + return { fn::clamp(), std::forward<E1>(x), std::forward<E2>(hi) }; +} + +/// @brief Creates expression that returns the approximate gamma function of an argument +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::gamma, E1> gamma(E1&& x) +{ + return { fn::gamma(), std::forward<E1>(x) }; +} + +/// @brief Creates expression that returns the approximate factorial of an argument +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::factorial_approx, E1> factorial_approx(E1&& x) +{ + return { fn::factorial_approx(), std::forward<E1>(x) }; +} + +/** + * @brief Returns template expression that returns the positive square root of the x. \f$\sqrt{x}\f$ + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sqrt, E1> sqrt(E1&& x) +{ + return { fn::sqrt(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::tan, E1> tan(E1&& x) +{ + return { fn::tan(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::tandeg, E1> tandeg(E1&& x) +{ + return { fn::tandeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns template expression that returns the arc sine of x. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::asin, E1> asin(E1&& x) +{ + return { fn::asin(), std::forward<E1>(x) }; +} + +/** + * @brief Returns template expression that returns the arc cosine of x. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::acos, E1> acos(E1&& x) +{ + return { fn::acos(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the sine of the the complex value x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::csin, E1> csin(E1&& x) +{ + return { fn::csin(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the hyperbolic sine of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::csinh, E1> csinh(E1&& x) +{ + return { fn::csinh(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the cosine of the the complex value x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::ccos, E1> ccos(E1&& x) +{ + return { fn::ccos(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the hyperbolic cosine of the the complex value x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::ccosh, E1> ccosh(E1&& x) +{ + return { fn::ccosh(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the squared absolute value (magnitude squared) of the +/// complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cabssqr, E1> cabssqr(E1&& x) +{ + return { fn::cabssqr(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the absolute value (magnitude) of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cabs, E1> cabs(E1&& x) +{ + return { fn::cabs(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the phase angle (argument) of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::carg, E1> carg(E1&& x) +{ + return { fn::carg(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the natural logarithm of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::clog, E1> clog(E1&& x) +{ + return { fn::clog(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the binary (base-2) logarithm of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::clog2, E1> clog2(E1&& x) +{ + return { fn::clog2(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the common (base-10) logarithm of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::clog10, E1> clog10(E1&& x) +{ + return { fn::clog10(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns \f$e\f$ raised to the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cexp, E1> cexp(E1&& x) +{ + return { fn::cexp(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns 2 raised to the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cexp2, E1> cexp2(E1&& x) +{ + return { fn::cexp2(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns 10 raised to the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cexp10, E1> cexp10(E1&& x) +{ + return { fn::cexp10(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that converts complex number to polar +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::polar, E1> polar(E1&& x) +{ + return { fn::polar(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that converts complex number to cartesian +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cartesian, E1> cartesian(E1&& x) +{ + return { fn::cartesian(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns square root of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::csqrt, E1> csqrt(E1&& x) +{ + return { fn::csqrt(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns square of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::csqr, E1> csqr(E1&& x) +{ + return { fn::csqr(), std::forward<E1>(x) }; +} + +/** + * @brief Returns template expression that returns the arc tangent of x. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::atan, E1> atan(E1&& x) +{ + return { fn::atan(), std::forward<E1>(x) }; +} + +/** + * @brief Returns template expression that returns the arc tangent of the x, expressed in degrees. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::atandeg, E1> atandeg(E1&& x) +{ + return { fn::atandeg(), std::forward<E1>(x) }; +} + +/** + * @brief Returns template expression that returns the arc tangent of y/x. + */ +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::atan2, E1, E2> atan2(E1&& x, E2&& y) +{ + return { fn::atan2(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/** + * @brief Returns template expression that returns the arc tangent of y/x (expressed in degrees). + */ +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::atan2deg, E1, E2> atan2deg(E1&& x, E2&& y) +{ + return { fn::atan2deg(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::modzerobessel, E1> modzerobessel(E1&& x) +{ + return { fn::modzerobessel(), std::forward<E1>(x) }; +} + +/// @brief Creates an expression that adds two arguments using saturation +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::satadd, E1, E2> satadd(E1&& x, E2&& y) +{ + return { fn::satadd(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/// @brief Creates an expression that subtracts two arguments using saturation +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::satsub, E1, E2> satsub(E1&& x, E2&& y) +{ + return { fn::satsub(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/// @brief Returns template expression that returns the hyperbolic sine of the x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sinh, E1> sinh(E1&& x) +{ + return { fn::sinh(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the hyperbolic cosine of the x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cosh, E1> cosh(E1&& x) +{ + return { fn::cosh(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the hyperbolic tangent of the x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::tanh, E1> tanh(E1&& x) +{ + return { fn::tanh(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the hyperbolic cotangent of the x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::coth, E1> coth(E1&& x) +{ + return { fn::coth(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the hyperbolic sine of the even elements of the x and the +/// hyperbolic cosine of the odd elements of the x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::sinhcosh, E1> sinhcosh(E1&& x) +{ + return { fn::sinhcosh(), std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the hyperbolic cosine of the even elements of the x and +/// the hyperbolic sine of the odd elements of the x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::coshsinh, E1> coshsinh(E1&& x) +{ + return { fn::coshsinh(), std::forward<E1>(x) }; +} + +/// @brief Returns e raised to the given power x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::exp, E1> exp(E1&& x) +{ + return { fn::exp(), std::forward<E1>(x) }; +} + +/// @brief Returns 2 raised to the given power x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::exp2, E1> exp2(E1&& x) +{ + return { fn::exp2(), std::forward<E1>(x) }; +} + +/// @brief Returns 10 raised to the given power x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::exp10, E1> exp10(E1&& x) +{ + return { fn::exp10(), std::forward<E1>(x) }; +} + +/// @brief Returns the natural logarithm of the x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::log, E1> log(E1&& x) +{ + return { fn::log(), std::forward<E1>(x) }; +} + +/// @brief Returns the binary (base-2) logarithm of the x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::log2, E1> log2(E1&& x) +{ + return { fn::log2(), std::forward<E1>(x) }; +} + +/// @brief Returns the common (base-10) logarithm of the x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::log10, E1> log10(E1&& x) +{ + return { fn::log10(), std::forward<E1>(x) }; +} + +/// @brief Returns the rounded binary (base-2) logarithm of the x. Version that accepts and returns +/// expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::logb, E1> logb(E1&& x) +{ + return { fn::logb(), std::forward<E1>(x) }; +} + +/// @brief Returns the logarithm of the x with base y. Accepts and returns expressions. +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::logn, E1, E2> logn(E1&& x, E2&& y) +{ + return { fn::logn(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/// @brief Returns log(x) * y. Accepts and returns expressions. +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::logm, E1, E2> logm(E1&& x, E2&& y) +{ + return { fn::logm(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/// @brief Returns exp(x * m + a). Accepts and returns expressions. +template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> +KFR_FUNCTION internal::expression_function<fn::exp_fmadd, E1, E2, E3> exp_fmadd(E1&& x, E2&& y, E3&& z) +{ + return { fn::exp_fmadd(), std::forward<E1>(x), std::forward<E2>(y), std::forward<E3>(z) }; +} + +/// @brief Returns log(x) * m + a. Accepts and returns expressions. +template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> +KFR_FUNCTION internal::expression_function<fn::log_fmadd, E1, E2, E3> log_fmadd(E1&& x, E2&& y, E3&& z) +{ + return { fn::log_fmadd(), std::forward<E1>(x), std::forward<E2>(y), std::forward<E3>(z) }; +} + +/// @brief Returns the x raised to the given power y. Accepts and returns expressions. +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::pow, E1, E2> pow(E1&& x, E2&& y) +{ + return { fn::pow(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/// @brief Returns the real nth root of the x. Accepts and returns expressions. +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_FUNCTION internal::expression_function<fn::root, E1, E2> root(E1&& x, E2&& y) +{ + return { fn::root(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/// @brief Returns the cube root of the x. Accepts and returns expressions. +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cbrt, E1> cbrt(E1&& x) +{ + return { fn::cbrt(), std::forward<E1>(x) }; +} + +} // namespace kfr +\ No newline at end of file diff --git a/include/kfr/base/random.hpp b/include/kfr/base/random.hpp @@ -29,6 +29,7 @@ #include "../simd/operators.hpp" #include "../simd/shuffle.hpp" #include "../simd/vec.hpp" +#include "expression.hpp" #include <functional> #ifdef CMT_ARCH_ARM diff --git a/include/kfr/base/simd_expressions.hpp b/include/kfr/base/simd_expressions.hpp @@ -0,0 +1,269 @@ +/** @addtogroup expressions + * @{ + */ +/* + Copyright (C) 2016 D Levin (https://www.kfrlib.com) + This file is part of KFR + + KFR is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + KFR is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with KFR. + + If GPL is not suitable for your project, you must purchase a commercial license to use KFR. + Buying a commercial license is mandatory as soon as you develop commercial activities without + disclosing the source code of your own applications. + See https://www.kfrlib.com for details. + */ +#pragma once + +#include "../simd/complex.hpp" +#include "../simd/operators.hpp" +#include "../simd/comparison.hpp" +#include "../simd/vec.hpp" +#include "basic_expressions.hpp" +#include "univector.hpp" +#include <algorithm> + +namespace kfr +{ + +/** + * @brief Returns template expression that returns sum of all the arguments passed to a function. + */ +template <typename... E, KFR_ENABLE_IF((is_input_expressions<E...>)&&true)> +KFR_INTRINSIC internal::expression_function<fn::add, E...> add(E&&... x) +{ + return { fn::add(), std::forward<E>(x)... }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::sub, E1, E2> sub(E1&& x, E2&& y) +{ + return { fn::sub(), std::forward<E1>(x), std::forward<E2>(y) }; +} + +/** + * @brief Returns template expression that returns product of all the arguments passed to a function. + */ +template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> +KFR_INTRINSIC internal::expression_function<fn::mul, E...> mul(E&&... x) +{ + return { fn::mul(), std::forward<E>(x)... }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::ipow, E1, E2> ipow(E1&& x, E2&& b) +{ + return { fn::ipow(), std::forward<E1>(x), std::forward<E2>(b) }; +} + +template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> +KFR_INTRINSIC internal::expression_function<fn::mix, E1, E2, E3> mix(E1&& c, E2&& x, E3&& y) +{ + return { fn::mix(), std::forward<E1>(c), std::forward<E2>(x), std::forward<E3>(y) }; +} + +template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> +KFR_INTRINSIC internal::expression_function<fn::mixs, E1, E2, E3> mixs(E1&& c, E2&& x, E3&& y) +{ + return { fn::mixs(), std::forward<E1>(c), std::forward<E2>(x), std::forward<E3>(y) }; +} + +template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> +KFR_INTRINSIC internal::expression_function<fn::horner, E...> horner(E&&... x) +{ + return { fn::horner(), std::forward<E>(x)... }; +} + +template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> +KFR_INTRINSIC internal::expression_function<fn::horner_even, E...> horner_even(E&&... x) +{ + return { fn::horner_even(), std::forward<E>(x)... }; +} + +template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> +KFR_INTRINSIC internal::expression_function<fn::horner_odd, E...> horner_odd(E&&... x) +{ + return { fn::horner_odd(), std::forward<E>(x)... }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::add, E1, E2> operator+(E1&& e1, E2&& e2) +{ + return { fn::add(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::sub, E1, E2> operator-(E1&& e1, E2&& e2) +{ + return { fn::sub(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::mul, E1, E2> operator*(E1&& e1, E2&& e2) +{ + return { fn::mul(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::div, E1, E2> operator/(E1&& e1, E2&& e2) +{ + return { fn::div(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::bitwiseand, E1, E2> operator&(E1&& e1, E2&& e2) +{ + return { fn::bitwiseand(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::bitwiseor, E1, E2> operator|(E1&& e1, E2&& e2) +{ + return { fn::bitwiseor(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::bitwisexor, E1, E2> operator^(E1&& e1, E2&& e2) +{ + return { fn::bitwisexor(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::shl, E1, E2> operator<<(E1&& e1, E2&& e2) +{ + return { fn::shl(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::shr, E1, E2> operator>>(E1&& e1, E2&& e2) +{ + return { fn::shr(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +/** + * @brief Returns template expression that returns square of x. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::sqr, E1> sqr(E1&& x) +{ + return { fn::sqr(), std::forward<E1>(x) }; +} + +/** + * @brief Returns template expression that returns cube of x. + */ +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::cub, E1> cub(E1&& x) +{ + return { fn::cub(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::pow2, E1> pow2(E1&& x) +{ + return { fn::pow2(), std::forward<E1>(x) }; +} +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::pow3, E1> pow3(E1&& x) +{ + return { fn::pow3(), std::forward<E1>(x) }; +} +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::pow4, E1> pow4(E1&& x) +{ + return { fn::pow4(), std::forward<E1>(x) }; +} +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::pow5, E1> pow5(E1&& x) +{ + return { fn::pow5(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::neg, E1> operator-(E1&& e1) +{ + return { fn::neg(), std::forward<E1>(e1) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::bitwisenot, E1> operator~(E1&& e1) +{ + return { fn::bitwisenot(), std::forward<E1>(e1) }; +} + +/// @brief Constructs complex value from real and imaginary parts +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::make_complex, E1, E2> make_complex(E1&& re, E2&& im) +{ + return { fn::make_complex{}, std::forward<E1>(re), std::forward<E2>(im) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::equal, E1, E2> operator==(E1&& e1, E2&& e2) +{ + return { fn::equal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::notequal, E1, E2> operator!=(E1&& e1, E2&& e2) +{ + return { fn::notequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::less, E1, E2> operator<(E1&& e1, E2&& e2) +{ + return { fn::less(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::greater, E1, E2> operator>(E1&& e1, E2&& e2) +{ + return { fn::greater(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::lessorequal, E1, E2> operator<=(E1&& e1, E2&& e2) +{ + return { fn::lessorequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + +template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> +KFR_INTRINSIC internal::expression_function<fn::greaterorequal, E1, E2> operator>=(E1&& e1, E2&& e2) +{ + return { fn::greaterorequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; +} + + +/// @brief Returns the real part of the complex value +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::real, E1> real(E1&& x) +{ + return { fn::real{}, std::forward<E1>(x) }; +} + +/// @brief Returns the imaginary part of the complex value +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_INTRINSIC internal::expression_function<fn::imag, E1> imag(E1&& x) +{ + return { fn::imag{}, std::forward<E1>(x) }; +} + +/// @brief Returns template expression that returns the complex conjugate of the complex number x +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> +KFR_FUNCTION internal::expression_function<fn::cconj, E1> cconj(E1&& x) +{ + return { fn::cconj(), std::forward<E1>(x) }; +} + +} // namespace kfr diff --git a/include/kfr/base/univector.hpp b/include/kfr/base/univector.hpp @@ -26,7 +26,7 @@ #pragma once #include "../cometa/array.hpp" - +#include "expression.hpp" #include "../simd/impl/function.hpp" #include "../simd/read_write.hpp" #include "../simd/types.hpp" diff --git a/include/kfr/dft/impl/convolution-impl.cpp b/include/kfr/dft/impl/convolution-impl.cpp @@ -24,6 +24,8 @@ See https://www.kfrlib.com for details. */ #include "../convolution.hpp" +#include "../../simd/complex.hpp" +#include "../../base/simd_expressions.hpp" namespace kfr { diff --git a/include/kfr/dft/impl/dft-impl.hpp b/include/kfr/dft/impl/dft-impl.hpp @@ -26,6 +26,8 @@ #pragma once #include "dft-fft.hpp" +#include "../../base/simd_expressions.hpp" +#include "../../base/math_expressions.hpp" CMT_PRAGMA_GNU(GCC diagnostic push) #if CMT_HAS_WARNING("-Wshadow") diff --git a/include/kfr/dsp/fir.hpp b/include/kfr/dsp/fir.hpp @@ -26,6 +26,7 @@ #pragma once #include "../base/basic_expressions.hpp" +#include "../base/simd_expressions.hpp" #include "../base/filter.hpp" #include "../base/memory.hpp" #include "../base/reduce.hpp" diff --git a/include/kfr/dsp/iir_design.hpp b/include/kfr/dsp/iir_design.hpp @@ -30,6 +30,7 @@ #include "../math/hyperbolic.hpp" #include "../simd/impl/function.hpp" #include "../simd/operators.hpp" +#include "../simd/complex.hpp" #include "../simd/vec.hpp" #include "../testo/assert.hpp" #include "biquad_design.hpp" @@ -897,8 +898,7 @@ template <typename T> KFR_FUNCTION univector<complex<T>> cplxreal(const univector<complex<T>>& list) { univector<complex<T>> x = list; - std::sort(x.begin(), x.end(), - [](const complex<T>& a, const complex<T>& b) { return a.real() < b.real(); }); + std::sort(x.begin(), x.end(), [](const complex<T>& a, const complex<T>& b) { return a.real() < b.real(); }); T tol = std::numeric_limits<T>::epsilon() * 100; univector<complex<T>> result = x; for (size_t i = result.size(); i > 1; i--) diff --git a/include/kfr/math/abs.hpp b/include/kfr/math/abs.hpp @@ -40,15 +40,6 @@ KFR_INTRINSIC T1 abs(const T1& x) { return intrinsics::abs(x); } - -/** - * @brief Returns template expression that returns the absolute value of x. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::abs, E1> abs(E1&& x) -{ - return { fn::abs(), std::forward<E1>(x) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/asin_acos.hpp b/include/kfr/math/asin_acos.hpp @@ -40,15 +40,6 @@ KFR_INTRINSIC flt_type<T1> asin(const T1& x) { return intrinsics::asin(x); } - -/** - * @brief Returns template expression that returns the arc sine of x. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::asin, E1> asin(E1&& x) -{ - return { fn::asin(), std::forward<E1>(x) }; -} /** * @brief Returns the arc cosine of x. The returned angle is in the range 0 through \f$\pi\f$. */ @@ -57,15 +48,6 @@ KFR_INTRINSIC flt_type<T1> acos(const T1& x) { return intrinsics::acos(x); } - -/** - * @brief Returns template expression that returns the arc cosine of x. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::acos, E1> acos(E1&& x) -{ - return { fn::acos(), std::forward<E1>(x) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/atan.hpp b/include/kfr/math/atan.hpp @@ -43,15 +43,6 @@ KFR_FUNCTION flt_type<T1> atan(const T1& x) } /** - * @brief Returns template expression that returns the arc tangent of x. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::atan, E1> atan(E1&& x) -{ - return { fn::atan(), std::forward<E1>(x) }; -} - -/** * @brief Returns the arc tangent of the x, expressed in degrees. The returned angle is in the range -90 * through 90. */ @@ -62,15 +53,6 @@ KFR_FUNCTION flt_type<T1> atandeg(const T1& x) } /** - * @brief Returns template expression that returns the arc tangent of the x, expressed in degrees. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::atandeg, E1> atandeg(E1&& x) -{ - return { fn::atandeg(), std::forward<E1>(x) }; -} - -/** * @brief Returns the arc tangent of y/x using the signs of arguments to determine the correct quadrant. */ template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>)> @@ -80,15 +62,6 @@ KFR_FUNCTION common_type<T1, T2> atan2(const T1& x, const T2& y) } /** - * @brief Returns template expression that returns the arc tangent of y/x. - */ -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_FUNCTION internal::expression_function<fn::atan2, E1, E2> atan2(E1&& x, E2&& y) -{ - return { fn::atan2(), std::forward<E1>(x), std::forward<E2>(y) }; -} - -/** * @brief Returns the arc tangent of y/x (expressed in degrees) using the signs of arguments to determine the * correct quadrant. */ @@ -97,14 +70,5 @@ KFR_FUNCTION common_type<T1, T2> atan2deg(const T1& x, const T2& y) { return intrinsics::atan2deg(x, y); } - -/** - * @brief Returns template expression that returns the arc tangent of y/x (expressed in degrees). - */ -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_FUNCTION internal::expression_function<fn::atan2deg, E1, E2> atan2deg(E1&& x, E2&& y) -{ - return { fn::atan2deg(), std::forward<E1>(x), std::forward<E2>(y) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/clamp.hpp b/include/kfr/math/clamp.hpp @@ -40,13 +40,6 @@ KFR_INTRINSIC Tout clamp(const T1& x, const T2& lo, const T3& hi) return intrinsics::clamp(static_cast<Tout>(x), static_cast<Tout>(lo), static_cast<Tout>(hi)); } -/// @brief Creates an expression that returns the first argument clamped to a range [lo, hi] -template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> -KFR_INTRINSIC internal::expression_function<fn::clamp, E1, E2, E3> clamp(E1&& x, E2&& lo, E3&& hi) -{ - return { fn::clamp(), std::forward<E1>(x), std::forward<E2>(lo), std::forward<E3>(hi) }; -} - /// @brief Returns the first argument clamped to a range [0, hi] template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>), typename Tout = common_type<T1, T2>> @@ -54,12 +47,5 @@ KFR_INTRINSIC Tout clamp(const T1& x, const T2& hi) { return intrinsics::clamp(static_cast<Tout>(x), static_cast<Tout>(hi)); } - -/// @brief Creates an expression that returns the first argument clamped to a range [0, hi] -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::clamp, E1, E2> clamp(E1&& x, E2&& hi) -{ - return { fn::clamp(), std::forward<E1>(x), std::forward<E2>(hi) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/complex_math.hpp b/include/kfr/math/complex_math.hpp @@ -223,13 +223,6 @@ KFR_FUNCTION T1 csin(const T1& x) return intrinsics::csin(x); } -/// @brief Returns template expression that returns the sine of the the complex value x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::csin, E1> csin(E1&& x) -{ - return { fn::csin(), std::forward<E1>(x) }; -} - /// @brief Returns the hyperbolic sine of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 csinh(const T1& x) @@ -237,13 +230,6 @@ KFR_FUNCTION T1 csinh(const T1& x) return intrinsics::csinh(x); } -/// @brief Returns template expression that returns the hyperbolic sine of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::csinh, E1> csinh(E1&& x) -{ - return { fn::csinh(), std::forward<E1>(x) }; -} - /// @brief Returns the cosine of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 ccos(const T1& x) @@ -251,13 +237,6 @@ KFR_FUNCTION T1 ccos(const T1& x) return intrinsics::ccos(x); } -/// @brief Returns template expression that returns the cosine of the the complex value x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::ccos, E1> ccos(E1&& x) -{ - return { fn::ccos(), std::forward<E1>(x) }; -} - /// @brief Returns the hyperbolic cosine of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 ccosh(const T1& x) @@ -265,13 +244,6 @@ KFR_FUNCTION T1 ccosh(const T1& x) return intrinsics::ccosh(x); } -/// @brief Returns template expression that returns the hyperbolic cosine of the the complex value x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::ccosh, E1> ccosh(E1&& x) -{ - return { fn::ccosh(), std::forward<E1>(x) }; -} - /// @brief Returns the squared absolute value (magnitude squared) of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION realtype<T1> cabssqr(const T1& x) @@ -279,14 +251,6 @@ KFR_FUNCTION realtype<T1> cabssqr(const T1& x) return intrinsics::cabssqr(x); } -/// @brief Returns template expression that returns the squared absolute value (magnitude squared) of the -/// complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cabssqr, E1> cabssqr(E1&& x) -{ - return { fn::cabssqr(), std::forward<E1>(x) }; -} - /// @brief Returns the absolute value (magnitude) of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION realtype<T1> cabs(const T1& x) @@ -294,13 +258,6 @@ KFR_FUNCTION realtype<T1> cabs(const T1& x) return intrinsics::cabs(x); } -/// @brief Returns template expression that returns the absolute value (magnitude) of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cabs, E1> cabs(E1&& x) -{ - return { fn::cabs(), std::forward<E1>(x) }; -} - /// @brief Returns the phase angle (argument) of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION realtype<T1> carg(const T1& x) @@ -308,13 +265,6 @@ KFR_FUNCTION realtype<T1> carg(const T1& x) return intrinsics::carg(x); } -/// @brief Returns template expression that returns the phase angle (argument) of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::carg, E1> carg(E1&& x) -{ - return { fn::carg(), std::forward<E1>(x) }; -} - /// @brief Returns the natural logarithm of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 clog(const T1& x) @@ -322,13 +272,6 @@ KFR_FUNCTION T1 clog(const T1& x) return intrinsics::clog(x); } -/// @brief Returns template expression that returns the natural logarithm of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::clog, E1> clog(E1&& x) -{ - return { fn::clog(), std::forward<E1>(x) }; -} - /// @brief Returns the binary (base-2) logarithm of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 clog2(const T1& x) @@ -336,13 +279,6 @@ KFR_FUNCTION T1 clog2(const T1& x) return intrinsics::clog2(x); } -/// @brief Returns template expression that returns the binary (base-2) logarithm of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::clog2, E1> clog2(E1&& x) -{ - return { fn::clog2(), std::forward<E1>(x) }; -} - /// @brief Returns the common (base-10) logarithm of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 clog10(const T1& x) @@ -350,13 +286,6 @@ KFR_FUNCTION T1 clog10(const T1& x) return intrinsics::clog10(x); } -/// @brief Returns template expression that returns the common (base-10) logarithm of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::clog10, E1> clog10(E1&& x) -{ - return { fn::clog10(), std::forward<E1>(x) }; -} - /// @brief Returns \f$e\f$ raised to the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 cexp(const T1& x) @@ -364,13 +293,6 @@ KFR_FUNCTION T1 cexp(const T1& x) return intrinsics::cexp(x); } -/// @brief Returns template expression that returns \f$e\f$ raised to the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cexp, E1> cexp(E1&& x) -{ - return { fn::cexp(), std::forward<E1>(x) }; -} - /// @brief Returns 2 raised to the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 cexp2(const T1& x) @@ -378,13 +300,6 @@ KFR_FUNCTION T1 cexp2(const T1& x) return intrinsics::cexp2(x); } -/// @brief Returns template expression that returns 2 raised to the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cexp2, E1> cexp2(E1&& x) -{ - return { fn::cexp2(), std::forward<E1>(x) }; -} - /// @brief Returns 10 raised to the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 cexp10(const T1& x) @@ -392,13 +307,6 @@ KFR_FUNCTION T1 cexp10(const T1& x) return intrinsics::cexp10(x); } -/// @brief Returns template expression that returns 10 raised to the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cexp10, E1> cexp10(E1&& x) -{ - return { fn::cexp10(), std::forward<E1>(x) }; -} - /// @brief Converts complex number to polar template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 polar(const T1& x) @@ -406,13 +314,6 @@ KFR_FUNCTION T1 polar(const T1& x) return intrinsics::polar(x); } -/// @brief Returns template expression that converts complex number to polar -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::polar, E1> polar(E1&& x) -{ - return { fn::polar(), std::forward<E1>(x) }; -} - /// @brief Converts complex number to cartesian template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 cartesian(const T1& x) @@ -420,13 +321,6 @@ KFR_FUNCTION T1 cartesian(const T1& x) return intrinsics::cartesian(x); } -/// @brief Returns template expression that converts complex number to cartesian -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cartesian, E1> cartesian(E1&& x) -{ - return { fn::cartesian(), std::forward<E1>(x) }; -} - /// @brief Returns square root of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 csqrt(const T1& x) @@ -434,13 +328,6 @@ KFR_FUNCTION T1 csqrt(const T1& x) return intrinsics::csqrt(x); } -/// @brief Returns template expression that returns square root of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::csqrt, E1> csqrt(E1&& x) -{ - return { fn::csqrt(), std::forward<E1>(x) }; -} - /// @brief Returns square of the complex number x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION T1 csqr(const T1& x) @@ -448,12 +335,5 @@ KFR_FUNCTION T1 csqr(const T1& x) return intrinsics::csqr(x); } -/// @brief Returns template expression that returns square of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::csqr, E1> csqr(E1&& x) -{ - return { fn::csqr(), std::forward<E1>(x) }; -} - } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/gamma.hpp b/include/kfr/math/gamma.hpp @@ -39,13 +39,6 @@ KFR_FUNCTION flt_type<T1> gamma(const T1& x) return intrinsics::gamma(x); } -/// @brief Creates expression that returns the approximate gamma function of an argument -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::gamma, E1> gamma(E1&& x) -{ - return { fn::gamma(), std::forward<E1>(x) }; -} - /// @brief Returns the approximate factorial of an argument template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> factorial_approx(const T1& x) @@ -53,13 +46,6 @@ KFR_FUNCTION flt_type<T1> factorial_approx(const T1& x) return intrinsics::factorial_approx(x); } -/// @brief Creates expression that returns the approximate factorial of an argument -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::factorial_approx, E1> factorial_approx(E1&& x) -{ - return { fn::factorial_approx(), std::forward<E1>(x) }; -} - constexpr inline uint64_t factorial_table[21] = { 0, 1, diff --git a/include/kfr/math/hyperbolic.hpp b/include/kfr/math/hyperbolic.hpp @@ -39,13 +39,6 @@ KFR_FUNCTION flt_type<T1> sinh(const T1& x) return intrinsics::sinh(x); } -/// @brief Returns template expression that returns the hyperbolic sine of the x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::sinh, E1> sinh(E1&& x) -{ - return { fn::sinh(), std::forward<E1>(x) }; -} - /// @brief Returns the hyperbolic cosine of the x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> cosh(const T1& x) @@ -53,13 +46,6 @@ KFR_FUNCTION flt_type<T1> cosh(const T1& x) return intrinsics::cosh(x); } -/// @brief Returns template expression that returns the hyperbolic cosine of the x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cosh, E1> cosh(E1&& x) -{ - return { fn::cosh(), std::forward<E1>(x) }; -} - /// @brief Returns the hyperbolic tangent of the x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> tanh(const T1& x) @@ -67,13 +53,6 @@ KFR_FUNCTION flt_type<T1> tanh(const T1& x) return intrinsics::tanh(x); } -/// @brief Returns template expression that returns the hyperbolic tangent of the x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::tanh, E1> tanh(E1&& x) -{ - return { fn::tanh(), std::forward<E1>(x) }; -} - /// @brief Returns the hyperbolic cotangent of the x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> coth(const T1& x) @@ -81,13 +60,6 @@ KFR_FUNCTION flt_type<T1> coth(const T1& x) return intrinsics::coth(x); } -/// @brief Returns template expression that returns the hyperbolic cotangent of the x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::coth, E1> coth(E1&& x) -{ - return { fn::coth(), std::forward<E1>(x) }; -} - /// @brief Returns the hyperbolic sine of the even elements of the x and the hyperbolic cosine of the odd /// elements of the x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -96,14 +68,6 @@ KFR_FUNCTION flt_type<T1> sinhcosh(const T1& x) return intrinsics::sinhcosh(x); } -/// @brief Returns template expression that returns the hyperbolic sine of the even elements of the x and the -/// hyperbolic cosine of the odd elements of the x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::sinhcosh, E1> sinhcosh(E1&& x) -{ - return { fn::sinhcosh(), std::forward<E1>(x) }; -} - /// @brief Returns the hyperbolic cosine of the even elements of the x and the hyperbolic sine of the odd /// elements of the x template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -111,13 +75,5 @@ KFR_FUNCTION flt_type<T1> coshsinh(const T1& x) { return intrinsics::coshsinh(x); } - -/// @brief Returns template expression that returns the hyperbolic cosine of the even elements of the x and -/// the hyperbolic sine of the odd elements of the x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::coshsinh, E1> coshsinh(E1&& x) -{ - return { fn::coshsinh(), std::forward<E1>(x) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/log_exp.hpp b/include/kfr/math/log_exp.hpp @@ -39,13 +39,6 @@ KFR_FUNCTION flt_type<T1> exp(const T1& x) return intrinsics::exp(x); } -/// @brief Returns e raised to the given power x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::exp, E1> exp(E1&& x) -{ - return { fn::exp(), std::forward<E1>(x) }; -} - /// @brief Returns 2 raised to the given power x. template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> exp2(const T1& x) @@ -53,13 +46,6 @@ KFR_FUNCTION flt_type<T1> exp2(const T1& x) return intrinsics::exp2(x); } -/// @brief Returns 2 raised to the given power x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::exp2, E1> exp2(E1&& x) -{ - return { fn::exp2(), std::forward<E1>(x) }; -} - /// @brief Returns 10 raised to the given power x. template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> exp10(const T1& x) @@ -67,13 +53,6 @@ KFR_FUNCTION flt_type<T1> exp10(const T1& x) return intrinsics::exp10(x); } -/// @brief Returns 10 raised to the given power x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::exp10, E1> exp10(E1&& x) -{ - return { fn::exp10(), std::forward<E1>(x) }; -} - /// @brief Returns the natural logarithm of the x. template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> log(const T1& x) @@ -81,13 +60,6 @@ KFR_FUNCTION flt_type<T1> log(const T1& x) return intrinsics::log(x); } -/// @brief Returns the natural logarithm of the x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::log, E1> log(E1&& x) -{ - return { fn::log(), std::forward<E1>(x) }; -} - /// @brief Returns the binary (base-2) logarithm of the x. template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> log2(const T1& x) @@ -95,13 +67,6 @@ KFR_FUNCTION flt_type<T1> log2(const T1& x) return intrinsics::log2(x); } -/// @brief Returns the binary (base-2) logarithm of the x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::log2, E1> log2(E1&& x) -{ - return { fn::log2(), std::forward<E1>(x) }; -} - /// @brief Returns the common (base-10) logarithm of the x. template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> log10(const T1& x) @@ -109,13 +74,6 @@ KFR_FUNCTION flt_type<T1> log10(const T1& x) return intrinsics::log10(x); } -/// @brief Returns the common (base-10) logarithm of the x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::log10, E1> log10(E1&& x) -{ - return { fn::log10(), std::forward<E1>(x) }; -} - /// @brief Returns the rounded binary (base-2) logarithm of the x. template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> logb(const T1& x) @@ -123,14 +81,6 @@ KFR_FUNCTION flt_type<T1> logb(const T1& x) return intrinsics::logb(x); } -/// @brief Returns the rounded binary (base-2) logarithm of the x. Version that accepts and returns -/// expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::logb, E1> logb(E1&& x) -{ - return { fn::logb(), std::forward<E1>(x) }; -} - /// @brief Returns the logarithm of the x with base y. template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>)> KFR_FUNCTION flt_type<common_type<T1, T2>> logn(const T1& x, const T2& y) @@ -138,13 +88,6 @@ KFR_FUNCTION flt_type<common_type<T1, T2>> logn(const T1& x, const T2& y) return intrinsics::logn(x, y); } -/// @brief Returns the logarithm of the x with base y. Accepts and returns expressions. -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_FUNCTION internal::expression_function<fn::logn, E1, E2> logn(E1&& x, E2&& y) -{ - return { fn::logn(), std::forward<E1>(x), std::forward<E2>(y) }; -} - /// @brief Returns log(x) * y. template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>)> KFR_FUNCTION flt_type<common_type<T1, T2>> logm(const T1& x, const T2& y) @@ -152,13 +95,6 @@ KFR_FUNCTION flt_type<common_type<T1, T2>> logm(const T1& x, const T2& y) return intrinsics::logm(x, y); } -/// @brief Returns log(x) * y. Accepts and returns expressions. -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_FUNCTION internal::expression_function<fn::logm, E1, E2> logm(E1&& x, E2&& y) -{ - return { fn::logm(), std::forward<E1>(x), std::forward<E2>(y) }; -} - /// @brief Returns exp(x * m + a). template <typename T1, typename T2, typename T3, KFR_ENABLE_IF(is_numeric_args<T1, T2, T3>)> KFR_FUNCTION flt_type<common_type<T1, T2, T3>> exp_fmadd(const T1& x, const T2& y, const T3& z) @@ -166,13 +102,6 @@ KFR_FUNCTION flt_type<common_type<T1, T2, T3>> exp_fmadd(const T1& x, const T2& return intrinsics::exp_fmadd(x, y, z); } -/// @brief Returns exp(x * m + a). Accepts and returns expressions. -template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> -KFR_FUNCTION internal::expression_function<fn::exp_fmadd, E1, E2, E3> exp_fmadd(E1&& x, E2&& y, E3&& z) -{ - return { fn::exp_fmadd(), std::forward<E1>(x), std::forward<E2>(y), std::forward<E3>(z) }; -} - /// @brief Returns log(x) * m + a. template <typename T1, typename T2, typename T3, KFR_ENABLE_IF(is_numeric_args<T1, T2, T3>)> KFR_FUNCTION flt_type<common_type<T1, T2, T3>> log_fmadd(const T1& x, const T2& y, const T3& z) @@ -180,13 +109,6 @@ KFR_FUNCTION flt_type<common_type<T1, T2, T3>> log_fmadd(const T1& x, const T2& return intrinsics::log_fmadd(x, y, z); } -/// @brief Returns log(x) * m + a. Accepts and returns expressions. -template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> -KFR_FUNCTION internal::expression_function<fn::log_fmadd, E1, E2, E3> log_fmadd(E1&& x, E2&& y, E3&& z) -{ - return { fn::log_fmadd(), std::forward<E1>(x), std::forward<E2>(y), std::forward<E3>(z) }; -} - /// @brief Returns the x raised to the given power y. template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>)> KFR_FUNCTION flt_type<common_type<T1, T2>> pow(const T1& x, const T2& y) @@ -194,13 +116,6 @@ KFR_FUNCTION flt_type<common_type<T1, T2>> pow(const T1& x, const T2& y) return intrinsics::pow(x, y); } -/// @brief Returns the x raised to the given power y. Accepts and returns expressions. -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_FUNCTION internal::expression_function<fn::pow, E1, E2> pow(E1&& x, E2&& y) -{ - return { fn::pow(), std::forward<E1>(x), std::forward<E2>(y) }; -} - /// @brief Returns the real nth root of the x. template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>)> KFR_FUNCTION flt_type<common_type<T1, T2>> root(const T1& x, const T2& y) @@ -208,25 +123,11 @@ KFR_FUNCTION flt_type<common_type<T1, T2>> root(const T1& x, const T2& y) return intrinsics::root(x, y); } -/// @brief Returns the real nth root of the x. Accepts and returns expressions. -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_FUNCTION internal::expression_function<fn::root, E1, E2> root(E1&& x, E2&& y) -{ - return { fn::root(), std::forward<E1>(x), std::forward<E2>(y) }; -} - /// @brief Returns the cube root of the x. template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> cbrt(const T1& x) { return intrinsics::cbrt(x); } - -/// @brief Returns the cube root of the x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cbrt, E1> cbrt(E1&& x) -{ - return { fn::cbrt(), std::forward<E1>(x) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/min_max.hpp b/include/kfr/math/min_max.hpp @@ -43,15 +43,6 @@ KFR_INTRINSIC Tout min(const T1& x, const T2& y) } /** - * @brief Returns the smaller of two values. Accepts and returns expressions. - */ -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::min, E1, E2> min(E1&& x, E2&& y) -{ - return { fn::min(), std::forward<E1>(x), std::forward<E2>(y) }; -} - -/** * @brief Returns the greater of two values. */ template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>), @@ -62,15 +53,6 @@ KFR_INTRINSIC Tout max(const T1& x, const T2& y) } /** - * @brief Returns the greater of two values. Accepts and returns expressions. - */ -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::max, E1, E2> max(E1&& x, E2&& y) -{ - return { fn::max(), std::forward<E1>(x), std::forward<E2>(y) }; -} - -/** * @brief Returns the smaller in magnitude of two values. */ template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>), @@ -81,15 +63,6 @@ KFR_INTRINSIC Tout absmin(const T1& x, const T2& y) } /** - * @brief Returns the smaller in magnitude of two values. Accepts and returns expressions. - */ -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::absmin, E1, E2> absmin(E1&& x, E2&& y) -{ - return { fn::absmin(), std::forward<E1>(x), std::forward<E2>(y) }; -} - -/** * @brief Returns the greater in magnitude of two values. */ template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>), @@ -98,14 +71,5 @@ KFR_INTRINSIC Tout absmax(const T1& x, const T2& y) { return intrinsics::absmax(x, y); } - -/** - * @brief Returns the greater in magnitude of two values. Accepts and returns expressions. - */ -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::absmax, E1, E2> absmax(E1&& x, E2&& y) -{ - return { fn::absmax(), std::forward<E1>(x), std::forward<E2>(y) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/modzerobessel.hpp b/include/kfr/math/modzerobessel.hpp @@ -37,11 +37,5 @@ KFR_FUNCTION T1 modzerobessel(const T1& x) { return intrinsics::modzerobessel(x); } - -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::modzerobessel, E1> modzerobessel(E1&& x) -{ - return { fn::modzerobessel(), std::forward<E1>(x) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/round.hpp b/include/kfr/math/round.hpp @@ -39,109 +39,54 @@ KFR_INTRINSIC T1 floor(const T1& x) return intrinsics::floor(x); } -/// @brief Returns the largest integer value not greater than x. Accepts and returns expressions. -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::floor, E1> floor(E1&& x) -{ - return { fn::floor(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC T1 ceil(const T1& x) { return intrinsics::ceil(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::ceil, E1> ceil(E1&& x) -{ - return { fn::ceil(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC T1 round(const T1& x) { return intrinsics::round(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::round, E1> round(E1&& x) -{ - return { fn::round(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC T1 trunc(const T1& x) { return intrinsics::trunc(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::trunc, E1> trunc(E1&& x) -{ - return { fn::trunc(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC T1 fract(const T1& x) { return intrinsics::fract(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::fract, E1> fract(E1&& x) -{ - return { fn::fract(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC itype<T1> ifloor(const T1& x) { return intrinsics::ifloor(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::ifloor, E1> ifloor(E1&& x) -{ - return { fn::ifloor(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC itype<T1> iceil(const T1& x) { return intrinsics::iceil(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::iceil, E1> iceil(E1&& x) -{ - return { fn::iceil(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC itype<T1> iround(const T1& x) { return intrinsics::iround(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::iround, E1> iround(E1&& x) -{ - return { fn::iround(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_INTRINSIC itype<T1> itrunc(const T1& x) { return intrinsics::itrunc(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::itrunc, E1> itrunc(E1&& x) -{ - return { fn::itrunc(), std::forward<E1>(x) }; -} - template <typename T, KFR_ENABLE_IF(is_f_class<T>)> KFR_INTRINSIC T fmod(const T& x, const T& y) { diff --git a/include/kfr/math/saturation.hpp b/include/kfr/math/saturation.hpp @@ -40,13 +40,6 @@ KFR_INTRINSIC Tout satadd(const T1& x, const T2& y) return intrinsics::satadd(x, y); } -/// @brief Creates an expression that adds two arguments using saturation -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::satadd, E1, E2> satadd(E1&& x, E2&& y) -{ - return { fn::satadd(), std::forward<E1>(x), std::forward<E2>(y) }; -} - /// @brief Subtracts two arguments using saturation template <typename T1, typename T2, KFR_ENABLE_IF(is_numeric_args<T1, T2>), typename Tout = common_type<T1, T2>> @@ -54,12 +47,5 @@ KFR_INTRINSIC Tout satsub(const T1& x, const T2& y) { return intrinsics::satsub(x, y); } - -/// @brief Creates an expression that subtracts two arguments using saturation -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::satsub, E1, E2> satsub(E1&& x, E2&& y) -{ - return { fn::satsub(), std::forward<E1>(x), std::forward<E2>(y) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/select.hpp b/include/kfr/math/select.hpp @@ -45,15 +45,5 @@ KFR_INTRINSIC vec<Tout, N> select(const mask<T1, N>& m, const T2& x, const T3& y static_assert(sizeof(T1) == sizeof(Tout), "select: incompatible types"); return intrinsics::select(bitcast<Tout>(m.asvec()).asmask(), innercast<Tout>(x), innercast<Tout>(y)); } - -/** - * @brief Returns template expression that returns x if m is true, otherwise return y. Order of the arguments - * is same as in ternary operator. - */ -template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> -KFR_INTRINSIC internal::expression_function<fn::select, E1, E2, E3> select(E1&& m, E2&& x, E3&& y) -{ - return { fn::select(), std::forward<E1>(m), std::forward<E2>(x), std::forward<E3>(y) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/sin_cos.hpp b/include/kfr/math/sin_cos.hpp @@ -42,15 +42,6 @@ KFR_FUNCTION flt_type<T1> sin(const T1& x) } /** - * @brief Returns the trigonometric sine of x. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::sin, E1> sin(E1&& x) -{ - return { fn::sin(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric cosine of x. */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -60,15 +51,6 @@ KFR_FUNCTION flt_type<T1> cos(const T1& x) } /** - * @brief Returns the trigonometric cosine of x. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cos, E1> cos(E1&& x) -{ - return { fn::cos(), std::forward<E1>(x) }; -} - -/** * @brief Returns an approximation of the trigonometric sine of x. */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -78,15 +60,6 @@ KFR_FUNCTION flt_type<T1> fastsin(const T1& x) } /** - * @brief Returns an approximation of the trigonometric sine of x. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::fastsin, E1> fastsin(E1&& x) -{ - return { fn::fastsin(), std::forward<E1>(x) }; -} - -/** * @brief Returns an approximation of the trigonometric cosine of x. */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -96,15 +69,6 @@ KFR_FUNCTION flt_type<T1> fastcos(const T1& x) } /** - * @brief Returns an approximation of the trigonometric cosine of x. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::fastcos, E1> fastcos(E1&& x) -{ - return { fn::fastcos(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric sine of the even elements of the x and cosine of the odd elements. x must * be a vector. */ @@ -115,16 +79,6 @@ KFR_FUNCTION flt_type<T1> sincos(const T1& x) } /** - * @brief Returns the trigonometric sine of the even elements of the x and - * cosine of the odd elements. x must be a vector. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::sincos, E1> sincos(E1&& x) -{ - return { fn::sincos(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric cosine of the even elements of the x and sine of the odd elements. x must * be a vector. */ @@ -135,16 +89,6 @@ KFR_FUNCTION flt_type<T1> cossin(const T1& x) } /** - * @brief Returns the trigonometric cosine of the even elements of the x and - * sine of the odd elements. x must be a vector. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cossin, E1> cossin(E1&& x) -{ - return { fn::cossin(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric sine of the x (expressed in degrees). */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -154,15 +98,6 @@ KFR_FUNCTION flt_type<T1> sindeg(const T1& x) } /** - * @brief Returns the trigonometric sine of the x (expressed in degrees). Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::sindeg, E1> sindeg(E1&& x) -{ - return { fn::sindeg(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric cosine of the x (expressed in degrees). */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -172,15 +107,6 @@ KFR_FUNCTION flt_type<T1> cosdeg(const T1& x) } /** - * @brief Returns the trigonometric cosine of the x (expressed in degrees). Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cosdeg, E1> cosdeg(E1&& x) -{ - return { fn::cosdeg(), std::forward<E1>(x) }; -} - -/** * @brief Returns an approximation of the trigonometric sine of the x (expressed in degrees). */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -190,16 +116,6 @@ KFR_FUNCTION flt_type<T1> fastsindeg(const T1& x) } /** - * @brief Returns an approximation of the trigonometric sine of the x - * (expressed in degrees). Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::fastsindeg, E1> fastsindeg(E1&& x) -{ - return { fn::fastsindeg(), std::forward<E1>(x) }; -} - -/** * @brief Returns an approximation of the trigonometric cosine of the x (expressed in degrees). */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -209,16 +125,6 @@ KFR_FUNCTION flt_type<T1> fastcosdeg(const T1& x) } /** - * @brief Returns an approximation of the trigonometric cosine of the x - * (expressed in degrees). Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::fastcosdeg, E1> fastcosdeg(E1&& x) -{ - return { fn::fastcosdeg(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric sine of the even elements of the x and cosine of the odd elements. x must * be a vector and expressed in degrees. */ @@ -229,16 +135,6 @@ KFR_FUNCTION flt_type<T1> sincosdeg(const T1& x) } /** - * @brief Returns the trigonometric sine of the even elements of the x and - * cosine of the odd elements. x must be expressed in degrees. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::sincosdeg, E1> sincosdeg(E1&& x) -{ - return { fn::sincosdeg(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric cosine of the even elements of the x and sine of the odd elements. x must * be a vector and expressed in degrees. */ @@ -249,16 +145,6 @@ KFR_FUNCTION flt_type<T1> cossindeg(const T1& x) } /** - * @brief Returns the trigonometric cosine of the even elements of the x and - * sine of the odd elements. x must be expressed in degrees. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cossindeg, E1> cossindeg(E1&& x) -{ - return { fn::cossindeg(), std::forward<E1>(x) }; -} - -/** * @brief Returns the sinc function of x. * \f[ * sinc(x) = \frac{sin(x)}{x} @@ -271,15 +157,6 @@ KFR_FUNCTION flt_type<T1> sinc(const T1& x) } /** - * @brief Returns the sinc function of x. Accepts and returns expressions. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::sinc, E1> sinc(E1&& x) -{ - return { fn::sinc(), std::forward<E1>(x) }; -} - -/** * @brief Returns the trigonometric sine of the angle 2x using sin(x) and cos(x). */ template <typename T> diff --git a/include/kfr/math/sqrt.hpp b/include/kfr/math/sqrt.hpp @@ -40,14 +40,5 @@ KFR_INTRINSIC flt_type<T1> sqrt(const T1& x) { return intrinsics::sqrt(x); } - -/** - * @brief Returns template expression that returns the positive square root of the x. \f$\sqrt{x}\f$ - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::sqrt, E1> sqrt(E1&& x) -{ - return { fn::sqrt(), std::forward<E1>(x) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/math/tan.hpp b/include/kfr/math/tan.hpp @@ -38,22 +38,10 @@ KFR_FUNCTION flt_type<T1> tan(const T1& x) return intrinsics::tan(x); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::tan, E1> tan(E1&& x) -{ - return { fn::tan(), std::forward<E1>(x) }; -} - template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> KFR_FUNCTION flt_type<T1> tandeg(const T1& x) { return intrinsics::tandeg(x); } - -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::tandeg, E1> tandeg(E1&& x) -{ - return { fn::tandeg(), std::forward<E1>(x) }; -} } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/include/kfr/simd/comparison.hpp b/include/kfr/simd/comparison.hpp @@ -71,42 +71,6 @@ KFR_FN(greater) KFR_FN(lessorequal) KFR_FN(greaterorequal) -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::equal, E1, E2> operator==(E1&& e1, E2&& e2) -{ - return { fn::equal(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::notequal, E1, E2> operator!=(E1&& e1, E2&& e2) -{ - return { fn::notequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::less, E1, E2> operator<(E1&& e1, E2&& e2) -{ - return { fn::less(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::greater, E1, E2> operator>(E1&& e1, E2&& e2) -{ - return { fn::greater(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::lessorequal, E1, E2> operator<=(E1&& e1, E2&& e2) -{ - return { fn::lessorequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::greaterorequal, E1, E2> operator>=(E1&& e1, E2&& e2) -{ - return { fn::greaterorequal(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - template <typename T, size_t N> KFR_INTRINSIC mask<T, N> isnan(const vec<T, N>& x) { diff --git a/include/kfr/simd/complex.hpp b/include/kfr/simd/complex.hpp @@ -28,62 +28,11 @@ #include "impl/function.hpp" #include "operators.hpp" -#ifdef KFR_STD_COMPLEX -#include <complex> -#endif - CMT_PRAGMA_MSVC(warning(push)) CMT_PRAGMA_MSVC(warning(disable : 4814)) namespace kfr { -#ifdef KFR_STD_COMPLEX - -template <typename T> -using complex = std::complex<T>; - -#else -#ifndef KFR_CUSTOM_COMPLEX - -/** - * @brief Represents the complex numbers. If KFR_STD_COMPLEX is defined, then kfr::complex is an alias for - * std::complex. - */ -template <typename T> -struct complex -{ - static_assert(is_simd_type<T>, "Incorrect type for complex"); - constexpr static bool is_pod = true; - constexpr complex() CMT_NOEXCEPT = default; - KFR_MEM_INTRINSIC constexpr complex(T re) CMT_NOEXCEPT : re(re), im(0) {} - KFR_MEM_INTRINSIC constexpr complex(T re, T im) CMT_NOEXCEPT : re(re), im(im) {} - constexpr complex(const complex&) CMT_NOEXCEPT = default; - constexpr complex(complex&&) CMT_NOEXCEPT = default; - template <typename U> - KFR_MEM_INTRINSIC constexpr complex(const complex<U>& other) CMT_NOEXCEPT : re(static_cast<T>(other.real())), - im(static_cast<T>(other.imag())) - { - } - template <typename U> - KFR_MEM_INTRINSIC constexpr complex(complex<U>&& other) CMT_NOEXCEPT : re(std::move(other.real())), - im(std::move(other.imag())) - { - } -#ifdef CMT_COMPILER_GNU - constexpr complex& operator=(const complex&) CMT_NOEXCEPT = default; - constexpr complex& operator=(complex&&) CMT_NOEXCEPT = default; -#else - complex& operator=(const complex&) = default; - complex& operator=(complex&&) = default; -#endif - KFR_MEM_INTRINSIC constexpr const T& real() const CMT_NOEXCEPT { return re; } - KFR_MEM_INTRINSIC constexpr const T& imag() const CMT_NOEXCEPT { return im; } - KFR_MEM_INTRINSIC constexpr void real(T value) CMT_NOEXCEPT { re = value; } - KFR_MEM_INTRINSIC constexpr void imag(T value) CMT_NOEXCEPT { im = value; } -private: - T re; - T im; -}; inline namespace CMT_ARCH_NAME { @@ -162,8 +111,6 @@ KFR_INTRINSIC complex<T> operator+(const complex<T>& x) } } // namespace CMT_ARCH_NAME -#endif -#endif } // namespace kfr namespace cometa { @@ -382,13 +329,6 @@ using realftype = ftype<decltype(kfr::real(std::declval<T>()))>; KFR_FN(real) -/// @brief Returns the real part of the complex value -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::real, E1> real(E1&& x) -{ - return { fn::real{}, std::forward<E1>(x) }; -} - /// @brief Returns the imaginary part of the complex value template <typename T> constexpr KFR_INTRINSIC T imag(const complex<T>& value) @@ -404,13 +344,6 @@ constexpr KFR_INTRINSIC vec<T, N> imag(const vec<complex<T>, N>& value) } KFR_FN(imag) -/// @brief Returns the imaginary part of the complex value -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::imag, E1> imag(E1&& x) -{ - return { fn::imag{}, std::forward<E1>(x) }; -} - /// @brief Constructs complex value from real and imaginary parts template <typename T1, typename T2 = T1, size_t N, typename T = common_type<T1, T2>> constexpr KFR_INTRINSIC vec<complex<T>, N> make_complex(const vec<T1, N>& real, @@ -428,13 +361,6 @@ constexpr KFR_INTRINSIC complex<T> make_complex(T1 real, T2 imag = T2(0)) } KFR_FN(make_complex) -/// @brief Constructs complex value from real and imaginary parts -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::make_complex, E1, E2> make_complex(E1&& re, E2&& im) -{ - return { fn::make_complex{}, std::forward<E1>(re), std::forward<E2>(im) }; -} - namespace intrinsics { template <typename T, size_t N> @@ -454,13 +380,6 @@ KFR_INTRINSIC T1 cconj(const T1& x) return intrinsics::cconj(x); } -/// @brief Returns template expression that returns the complex conjugate of the complex number x -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_FUNCTION internal::expression_function<fn::cconj, E1> cconj(E1&& x) -{ - return { fn::cconj(), std::forward<E1>(x) }; -} - template <size_t N> struct vec_of_complex { diff --git a/include/kfr/simd/complex_type.hpp b/include/kfr/simd/complex_type.hpp @@ -0,0 +1,88 @@ +/** @addtogroup complex + * @{ + */ +/* + Copyright (C) 2016 D Levin (https://www.kfrlib.com) + This file is part of KFR + + KFR is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + KFR is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with KFR. + + If GPL is not suitable for your project, you must purchase a commercial license to use KFR. + Buying a commercial license is mandatory as soon as you develop commercial activities without + disclosing the source code of your own applications. + See https://www.kfrlib.com for details. + */ +#pragma once + +#include "constants.hpp" + +#ifdef KFR_STD_COMPLEX +#include <complex> +#endif + +namespace kfr +{ +#ifdef KFR_STD_COMPLEX + +template <typename T> +using complex = std::complex<T>; + +#else +#ifndef KFR_CUSTOM_COMPLEX + +/** + * @brief Represents the complex numbers. If KFR_STD_COMPLEX is defined, then kfr::complex is an alias for + * std::complex. + */ +template <typename T> +struct complex +{ + static_assert(is_simd_type<T>, "Incorrect type for complex"); + constexpr static bool is_pod = true; + constexpr complex() CMT_NOEXCEPT = default; + KFR_MEM_INTRINSIC constexpr complex(T re) CMT_NOEXCEPT : re(re), im(0) {} + KFR_MEM_INTRINSIC constexpr complex(T re, T im) CMT_NOEXCEPT : re(re), im(im) {} + constexpr complex(const complex&) CMT_NOEXCEPT = default; + constexpr complex(complex&&) CMT_NOEXCEPT = default; + template <typename U> + KFR_MEM_INTRINSIC constexpr complex(const complex<U>& other) CMT_NOEXCEPT + : re(static_cast<T>(other.real())), + im(static_cast<T>(other.imag())) + { + } + template <typename U> + KFR_MEM_INTRINSIC constexpr complex(complex<U>&& other) CMT_NOEXCEPT : re(std::move(other.real())), + im(std::move(other.imag())) + { + } +#ifdef CMT_COMPILER_GNU + constexpr complex& operator=(const complex&) CMT_NOEXCEPT = default; + constexpr complex& operator=(complex&&) CMT_NOEXCEPT = default; +#else + complex& operator=(const complex&) = default; + complex& operator=(complex&&) = default; +#endif + KFR_MEM_INTRINSIC constexpr const T& real() const CMT_NOEXCEPT { return re; } + KFR_MEM_INTRINSIC constexpr const T& imag() const CMT_NOEXCEPT { return im; } + KFR_MEM_INTRINSIC constexpr void real(T value) CMT_NOEXCEPT { re = value; } + KFR_MEM_INTRINSIC constexpr void imag(T value) CMT_NOEXCEPT { im = value; } + +private: + T re; + T im; +}; +#endif +#endif + +} // namespace kfr +\ No newline at end of file diff --git a/include/kfr/simd/impl/basicoperators_complex.hpp b/include/kfr/simd/impl/basicoperators_complex.hpp @@ -0,0 +1,110 @@ +/** @addtogroup complex + * @{ + */ +/* + Copyright (C) 2016 D Levin (https://www.kfrlib.com) + This file is part of KFR + + KFR is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + KFR is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with KFR. + + If GPL is not suitable for your project, you must purchase a commercial license to use KFR. + Buying a commercial license is mandatory as soon as you develop commercial activities without + disclosing the source code of your own applications. + See https://www.kfrlib.com for details. + */ +#pragma once + +#include "../complex_type.hpp" +#include "../vec.hpp" + +namespace kfr +{ +inline namespace CMT_ARCH_NAME +{ +namespace intrinsics +{ + +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> neg(const vec<complex<T>, N>& x) +{ + return neg(x.flatten()).v; +} + +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> add(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) +{ + return add(x.flatten(), y.flatten()).v; +} + +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> sub(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) +{ + return sub(x.flatten(), y.flatten()).v; +} + +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> mul(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) +{ + const vec<T, (N * 2)> xx = x.v; + const vec<T, (N * 2)> yy = y.v; + return subadd(mul(xx, dupeven(yy)), mul(swap<2>(xx), dupodd(yy))).v; +} + +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> div(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) +{ + const vec<T, (N * 2)> xx = x.v; + const vec<T, (N * 2)> yy = y.v; + const vec<T, (N * 2)> m = (add(sqr(dupeven(yy)), sqr(dupodd(yy)))); + return swap<2>(subadd(mul(swap<2>(xx), dupeven(yy)), mul(xx, dupodd(yy))) / m).v; +} + +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> bor(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) +{ + return bor(x.flatten(), y.flatten()).v; +} +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> bxor(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) +{ + return bxor(x.flatten(), y.flatten()).v; +} +template <typename T, size_t N> +KFR_INTRINSIC vec<complex<T>, N> band(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) +{ + return band(x.flatten(), y.flatten()).v; +} + +#define KFR_COMPLEX_OP_CVT(fn) \ + template <typename T, size_t N> \ + KFR_INTRINSIC vec<complex<T>, N> fn(const vec<complex<T>, N>& x, const complex<T>& y) \ + { \ + return fn(x, vec<complex<T>, N>(y)); \ + } \ + template <typename T, size_t N> \ + KFR_INTRINSIC vec<complex<T>, N> fn(const complex<T>& x, const vec<complex<T>, N>& y) \ + { \ + return fn(vec<complex<T>, N>(x), y); \ + } + +KFR_COMPLEX_OP_CVT(mul) +KFR_COMPLEX_OP_CVT(div) +KFR_COMPLEX_OP_CVT(band) +KFR_COMPLEX_OP_CVT(bxor) +KFR_COMPLEX_OP_CVT(bor) + +} // namespace intrinsics +} // namespace CMT_ARCH_NAME + +} // namespace kfr diff --git a/include/kfr/simd/impl/function.hpp b/include/kfr/simd/impl/function.hpp @@ -22,7 +22,6 @@ */ #pragma once -#include "../../base/expression.hpp" #include "../shuffle.hpp" #include "../types.hpp" #include "../vec.hpp" diff --git a/include/kfr/simd/impl/operators.hpp b/include/kfr/simd/impl/operators.hpp @@ -33,83 +33,15 @@ #include "basicoperators_generic.hpp" #endif +#include "basicoperators_complex.hpp" + namespace kfr { inline namespace CMT_ARCH_NAME { - namespace intrinsics { -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> neg(const vec<complex<T>, N>& x) -{ - return neg(x.flatten()).v; -} - -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> add(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) -{ - return add(x.flatten(), y.flatten()).v; -} - -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> sub(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) -{ - return sub(x.flatten(), y.flatten()).v; -} - -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> mul(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) -{ - const vec<T, (N * 2)> xx = x.v; - const vec<T, (N * 2)> yy = y.v; - return subadd(mul(xx, dupeven(yy)), mul(swap<2>(xx), dupodd(yy))).v; -} - -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> div(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) -{ - const vec<T, (N * 2)> xx = x.v; - const vec<T, (N * 2)> yy = y.v; - const vec<T, (N * 2)> m = (add(sqr(dupeven(yy)), sqr(dupodd(yy)))); - return swap<2>(subadd(mul(swap<2>(xx), dupeven(yy)), mul(xx, dupodd(yy))) / m).v; -} - -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> bor(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) -{ - return bor(x.flatten(), y.flatten()).v; -} -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> bxor(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) -{ - return bxor(x.flatten(), y.flatten()).v; -} -template <typename T, size_t N> -KFR_INTRINSIC vec<complex<T>, N> band(const vec<complex<T>, N>& x, const vec<complex<T>, N>& y) -{ - return band(x.flatten(), y.flatten()).v; -} - -#define KFR_COMPLEX_OP_CVT(fn) \ - template <typename T, size_t N> \ - KFR_INTRINSIC vec<complex<T>, N> fn(const vec<complex<T>, N>& x, const complex<T>& y) \ - { \ - return fn(x, vec<complex<T>, N>(y)); \ - } \ - template <typename T, size_t N> \ - KFR_INTRINSIC vec<complex<T>, N> fn(const complex<T>& x, const vec<complex<T>, N>& y) \ - { \ - return fn(vec<complex<T>, N>(x), y); \ - } - -KFR_COMPLEX_OP_CVT(mul) -KFR_COMPLEX_OP_CVT(div) -KFR_COMPLEX_OP_CVT(band) -KFR_COMPLEX_OP_CVT(bxor) -KFR_COMPLEX_OP_CVT(bor) - #define KFR_VECVEC_OP1(fn) \ template <typename T1, size_t N1, size_t N2> \ KFR_INTRINSIC vec<vec<T1, N1>, N2> fn(const vec<vec<T1, N1>, N2>& x) \ diff --git a/include/kfr/simd/operators.hpp b/include/kfr/simd/operators.hpp @@ -304,15 +304,6 @@ constexpr KFR_INTRINSIC T add(initialvalue<T>) } KFR_FN(add) -/** - * @brief Returns template expression that returns sum of all the arguments passed to a function. - */ -template <typename... E, KFR_ENABLE_IF((is_input_expressions<E...>)&&true)> -KFR_INTRINSIC internal::expression_function<fn::add, E...> add(E&&... x) -{ - return { fn::add(), std::forward<E>(x)... }; -} - template <typename T1, typename T2> constexpr KFR_INTRINSIC common_type<T1, T2> sub(const T1& x, const T2& y) { @@ -325,12 +316,6 @@ constexpr KFR_INTRINSIC T sub(initialvalue<T>) } KFR_FN(sub) -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::sub, E1, E2> sub(E1&& x, E2&& y) -{ - return { fn::sub(), std::forward<E1>(x), std::forward<E2>(y) }; -} - template <typename T1> constexpr KFR_INTRINSIC T1 mul(const T1& x) { @@ -354,15 +339,6 @@ constexpr KFR_INTRINSIC T mul(initialvalue<T>) KFR_FN(mul) /** - * @brief Returns template expression that returns product of all the arguments passed to a function. - */ -template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> -KFR_INTRINSIC internal::expression_function<fn::mul, E...> mul(E&&... x) -{ - return { fn::mul(), std::forward<E>(x)... }; -} - -/** * @brief Returns square of x. */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -373,15 +349,6 @@ constexpr inline T1 sqr(const T1& x) KFR_FN(sqr) /** - * @brief Returns template expression that returns square of x. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::sqr, E1> sqr(E1&& x) -{ - return { fn::sqr(), std::forward<E1>(x) }; -} - -/** * @brief Returns cube of x. */ template <typename T1, KFR_ENABLE_IF(is_numeric<T1>)> @@ -391,15 +358,6 @@ constexpr inline T1 cub(const T1& x) } KFR_FN(cub) -/** - * @brief Returns template expression that returns cube of x. - */ -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::cub, E1> cub(E1&& x) -{ - return { fn::cub(), std::forward<E1>(x) }; -} - template <typename T, KFR_ENABLE_IF(is_numeric_args<T>)> constexpr KFR_INTRINSIC T pow2(const T& x) { @@ -428,27 +386,6 @@ KFR_FN(pow3) KFR_FN(pow4) KFR_FN(pow5) -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::pow2, E1> pow2(E1&& x) -{ - return { fn::pow2(), std::forward<E1>(x) }; -} -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::pow3, E1> pow3(E1&& x) -{ - return { fn::pow3(), std::forward<E1>(x) }; -} -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::pow4, E1> pow4(E1&& x) -{ - return { fn::pow4(), std::forward<E1>(x) }; -} -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::pow5, E1> pow5(E1&& x) -{ - return { fn::pow5(), std::forward<E1>(x) }; -} - /// Raise x to the power base \f$ x^{base} \f$ /// @code /// CHECK( ipow( 10, 3 ) == 1000 ); @@ -470,12 +407,6 @@ constexpr inline T ipow(const T& x, int base) } KFR_FN(ipow) -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::ipow, E1, E2> ipow(E1&& x, E2&& b) -{ - return { fn::ipow(), std::forward<E1>(x), std::forward<E2>(b) }; -} - /// Return square of the sum of all arguments /// @code /// CHECK(sqrsum(1,2,3) == 36); @@ -550,18 +481,6 @@ KFR_INTRINSIC constexpr common_type<T1, T2, T3> mixs(const T1& c, const T2& x, c KFR_FN(mix) KFR_FN(mixs) -template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> -KFR_INTRINSIC internal::expression_function<fn::mix, E1, E2, E3> mix(E1&& c, E2&& x, E3&& y) -{ - return { fn::mix(), std::forward<E1>(c), std::forward<E2>(x), std::forward<E3>(y) }; -} - -template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2, E3>)> -KFR_INTRINSIC internal::expression_function<fn::mixs, E1, E2, E3> mixs(E1&& c, E2&& x, E3&& y) -{ - return { fn::mixs(), std::forward<E1>(c), std::forward<E2>(x), std::forward<E3>(y) }; -} - namespace intrinsics { @@ -617,12 +536,6 @@ constexpr KFR_INTRINSIC common_type<T1, Ts...> horner(const T1& x, const Ts&... } KFR_FN(horner) -template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> -KFR_INTRINSIC internal::expression_function<fn::horner, E...> horner(E&&... x) -{ - return { fn::horner(), std::forward<E>(x)... }; -} - /// @brief Calculate polynomial using Horner's method (even powers) /// /// ``horner_even(x, 1, 2, 3)`` is equivalent to \(3x^4 + 2x^2 + 1\) @@ -633,12 +546,6 @@ constexpr KFR_INTRINSIC common_type<T1, Ts...> horner_even(const T1& x, const Ts } KFR_FN(horner_even) -template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> -KFR_INTRINSIC internal::expression_function<fn::horner_even, E...> horner_even(E&&... x) -{ - return { fn::horner_even(), std::forward<E>(x)... }; -} - /// @brief Calculate polynomial using Horner's method (odd powers) /// /// ``horner_odd(x, 1, 2, 3)`` is equivalent to \(3x^5 + 2x^3 + 1x\) @@ -649,12 +556,6 @@ constexpr KFR_INTRINSIC common_type<T1, Ts...> horner_odd(const T1& x, const Ts& } KFR_FN(horner_odd) -template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>)> -KFR_INTRINSIC internal::expression_function<fn::horner_odd, E...> horner_odd(E&&... x) -{ - return { fn::horner_odd(), std::forward<E>(x)... }; -} - /// @brief Calculate Multiplicative Inverse of `x` /// Returns `1/x` template <typename T> @@ -725,72 +626,6 @@ KFR_INTRINSIC vec<T, N> negodd(const vec<T, N>& x) return x ^ broadcast<N>(T(), -T()); } -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::neg, E1> operator-(E1&& e1) -{ - return { fn::neg(), std::forward<E1>(e1) }; -} - -template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>)> -KFR_INTRINSIC internal::expression_function<fn::bitwisenot, E1> operator~(E1&& e1) -{ - return { fn::bitwisenot(), std::forward<E1>(e1) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::add, E1, E2> operator+(E1&& e1, E2&& e2) -{ - return { fn::add(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::sub, E1, E2> operator-(E1&& e1, E2&& e2) -{ - return { fn::sub(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::mul, E1, E2> operator*(E1&& e1, E2&& e2) -{ - return { fn::mul(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::div, E1, E2> operator/(E1&& e1, E2&& e2) -{ - return { fn::div(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::bitwiseand, E1, E2> operator&(E1&& e1, E2&& e2) -{ - return { fn::bitwiseand(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::bitwiseor, E1, E2> operator|(E1&& e1, E2&& e2) -{ - return { fn::bitwiseor(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::bitwisexor, E1, E2> operator^(E1&& e1, E2&& e2) -{ - return { fn::bitwisexor(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::shl, E1, E2> operator<<(E1&& e1, E2&& e2) -{ - return { fn::shl(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - -template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>)> -KFR_INTRINSIC internal::expression_function<fn::shr, E1, E2> operator>>(E1&& e1, E2&& e2) -{ - return { fn::shr(), std::forward<E1>(e1), std::forward<E2>(e2) }; -} - template <typename T, size_t N1, size_t... Ns> vec<vec<T, sizeof...(Ns) + 1>, N1> packtranspose(const vec<T, N1>& x, const vec<T, Ns>&... rest) { diff --git a/include/kfr/simd/read_write.hpp b/include/kfr/simd/read_write.hpp @@ -141,7 +141,7 @@ KFR_INTRINSIC void scatter_helper_s(T* base, size_t stride, const vec<T, N>& val template <size_t groupsize = 1, typename T, size_t N, size_t Nout = N* groupsize, typename IT> KFR_INTRINSIC void scatter(T* base, const vec<IT, N>& offset, const vec<T, Nout>& value) { - return scatter_helper<groupsize>(base, offset, value, csizeseq<N>); + return internal::scatter_helper<groupsize>(base, offset, value, csizeseq<N>); } template <size_t groupsize = 1, typename T, size_t N> diff --git a/sources.cmake b/sources.cmake @@ -17,6 +17,7 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/version.hpp ${PROJECT_SOURCE_DIR}/include/kfr/capi.h ${PROJECT_SOURCE_DIR}/include/kfr/cident.h + ${PROJECT_SOURCE_DIR}/include/kfr/config.h ${PROJECT_SOURCE_DIR}/include/kfr/kfr.h ${PROJECT_SOURCE_DIR}/include/kfr/base/basic_expressions.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/conversion.hpp @@ -25,13 +26,18 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/base/fraction.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/function_expressions.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/generators.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/base/math_expressions.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/memory.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/pointer.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/random.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/reduce.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/base/shape.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/base/simd_expressions.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/small_buffer.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/sort.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/base/tensor.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base/univector.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/base/impl/static_array.hpp ${PROJECT_SOURCE_DIR}/include/kfr/cometa/array.hpp ${PROJECT_SOURCE_DIR}/include/kfr/cometa/cstring.hpp ${PROJECT_SOURCE_DIR}/include/kfr/cometa/ctti.hpp @@ -71,6 +77,7 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/dsp/sample_rate_conversion.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/speaker.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/special.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/dsp/state_holder.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/units.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/waveshaper.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/weighting.hpp @@ -124,6 +131,7 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/runtime/cpuid_auto.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/comparison.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/complex.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/simd/complex_type.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/constants.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/digitreverse.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/horizontal.hpp @@ -138,6 +146,7 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/simd/impl/backend_clang.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/impl/backend_generic.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/impl/basicoperators_clang.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/simd/impl/basicoperators_complex.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/impl/basicoperators_generic.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/impl/function.hpp ${PROJECT_SOURCE_DIR}/include/kfr/simd/impl/operators.hpp @@ -176,6 +185,7 @@ set( ${PROJECT_SOURCE_DIR}/tests/unit/base/fraction.cpp ${PROJECT_SOURCE_DIR}/tests/unit/base/random.cpp ${PROJECT_SOURCE_DIR}/tests/unit/base/reduce.cpp + ${PROJECT_SOURCE_DIR}/tests/unit/base/tensor.cpp ${PROJECT_SOURCE_DIR}/tests/unit/graphics/color.cpp ${PROJECT_SOURCE_DIR}/tests/unit/graphics/geometry.cpp ${PROJECT_SOURCE_DIR}/tests/unit/math/abs.cpp diff --git a/tests/unit/base/conversion.cpp b/tests/unit/base/conversion.cpp @@ -7,6 +7,7 @@ #include <kfr/base/conversion.hpp> #include <kfr/base/basic_expressions.hpp> +#include <kfr/base/simd_expressions.hpp> #include <kfr/base/reduce.hpp>