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
00148 template<typename T>
00149 struct ShConcreteRegularOp<SH_OP_CSUM, T>
00150 {
00151 typedef ShDataVariant<T, SH_HOST> Variant;
00152 typedef Variant* DataPtr;
00153 typedef const Variant* DataCPtr;
00154
00155 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00156 {
00157
00158 (*dest)[0] = std::accumulate(a->begin(), a->end(),
00159 ShDataTypeInfo<T, SH_HOST>::Zero,
00160 std::plus<typename Variant::DataType>());
00161 }
00162 };
00163
00164 SHCRO_UNARY_OP(SH_OP_EXP, exp(*A));
00165 SHCRO_UNARY_OP(SH_OP_EXP2, exp2(*A));
00166 SHCRO_UNARY_OP(SH_OP_EXP10, exp10(*A));
00167 SHCRO_UNARY_OP(SH_OP_FLR, floor(*A));
00168 SHCRO_UNARY_OP(SH_OP_FRAC, frac(*A));
00169 SHCRO_UNARY_OP(SH_OP_LOG, log(*A));
00170 SHCRO_UNARY_OP(SH_OP_LOG2, log(*A));
00171 SHCRO_UNARY_OP(SH_OP_LOG10, log10(*A));
00172
00173 template<typename T>
00174 struct ShConcreteRegularOp<SH_OP_LIT, T>
00175 {
00176 typedef ShDataVariant<T, SH_HOST> Variant;
00177 typedef Variant* DataPtr;
00178 typedef const Variant* DataCPtr;
00179 typedef typename Variant::DataType DataType;
00180
00181 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00182 {
00183 DataType x, y, w;
00184 x = max((*a)[0], 0);
00185 y = max((*a)[1], 0);
00186 w = (*a)[2];
00187 w = min(w, 128);
00188 w = max(w, -128);
00189 (*dest)[0] = 1;
00190 (*dest)[1] = x;
00191 (*dest)[2] = (x > 0) * pow(y,w);
00192 (*dest)[3] = 1;
00193 }
00194 };
00195
00196 template<typename T>
00197 struct ShConcreteRegularOp<SH_OP_NORM, T>
00198 {
00199 typedef ShDataVariant<T, SH_HOST> Variant;
00200 typedef Variant* DataPtr;
00201 typedef const Variant* DataCPtr;
00202
00203 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00204 {
00205 SH_DEBUG_ASSERT(dest && a);
00206 typename Variant::DataType m = sqrt(std::inner_product(a->begin(), a->end(),
00207 a->begin(), ShDataTypeInfo<T, SH_HOST>::Zero));
00208
00209 typename Variant::iterator D = dest->begin();
00210 typename Variant::const_iterator A = a->begin();
00211 for(; D != dest->end(); ++A, ++D) (*D) = (*A) / m;
00212 }
00213 };
00214
00215 SHCRO_UNARY_OP(SH_OP_RCP, rcp(*A));
00216 SHCRO_UNARY_OP(SH_OP_RND, rnd(*A));
00217 SHCRO_UNARY_OP(SH_OP_RSQ, rsq(*A));
00218 SHCRO_UNARY_OP(SH_OP_SIN, sin(*A));
00219 SHCRO_UNARY_OP(SH_OP_SGN, sgn(*A));
00220 SHCRO_UNARY_OP(SH_OP_SQRT, sqrt(*A));
00221 SHCRO_UNARY_OP(SH_OP_TAN, tan(*A));
00222
00223
00224 SHCRO_BINARY_OP(SH_OP_ADD, (*A) + (*B));
00225 SHCRO_BINARY_OP(SH_OP_ATAN2, atan2((*A), (*B)));
00226 SHCRO_BINARY_OP(SH_OP_DIV, (*A) / (*B));
00227 SHCRO_BINARY_OP(SH_OP_MAX, max((*A), (*B)));
00228 SHCRO_BINARY_OP(SH_OP_MIN, min((*A), (*B)));
00229 SHCRO_BINARY_OP(SH_OP_MOD, (*A) % (*B));
00230 SHCRO_BINARY_OP(SH_OP_MUL, (*A) * (*B));
00231 SHCRO_BINARY_OP(SH_OP_POW, pow((*A), (*B)));
00232
00233 template<typename T>
00234 struct ShConcreteRegularOp<SH_OP_DOT, T>
00235 {
00236 typedef ShDataVariant<T, SH_HOST> Variant;
00237 typedef Variant* DataPtr;
00238 typedef const Variant* DataCPtr;
00239
00240 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00241 {
00242
00243 (*dest)[0] = std::inner_product(a->begin(), a->end(), b->begin(),
00244 ShDataTypeInfo<T, SH_HOST>::Zero);
00245 }
00246 };
00247
00248 SHCRO_BINARY_OP(SH_OP_SEQ, (*A) == (*B));
00249 SHCRO_BINARY_OP(SH_OP_SGE, (*A) >= (*B));
00250 SHCRO_BINARY_OP(SH_OP_SGT, (*A) > (*B));
00251 SHCRO_BINARY_OP(SH_OP_SLE, (*A) <= (*B));
00252 SHCRO_BINARY_OP(SH_OP_SLT, (*A) < (*B));
00253 SHCRO_BINARY_OP(SH_OP_SNE, (*A) != (*B));
00254
00255 template<typename T>
00256 struct ShConcreteRegularOp<SH_OP_XPD, T>
00257 {
00258 typedef ShDataVariant<T, SH_HOST> Variant;
00259 typedef Variant* DataPtr;
00260 typedef const Variant* DataCPtr;
00261
00262 static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0)
00263 {
00264 (*dest)[0] = (*a)[1] * (*b)[2] - (*a)[2] * (*b)[1];
00265 (*dest)[1] = -((*a)[0] * (*b)[2] - (*a)[2] * (*b)[0]);
00266 (*dest)[2] = (*a)[0] * (*b)[1] - (*a)[1] * (*b)[0];
00267 }
00268 };
00269
00270
00271 SHCRO_TERNARY_OP(SH_OP_COND, cond(*A, *B, *C));
00272 SHCRO_TERNARY_OP(SH_OP_LRP, lerp(*A, *B, *C));
00273 SHCRO_TERNARY_OP(SH_OP_MAD, (*A) * (*B) + (*C));
00274
00275 }
00276 #endif