#ifndef __ALTIVEC_H__
#define __ALTIVEC_H__

#include <vecLib/vDSP.h>

#include <utility> //for<T,U>
using namespace std;

namespace Altivec{

template<typename T> inline T sqr(T x) {return x*x;}

inline void vadd(const float* in1, const float* in2, float* out, unsigned int size)
                {::vadd(in1,1,in2,1,out,1,size);}
inline void vsub(const float* in1, const float* in2, float* out, unsigned int size)
                {::vsub(in2,1,in1,1,out,1,size);}//tricky:reverse order
inline void vmul(const float* in1, const float* in2, float* out, unsigned int size)
                {::vmul(in1,1,in2,1,out,1,size);}
inline void vmul(const float* in1, float x, float* out, unsigned int size)
                {::vsmul(in1,1,&x,out,1,size);}
inline void vdiv(const float* in1, float x, float* out, unsigned int size)
                {float y=1/x;::vsmul(in1,1,&y,out,1,size);}
inline void vsqr(const float* in1, float* out, unsigned int size)
                {::vsq(in1,1,out,1,size);}
inline void vam(const float* in1, const float* in2, const float* in3,
                float* out, unsigned int size)
                {::vam(in1,1,in2,1,in3,1,out,1,size);}
inline float vdotpr(const float* in1, const float* in2, unsigned int size)
                {float result; ::dotpr(in1,1,in2,1,&result, size);return result;}
               
float vsum(const float* in1, unsigned int size);
float vabssum(const float* in1, unsigned int size);
pair<float,float> meanAndStandardDeviation(const float* input, unsigned int size);
pair<float,float> vzMeanAndStandardDeviation(const float* in_re, const float* in_im,
                                             unsigned int size);
void vzmul(const float* in1_re, const float* in1_im,
           const float* in2_re, const float* in2_im,
           float* out_re, float* out_im,
           unsigned int size);

} //end namespace Altivec

#endif
