/**
*** Copyright (C) 2008 Intel Corporation.  All rights reserved.
***
*** The information and source code contained herein is the exclusive
*** property of Intel Corporation and may not be disclosed, examined
*** or reproduced in whole or in part without explicit written authorization
*** from the company.
***
**/

/**
*** ippvalarray
***
*** IPP specialization of several valarray operators
***
**/

#ifndef _INC_IPPVALARRAY
#define _INC_IPPVALARRAY

/// generated for IPP needs
#ifdef _MSC_VER
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
#if defined(min)
#pragma push_macro("min")
#undef min
#define _POP_MIN
#endif
#if defined(max)
#pragma push_macro("max")
#undef max
#define _POP_MAX
#endif
#endif

#include <ipp.h>

namespace std {

inline static Ipp32f* __data(const valarray<Ipp32f>& va) {
     return &(const_cast<valarray<Ipp32f>& >(va)[0]);
}

inline static Ipp64f* __data(const valarray<Ipp64f>& va) {
     return &(const_cast<valarray<Ipp64f>& >(va)[0]);
}

inline static Ipp8u* __data(const valarray<Ipp8u>& va) {
     return &(const_cast<valarray<Ipp8u>& >(va)[0]);
}

inline static Ipp16u* __data(const valarray<Ipp16u>& va) {
     return &(const_cast<valarray<Ipp16u>& >(va)[0]);
}

inline static Ipp32u* __data(const valarray<Ipp32u>& va) {
     return &(const_cast<valarray<Ipp32u>& >(va)[0]);
}

inline static Ipp16s* __data(const valarray<Ipp16s>& va) {
     return &(const_cast<valarray<Ipp16s>& >(va)[0]);
}

inline static Ipp32s* __data(const valarray<Ipp32s>& va) {
     return &(const_cast<valarray<Ipp32s>& >(va)[0]);
}

inline valarray<Ipp32f> abs(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsAbs_32f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> abs(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsAbs_64f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> acos(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsAcos_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> acos(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsAcos_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> asin(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsAsin_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> asin(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsAsin_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> atan(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsAtan_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> atan(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsAtan_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> atan2(const valarray<Ipp32f>& va ,const valarray<Ipp32f>& vb) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsAtan2_32f_A21(__data(va),__data(vb),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> atan2(const valarray<Ipp64f>& va ,const valarray<Ipp64f>& vb) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsAtan2_64f_A53(__data(va),__data(vb),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> cos(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsCos_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> cos(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsCos_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> cosh(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsCosh_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> cosh(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsCosh_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> exp(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsExp_32f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> exp(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsExp_64f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> log(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsLn_32f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> log(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsLn_64f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> log10(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsLog10_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> log10(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsLog10_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> pow(const valarray<Ipp32f>& va ,const valarray<Ipp32f>& vb) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsPow_32f_A21(__data(va),__data(vb),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> pow(const valarray<Ipp64f>& va ,const valarray<Ipp64f>& vb) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsPow_64f_A53(__data(va),__data(vb),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> sin(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsSin_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> sin(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsSin_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> sinh(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsSinh_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> sinh(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsSinh_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> sqrt(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsSqrt_32f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> sqrt(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsSqrt_64f(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> tan(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsTan_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> tan(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsTan_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp32f> tanh(const valarray<Ipp32f>& va ) {
        valarray<Ipp32f> v(static_cast<int>(va.size()));
        ippsTanh_32f_A21(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}

inline valarray<Ipp64f> tanh(const valarray<Ipp64f>& va ) {
        valarray<Ipp64f> v(static_cast<int>(va.size()));
        ippsTanh_64f_A53(__data(va),&v[0],static_cast<int>(va.size()));
        return v;
}
inline valarray<Ipp32f> operator+(const valarray<Ipp32f>&va,const valarray<Ipp32f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp32f> v(minlen);
        ippsAdd_32f(__data(vb), __data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp32f>& valarray<Ipp32f>::operator+=(const valarray<Ipp32f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsAdd_32f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp64f> operator+(const valarray<Ipp64f>&va,const valarray<Ipp64f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp64f> v(minlen);
        ippsAdd_64f(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp64f>& valarray<Ipp64f>::operator+=(const valarray<Ipp64f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsAdd_64f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp32f> operator-(const valarray<Ipp32f>&va,const valarray<Ipp32f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp32f> v(minlen);
        ippsSub_32f(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp32f>& valarray<Ipp32f>::operator-=(const valarray<Ipp32f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsSub_32f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp64f> operator-(const valarray<Ipp64f>&va,const valarray<Ipp64f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp64f> v(minlen);
        ippsSub_64f(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp64f>& valarray<Ipp64f>::operator-=(const valarray<Ipp64f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsSub_64f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp32f> operator/(const valarray<Ipp32f>&va,const valarray<Ipp32f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp32f> v(minlen);
        ippsDiv_32f(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp32f>& valarray<Ipp32f>::operator/=(const valarray<Ipp32f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsDiv_32f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp64f> operator/(const valarray<Ipp64f>&va,const valarray<Ipp64f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp64f> v(minlen);
        ippsDiv_64f(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp64f>& valarray<Ipp64f>::operator/=(const valarray<Ipp64f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsDiv_64f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp32f> operator*(const valarray<Ipp32f>&va,const valarray<Ipp32f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp32f> v(minlen);
        ippsMul_32f(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp32f>& valarray<Ipp32f>::operator*=(const valarray<Ipp32f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsMul_32f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp64f> operator*(const valarray<Ipp64f>&va,const valarray<Ipp64f>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp64f> v(minlen);
        ippsMul_64f(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp64f>& valarray<Ipp64f>::operator*=(const valarray<Ipp64f>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsMul_64f_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp8u> operator|(const valarray<Ipp8u>&va,const valarray<Ipp8u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp8u> v(minlen);
        ippsOr_8u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp8u>& valarray<Ipp8u>::operator|=(const valarray<Ipp8u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsOr_8u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp16u> operator|(const valarray<Ipp16u>&va,const valarray<Ipp16u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp16u> v(minlen);
        ippsOr_16u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp16u>& valarray<Ipp16u>::operator|=(const valarray<Ipp16u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsOr_16u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp32u> operator|(const valarray<Ipp32u>&va,const valarray<Ipp32u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp32u> v(minlen);
        ippsOr_32u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp32u>& valarray<Ipp32u>::operator|=(const valarray<Ipp32u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsOr_32u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp8u> operator&(const valarray<Ipp8u>&va,const valarray<Ipp8u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp8u> v(minlen);
        ippsAnd_8u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp8u>& valarray<Ipp8u>::operator&=(const valarray<Ipp8u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsAnd_8u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp16u> operator&(const valarray<Ipp16u>&va,const valarray<Ipp16u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp16u> v(minlen);
        ippsAnd_16u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp16u>& valarray<Ipp16u>::operator&=(const valarray<Ipp16u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsAnd_16u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp32u> operator&(const valarray<Ipp32u>&va,const valarray<Ipp32u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp32u> v(minlen);
        ippsAnd_32u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp32u>& valarray<Ipp32u>::operator&=(const valarray<Ipp32u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsAnd_32u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp8u> operator^(const valarray<Ipp8u>&va,const valarray<Ipp8u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp8u> v(minlen);
        ippsXor_8u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp8u>& valarray<Ipp8u>::operator^=(const valarray<Ipp8u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsXor_8u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp16u> operator^(const valarray<Ipp16u>&va,const valarray<Ipp16u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp16u> v(minlen);
        ippsXor_16u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp16u>& valarray<Ipp16u>::operator^=(const valarray<Ipp16u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsXor_16u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline valarray<Ipp32u> operator^(const valarray<Ipp32u>&va,const valarray<Ipp32u>&vb) {
        size_t minlen = va.size()<vb.size()?va.size():vb.size();
        valarray<Ipp32u> v(minlen);
        ippsXor_32u(__data(vb),__data(va),&v[0],static_cast<int>(minlen));
        return v;
}
inline valarray<Ipp32u>& valarray<Ipp32u>::operator^=(const valarray<Ipp32u>&va) {
        size_t minlen = va.size()<this->size()?va.size():this->size();
        ippsXor_32u_I(__data(va),__data(*this),static_cast<int>(minlen));
        return *this;
}
inline Ipp16s valarray<Ipp16s>::min() const {
        Ipp16s mm;
        ippsMin_16s(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp16s valarray<Ipp16s>::max() const {
        Ipp16s mm;
        ippsMax_16s(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp32s valarray<Ipp32s>::min() const {
        Ipp32s mm;
        ippsMin_32s(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp32s valarray<Ipp32s>::max() const {
        Ipp32s mm;
        ippsMax_32s(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp32f valarray<Ipp32f>::min() const {
        Ipp32f mm;
        ippsMin_32f(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp32f valarray<Ipp32f>::max() const {
        Ipp32f mm;
        ippsMax_32f(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp64f valarray<Ipp64f>::min() const {
        Ipp64f mm;
        ippsMin_64f(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp64f valarray<Ipp64f>::max() const {
        Ipp64f mm;
        ippsMax_64f(__data(*this),static_cast<int>(this->size()),&mm);
        return mm;
}
inline Ipp16s valarray<Ipp16s>::sum() const {
        Ipp16s sm;
        ippsSum_16s_Sfs(__data(*this),static_cast<int>(size()),&sm,0);
        return sm;
}
inline Ipp32s valarray<Ipp32s>::sum() const {
        Ipp32s sm;
        ippsSum_32s_Sfs(__data(*this),static_cast<int>(size()),&sm,0);
        return sm;
}
inline Ipp32f valarray<Ipp32f>::sum() const {
        Ipp32f sm;
        ippsSum_32f(__data(*this),static_cast<int>(size()),&sm,ippAlgHintNone);
        return sm;
}
inline Ipp64f valarray<Ipp64f>::sum() const {
        Ipp64f sm;
        ippsSum_64f(__data(*this),static_cast<int>(size()),&sm);
        return sm;
}

} /* End namespace std */

#ifdef _MSC_VER
#ifdef _POP_MIN
#pragma pop_macro("min")
#endif
#ifdef _POP_MAX
#pragma pop_macro("max")
#endif

#pragma warning(pop)
#pragma pack(pop)
#endif


#endif /* _INC_IPPVALARRAY */
