/* *****************************************************
   THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT.
   *****************************************************

   Generated by:
     scitbx.source_generators.array_family.generate_algebras
 */

#ifndef SCITBX_ARRAY_FAMILY_TINY_ALGEBRA_H
#define SCITBX_ARRAY_FAMILY_TINY_ALGEBRA_H

#ifndef DOXYGEN_SHOULD_SKIP_THIS

#include <scitbx/array_family/tiny.h>

#include <scitbx/array_family/operator_traits_builtin.h>
#include <scitbx/array_family/detail/operator_functors.h>
#include <scitbx/array_family/detail/generic_array_operators.h>
#include <scitbx/array_family/detail/std_imports.h>
#include <scitbx/array_family/misc_functions.h>

namespace scitbx { namespace af {

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator-(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_negate<
        return_element_type,
        ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator!(tiny<ElementType, N> const& a) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_logical_not<
        return_element_type,
        ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<
    typename binary_operator_traits<
        ElementType1, ElementType2>::arithmetic, N>
  operator+(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<
      typename binary_operator_traits<
          ElementType1, ElementType2>::arithmetic, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_plus<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator+(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_plus<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator+(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_plus<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>&
  operator+=(
    tiny<ElementType1, N>& a1,
    tiny<ElementType2, N> const& a2) {
    array_operation_in_place_a_a(fn::functor_ip_plus<
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), N);
    return a1;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>&
  operator+=(
    tiny<ElementType, N>& a1,
    ElementType const& a2) {
    array_operation_in_place_a_s(fn::functor_ip_plus<
        ElementType,
        ElementType>(),
      a1.begin(), a2, N);
    return a1;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<
    typename binary_operator_traits<
        ElementType1, ElementType2>::arithmetic, N>
  operator-(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<
      typename binary_operator_traits<
          ElementType1, ElementType2>::arithmetic, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_minus<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator-(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_minus<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator-(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_minus<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>&
  operator-=(
    tiny<ElementType1, N>& a1,
    tiny<ElementType2, N> const& a2) {
    array_operation_in_place_a_a(fn::functor_ip_minus<
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), N);
    return a1;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>&
  operator-=(
    tiny<ElementType, N>& a1,
    ElementType const& a2) {
    array_operation_in_place_a_s(fn::functor_ip_minus<
        ElementType,
        ElementType>(),
      a1.begin(), a2, N);
    return a1;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<
    typename binary_operator_traits<
        ElementType1, ElementType2>::arithmetic, N>
  operator*(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<
      typename binary_operator_traits<
          ElementType1, ElementType2>::arithmetic, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_multiplies<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator*(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_multiplies<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator*(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_multiplies<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>&
  operator*=(
    tiny<ElementType1, N>& a1,
    tiny<ElementType2, N> const& a2) {
    array_operation_in_place_a_a(fn::functor_ip_multiplies<
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), N);
    return a1;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>&
  operator*=(
    tiny<ElementType, N>& a1,
    ElementType const& a2) {
    array_operation_in_place_a_s(fn::functor_ip_multiplies<
        ElementType,
        ElementType>(),
      a1.begin(), a2, N);
    return a1;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<
    typename binary_operator_traits<
        ElementType1, ElementType2>::arithmetic, N>
  operator/(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<
      typename binary_operator_traits<
          ElementType1, ElementType2>::arithmetic, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_divides<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator/(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_divides<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator/(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_divides<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>&
  operator/=(
    tiny<ElementType1, N>& a1,
    tiny<ElementType2, N> const& a2) {
    array_operation_in_place_a_a(fn::functor_ip_divides<
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), N);
    return a1;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>&
  operator/=(
    tiny<ElementType, N>& a1,
    ElementType const& a2) {
    array_operation_in_place_a_s(fn::functor_ip_divides<
        ElementType,
        ElementType>(),
      a1.begin(), a2, N);
    return a1;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<
    typename binary_operator_traits<
        ElementType1, ElementType2>::arithmetic, N>
  operator%(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<
      typename binary_operator_traits<
          ElementType1, ElementType2>::arithmetic, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_modulus<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator%(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_modulus<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  operator%(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_modulus<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>&
  operator%=(
    tiny<ElementType1, N>& a1,
    tiny<ElementType2, N> const& a2) {
    array_operation_in_place_a_a(fn::functor_ip_modulus<
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), N);
    return a1;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>&
  operator%=(
    tiny<ElementType, N>& a1,
    ElementType const& a2) {
    array_operation_in_place_a_s(fn::functor_ip_modulus<
        ElementType,
        ElementType>(),
      a1.begin(), a2, N);
    return a1;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator&&(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_logical_and<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator&&(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_logical_and<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator&&(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_logical_and<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator||(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_logical_or<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator||(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_logical_or<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator||(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_logical_or<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator==(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_equal_to<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator==(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_equal_to<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator==(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_equal_to<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator!=(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_not_equal_to<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator!=(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_not_equal_to<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator!=(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_not_equal_to<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator>(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_greater<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator>(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_greater<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator>(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_greater<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator<(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_less<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator<(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_less<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator<(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_less<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator>=(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_greater_equal<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator>=(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_greater_equal<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator>=(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_greater_equal<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<bool, N>
  operator<=(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_a(fn::functor_less_equal<
        return_element_type,
        ElementType1,
        ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator<=(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a_s(fn::functor_less_equal<
        return_element_type,
        ElementType,
        ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  operator<=(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_s_a(fn::functor_less_equal<
        return_element_type,
        ElementType,
        ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  absolute(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_absolute<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  pow2(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_pow2<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  acos(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_acos<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  cos(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_cos<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  tan(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_tan<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  asin(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_asin<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  cosh(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_cosh<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  tanh(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_tanh<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  atan(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_atan<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  exp(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_exp<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  sin(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_sin<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  fabs(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_fabs<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  log(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_log<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  sinh(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_sinh<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  ceil(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_ceil<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  floor(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_floor<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  log10(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_log10<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  sqrt(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_sqrt<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  abs(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_abs<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  conj(tiny<ElementType, N> const& a) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;
    return_array_type result;
    array_operation_a(fn::functor_conj<return_element_type, ElementType>(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>
  fmod_positive(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<ElementType1, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_a(fn::functor_fmod_positive<
        return_element_type, ElementType1, ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  fmod_positive(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_s(fn::functor_fmod_positive<
        return_element_type, ElementType, ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  fmod_positive(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_s_a(fn::functor_fmod_positive<
        return_element_type, ElementType, ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>
  fmod(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<ElementType1, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_a(fn::functor_fmod<
        return_element_type, ElementType1, ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  fmod(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_s(fn::functor_fmod<
        return_element_type, ElementType, ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  fmod(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_s_a(fn::functor_fmod<
        return_element_type, ElementType, ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>
  pow(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<ElementType1, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_a(fn::functor_pow<
        return_element_type, ElementType1, ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  pow(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_s(fn::functor_pow<
        return_element_type, ElementType, ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  pow(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_s_a(fn::functor_pow<
        return_element_type, ElementType, ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>
  atan2(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<ElementType1, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_a(fn::functor_atan2<
        return_element_type, ElementType1, ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  atan2(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_s(fn::functor_atan2<
        return_element_type, ElementType, ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  atan2(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_s_a(fn::functor_atan2<
        return_element_type, ElementType, ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>
  each_min(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<ElementType1, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_a(fn::functor_each_min<
        return_element_type, ElementType1, ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  each_min(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_s(fn::functor_each_min<
        return_element_type, ElementType, ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  each_min(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_s_a(fn::functor_each_min<
        return_element_type, ElementType, ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType1, std::size_t N, typename ElementType2>
  inline
  tiny<ElementType1, N>
  each_max(
    tiny<ElementType1, N> const& a1,
    tiny<ElementType2, N> const& a2) {
    typedef tiny<ElementType1, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_a(fn::functor_each_max<
        return_element_type, ElementType1, ElementType2>(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  each_max(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_s(fn::functor_each_max<
        return_element_type, ElementType, ElementType>(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  each_max(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<ElementType, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_s_a(fn::functor_each_max<
        return_element_type, ElementType, ElementType>(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  real(tiny<std::complex<ElementType>, N> const& a) {
    typedef tiny<ElementType, N> return_array_type;
    return_array_type result;
    array_operation_a(fn::functor_real<
      ElementType,
      std::complex<ElementType> >(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  imag(tiny<std::complex<ElementType>, N> const& a) {
    typedef tiny<ElementType, N> return_array_type;
    return_array_type result;
    array_operation_a(fn::functor_imag<
      ElementType,
      std::complex<ElementType> >(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  abs(tiny<std::complex<ElementType>, N> const& a) {
    typedef tiny<ElementType, N> return_array_type;
    return_array_type result;
    array_operation_a(fn::functor_abs<
      ElementType,
      std::complex<ElementType> >(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  arg(tiny<std::complex<ElementType>, N> const& a) {
    typedef tiny<ElementType, N> return_array_type;
    return_array_type result;
    array_operation_a(fn::functor_arg<
      ElementType,
      std::complex<ElementType> >(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<ElementType, N>
  norm(tiny<std::complex<ElementType>, N> const& a) {
    typedef tiny<ElementType, N> return_array_type;
    return_array_type result;
    array_operation_a(fn::functor_norm<
      ElementType,
      std::complex<ElementType> >(),
      a.begin(), result.begin(), a.size(), true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<std::complex<ElementType>, N> const& a1,
    tiny<int, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_a(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        int >(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<std::complex<ElementType>, N> const& a1,
    int const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_s(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        int >(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    std::complex<ElementType> const& a1,
    tiny<int, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_s_a(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        int >(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<std::complex<ElementType>, N> const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_a(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        ElementType >(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<std::complex<ElementType>, N> const& a1,
    ElementType const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_s(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        ElementType >(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    std::complex<ElementType> const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_s_a(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        ElementType >(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<std::complex<ElementType>, N> const& a1,
    tiny<std::complex<ElementType>, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_a(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        std::complex<ElementType> >(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<std::complex<ElementType>, N> const& a1,
    std::complex<ElementType> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_s(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        std::complex<ElementType> >(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    std::complex<ElementType> const& a1,
    tiny<std::complex<ElementType>, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_s_a(fn::functor_pow<
        std::complex<ElementType>,
        std::complex<ElementType>,
        std::complex<ElementType> >(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<ElementType, N> const& a1,
    tiny<std::complex<ElementType>, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_a(fn::functor_pow<
        std::complex<ElementType>,
        ElementType,
        std::complex<ElementType> >(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    tiny<ElementType, N> const& a1,
    std::complex<ElementType> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_s(fn::functor_pow<
        std::complex<ElementType>,
        ElementType,
        std::complex<ElementType> >(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  pow(
    ElementType const& a1,
    tiny<std::complex<ElementType>, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_s_a(fn::functor_pow<
        std::complex<ElementType>,
        ElementType,
        std::complex<ElementType> >(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  polar(
    tiny<ElementType, N> const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_a(fn::functor_polar<
        std::complex<ElementType>,
        ElementType,
        ElementType >(),
      a1.begin(), a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  polar(
    tiny<ElementType, N> const& a1,
    ElementType const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_a_s(fn::functor_polar<
        std::complex<ElementType>,
        ElementType,
        ElementType >(),
      a1.begin(), a2, result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<std::complex<ElementType>, N>
  polar(
    ElementType const& a1,
    tiny<ElementType, N> const& a2) {
    typedef tiny<std::complex<ElementType>, N> return_array_type;
    return_array_type result;
    array_operation_s_a(fn::functor_polar<
        std::complex<ElementType>,
        ElementType,
        ElementType >(),
      a1, a2.begin(), result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  approx_equal(
    tiny<ElementType, N> const& a1,
    tiny<ElementType, N> const& a2,
    ElementType const& tolerance) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_a_s(fn::functor_approx_equal<
        return_element_type, ElementType, ElementType, ElementType>(),
      a1.begin(), a2.begin(), tolerance,
      result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  approx_equal(
    tiny<ElementType, N> const& a1,
    ElementType const& a2,
    ElementType const& tolerance) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_a_s_s(fn::functor_approx_equal<
        return_element_type, ElementType, ElementType, ElementType>(),
      a1.begin(), a2, tolerance,
      result.begin(), N, true_type());
    return result;
  }

  template<typename ElementType, std::size_t N>
  inline
  tiny<bool, N>
  approx_equal(
    ElementType const& a1,
    tiny<ElementType, N> const& a2,
    ElementType const& tolerance) {
    typedef tiny<bool, N>
    return_array_type;
    typedef typename return_array_type::value_type return_element_type;

    return_array_type result;
    array_operation_s_a_s(fn::functor_approx_equal<
        return_element_type, ElementType, ElementType, ElementType>(),
      a1, a2.begin(), tolerance,
      result.begin(), N, true_type());
    return result;
  }

}} // namespace scitbx::af

#endif // DOXYGEN_SHOULD_SKIP_THIS

#endif // SCITBX_ARRAY_FAMILY_TINY_ALGEBRA_H
