00001 #ifndef Impala_Core_Array_Pattern_FuncRecGenConv2d_h
00002 #define Impala_Core_Array_Pattern_FuncRecGenConv2d_h
00003
00004 #include "Core/Array/Pattern/Categories.h"
00005 #include "Core/Array/Pattern/ArrayFunc.h"
00006
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Array
00012 {
00013 namespace Pattern
00014 {
00015
00016
00018 template <class ArrayT, class KerArrayT, class PixOpT, class RedOpT>
00019 void
00020 FuncRecGenConv2d_XYdirSim(ArrayT* array, KerArrayT* ker, PixOpT& pixOp,
00021 RedOpT& redOp)
00022 {
00023 typedef typename ArrayT::StorType StorT;
00024 typedef typename ArrayT::ArithType ArithT;
00025 typedef typename KerArrayT::StorType KerStorT;
00026 typedef typename KerArrayT::ArithType KerArithT;
00027
00028 int aWidth = ArrayCW(array);
00029 int aHeight = ArrayCH(array);
00030 int kerWidth = ArrayCW(ker);
00031 int kerHeight = ArrayCH(ker);
00032 int kerBW = ArrayCW(ker) / 2;
00033 int kerBH = ArrayCH(ker) / 2;
00034 int decXincY = ArrayInc(array, -kerWidth, 1);
00035 KerArithT neutralElement(RedOpT::NeutralElement());
00036 int y;
00037
00038
00039
00040 for (y=0 ; y<aHeight ; y++)
00041 {
00042 StorT* aPtr = ArrayCPB(array, -kerBW, -kerBH + y);
00043 for (int x=0 ; x<aWidth ; x++)
00044 {
00045 StorT* nPtr = aPtr;
00046 KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00047 KerArithT result = neutralElement;
00048 for (int j=0 ; j<kerBH ; j++)
00049 {
00050 for (int i=0 ; i<kerWidth ; i++)
00051 {
00052 redOp.DoIt(result, pixOp.DoIt(PtrRead(nPtr, KerArithT()),
00053 PtrRead(kPtr, KerArithT())));
00054 nPtr += ArrayT::ElemSize();
00055 kPtr += KerArrayT::ElemSize();
00056 }
00057 nPtr += decXincY;
00058 }
00059 for (int i=0 ; i<=kerBW ; i++)
00060 {
00061 redOp.DoIt(result, pixOp.DoIt(PtrRead(nPtr, KerArithT()),
00062 PtrRead(kPtr, KerArithT())));
00063 nPtr += ArrayT::ElemSize();
00064 kPtr += KerArrayT::ElemSize();
00065 }
00066 nPtr -= ArrayT::ElemSize();
00067 PtrWrite(nPtr, result);
00068 aPtr += ArrayT::ElemSize();
00069 }
00070 }
00071
00072
00073
00074 for (y=0 ; y<aHeight ; y++)
00075 {
00076 StorT* aPtr = ArrayCPE(array, kerBW, kerBH - y);
00077 for (int x=0 ; x<aWidth ; x++)
00078 {
00079 StorT* nPtr = aPtr;
00080 KerStorT* kPtr = ArrayCPE(ker, 0, 0);
00081 KerArithT result = neutralElement;
00082 for (int j=0 ; j<kerBH ; j++)
00083 {
00084 for (int i=0 ; i<kerWidth ; i++)
00085 {
00086 redOp.DoIt(result, pixOp.DoIt(PtrRead(nPtr, KerArithT()),
00087 PtrRead(kPtr, KerArithT())));
00088 nPtr -= ArrayT::ElemSize();
00089 kPtr -= KerArrayT::ElemSize();
00090 }
00091 nPtr -= decXincY;
00092 }
00093 for (int i=0 ; i<=kerBW ; i++)
00094 {
00095 redOp.DoIt(result, pixOp.DoIt(PtrRead(nPtr, KerArithT()),
00096 PtrRead(kPtr, KerArithT())));
00097 nPtr -= ArrayT::ElemSize();
00098 kPtr -= KerArrayT::ElemSize();
00099 }
00100 nPtr += ArrayT::ElemSize();
00101 PtrWrite(nPtr, result);
00102 aPtr -= ArrayT::ElemSize();
00103 }
00104 }
00105 }
00106
00107
00110 template <class ArrayT, class KerArrayT, class PixOpT, class RedOpT>
00111 void
00112 FuncRecGenConv2dDispatch(ArrayT* a, KerArrayT* ker, PixOpT& pixOp, RedOpT& redOp)
00113 {
00114 FuncRecGenConv2d_XYdirSim(a, ker, pixOp, redOp);
00115 }
00116
00117 }
00118 }
00119 }
00120 }
00121
00122 #endif