00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_CURSOR_PSEUDO_DOT_INCLUDE
00013 #define MTL_CURSOR_PSEUDO_DOT_INCLUDE
00014
00015 namespace mtl {
00016
00017
00018
00019 namespace functor {
00020
00021 template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2, unsigned Depth>
00022 struct cursor_pseudo_dot_block
00023 {
00024 static unsigned const offset= MaxDepth - Depth;
00025
00026 void operator() (Cursor1 i1, Prop1& prop1, Cursor2 i2, Prop2& prop2,
00027 Value& s0, Value& s1, Value& s2, Value& s3,
00028 Value& s4, Value& s5, Value& s6, Value& s7)
00029 {
00030 Cursor1 tmp1(i1); tmp1+= offset;
00031 Cursor2 tmp2(i2); tmp2+= offset;
00032 s0+= prop1(*tmp1) * prop2(*tmp2);
00033
00034 typedef cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, Depth-1> block_rest;
00035 block_rest() (i1, prop1, i2, prop2, s1, s2, s3, s4, s5, s6, s7, s0);
00036 }
00037 };
00038
00039
00040 template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2>
00041 struct cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, 1>
00042 {
00043 static unsigned const offset= MaxDepth - 1;
00044
00045 void operator() (Cursor1 i1, Prop1& prop1, Cursor2 i2, Prop2& prop2,
00046 Value& s0, Value&, Value&, Value&,
00047 Value&, Value&, Value&, Value&)
00048 {
00049 s0+= prop1(*(i1 + offset)) * prop2(*(i2 + offset));
00050 }
00051 };
00052
00053 template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2>
00054 struct cursor_pseudo_dot_t
00055 {
00056 Value operator() (Cursor1 i1, Cursor1 end1, Prop1& prop1, Cursor2 i2, Prop2& prop2)
00057 {
00058 using math::zero;
00059 Value ref, my_zero(zero(ref)),
00060 s0= my_zero, s1= my_zero, s2= my_zero, s3= my_zero,
00061 s4= my_zero, s5= my_zero, s6= my_zero, s7= my_zero;
00062 std::size_t size= end1 - i1, blocks= size / MaxDepth, blocked_size= blocks * MaxDepth;
00063
00064 typedef cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, MaxDepth> dot_block_type;
00065 for (unsigned i= 0; i < blocked_size; i+= MaxDepth, i1+= MaxDepth, i2+= MaxDepth) {
00066 dot_block_type()(i1, prop1, i2, prop2, s0, s1, s2, s3, s4, s5, s6, s7);
00067 }
00068
00069 typedef cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, MaxDepth> dot_single_type;
00070 s0+= s1 + s2 + s3 + s4 + s5 + s6 + s7;
00071 for (unsigned i= blocked_size; i < size; ++i, ++i1, ++i2)
00072 dot_single_type()(i1, prop1, i2, prop2, s0, s1, s2, s3, s4, s5, s6, s7);
00073 return s0;
00074 }
00075 };
00076
00077 }
00078
00079 template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2>
00080 Value cursor_pseudo_dot(Cursor1 i1, Cursor1 end1, Prop1 prop1, Cursor2 i2, Prop2 prop2, Value)
00081 {
00082 return functor::cursor_pseudo_dot_t<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2>()(i1, end1, prop1, i2, prop2);
00083 }
00084
00085
00086
00087 }
00088
00089 #endif // MTL_CURSOR_PSEUDO_DOT_INCLUDE