00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027
#include <cmath>
00028
#include "ShInstructions.hpp"
00029
#include "ShStatement.hpp"
00030
#include "ShContext.hpp"
00031
#include "ShDebug.hpp"
00032
#include "ShError.hpp"
00033
00034
#ifdef WIN32
00035
00036
00037
inline float roundf(
float f) {
return floorf(f + 0.5); }
00038
inline float cbrtf(
float f) {
return pow(f, 1.0f/3.0f); }
00039
#endif
00040
00041
namespace {
00042
00043
using namespace SH;
00044
00045
inline bool immediate()
00046 {
00047
return !ShContext::current()->parsing();
00048 }
00049
00050
inline void sizes_match(
const ShVariable& a,
const ShVariable& b)
00051 {
00052 SH_DEBUG_ASSERT(a.size() == b.size());
00053 }
00054
00055
inline void sizes_match(
const ShVariable& a,
const ShVariable& b,
00056
const ShVariable& c,
bool scalar_b =
false,
bool scalar_c =
false)
00057 {
00058 SH_DEBUG_ASSERT(((scalar_b && b.size() == 1) || a.size() == b.size()) &&
00059 ((scalar_c && c.size() == 1) || a.size() == c.size()));
00060 }
00061
00062
inline void has_values(
const ShVariable& a)
00063 {
00064 SH_DEBUG_ASSERT(a.hasValues());
00065 }
00066
00067
inline void has_values(
const ShVariable& a,
const ShVariable& b)
00068 {
00069 SH_DEBUG_ASSERT(a.hasValues());
00070 SH_DEBUG_ASSERT(b.hasValues());
00071 }
00072
00073
inline void has_values(
const ShVariable& a,
const ShVariable& b,
const ShVariable& c)
00074 {
00075 SH_DEBUG_ASSERT(a.hasValues());
00076 SH_DEBUG_ASSERT(b.hasValues());
00077 SH_DEBUG_ASSERT(c.hasValues());
00078 }
00079
00080
inline void has_values(
const ShVariable& a,
const ShVariable& b,
00081
const ShVariable& c,
const ShVariable& d)
00082 {
00083 SH_DEBUG_ASSERT(a.hasValues());
00084 SH_DEBUG_ASSERT(b.hasValues());
00085 SH_DEBUG_ASSERT(c.hasValues());
00086 SH_DEBUG_ASSERT(d.hasValues());
00087 }
00088
00089
inline void addStatement(
const ShStatement& stmt)
00090 {
00091 ShContext::current()->parsing()->tokenizer.blockList()->addStatement(stmt);
00092 }
00093
00094
typedef float T;
00095
00096
inline T slt(T a, T b) {
return a < b ? 1.0f : 0.0f; }
00097
inline T sle(T a, T b) {
return a <= b ? 1.0f : 0.0f; }
00098
inline T sgt(T a, T b) {
return a > b ? 1.0f : 0.0f; }
00099
inline T sge(T a, T b) {
return a >= b ? 1.0f : 0.0f; }
00100
inline T seq(T a, T b) {
return a == b ? 1.0f : 0.0f; }
00101
inline T sne(T a, T b) {
return a != b ? 1.0f : 0.0f; }
00102
inline T max(T a, T b) {
return a > b ? a : b; }
00103
inline T min(T a, T b) {
return a < b ? a : b; }
00104
inline T lrp(T alpha, T a, T b) {
return alpha*a + (1.0f-alpha)*b; }
00105
inline T cond(T alpha, T a, T b) {
return alpha > 0.0f ? a : b; }
00106
inline T mad(T a, T b, T c) {
return a * b + c; }
00107
inline T frac(T a) {
return fmodf(a, 1.0f); }
00108
inline T sgn(T a) {
return (a < 0.0f ? -1.0f : (a == 0.0f ? 0.0f : 1.0f)); }
00109
00110
00111
#ifdef WIN32
00112
inline T exp2f(T a) {
return powf(2.0, a); }
00113
inline T exp10f(T a) {
return powf(10.0, a); }
00114
inline T log2f(T a) {
return logf(a)/logf(2.0); }
00115
#endif
00116
#ifdef __APPLE__
00117
inline T exp10f(T a) {
return powf(10.0, a); }
00118
#endif
00119
}
00120
00121
#define CWISE_BINARY_OP(d, a, b, op) \
00122
do {\
00123
has_values(d, a, b);\
00124
T* v_d = new T[d.size()];\
00125
T* v_a = new T[a.size()];\
00126
a.getValues(v_a);\
00127
T* v_b = new T[b.size()];\
00128
b.getValues(v_b);\
00129
for (int i = 0; i < d.size(); i++) v_d[i] = op(v_a[(a.size() == 1 ? 0 : i)],\
00130
v_b[(b.size() == 1 ? 0 : i)]);\
00131
d.setValues(v_d);\
00132
delete [] v_d;\
00133
delete [] v_a;\
00134
delete [] v_b;\
00135
} while (0)
00136
00137
#define CWISE_BINARY_INLOP(d, a, b, op) \
00138
do {\
00139
has_values(d, a, b);\
00140
T* v_d = new T[d.size()];\
00141
T* v_a = new T[a.size()];\
00142
a.getValues(v_a);\
00143
T* v_b = new T[b.size()];\
00144
b.getValues(v_b);\
00145
for (int i = 0; i < d.size(); i++) v_d[i] = v_a[(a.size() == 1 ? 0 : i)] op\
00146
v_b[(b.size() == 1 ? 0 : i)];\
00147
d.setValues(v_d);\
00148
delete [] v_d;\
00149
delete [] v_a;\
00150
delete [] v_b;\
00151
} while (0)
00152
00153
#define CWISE_TRINARY_OP(d, a, b, c, op) \
00154
do {\
00155
has_values(d, a, b, c);\
00156
T* v_a = new T[a.size()];\
00157
a.getValues(v_a);\
00158
T* v_b = new T[b.size()];\
00159
b.getValues(v_b);\
00160
T* v_c = new T[c.size()];\
00161
c.getValues(v_c);\
00162
T* v_d = new T[d.size()];\
00163
for (int i = 0; i < d.size(); i++) v_d[i] = op(v_a[(a.size() == 1 ? 0 : i)],\
00164
v_b[(b.size() == 1 ? 0 : i)],\
00165
v_c[(c.size() == 1 ? 0 : i)]\
00166
);\
00167
d.setValues(v_d);\
00168
delete [] v_d;\
00169
delete [] v_a;\
00170
delete [] v_b;\
00171
delete [] v_c;\
00172
} while (0)
00173
00174
#define CWISE_UNARY_OP(d, a, op) \
00175
do {\
00176
has_values(d, a);\
00177
T* v_a = new T[a.size()];\
00178
T* v_d = new T[d.size()];\
00179
a.getValues(v_a);\
00180
for (int i = 0; i < d.size(); i++) v_d[i] = op(v_a[(a.size() == 1 ? 0 : i)]);\
00181
d.setValues(v_d);\
00182
delete [] v_a;\
00183
delete [] v_d;\
00184
} while (0)
00185
00186
namespace SH {
00187
00188
void shASN(ShVariable& dest,
const ShVariable& src)
00189 {
00190 sizes_match(dest, src);
00191
if (immediate()) {
00192 has_values(dest, src);
00193 T* vals =
new T[src.size()];
00194 src.getValues(vals);
00195 dest.setValues(vals);
00196
delete [] vals;
00197 }
else {
00198 ShStatement stmt(dest, SH_OP_ASN, src);
00199 addStatement(stmt);
00200 }
00201 }
00202
00203
void shADD(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00204 {
00205 sizes_match(dest, a, b,
true,
true);
00206
if (immediate()) {
00207 CWISE_BINARY_INLOP(dest, a, b, +);
00208 }
else {
00209 ShStatement stmt(dest, a, SH_OP_ADD, b);
00210 addStatement(stmt);
00211 }
00212 }
00213
00214
void shMUL(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00215 {
00216 sizes_match(dest, a, b,
true,
true);
00217
if (immediate()) {
00218 CWISE_BINARY_INLOP(dest, a, b, *);
00219 }
else {
00220 ShStatement stmt(dest, a, SH_OP_MUL, b);
00221 addStatement(stmt);
00222 }
00223 }
00224
00225
void shDIV(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00226 {
00227 sizes_match(dest, a, b,
true,
true);
00228
if (immediate()) {
00229 CWISE_BINARY_INLOP(dest, a, b, /);
00230 }
else {
00231 ShStatement stmt(dest, a, SH_OP_DIV, b);
00232 addStatement(stmt);
00233 }
00234 }
00235
00236
void shSLT(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00237 {
00238 sizes_match(dest, a, b,
true,
true);
00239
if (immediate()) {
00240 CWISE_BINARY_OP(dest, a, b, slt);
00241 }
else {
00242 ShStatement stmt(dest, a, SH_OP_SLT, b);
00243 addStatement(stmt);
00244 }
00245 }
00246
00247
void shSLE(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00248 {
00249 sizes_match(dest, a, b,
true,
true);
00250
if (immediate()) {
00251 CWISE_BINARY_OP(dest, a, b, sle);
00252 }
else {
00253 ShStatement stmt(dest, a, SH_OP_SLE, b);
00254 addStatement(stmt);
00255 }
00256 }
00257
00258
void shSGT(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00259 {
00260 sizes_match(dest, a, b,
true,
true);
00261
if (immediate()) {
00262 CWISE_BINARY_OP(dest, a, b, sgt);
00263 }
else {
00264 ShStatement stmt(dest, a, SH_OP_SGT, b);
00265 addStatement(stmt);
00266 }
00267 }
00268
00269
void shSGE(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00270 {
00271 sizes_match(dest, a, b,
true,
true);
00272
if (immediate()) {
00273 CWISE_BINARY_OP(dest, a, b, sge);
00274 }
else {
00275 ShStatement stmt(dest, a, SH_OP_SGE, b);
00276 addStatement(stmt);
00277 }
00278 }
00279
00280
void shSEQ(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00281 {
00282 sizes_match(dest, a, b,
true,
true);
00283
if (immediate()) {
00284 CWISE_BINARY_OP(dest, a, b, seq);
00285 }
else {
00286 ShStatement stmt(dest, a, SH_OP_SEQ, b);
00287 addStatement(stmt);
00288 }
00289 }
00290
00291
void shSNE(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00292 {
00293 sizes_match(dest, a, b,
true,
true);
00294
if (immediate()) {
00295 CWISE_BINARY_OP(dest, a, b, sne);
00296 }
else {
00297 ShStatement stmt(dest, a, SH_OP_SNE, b);
00298 addStatement(stmt);
00299 }
00300 }
00301
00302
void shABS(ShVariable& dest,
const ShVariable& a)
00303 {
00304 sizes_match(dest, a);
00305
if (immediate()) {
00306 CWISE_UNARY_OP(dest, a, std::fabs);
00307 }
else {
00308 ShStatement stmt(dest, SH_OP_ABS, a);
00309 addStatement(stmt);
00310 }
00311 }
00312
00313
void shACOS(ShVariable& dest,
const ShVariable& a)
00314 {
00315 sizes_match(dest, a);
00316
if (immediate()) {
00317 CWISE_UNARY_OP(dest, a, std::acos);
00318 }
else {
00319 ShStatement stmt(dest, SH_OP_ACOS, a);
00320 addStatement(stmt);
00321 }
00322 }
00323
00324
void shASIN(ShVariable& dest,
const ShVariable& a)
00325 {
00326 sizes_match(dest, a);
00327
if (immediate()) {
00328 CWISE_UNARY_OP(dest, a, std::asin);
00329 }
else {
00330 ShStatement stmt(dest, SH_OP_ASIN, a);
00331 addStatement(stmt);
00332 }
00333 }
00334
00335
void shATAN(ShVariable& dest,
const ShVariable& a)
00336 {
00337 sizes_match(dest, a);
00338
if (immediate()) {
00339 CWISE_UNARY_OP(dest, a, std::atan);
00340 }
else {
00341 ShStatement stmt(dest, SH_OP_ATAN, a);
00342 addStatement(stmt);
00343 }
00344 }
00345
00346
void shATAN2(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00347 {
00348 sizes_match(dest, a, b);
00349
if (immediate()) {
00350 CWISE_BINARY_OP(dest, a, b, atan2f);
00351 }
else {
00352 ShStatement stmt(dest, a, SH_OP_ATAN2, b);
00353 addStatement(stmt);
00354 }
00355 }
00356
00357
void shCBRT(ShVariable& dest,
const ShVariable& a)
00358 {
00359 sizes_match(dest, a);
00360
if (immediate()) {
00361 CWISE_UNARY_OP(dest, a, cbrtf);
00362 }
else {
00363 ShStatement stmt(dest, SH_OP_CBRT, a);
00364 addStatement(stmt);
00365 }
00366 }
00367
void shCEIL(ShVariable& dest,
const ShVariable& a)
00368 {
00369 sizes_match(dest, a);
00370
if (immediate()) {
00371 CWISE_UNARY_OP(dest, a, ceilf);
00372 }
else {
00373 ShStatement stmt(dest, SH_OP_CEIL, a);
00374 addStatement(stmt);
00375 }
00376 }
00377
00378
void shCOS(ShVariable& dest,
const ShVariable& a)
00379 {
00380 sizes_match(dest, a);
00381
if (immediate()) {
00382 CWISE_UNARY_OP(dest, a, std::cos);
00383 }
else {
00384 ShStatement stmt(dest, SH_OP_COS, a);
00385 addStatement(stmt);
00386 }
00387 }
00388
00389
void shCMUL(ShVariable& dest,
const ShVariable& a)
00390 {
00391 SH_DEBUG_ASSERT(dest.size() == 1);
00392
if (immediate()) {
00393 T* v_a =
new T[a.size()];
00394 a.getValues(v_a);
00395 T f = v_a[0];
00396
for (
int i = 1; i < a.size(); i++) f *= v_a[i];
00397 dest.setValues(&f);
00398
delete [] v_a;
00399 }
else {
00400 ShStatement stmt(dest, SH_OP_CMUL, a);
00401 addStatement(stmt);
00402 }
00403 }
00404
00405
void shCSUM(ShVariable& dest,
const ShVariable& a)
00406 {
00407 SH_DEBUG_ASSERT(dest.size() == 1);
00408
if (immediate()) {
00409 T* v_a =
new T[a.size()];
00410 a.getValues(v_a);
00411 T f = v_a[0];
00412
for (
int i = 1; i < a.size(); i++) f += v_a[i];
00413 dest.setValues(&f);
00414
delete [] v_a;
00415 }
else {
00416 ShStatement stmt(dest, SH_OP_CMUL, a);
00417 addStatement(stmt);
00418 }
00419 }
00420
00421
void shDOT(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00422 {
00423 SH_DEBUG_ASSERT(dest.size() == 1);
00424 sizes_match(a, b);
00425
if (immediate()) {
00426 T* v_a =
new T[a.size()];
00427 a.getValues(v_a);
00428 T* v_b =
new T[a.size()];
00429 b.getValues(v_b);
00430 T f = 0.0;
00431
for (
int i = 0; i < a.size(); i++) f += v_a[i] * v_b[i];
00432 dest.setValues(&f);
00433
delete [] v_a;
00434
delete [] v_b;
00435 }
else {
00436 ShStatement stmt(dest, a, SH_OP_DOT, b);
00437 addStatement(stmt);
00438 }
00439 }
00440
00441
void shDX(ShVariable& dest,
const ShVariable& a)
00442 {
00443 sizes_match(dest, a);
00444
if (immediate()) {
00445
shError(ShScopeException(
"Cannot take derivatives in immediate mode"));
00446 }
else {
00447 ShStatement stmt(dest, SH_OP_DX, a);
00448 addStatement(stmt);
00449 }
00450 }
00451
00452
void shDY(ShVariable& dest,
const ShVariable& a)
00453 {
00454 sizes_match(dest, a);
00455
if (immediate()) {
00456
shError(ShScopeException(
"Cannot take derivatives in immediate mode"));
00457 }
else {
00458 ShStatement stmt(dest, SH_OP_DY, a);
00459 addStatement(stmt);
00460 }
00461 }
00462
00463
void shEXP(ShVariable& dest,
const ShVariable& a)
00464 {
00465 sizes_match(dest, a);
00466
if (immediate()) {
00467 CWISE_UNARY_OP(dest, a, expf);
00468 }
else {
00469 ShStatement stmt(dest, SH_OP_EXP, a);
00470 addStatement(stmt);
00471 }
00472 }
00473
00474
void shEXP2(ShVariable& dest,
const ShVariable& a)
00475 {
00476 sizes_match(dest, a);
00477
if (immediate()) {
00478 CWISE_UNARY_OP(dest, a, exp2f);
00479 }
else {
00480 ShStatement stmt(dest, SH_OP_EXP2, a);
00481 addStatement(stmt);
00482 }
00483 }
00484
00485
void shEXP10(ShVariable& dest,
const ShVariable& a)
00486 {
00487 sizes_match(dest, a);
00488
if (immediate()) {
00489 CWISE_UNARY_OP(dest, a, exp10f);
00490 }
else {
00491 ShStatement stmt(dest, SH_OP_EXP10, a);
00492 addStatement(stmt);
00493 }
00494 }
00495
00496
void shFLR(ShVariable& dest,
const ShVariable& a)
00497 {
00498 sizes_match(dest, a);
00499
if (immediate()) {
00500 CWISE_UNARY_OP(dest, a, floorf);
00501 }
else {
00502 ShStatement stmt(dest, SH_OP_FLR, a);
00503 addStatement(stmt);
00504 }
00505 }
00506
00507
void shMOD(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00508 {
00509 sizes_match(dest, a, b);
00510
if (immediate()) {
00511 CWISE_BINARY_OP(dest, a, b, fmodf);
00512 }
else {
00513 ShStatement stmt(dest, a, SH_OP_MOD, b);
00514 addStatement(stmt);
00515 }
00516 }
00517
00518
void shFRAC(ShVariable& dest,
const ShVariable& a)
00519 {
00520 sizes_match(dest, a);
00521
if (immediate()) {
00522 CWISE_UNARY_OP(dest, a, frac);
00523 }
else {
00524 ShStatement stmt(dest, SH_OP_FRAC, a);
00525 addStatement(stmt);
00526 }
00527 }
00528
00529
void shLRP(ShVariable& dest,
const ShVariable& alpha,
00530
const ShVariable& a,
const ShVariable& b)
00531 {
00532 SH_DEBUG_ASSERT(dest.size() == a.size() &&
00533 dest.size() == b.size() &&
00534 (dest.size() == alpha.size() || alpha.size() == 1));
00535
if (immediate()) {
00536 CWISE_TRINARY_OP(dest, alpha, a, b, lrp);
00537 }
else {
00538 ShStatement stmt(dest, SH_OP_LRP, alpha, a, b);
00539 addStatement(stmt);
00540 }
00541 }
00542
00543
void shLOG(ShVariable& dest,
const ShVariable& a)
00544 {
00545 sizes_match(dest, a);
00546
if (immediate()) {
00547 CWISE_UNARY_OP(dest, a, logf);
00548 }
else {
00549 ShStatement stmt(dest, SH_OP_LOG, a);
00550 addStatement(stmt);
00551 }
00552 }
00553
00554
void shLOG2(ShVariable& dest,
const ShVariable& a)
00555 {
00556 sizes_match(dest, a);
00557
if (immediate()) {
00558 CWISE_UNARY_OP(dest, a, log2f);
00559 }
else {
00560 ShStatement stmt(dest, SH_OP_LOG2, a);
00561 addStatement(stmt);
00562 }
00563 }
00564
00565
void shLOG10(ShVariable& dest,
const ShVariable& a)
00566 {
00567 sizes_match(dest, a);
00568
if (immediate()) {
00569 CWISE_UNARY_OP(dest, a, log10f);
00570 }
else {
00571 ShStatement stmt(dest, SH_OP_LOG10, a);
00572 addStatement(stmt);
00573 }
00574 }
00575
00576
void shMAD(ShVariable& dest,
const ShVariable& a,
00577
const ShVariable& b,
const ShVariable& c)
00578 {
00579 SH_DEBUG_ASSERT(dest.size() == c.size() &&
00580 (dest.size() == a.size() || (dest.size() == b.size() && a.size() == 1)) &&
00581 (dest.size() == b.size() || (dest.size() == a.size() && b.size() == 1)));
00582
if (immediate()) {
00583 CWISE_TRINARY_OP(dest, a, b, c, mad);
00584 }
else {
00585 ShStatement stmt(dest, SH_OP_MAD, a, b, c);
00586 addStatement(stmt);
00587 }
00588 }
00589
00590
void shMAX(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00591 {
00592 sizes_match(dest, a, b);
00593
if (immediate()) {
00594 CWISE_BINARY_OP(dest, a, b, max);
00595 }
else {
00596 ShStatement stmt(dest, a, SH_OP_MAX, b);
00597 addStatement(stmt);
00598 }
00599 }
00600
00601
void shMIN(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00602 {
00603 sizes_match(dest, a, b);
00604
if (immediate()) {
00605 CWISE_BINARY_OP(dest, a, b, min);
00606 }
else {
00607 ShStatement stmt(dest, a, SH_OP_MIN, b);
00608 addStatement(stmt);
00609 }
00610 }
00611
00612
void shPOW(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00613 {
00614 sizes_match(dest, a, b,
false,
true);
00615
if (immediate()) {
00616 CWISE_BINARY_OP(dest, a, b, powf);
00617 }
else {
00618 ShStatement stmt(dest, a, SH_OP_POW, b);
00619 addStatement(stmt);
00620 }
00621 }
00622
00623
void shRCP(ShVariable& dest,
const ShVariable& a)
00624 {
00625 sizes_match(dest, a);
00626
if (immediate()) {
00627 CWISE_UNARY_OP(dest, a, 1.0f / );
00628 }
else {
00629 ShStatement stmt(dest, SH_OP_RCP, a);
00630 addStatement(stmt);
00631 }
00632 }
00633
00634
void shRND(ShVariable& dest,
const ShVariable& a)
00635 {
00636 sizes_match(dest, a);
00637
if (immediate()) {
00638 CWISE_UNARY_OP(dest, a, roundf);
00639 }
else {
00640 ShStatement stmt(dest, SH_OP_RND, a);
00641 addStatement(stmt);
00642 }
00643 }
00644
00645
void shRSQ(ShVariable& dest,
const ShVariable& a)
00646 {
00647 sizes_match(dest, a);
00648
if (immediate()) {
00649 CWISE_UNARY_OP(dest, a, 1.0f / sqrt);
00650 }
else {
00651 ShStatement stmt(dest, SH_OP_RSQ, a);
00652 addStatement(stmt);
00653 }
00654 }
00655
00656
void shSGN(ShVariable& dest,
const ShVariable& a)
00657 {
00658 sizes_match(dest, a);
00659
if (immediate()) {
00660 CWISE_UNARY_OP(dest, a, sgn);
00661 }
else {
00662 ShStatement stmt(dest, SH_OP_SGN, a);
00663 addStatement(stmt);
00664 }
00665 }
00666
00667
void shSIN(ShVariable& dest,
const ShVariable& a)
00668 {
00669 sizes_match(dest, a);
00670
if (immediate()) {
00671 CWISE_UNARY_OP(dest, a, std::sin);
00672 }
else {
00673 ShStatement stmt(dest, SH_OP_SIN, a);
00674 addStatement(stmt);
00675 }
00676 }
00677
00678
void shSQRT(ShVariable& dest,
const ShVariable& a)
00679 {
00680 sizes_match(dest, a);
00681
if (immediate()) {
00682 CWISE_UNARY_OP(dest, a, std::sqrt);
00683 }
else {
00684 ShStatement stmt(dest, SH_OP_SQRT, a);
00685 addStatement(stmt);
00686 }
00687 }
00688
00689
void shTAN(ShVariable& dest,
const ShVariable& a)
00690 {
00691 sizes_match(dest, a);
00692
if (immediate()) {
00693 CWISE_UNARY_OP(dest, a, std::tan);
00694 }
else {
00695 ShStatement stmt(dest, SH_OP_TAN, a);
00696 addStatement(stmt);
00697 }
00698 }
00699
00700
void shNORM(ShVariable& dest,
const ShVariable& a)
00701 {
00702 sizes_match(dest, a);
00703
if (immediate()) {
00704 T* v_a =
new T[a.size()];
00705 a.getValues(v_a);
00706 T s = 0.0;
00707
for (
int i = 0; i < a.size(); i++) s += v_a[i] * v_a[i];
00708 s = std::sqrt(s);
00709
for (
int i = 0; i < a.size(); i++) v_a[i] /= s;
00710 dest.setValues(v_a);
00711
delete [] v_a;
00712 }
else {
00713 ShStatement stmt(dest, SH_OP_NORM, a);
00714 addStatement(stmt);
00715 }
00716 }
00717
00718
void shXPD(ShVariable& dest,
const ShVariable& a,
const ShVariable& b)
00719 {
00720 SH_DEBUG_ASSERT(dest.size() == 3 && a.size() == 3 && b.size() == 3);
00721
if (immediate()) {
00722 T v_a[3];
00723 a.getValues(v_a);
00724 T v_b[3];
00725 b.getValues(v_b);
00726 T result[3];
00727 result[0] = v_a[1] * v_b[2] - v_a[2] * v_b[1];
00728 result[1] = -(v_a[0] * v_b[2] - v_a[2] * v_b[0]);
00729 result[2] = v_a[0] * v_b[1] - v_a[1] * v_b[0];
00730 dest.setValues(result);
00731 }
else {
00732 ShStatement stmt(dest, a, SH_OP_XPD, b);
00733 addStatement(stmt);
00734 }
00735 }
00736
00737
void shCOND(ShVariable& dest,
const ShVariable& alpha,
00738
const ShVariable& a,
const ShVariable& b)
00739 {
00740 SH_DEBUG_ASSERT(dest.size() == a.size() &&
00741 dest.size() == b.size() &&
00742 (dest.size() == alpha.size() || alpha.size() == 1));
00743
if (immediate()) {
00744 CWISE_TRINARY_OP(dest, alpha, a, b, cond);
00745 }
else {
00746 ShStatement stmt(dest, SH_OP_COND, alpha, a, b);
00747 addStatement(stmt);
00748 }
00749 }
00750
00751
void shKIL(
const ShVariable& a)
00752 {
00753 SH_DEBUG_ASSERT(!immediate());
00754 ShStatement stmt(a, SH_OP_KIL, a);
00755 addStatement(stmt);
00756 }
00757
00758 }