From 0f9575462eb37a7c9985583ca33ae315f6e6431d Mon Sep 17 00:00:00 2001 From: Alberto Ruiz Date: Wed, 14 May 2014 19:46:44 +0200 Subject: vectorized operations in base --- packages/base/src/C/vector-aux.c | 676 ++++++++++++++++++++++++++++++++ packages/base/src/Numeric/Vectorized.hs | 273 +++++++++++++ 2 files changed, 949 insertions(+) create mode 100644 packages/base/src/C/vector-aux.c create mode 100644 packages/base/src/Numeric/Vectorized.hs (limited to 'packages/base/src') diff --git a/packages/base/src/C/vector-aux.c b/packages/base/src/C/vector-aux.c new file mode 100644 index 0000000..07ccf76 --- /dev/null +++ b/packages/base/src/C/vector-aux.c @@ -0,0 +1,676 @@ +#include "lapack-aux.h" + +#define V(x) x##n,x##p + +#include +#include +#include + +#define MACRO(B) do {B} while (0) +#define ERROR(CODE) MACRO(return CODE;) +#define REQUIRES(COND, CODE) MACRO(if(!(COND)) {ERROR(CODE);}) +#define OK return 0; + +#define MIN(A,B) ((A)<(B)?(A):(B)) +#define MAX(A,B) ((A)>(B)?(A):(B)) + +#ifdef DBG +#define DEBUGMSG(M) printf("*** calling aux C function: %s\n",M); +#else +#define DEBUGMSG(M) +#endif + +#define CHECK(RES,CODE) MACRO(if(RES) return CODE;) + +#ifdef DBG +#define DEBUGMAT(MSG,X) printf(MSG" = \n"); gsl_matrix_fprintf(stdout,X,"%f"); printf("\n"); +#else +#define DEBUGMAT(MSG,X) +#endif + +#ifdef DBG +#define DEBUGVEC(MSG,X) printf(MSG" = \n"); gsl_vector_fprintf(stdout,X,"%f"); printf("\n"); +#else +#define DEBUGVEC(MSG,X) +#endif + + +#define BAD_SIZE 2000 +#define BAD_CODE 2001 +#define MEM 2002 +#define BAD_FILE 2003 + + +int sumF(KFVEC(x),FVEC(r)) { + DEBUGMSG("sumF"); + printf("hello!\n"); + REQUIRES(rn==1,BAD_SIZE); + int i; + float res = 0; + for (i = 0; i < xn; i++) res += xp[i]; + rp[0] = res; + OK +} + +int sumR(KDVEC(x),DVEC(r)) { + DEBUGMSG("sumR"); + REQUIRES(rn==1,BAD_SIZE); + int i; + double res = 0; + for (i = 0; i < xn; i++) res += xp[i]; + rp[0] = res; + OK +} + + +int sumQ(KQVEC(x),QVEC(r)) { + DEBUGMSG("sumQ"); + REQUIRES(rn==1,BAD_SIZE); + int i; + complex res; + res.r = 0; + res.i = 0; + for (i = 0; i < xn; i++) { + res.r += xp[i].r; + res.i += xp[i].i; + } + rp[0] = res; + OK +} + +int sumC(KCVEC(x),CVEC(r)) { + DEBUGMSG("sumC"); + REQUIRES(rn==1,BAD_SIZE); + int i; + doublecomplex res; + res.r = 0; + res.i = 0; + for (i = 0; i < xn; i++) { + res.r += xp[i].r; + res.i += xp[i].i; + } + rp[0] = res; + OK +} + + +int prodF(KFVEC(x),FVEC(r)) { + DEBUGMSG("prodF"); + REQUIRES(rn==1,BAD_SIZE); + int i; + float res = 1; + for (i = 0; i < xn; i++) res *= xp[i]; + rp[0] = res; + OK +} + +int prodR(KDVEC(x),DVEC(r)) { + DEBUGMSG("prodR"); + REQUIRES(rn==1,BAD_SIZE); + int i; + double res = 1; + for (i = 0; i < xn; i++) res *= xp[i]; + rp[0] = res; + OK +} + + +int prodQ(KQVEC(x),QVEC(r)) { + DEBUGMSG("prodQ"); + REQUIRES(rn==1,BAD_SIZE); + int i; + complex res; + float temp; + res.r = 1; + res.i = 0; + for (i = 0; i < xn; i++) { + temp = res.r * xp[i].r - res.i * xp[i].i; + res.i = res.r * xp[i].i + res.i * xp[i].r; + res.r = temp; + } + rp[0] = res; + OK +} + +int prodC(KCVEC(x),CVEC(r)) { + DEBUGMSG("prodC"); + REQUIRES(rn==1,BAD_SIZE); + int i; + doublecomplex res; + double temp; + res.r = 1; + res.i = 0; + for (i = 0; i < xn; i++) { + temp = res.r * xp[i].r - res.i * xp[i].i; + res.i = res.r * xp[i].i + res.i * xp[i].r; + res.r = temp; + } + rp[0] = res; + OK +} + + +double dnrm2_(integer*, const double*, integer*); +double dasum_(integer*, const double*, integer*); + +double vector_max(KDVEC(x)) { + double r = xp[0]; + int k; + for (k = 1; kr) { + r = xp[k]; + } + } + return r; +} + +double vector_min(KDVEC(x)) { + double r = xp[0]; + int k; + for (k = 1; kxp[0]) { + r = k; + } + } + return r; +} + +double vector_min_index(KDVEC(x)) { + int k, r = 0; + for (k = 1; kr) { + r = xp[k]; + } + } + return r; +} + +float vector_min_f(KFVEC(x)) { + float r = xp[0]; + int k; + for (k = 1; kxp[0]) { + r = k; + } + } + return r; +} + +float vector_min_index_f(KFVEC(x)) { + int k, r = 0; + for (k = 1; k0) { + return +1.0; + } else if (x<0) { + return -1.0; + } else { + return 0.0; + } +} + +inline float float_sign(float x) { + if(x>0) { + return +1.0; + } else if (x<0) { + return -1.0; + } else { + return 0.0; + } +} + + +#define OP(C,F) case C: { for(k=0;k Float +sumF x = unsafePerformIO $ do + r <- createVector 1 + app2 c_sumF vec x vec r "sumF" + return $ r @> 0 + +-- | sum of elements +sumR :: Vector Double -> Double +sumR x = unsafePerformIO $ do + r <- createVector 1 + app2 c_sumR vec x vec r "sumR" + return $ r @> 0 + +-- | sum of elements +sumQ :: Vector (Complex Float) -> Complex Float +sumQ x = unsafePerformIO $ do + r <- createVector 1 + app2 c_sumQ vec x vec r "sumQ" + return $ r @> 0 + +-- | sum of elements +sumC :: Vector (Complex Double) -> Complex Double +sumC x = unsafePerformIO $ do + r <- createVector 1 + app2 c_sumC vec x vec r "sumC" + return $ r @> 0 + +foreign import ccall unsafe "sumF" c_sumF :: TFF +foreign import ccall unsafe "sumR" c_sumR :: TVV +foreign import ccall unsafe "sumQ" c_sumQ :: TQVQV +foreign import ccall unsafe "sumC" c_sumC :: TCVCV + +-- | product of elements +prodF :: Vector Float -> Float +prodF x = unsafePerformIO $ do + r <- createVector 1 + app2 c_prodF vec x vec r "prodF" + return $ r @> 0 + +-- | product of elements +prodR :: Vector Double -> Double +prodR x = unsafePerformIO $ do + r <- createVector 1 + app2 c_prodR vec x vec r "prodR" + return $ r @> 0 + +-- | product of elements +prodQ :: Vector (Complex Float) -> Complex Float +prodQ x = unsafePerformIO $ do + r <- createVector 1 + app2 c_prodQ vec x vec r "prodQ" + return $ r @> 0 + +-- | product of elements +prodC :: Vector (Complex Double) -> Complex Double +prodC x = unsafePerformIO $ do + r <- createVector 1 + app2 c_prodC vec x vec r "prodC" + return $ r @> 0 + +foreign import ccall unsafe "prodF" c_prodF :: TFF +foreign import ccall unsafe "prodR" c_prodR :: TVV +foreign import ccall unsafe "prodQ" c_prodQ :: TQVQV +foreign import ccall unsafe "prodC" c_prodC :: TCVCV + +------------------------------------------------------------------ + +toScalarAux fun code v = unsafePerformIO $ do + r <- createVector 1 + app2 (fun (fromei code)) vec v vec r "toScalarAux" + return (r `at` 0) + +vectorMapAux fun code v = unsafePerformIO $ do + r <- createVector (dim v) + app2 (fun (fromei code)) vec v vec r "vectorMapAux" + return r + +vectorMapValAux fun code val v = unsafePerformIO $ do + r <- createVector (dim v) + pval <- newArray [val] + app2 (fun (fromei code) pval) vec v vec r "vectorMapValAux" + free pval + return r + +vectorZipAux fun code u v = unsafePerformIO $ do + r <- createVector (dim u) + app3 (fun (fromei code)) vec u vec v vec r "vectorZipAux" + return r + +--------------------------------------------------------------------- + +-- | obtains different functions of a vector: norm1, norm2, max, min, posmax, posmin, etc. +toScalarR :: FunCodeS -> Vector Double -> Double +toScalarR oper = toScalarAux c_toScalarR (fromei oper) + +foreign import ccall unsafe "toScalarR" c_toScalarR :: CInt -> TVV + +-- | obtains different functions of a vector: norm1, norm2, max, min, posmax, posmin, etc. +toScalarF :: FunCodeS -> Vector Float -> Float +toScalarF oper = toScalarAux c_toScalarF (fromei oper) + +foreign import ccall unsafe "toScalarF" c_toScalarF :: CInt -> TFF + +-- | obtains different functions of a vector: only norm1, norm2 +toScalarC :: FunCodeS -> Vector (Complex Double) -> Double +toScalarC oper = toScalarAux c_toScalarC (fromei oper) + +foreign import ccall unsafe "toScalarC" c_toScalarC :: CInt -> TCVV + +-- | obtains different functions of a vector: only norm1, norm2 +toScalarQ :: FunCodeS -> Vector (Complex Float) -> Float +toScalarQ oper = toScalarAux c_toScalarQ (fromei oper) + +foreign import ccall unsafe "toScalarQ" c_toScalarQ :: CInt -> TQVF + +------------------------------------------------------------------ + +-- | map of real vectors with given function +vectorMapR :: FunCodeV -> Vector Double -> Vector Double +vectorMapR = vectorMapAux c_vectorMapR + +foreign import ccall unsafe "mapR" c_vectorMapR :: CInt -> TVV + +-- | map of complex vectors with given function +vectorMapC :: FunCodeV -> Vector (Complex Double) -> Vector (Complex Double) +vectorMapC oper = vectorMapAux c_vectorMapC (fromei oper) + +foreign import ccall unsafe "mapC" c_vectorMapC :: CInt -> TCVCV + +-- | map of real vectors with given function +vectorMapF :: FunCodeV -> Vector Float -> Vector Float +vectorMapF = vectorMapAux c_vectorMapF + +foreign import ccall unsafe "mapF" c_vectorMapF :: CInt -> TFF + +-- | map of real vectors with given function +vectorMapQ :: FunCodeV -> Vector (Complex Float) -> Vector (Complex Float) +vectorMapQ = vectorMapAux c_vectorMapQ + +foreign import ccall unsafe "mapQ" c_vectorMapQ :: CInt -> TQVQV + +------------------------------------------------------------------- + +-- | map of real vectors with given function +vectorMapValR :: FunCodeSV -> Double -> Vector Double -> Vector Double +vectorMapValR oper = vectorMapValAux c_vectorMapValR (fromei oper) + +foreign import ccall unsafe "mapValR" c_vectorMapValR :: CInt -> Ptr Double -> TVV + +-- | map of complex vectors with given function +vectorMapValC :: FunCodeSV -> Complex Double -> Vector (Complex Double) -> Vector (Complex Double) +vectorMapValC = vectorMapValAux c_vectorMapValC + +foreign import ccall unsafe "mapValC" c_vectorMapValC :: CInt -> Ptr (Complex Double) -> TCVCV + +-- | map of real vectors with given function +vectorMapValF :: FunCodeSV -> Float -> Vector Float -> Vector Float +vectorMapValF oper = vectorMapValAux c_vectorMapValF (fromei oper) + +foreign import ccall unsafe "mapValF" c_vectorMapValF :: CInt -> Ptr Float -> TFF + +-- | map of complex vectors with given function +vectorMapValQ :: FunCodeSV -> Complex Float -> Vector (Complex Float) -> Vector (Complex Float) +vectorMapValQ oper = vectorMapValAux c_vectorMapValQ (fromei oper) + +foreign import ccall unsafe "mapValQ" c_vectorMapValQ :: CInt -> Ptr (Complex Float) -> TQVQV + +------------------------------------------------------------------- + +-- | elementwise operation on real vectors +vectorZipR :: FunCodeVV -> Vector Double -> Vector Double -> Vector Double +vectorZipR = vectorZipAux c_vectorZipR + +foreign import ccall unsafe "zipR" c_vectorZipR :: CInt -> TVVV + +-- | elementwise operation on complex vectors +vectorZipC :: FunCodeVV -> Vector (Complex Double) -> Vector (Complex Double) -> Vector (Complex Double) +vectorZipC = vectorZipAux c_vectorZipC + +foreign import ccall unsafe "zipC" c_vectorZipC :: CInt -> TCVCVCV + +-- | elementwise operation on real vectors +vectorZipF :: FunCodeVV -> Vector Float -> Vector Float -> Vector Float +vectorZipF = vectorZipAux c_vectorZipF + +foreign import ccall unsafe "zipF" c_vectorZipF :: CInt -> TFFF + +-- | elementwise operation on complex vectors +vectorZipQ :: FunCodeVV -> Vector (Complex Float) -> Vector (Complex Float) -> Vector (Complex Float) +vectorZipQ = vectorZipAux c_vectorZipQ + +foreign import ccall unsafe "zipQ" c_vectorZipQ :: CInt -> TQVQVQV + -- cgit v1.2.3