# Templates
vec_act_vec = """
/**
 * @brief Calculate Z = X <op> Y
 *
 * @tparam vx_t datatype of vector x
 * @tparam vy_t datatype of vector y
 * @tparam vz_t datatype of vector z
 * @param[in] x left operand
 * @param[in] y right operand
 * @param[out] z result
 */
template <typename vx_t, typename vy_t, typename vz_t>
void vec_<act>_vec(const Eigen::MatrixBase<vx_t>& x, const Eigen::MatrixBase<vy_t>& y,
    Eigen::MatrixBase<vz_t>& z)
{
    size_t dim = x.size();
    assert(dim == y.size());
    assert(dim == z.size());
#pragma omp parallel for simd
    for (size_t i = 0; i < dim; ++i) {
        z[i] = x[i] <op> y[i];
    }
}
"""

vec_act_sca = """
/**
 * @brief Calculate Y = X <op> a
 *
 * @tparam vx_t datatype of vector x
 * @tparam sa_t datatype of scalar a
 * @tparam vy_t datatype of vector y
 * @param[in] x left operand
 * @param[in] a right operand
 * @param[out] y result
 */
template <typename vx_t, typename sa_t, typename vy_t>
void vec_<act>_sca(const Eigen::MatrixBase<vx_t>& x, const sa_t& a,
    Eigen::MatrixBase<vy_t>& y)
{
    size_t dim = x.size();
    assert(dim == y.size());
#pragma omp parallel for simd
    for (size_t i = 0; i < dim; ++i) {
        y[i] = x[i] <op> a;
    }
}
"""

vec_self_act_vec = """
/**
 * @brief Calculate X <op>= Y
 *
 * @tparam vx_t datatype of vector x
 * @tparam vy_t datatype of vector y
 * @param[inout] x left operand
 * @param[in] y right operand
 */
template <typename vx_t, typename vy_t>
void vec_self_<act>_vec(Eigen::MatrixBase<vx_t>& x, const Eigen::MatrixBase<vy_t>& y)
{
    size_t dim = x.size();
    assert(dim == y.size());
#pragma omp parallel for simd
    for (size_t i = 0; i < dim; ++i) {
        x[i] <op>= y[i];
    }
}
"""

vec_self_act_sca = """
/**
 * @brief Calculate X <op>= a
 *
 * @tparam vx_t datatype of vector x
 * @tparam sa_t datatype of scalar a
 * @param[inout] x left operand
 * @param[in] a right operand
 */
template <typename vx_t, typename sa_t>
void vec_self_<act>_sca(Eigen::MatrixBase<vx_t>& x, const sa_t& a)
{
    size_t dim = x.size();
#pragma omp parallel for simd
    for (size_t i = 0; i < dim; ++i) {
        x[i] <op>= a;
    }
}
"""
