00001 #ifndef SHCONCRETEREGULAROPIMPL_HPP
00002 #define SHCONCRETEREGULAROPIMPL_HPP
00003 #include <numeric>
00004 #include "ShEval.hpp"
00005 #include "ShDebug.hpp"
00006 #include "ShError.hpp"
00007 #include "ShTypeInfo.hpp"
00008 #include "ShVariant.hpp"
00009
00010 namespace SH {
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define SHCRO_UNARY_OP(op, opsrc)\
00027 template<typename T>\
00028 struct ShConcreteRegularOp<op, T>\
00029 { \
00030 typedef ShDataVariant<T, SH_HOST> Variant; \
00031 typedef Variant* DataPtr; \
00032 typedef const Variant* DataCPtr; \
00033 \
00034 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00035 {\
00036 SH_DEBUG_ASSERT(dest && a);\
00037 int ao = a->size() > 1;\
00038 \
00039 typename Variant::iterator D = dest->begin();\
00040 typename Variant::const_iterator A = a->begin();\
00041 for(; D != dest->end(); A += ao, ++D) {\
00042 (*D) = opsrc;\
00043 }\
00044 } \
00045 };
00046
00047 #define SHCRO_BINARY_OP(op, opsrc)\
00048 template<typename T>\
00049 struct ShConcreteRegularOp<op, T>\
00050 { \
00051 typedef ShDataVariant<T, SH_HOST> Variant; \
00052 typedef Variant* DataPtr; \
00053 typedef const Variant* DataCPtr; \
00054 \
00055 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00056 {\
00057 SH_DEBUG_ASSERT(dest && a && b);\
00058 int ao = a->size() > 1;\
00059 int bo = b->size() > 1;\
00060 \
00061 typename Variant::iterator D = dest->begin();\
00062 typename Variant::const_iterator A, B;\
00063 A = a->begin();\
00064 B = b->begin();\
00065 for(; D != dest->end(); A += ao, B += bo, ++D) {\
00066 (*D) = opsrc;\
00067 }\
00068 } \
00069 };
00070
00071 #define SHCRO_TERNARY_OP(op, opsrc)\
00072 template<typename T>\
00073 struct ShConcreteRegularOp<op, T>\
00074 { \
00075 typedef ShDataVariant<T, SH_HOST> Variant; \
00076 typedef Variant* DataPtr; \
00077 typedef const Variant* DataCPtr; \
00078 \
00079 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0) \
00080 {\
00081 SH_DEBUG_ASSERT(dest && a && b && c);\
00082 int ao = a->size() > 1;\
00083 int bo = b->size() > 1;\
00084 int co = c->size() > 1;\
00085 \
00086 typename Variant::iterator D = dest->begin();\
00087 typename Variant::const_iterator A, B, C;\
00088 A = a->begin();\
00089 B = b->begin();\
00090 C = c->begin();\
00091 for(; D != dest->end(); A += ao, B += bo, C += co, ++D) {\
00092 (*D) = opsrc;\
00093 }\
00094 }\
00095 };
00096
00097
00098 SHCRO_UNARY_OP(SH_OP_ABS, abs(*A));
00099 SHCRO_UNARY_OP(SH_OP_ACOS, acos(*A));
00100 SHCRO_UNARY_OP(SH_OP_ASIN, asin(*A));
00101 SHCRO_UNARY_OP(SH_OP_ASN, (*A));
00102 SHCRO_UNARY_OP(SH_OP_ATAN, atan(*A));
00103 SHCRO_UNARY_OP(SH_OP_CBRT, cbrt(*A));
00104 SHCRO_UNARY_OP(SH_OP_CEIL, ceil(*A));
00105
00106 template<typename T>
00107 struct ShConcreteRegularOp<SH_OP_CMUL, T>
00108 {
00109 typedef ShDataVariant<T, SH_HOST> Variant;
00110 typedef Variant* DataPtr;
00111 typedef const Variant* DataCPtr;
00112
00113 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00114 {
00115
00116 (*dest)[0] = std::accumulate(a->begin(), a->end(),
00117 ShDataTypeInfo<T, SH_HOST>::Zero,
00118 std::multiplies<typename Variant::DataType>());
00119 }
00120 };
00121
00122 SHCRO_UNARY_OP(SH_OP_COS, cos(*A));
00123
00124 template<typename T>
00125 struct ShConcreteRegularOp<SH_OP_CSUM, T>
00126 {
00127 typedef ShDataVariant<T, SH_HOST> Variant;
00128 typedef Variant* DataPtr;
00129 typedef const Variant* DataCPtr;
00130
00131 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00132 {
00133
00134 (*dest)[0] = std::accumulate(a->begin(), a->end(),
00135 ShDataTypeInfo<T, SH_HOST>::Zero,
00136 std::plus<typename Variant::DataType>());
00137 }
00138 };
00139
00140 SHCRO_UNARY_OP(SH_OP_EXP, exp(*A));
00141 SHCRO_UNARY_OP(SH_OP_EXP2, exp2(*A));
00142 SHCRO_UNARY_OP(SH_OP_EXP10, exp10(*A));
00143 SHCRO_UNARY_OP(SH_OP_FLR, floor(*A));
00144 SHCRO_UNARY_OP(SH_OP_FRAC, frac(*A));
00145 SHCRO_UNARY_OP(SH_OP_LOG, log(*A));
00146 SHCRO_UNARY_OP(SH_OP_LOG2, log(*A));
00147 SHCRO_UNARY_OP(SH_OP_LOG10, log10(*A));
00148
00149 template<typename T>
00150 struct ShConcreteRegularOp<SH_OP_NORM, T>
00151 {
00152 typedef ShDataVariant<T, SH_HOST> Variant;
00153 typedef Variant* DataPtr;
00154 typedef const Variant* DataCPtr;
00155
00156 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00157 {
00158 SH_DEBUG_ASSERT(dest && a);
00159 typename Variant::DataType m = sqrt(std::inner_product(a->begin(), a->end(),
00160 a->begin(), ShDataTypeInfo<T, SH_HOST>::Zero));
00161
00162 typename Variant::iterator D = dest->begin();
00163 typename Variant::const_iterator A = a->begin();
00164 for(; D != dest->end(); ++A, ++D) (*D) = (*A) / m;
00165 }
00166 };
00167
00168 SHCRO_UNARY_OP(SH_OP_RCP, rcp(*A));
00169 SHCRO_UNARY_OP(SH_OP_RND, rnd(*A));
00170 SHCRO_UNARY_OP(SH_OP_RSQ, rsq(*A));
00171 SHCRO_UNARY_OP(SH_OP_SIN, sin(*A));
00172 SHCRO_UNARY_OP(SH_OP_SGN, sgn(*A));
00173 SHCRO_UNARY_OP(SH_OP_SQRT, sqrt(*A));
00174 SHCRO_UNARY_OP(SH_OP_TAN, tan(*A));
00175
00176
00177 SHCRO_BINARY_OP(SH_OP_ADD, (*A) + (*B));
00178 SHCRO_BINARY_OP(SH_OP_ATAN2, atan2((*A), (*B)));
00179 SHCRO_BINARY_OP(SH_OP_DIV, (*A) / (*B));
00180 SHCRO_BINARY_OP(SH_OP_MAX, max((*A), (*B)));
00181 SHCRO_BINARY_OP(SH_OP_MIN, min((*A), (*B)));
00182 SHCRO_BINARY_OP(SH_OP_MOD, (*A) % (*B));
00183 SHCRO_BINARY_OP(SH_OP_MUL, (*A) * (*B));
00184 SHCRO_BINARY_OP(SH_OP_POW, pow((*A), (*B)));
00185
00186 template<typename T>
00187 struct ShConcreteRegularOp<SH_OP_DOT, T>
00188 {
00189 typedef ShDataVariant<T, SH_HOST> Variant;
00190 typedef Variant* DataPtr;
00191 typedef const Variant* DataCPtr;
00192
00193 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00194 {
00195
00196 (*dest)[0] = std::inner_product(a->begin(), a->end(), b->begin(),
00197 ShDataTypeInfo<T, SH_HOST>::Zero);
00198 }
00199 };
00200
00201 SHCRO_BINARY_OP(SH_OP_SEQ, (*A) == (*B));
00202 SHCRO_BINARY_OP(SH_OP_SGE, (*A) >= (*B));
00203 SHCRO_BINARY_OP(SH_OP_SGT, (*A) > (*B));
00204 SHCRO_BINARY_OP(SH_OP_SLE, (*A) <= (*B));
00205 SHCRO_BINARY_OP(SH_OP_SLT, (*A) < (*B));
00206 SHCRO_BINARY_OP(SH_OP_SNE, (*A) != (*B));
00207
00208 template<typename T>
00209 struct ShConcreteRegularOp<SH_OP_XPD, T>
00210 {
00211 typedef ShDataVariant<T, SH_HOST> Variant;
00212 typedef Variant* DataPtr;
00213 typedef const Variant* DataCPtr;
00214
00215 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00216 {
00217 (*dest)[0] = (*a)[1] * (*b)[2] - (*a)[2] * (*b)[1];
00218 (*dest)[1] = -((*a)[0] * (*b)[2] - (*a)[2] * (*b)[0]);
00219 (*dest)[2] = (*a)[0] * (*b)[1] - (*a)[1] * (*b)[0];
00220 }
00221 };
00222
00223
00224 SHCRO_TERNARY_OP(SH_OP_COND, cond(*A, *B, *C));
00225 SHCRO_TERNARY_OP(SH_OP_LRP, lerp(*A, *B, *C));
00226 SHCRO_TERNARY_OP(SH_OP_MAD, (*A) * (*B) + (*C));
00227
00228 }
00229 #endif