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