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