39 #include "classdesc.h" 80 template <
class E,
class Op>
class unop;
81 template <
class E1,
class E2,
class Op>
class binop;
82 template <
class E,
class I>
class RVindex;
83 template <
class E,
class I>
class LVindex;
92 {
static const bool value=
false;};
95 {
static const bool value=
true;};
98 {
static const bool value=
true;};
101 {
static const bool value=
true;};
112 template <
class T>
struct is_scalar {
static const bool value=
false;};
114 template <>
struct is_scalar<bool> {
static const bool value=
true;};
115 template <>
struct is_scalar<char> {
static const bool value=
true;};
116 template <>
struct is_scalar<short> {
static const bool value=
true;};
117 template <>
struct is_scalar<int> {
static const bool value=
true;};
118 template <>
struct is_scalar<long> {
static const bool value=
true;};
119 template <>
struct is_scalar<unsigned char> {
static const bool value=
true;};
120 template <>
struct is_scalar<unsigned short> {
static const bool value=
true;};
121 template <>
struct is_scalar<unsigned int> {
static const bool value=
true;};
122 template <>
struct is_scalar<unsigned long> {
static const bool value=
true;};
123 template <>
struct is_scalar<float> {
static const bool value=
true;};
124 template <>
struct is_scalar<double> {
static const bool value=
true;};
127 template <
class T>
struct is_integer {
static const bool value=
false;};
128 template <>
struct is_integer<bool> {
static const bool value=
true;};
129 template <>
struct is_integer<char> {
static const bool value=
true;};
130 template <>
struct is_integer<short> {
static const bool value=
true;};
131 template <>
struct is_integer<int> {
static const bool value=
true;};
132 template <>
struct is_integer<long> {
static const bool value=
true;};
133 template <>
struct is_integer<unsigned char> {
static const bool value=
true;};
134 template <>
struct is_integer<unsigned short> {
static const bool value=
true;};
135 template <>
struct is_integer<unsigned int> {
static const bool value=
true;};
136 template <>
struct is_integer<unsigned long> {
static const bool value=
true;};
139 template <>
struct is_scalar<long long> {
static const bool value=
true;};
140 template <>
struct is_scalar<unsigned long long> {
static const bool value=
true;};
141 template <>
struct is_integer<long long> {
static const bool value=
true;};
142 template <>
struct is_integer<unsigned long long> {
static const bool value=
true;};
146 template <
class T>
struct is_float {
static const bool value=
false;};
147 template <>
struct is_float<float> {
static const bool value=
true;};
148 template <>
struct is_float<double> {
static const bool value=
true;};
154 template <
bool,
class type=
void>
struct enable_if_c {
typedef type T;};
170 template <
class T,
bool=false,
bool=false>
173 typedef void value_type;
178 struct tt<E,true,false>
180 typedef typename E::value_type value_type;
185 struct tt<S,false,true>
187 typedef S value_type;
192 struct traits:
public tt<T,is_expression<T>::value,is_scalar<T>::value> {};
197 template <
class E1,
class E2>
201 typename traits<E1>::value_type,
202 typename traits<E2>::value_type
207 template <
class T>
struct result<void,T> {
typedef void value_type;};
208 template <
class T>
struct result<T,void> {
typedef void value_type;};
209 template <>
struct result<void,void> {
typedef void value_type;};
214 #define RESULTIII(T1,T2,R) \ 215 template <> struct result<T1,T2> {typedef R value_type;}; \ 216 template <> struct result<T1,unsigned T2> {typedef R value_type;}; \ 217 template <> struct result<unsigned T1, T2> {typedef R value_type;}; \ 218 template <> struct result<unsigned T1,unsigned T2>{typedef unsigned R value_type;}; 223 #define RESULTBI(T1) \ 224 template <> struct result<T1,bool> {typedef T1 value_type;}; \ 225 template <> struct result<bool,T1> {typedef T1 value_type;}; \ 226 template <> struct result<bool,unsigned T1> {typedef unsigned T1 value_type;}; \ 227 template <> struct result<unsigned T1, bool> {typedef unsigned T1 value_type;}; \ 232 #define RESULTBF(T1) \ 233 template <> struct result<T1,bool> {typedef T1 value_type;}; \ 234 template <> struct result<bool,T1> {typedef T1 value_type;}; \ 239 #define RESULTIFF(T1,T2,R) \ 240 template <> struct result<T1,T2> {typedef R value_type;}; \ 241 template <> struct result<unsigned T1, T2> {typedef R value_type;}; \ 246 #define RESULTFIF(T1,T2,R) \ 247 template <> struct result<T1,T2> {typedef R value_type;}; \ 248 template <> struct result<T1,unsigned T2> {typedef R value_type;}; \ 253 #define RESULTFFF(T1,T2,R) \ 254 template <> struct result<T1,T2> {typedef R value_type;}; 256 template <>
struct result<bool,bool> {
typedef int value_type;};
266 RESULTIII(
char,
char,
char);
268 RESULTIII(
short,
short,
short);
269 RESULTIII(
char,
short,
short);
270 RESULTIII(
short,
char,
short);
272 RESULTIII(
int,
int,
int);
273 RESULTIII(
short,
int,
int);
274 RESULTIII(
int,
short,
int);
275 RESULTIII(
char,
int,
int);
276 RESULTIII(
int,
char,
int);
278 RESULTIII(
long,
long,
long);
279 RESULTIII(
int,
long,
long);
280 RESULTIII(
long,
int,
long);
281 RESULTIII(
short,
long,
long);
282 RESULTIII(
long,
short,
long);
283 RESULTIII(
char,
long,
long);
284 RESULTIII(
long,
char,
long);
287 RESULTIII(
long long,
long long,
long long);
288 RESULTIII(
long,
long long,
long long);
289 RESULTIII(
long long,
long,
long long);
290 RESULTIII(
int,
long long,
long long);
291 RESULTIII(
long long,
int,
long long);
292 RESULTIII(
short,
long long,
long long);
293 RESULTIII(
long long,
short,
long long);
294 RESULTIII(
char,
long long,
long long);
295 RESULTIII(
long long,
char,
long long);
298 RESULTFFF(
float,
float,
float);
299 RESULTIFF(
long,
float,
float);
300 RESULTFIF(
float,
long,
float);
301 RESULTIFF(
int,
float,
float);
302 RESULTFIF(
float,
int,
float);
303 RESULTIFF(
short,
float,
float);
304 RESULTFIF(
float,
short,
float);
305 RESULTIFF(
char,
float,
float);
306 RESULTFIF(
float,
char,
float);
309 RESULTFIF(
float,__int64,
float);
310 RESULTFIF(
double,__int64,
double);
313 RESULTFFF(
double,
double,
double);
314 RESULTFFF(
float,
double,
double);
315 RESULTFFF(
double,
float,
double);
316 RESULTIFF(
long,
double,
double);
317 RESULTFIF(
double,
long,
double);
318 RESULTIFF(
int,
double,
double);
319 RESULTFIF(
double,
int,
double);
320 RESULTIFF(
short,
double,
double);
321 RESULTFIF(
double,
short,
double);
322 RESULTIFF(
char,
double,
double);
323 RESULTFIF(
double,
char,
double);
326 RESULTIFF(
long long,
float,
float);
327 RESULTFIF(
float,
long long,
float);
328 RESULTIFF(
long long,
double,
double);
329 RESULTFIF(
double,
long long,
double);
334 template <
class E>
typename 335 E::value_type&
at(E& x,
size_t i,
339 template <
class E>
typename 340 E::value_type
at(
const E& x,
size_t i,
345 S&
at(S& x,
size_t i,
357 template <
class E>
typename 361 template <
class S>
typename 369 template <
class E1,
class E2>
370 void conformance_check(
const E1& e1,
const E2& e2)
382 typedef T value_type;
383 T operator()(T x)
const {
return -x;}
391 typedef bool value_type;
392 bool operator()(T x)
const {
return !x;}
397 template <
class E1,
class E2>
400 typedef typename traits<E1>::value_type E1v;
401 typedef typename traits<E2>::value_type E2v;
402 typedef typename result<E1v,E2v>::value_type value_type;
403 value_type operator()(E1v x, E2v y)
const {
return x+y;}
408 template <
class E1,
class E2>
411 typedef typename traits<E1>::value_type E1v;
412 typedef typename traits<E2>::value_type E2v;
413 typedef typename result<E1v,E2v>::value_type value_type;
414 value_type operator()(E1v x, E2v y)
const {
return x-y;}
419 template <
class E1,
class E2>
422 typedef typename traits<E1>::value_type E1v;
423 typedef typename traits<E2>::value_type E2v;
424 typedef typename result<E1v,E2v>::value_type value_type;
425 value_type operator()(E1v x, E2v y)
const {
return x*y;}
430 template <
class E1,
class E2>
433 typedef typename traits<E1>::value_type E1v;
434 typedef typename traits<E2>::value_type E2v;
435 typedef typename result<E1v,E2v>::value_type value_type;
436 value_type operator()(E1v x, E2v y)
const {
return x/y;}
440 template <
class E1,
class E2>
443 typedef typename traits<E1>::value_type E1v;
444 typedef typename traits<E2>::value_type E2v;
445 typedef typename result<E1v,E2v>::value_type value_type;
446 value_type operator()(E1v x, E2v y)
const {
return x%y;}
450 template <
class E1,
class E2>
453 typedef typename traits<E1>::value_type E1v;
454 typedef typename traits<E2>::value_type E2v;
455 typedef bool value_type;
456 bool operator()(E1v x, E2v y)
const {
return x==y;}
460 template <
class E1,
class E2>
463 typedef typename traits<E1>::value_type E1v;
464 typedef typename traits<E2>::value_type E2v;
465 typedef bool value_type;
466 bool operator()(E1v x, E2v y)
const {
return x!=y;}
470 template <
class E1,
class E2>
473 typedef typename traits<E1>::value_type E1v;
474 typedef typename traits<E2>::value_type E2v;
475 typedef bool value_type;
476 bool operator()(E1v x, E2v y)
const {
return x>y;}
480 template <
class E1,
class E2>
483 typedef typename traits<E1>::value_type E1v;
484 typedef typename traits<E2>::value_type E2v;
485 typedef bool value_type;
486 bool operator()(E1v x, E2v y)
const {
return x>=y;}
490 template <
class E1,
class E2>
493 typedef typename traits<E1>::value_type E1v;
494 typedef typename traits<E2>::value_type E2v;
495 typedef bool value_type;
496 bool operator()(E1v x, E2v y)
const {
return x<y;}
500 template <
class E1,
class E2>
503 typedef typename traits<E1>::value_type E1v;
504 typedef typename traits<E2>::value_type E2v;
505 typedef bool value_type;
506 bool operator()(E1v x, E2v y)
const {
return x<=y;}
510 template <
class E1,
class E2>
513 typedef typename traits<E1>::value_type E1v;
514 typedef typename traits<E2>::value_type E2v;
515 typedef bool value_type;
516 bool operator()(E1v x, E2v y)
const {
return x&&y;}
520 template <
class E1,
class E2>
523 typedef typename traits<E1>::value_type E1v;
524 typedef typename traits<E2>::value_type E2v;
525 typedef bool value_type;
526 bool operator()(E1v x, E2v y)
const {
return x||y;}
537 template <
class E1,
class E2>
539 operator+(
const E1& e1,
const E2& e2)
544 template <
class E1,
class E2>
546 operator-(
const E1& e1,
const E2& e2)
551 template <
class E1,
class E2>
553 operator*(
const E1& e1,
const E2& e2)
567 operator/(
typename E::value_type x,
const E& y)
570 return operator/(x,Y);
573 template <
class E1,
class E2>
576 operator/(
const E1& x,
const E2& y)
580 return operator/(X,Y);
583 template <
class E1,
class E2>
585 operator/(
const E1& e1,
const E2& e2)
592 template <
class E1,
class E2>
594 operator/(
const E1& e1,
const E2& e2)
601 template <
class E1,
class E2>
603 operator%(
const E1& e1,
const E2& e2)
608 namespace both_are_expressions_ns
611 template <
class E1,
class E2>
616 typename E1::value_type,
617 typename E2::value_type
621 operator<<(
const E1& e1,
const E2& e2)
625 typename E1::value_type,
626 typename E2::value_type
628 > ret(e1.size()+e2.size());
629 for (
size_t i=0; i<e1.size(); i++)
631 for (
size_t i=0; i<e2.size(); i++)
632 ret[i+e1.size()]=e2[i];
637 namespace expression_scalar_ns
640 template <
class E1,
class E2>
645 typename result<typename E1::value_type,E2>::value_type
649 operator<<(
const E1& e1,
const E2& e2)
652 typename result<typename E1::value_type,E2>::value_type
654 for (
size_t i=0; i<e1.size(); i++)
661 namespace scalar_expression_ns
664 template <
class E1,
class E2>
671 operator<<(
const E1& e1,
const E2& e2)
676 for (
size_t i=0; i<e2.size(); i++)
682 using both_are_expressions_ns::operator<<;
683 using expression_scalar_ns::operator<<;
684 using scalar_expression_ns::operator<<;
686 template <
class E1,
class E2>
688 operator==(
const E1& e1,
const E2& e2)
693 template <
class E1,
class E2>
695 operator!=(
const E1& e1,
const E2& e2)
700 template <
class E1,
class E2>
702 operator>(
const E1& e1,
const E2& e2)
707 template <
class E1,
class E2>
709 operator>=(
const E1& e1,
const E2& e2)
714 template <
class E1,
class E2>
716 operator<(
const E1& e1,
const E2& e2)
721 template <
class E1,
class E2>
723 operator<=(
const E1& e1,
const E2& e2)
728 template <
class E1,
class E2>
730 operator&&(
const E1& e1,
const E2& e2)
735 template <
class E1,
class E2>
737 operator||(
const E1& e1,
const E2& e2)
746 template <
class E1,
class E2>
747 bool eq(
const E1& e1,
const E2& e2)
750 array_ns::len(e1)!=1 && array_ns::len(e2)!=1 &&
751 array_ns::len(e1)!=array_ns::len(e2)
754 for (
size_t i=0; i<std::max(array_ns::len(e1), array_ns::len(e2)); i++)
755 if(array_ns::at(e1,i)!=array_ns::at(e2,i))
764 template <
class E1,
class E2>
767 typedef typename traits<E1>::value_type E1v;
768 typedef typename traits<E2>::value_type E2v;
769 typedef typename result<E1v,E2v>::value_type value_type;
770 value_type operator()(E1v x, E2v y)
const {
771 return std::pow(static_cast<value_type>(x),static_cast<value_type>(y));
776 template <
class E1,
class E2>
786 typedef T value_type;
787 T operator()(T x)
const {
return std::exp(x);}
799 typedef T value_type;
800 T operator()(T x)
const {
return std::log(x);}
812 typedef T value_type;
813 T operator()(T x)
const {
return std::log10(x);}
825 typedef T value_type;
826 T operator()(T x)
const {
return std::sin(x);}
838 typedef T value_type;
839 T operator()(T x)
const {
return std::cos(x);}
851 typedef T value_type;
852 T operator()(T x)
const {
return std::tan(x);}
864 typedef T value_type;
865 T operator()(T x)
const {
return std::asin(x);}
877 typedef T value_type;
878 T operator()(T x)
const {
return std::acos(x);}
890 typedef T value_type;
891 T operator()(T x)
const {
return std::atan(x);}
900 template <
class E1,
class E2>
903 typedef typename traits<E1>::value_type E1v;
904 typedef typename traits<E2>::value_type E2v;
905 typedef typename result<E1v,E2v>::value_type value_type;
906 value_type operator()(E1v x, E2v y)
const {
return std::atan2(x,y);}
910 template <
class E1,
class E2>
920 typedef T value_type;
921 T operator()(T x)
const {
return std::sinh(x);}
933 typedef T value_type;
934 T operator()(T x)
const {
return std::cosh(x);}
946 typedef T value_type;
947 T operator()(T x)
const {
return std::tanh(x);}
959 typedef T value_type;
960 T operator()(T x)
const {
return std::sqrt(x);}
973 typedef T value_type;
974 T operator()(T x)
const {
return std::abs(x);}
981 typedef T value_type;
982 T operator()(T x)
const {
return x>=0? 1: -1;}
1008 typedef T value_type;
1009 T operator()(T x)
const {
return std::ceil(x);}
1021 typedef T value_type;
1022 T operator()(T x)
const {
return std::floor(x);}
1031 template <
class E1,
class E2>
1034 typedef typename traits<E1>::value_type E1v;
1035 typedef typename traits<E2>::value_type E2v;
1036 typedef typename result<E1v,E2v>::value_type value_type;
1037 value_type operator()(E1v x, E2v y)
const {
return std::ldexp(x,y);}
1041 template <
class E1,
class E2>
1048 template <
class E1,
class E2>
1051 typedef typename traits<E1>::value_type E1v;
1052 typedef typename traits<E2>::value_type E2v;
1053 typedef typename result<E1v,E2v>::value_type value_type;
1054 value_type operator()(E1v x, E2v y)
const {
return std::fmod(x,y);}
1058 template <
class E1,
class E2>
1065 template <
class E1,
class E2>
1068 typedef typename traits<E1>::value_type E1v;
1069 typedef typename traits<E2>::value_type E2v;
1070 typedef typename result<E1v,E2v>::value_type value_type;
1071 value_type operator()(E1v x, E2v y)
const {
1072 return std::max(static_cast<value_type>(x),static_cast<value_type>(y));
1077 template <
class E1,
class E2>
1079 max(
const E1& e1,
const E2& e2)
1085 template <
class E1,
class E2>
1088 typedef typename traits<E1>::value_type E1v;
1089 typedef typename traits<E2>::value_type E2v;
1090 typedef typename result<E1v,E2v>::value_type value_type;
1091 value_type operator()(E1v x, E2v y)
const {
1092 return std::min(static_cast<value_type>(x),static_cast<value_type>(y));
1097 template <
class E1,
class E2>
1099 min(
const E1& e1,
const E2& e2)
1107 template <
class E,
class I>
1112 void operator=(
const RVindex&);
1114 typedef typename E::value_type value_type;
1115 size_t size()
const {
return idx.size();}
1116 value_type operator[](
size_t i)
const {
return expr[idx[i]];}
1117 RVindex(
const E& e,
const I& i): expr(e), idx(i) {}
1121 template <
class E,
class I>
1127 typedef typename E::value_type value_type;
1128 size_t size()
const {
return idx.size();}
1129 value_type& operator[](
size_t i) {
return expr[idx[i]];}
1130 value_type operator[](
size_t i)
const {
return expr[idx[i]];}
1131 LVindex(E& e,
const I& i): expr(e), idx(i) {}
1132 template <
class E1>
typename 1134 operator=(
const E1& x) {
1135 conformance_check(idx,x);
1136 for (
size_t i=0; i<size(); i++) expr[idx[i]]=x[i];
1139 template <
class E1>
typename 1141 operator+=(
const E1& x) {
1142 conformance_check(idx,x);
1143 for (
size_t i=0; i<size(); i++)
1148 template <
class E1>
typename 1150 operator*=(
const E1& x) {
1151 conformance_check(idx,x);
1152 for (
size_t i=0; i<size(); i++) expr[idx[i]]*=x[i];
1155 template <
class E1>
typename 1157 operator&=(
const E1& x) {
1158 conformance_check(idx,x);
1159 for (
size_t i=0; i<size(); i++) expr[idx[i]]&=x[i];
1162 template <
class E1>
typename 1164 operator|=(
const E1& x) {
1165 conformance_check(idx,x);
1166 for (
size_t i=0; i<size(); i++) expr[idx[i]]|=x[i];
1169 value_type operator=(value_type x) {
1170 for (
size_t i=0; i<size(); i++) expr[idx[i]]=x;
1173 value_type operator+=(value_type x) {
1174 for (
size_t i=0; i<size(); i++) expr[idx[i]]+=x;
1177 value_type operator-=(value_type x) {
1178 for (
size_t i=0; i<size(); i++) expr[idx[i]]-=x;
1181 value_type operator*=(value_type x) {
1182 for (
size_t i=0; i<size(); i++) expr[idx[i]]*=x;
1185 value_type operator/=(value_type x) {
1186 for (
size_t i=0; i<size(); i++) expr[idx[i]]/=x;
1189 value_type operator%=(value_type x) {
1190 for (
size_t i=0; i<size(); i++) expr[idx[i]]%=x;
1193 value_type operator&=(value_type x) {
1194 for (
size_t i=0; i<size(); i++) expr[idx[i]]&=x;
1197 value_type operator|=(value_type x) {
1198 for (
size_t i=0; i<size(); i++) expr[idx[i]]|=x;
1205 {
static const bool value=
true;};
1208 {
static const bool value=
true;};
1211 template <
class E,
class Op>
1218 unop(
const E& expr): e(expr) {}
1221 size_t size()
const {
return e.size();}
1223 value_type operator[](
size_t i)
const {
return op(e[i]);}
1226 template <
class I>
typename 1233 template <
class E1,
class E2,
class Op>
1241 binop(
const E1& ex1,
const E2& ex2): e1(ex1), e2(ex2) {conformance_check(e1,e2);}
1245 {
return (array_ns::len(e1)==1)? array_ns::len(e2): array_ns::len(e1);}
1246 typename Op::value_type operator[](
size_t i)
const {
1248 return op(array_ns::at(e1,i),array_ns::at(e2,i));
1252 template <
class I>
typename 1268 binop(
const E1& ex1,
double ex2): e1(ex1), e2(1/ex2) {conformance_check(e1,e2);}
1269 typedef typename result<typename E1::value_type,double>::value_type value_type;
1271 {
return (array_ns::len(e1)==1)? array_ns::len(e2): array_ns::len(e1);}
1273 value_type operator[](
size_t i)
const {
return array_ns::at(e1,i)*e2;}
1276 template <
class I>
typename 1291 binop(
const E1& ex1,
float ex2): e1(ex1), e2(1/ex2) {conformance_check(e1,e2);}
1292 typedef typename result<typename E1::value_type,float>::value_type value_type;
1294 {
return (array_ns::len(e1)==1)? array_ns::len(e2): array_ns::len(e1);}
1296 value_type operator[](
size_t i)
const {
return array_ns::at(e1,i)*e2;}
1299 template <
class I>
typename 1306 void asg(T* dt,
size_t sz, T x) {
1308 #pragma loop count(1000) 1310 #pragma vector aligned 1312 for (
size_t i=0; i<sz; i++) dt[i]=x;
1316 void asg_plus(T* dt,
size_t sz, T x) {
1318 #pragma loop count(1000) 1320 #pragma vector aligned 1322 for (
size_t i=0; i<sz; i++) dt[i]+=x;
1327 void asg_minus(T* dt,
size_t sz, T x) {
1329 #pragma loop count(1000) 1331 #pragma vector aligned 1333 for (
size_t i=0; i<sz; i++) dt[i]-=x;
1337 void asg_mul(T* dt,
size_t sz, T x) {
1339 #pragma loop count(1000) 1341 #pragma vector aligned 1343 for (
size_t i=0; i<sz; i++) dt[i]*=x;
1348 void asg_div(T* dt,
size_t sz, T x) {
1350 #pragma loop count(1000) 1352 #pragma vector aligned 1354 for (
size_t i=0; i<sz; i++) dt[i]/=x;
1359 template <
class T>
typename 1361 asg_mod(T* dt,
size_t sz, T x) {
1363 #pragma loop count(1000) 1365 #pragma vector aligned 1367 for (
size_t i=0; i<sz; i++) dt[i]%=x;
1372 template <
class T>
typename 1374 asg_and(T* dt,
size_t sz, T x) {
1376 #pragma loop count(1000) 1378 #pragma vector aligned 1380 for (
size_t i=0; i<sz; i++) dt[i]&=x;
1385 template <
class T>
typename 1387 asg_or(T* dt,
size_t sz, T x) {
1389 #pragma loop count(1000) 1391 #pragma vector aligned 1393 for (
size_t i=0; i<sz; i++) dt[i]|=x;
1398 template <
class T,
class U>
1399 void asg_v(T * dt,
size_t sz,
const U& x) {
1401 #pragma loop count(1000) 1403 #pragma vector aligned 1405 for (
size_t i=0; i<sz; i++) dt[i]=x[i];
1409 template <
class T,
class U>
1410 void asg_plus_v(T * dt,
size_t sz,
const U& x) {
1412 #pragma loop count(1000) 1414 #pragma vector aligned 1416 for (
size_t i=0; i<sz; i++) dt[i]+=x[i];
1420 template <
class T,
class U>
1421 void asg_minus_v(T * dt,
size_t sz,
const U& x) {
1423 #pragma loop count(1000) 1425 #pragma vector aligned 1427 for (
size_t i=0; i<sz; i++) dt[i]-=x[i];
1431 template <
class T,
class U>
1432 void asg_mul_v(T * dt,
size_t sz,
const U& x) {
1434 #pragma loop count(1000) 1436 #pragma vector aligned 1438 for (
size_t i=0; i<sz; i++) dt[i]*=x[i];
1442 template <
class T,
class U>
1443 void asg_div_v(T * dt,
size_t sz,
const U& x) {
1445 #pragma loop count(1000) 1447 #pragma vector aligned 1449 for (
size_t i=0; i<sz; i++) dt[i]/=x[i];
1453 template <
class T,
class U>
1454 void asg_mod_v(T * dt,
size_t sz,
const U& x) {
1456 #pragma loop count(1000) 1458 #pragma vector aligned 1460 for (
size_t i=0; i<sz; i++) dt[i]%=x[i];
1464 template <
class T,
class U>
1465 void asg_and_v(T * dt,
size_t sz,
const U& x) {
1467 #pragma loop count(1000) 1469 #pragma vector aligned 1471 for (
size_t i=0; i<sz; i++) dt[i]&=x[i];
1475 template <
class T,
class U>
1476 void asg_or_v(T * dt,
size_t sz,
const U& x) {
1478 #pragma loop count(1000) 1480 #pragma vector aligned 1482 for (
size_t i=0; i<sz; i++) dt[i]|=x[i];
1489 void *allocated_pointer;
1492 static const unsigned debug_display=10;
1493 T dt[debug_display];
1494 friend class array<T>;
1506 friend class WhereContext;
1516 size_t d = (size_t)(
reinterpret_cast<array_data<T>*
>(p)->dt);
1517 size_t offs = (16 - (d&15)) & 15;
1522 r->allocated_pointer=p;
1532 std::free(p->allocated_pointer);
1535 void set_size(
size_t s) {dt = alloc(s);}
1561 bool freeMem =
ref()-- == 0;
1563 memcpy(data(),oldData->dt,size()*
sizeof(T));
1564 if (freeMem) free(oldData);
1569 typedef T value_type;
1571 explicit array(
size_t s=0)
1576 array(
size_t s, T val)
1579 array_ns::asg(data(),size(),val);
1588 template <
class expr>
1589 array(
const expr& e,
1596 ~
array() {release();}
1600 if (!dt || s>dt->sz ||
ref()>1)
1612 void swap(
array& x) {
1613 std::swap(dt, x.dt);
1616 T& operator[](
size_t i) {assert(i<size()); copy();
return data()[i];}
1617 T operator[](
size_t i)
const {assert(i<size());
return data()[i];}
1620 template <
class I>
typename 1623 template <
class I>
typename 1628 if (x.dt==dt)
return *
this;
1635 template <
class expr>
typename 1637 operator=(
const expr& x) {
1638 if ((
void*)(&x)==(
void*)(
this))
return *
this;
1640 array tmp(x.size());
1641 array_ns::asg_v(tmp.data(),tmp.size(),x);
1644 template <
class expr>
typename 1646 operator+=(
const expr& x) {
1647 assert(size()==x.size());
1649 array_ns::asg_plus_v(data(),size(),x);
1652 template <
class expr>
typename 1654 operator-=(
const expr& x) {
1655 assert(size()==x.size());
1657 array_ns::asg_minus_v(data(),size(),x);
1660 template <
class expr>
typename 1662 operator*=(
const expr& x) {
1663 assert(size()==x.size());
1665 array_ns::asg_mul_v(data(),size(),x);
1668 template <
class expr>
typename 1670 operator/=(
const expr& x) {
1671 assert(size()==x.size());
1673 array_ns::asg_div_v(data(),size(),x);
1676 template <
class expr>
typename 1678 operator%=(
const expr& x) {
1679 assert(size()==x.size());
1681 array_ns::asg_mod_v(data(),size(),x);
1684 template <
class expr>
typename 1686 operator&=(
const expr& x) {
1687 assert(size()==x.size());
1689 array_ns::asg_and_v(data(),size(),x);
1692 template <
class expr>
typename 1694 operator|=(
const expr& x) {
1695 assert(size()==x.size());
1697 array_ns::asg_or_v(data(),size(),x);
1703 typename enable_if<is_expression<E>,
array&>::T
1704 operator<<=(
const E& x) {
1706 resize(orig.
size()+x.size());
1707 asg_v(data(),orig.
size(),orig);
1708 asg_v(data()+orig.
size(),x.size(),x);
1716 resize(orig.
size()+1);
1717 asg_v(data(),orig.
size(),orig);
1718 data()[orig.
size()]=x;
1723 template <
class scalar>
typename 1725 operator=(scalar x) {copy(); asg(data(),size(),T(x));
return *
this;}
1728 template <
class scalar>
typename 1730 operator+=(scalar x) {copy(); asg_plus(data(),size(),T(x));
return *
this;}
1733 template <
class scalar>
typename 1735 operator-=(scalar x) {copy(); asg_minus(data(),size(),T(x));
return *
this;}
1738 template <
class scalar>
typename 1740 operator*=(scalar x) {copy(); asg_mul(data(),size(),T(x));
return *
this;}
1743 template <
class scalar>
typename 1745 operator/=(scalar x) {copy(); asg_div(data(),size(),T(x));
return *
this;}
1748 template <
class scalar>
typename 1750 operator%=(scalar x) {copy(); asg_mod(data(),size(),T(x));
return *
this;}
1753 template <
class scalar>
typename 1755 operator&=(scalar x) {copy(); asg_and(data(),size(),T(x));
return *
this;}
1758 template <
class scalar>
typename 1760 operator|=(scalar x) {copy(); asg_or(data(),size(),T(x));
return *
this;}
1766 size_t size()
const {
return dt? dt->sz: 0;}
1768 T*
data() {copy();
return dt? dt->dt: 0;}
1770 const T*
data()
const {
return dt? dt->dt: 0;}
1772 typedef T *iterator;
1773 typedef const T *const_iterator;
1775 iterator begin(
void) {copy();
return iterator(data()); }
1776 iterator end(
void) {copy();
return iterator(data()+size()); }
1778 const_iterator begin(
void)
const {
return const_iterator(data()); }
1779 const_iterator end(
void)
const {
return const_iterator(data() + size()); }
1787 vsInv(static_cast<int>(y.
size()),y.
data(),r.data());
1793 {
return operator/(static_cast<float>(x),y);}
1798 vdInv(static_cast<int>(y.
size()),y.
data(),r.data());
1805 conformance_check(x,y);
1807 vsDiv(static_cast<int>(x.
size()),x.
data(),y.
data(),r.data());
1813 conformance_check(x,y);
1815 vdDiv(static_cast<int>(x.
size()),x.
data(),y.
data(),r.data());
1820 inline void asg_div_v(
float *dt,
size_t sz,
array<float>& x)
1821 {vsDiv(static_cast<int>(sz),dt,x.
data(),dt);}
1823 inline void asg_div_v(
double *dt,
size_t sz,
array<double>& x)
1824 {vdDiv(static_cast<int>(sz),dt,x.
data(),dt);}
1829 vsSqrt(static_cast<int>(x.
size()),x.
data(),r.data());
1836 vdSqrt(static_cast<int>(x.
size()),x.
data(),r.data());
1843 vsPowx(static_cast<int>(x.
size()),x.
data(),y,r.data());
1848 {
return pow(x,static_cast<float>(y));}
1853 vdPowx(static_cast<int>(x.
size()),x.
data(),y,r.data());
1860 conformance_check(x,y);
1861 vsPow(static_cast<int>(x.
size()),x.
data(),y.
data(),r.data());
1868 conformance_check(x,y);
1869 vdPow(static_cast<int>(x.
size()),x.
data(),y.
data(),r.data());
1876 vsExp(static_cast<int>(x.
size()),x.
data(),r.data());
1883 vdExp(static_cast<int>(x.
size()),x.
data(),r.data());
1890 vsLn(static_cast<int>(x.
size()),x.
data(),r.data());
1897 vdLn(static_cast<int>(x.
size()),x.
data(),r.data());
1904 vsLog10(static_cast<int>(x.
size()),x.
data(),r.data());
1911 vdLog10(static_cast<int>(x.
size()),x.
data(),r.data());
1918 vsCos(static_cast<int>(x.
size()),x.
data(),r.data());
1925 vdCos(static_cast<int>(x.
size()),x.
data(),r.data());
1932 vsSin(static_cast<int>(x.
size()),x.
data(),r.data());
1939 vdSin(static_cast<int>(x.
size()),x.
data(),r.data());
1946 vsTan(static_cast<int>(x.
size()),x.
data(),r.data());
1953 vdTan(static_cast<int>(x.
size()),x.
data(),r.data());
1960 vsAsin(static_cast<int>(x.
size()),x.
data(),r.data());
1967 vdAsin(static_cast<int>(x.
size()),x.
data(),r.data());
1974 vsAcos(static_cast<int>(x.
size()),x.
data(),r.data());
1981 vdAcos(static_cast<int>(x.
size()),x.
data(),r.data());
1988 vsAtan(static_cast<int>(x.
size()),x.
data(),r.data());
1995 vdAtan(static_cast<int>(x.
size()),x.
data(),r.data());
2002 conformance_check(x,y);
2003 vsAtan2(static_cast<int>(x.
size()),x.
data(),y.
data(),r.data());
2010 conformance_check(x,y);
2011 vdAtan2(static_cast<int>(x.
size()),x.
data(),y.
data(),r.data());
2018 vsCosh(static_cast<int>(x.
size()),x.
data(),r.data());
2025 vdCosh(static_cast<int>(x.
size()),x.
data(),r.data());
2032 vsSinh(static_cast<int>(x.
size()),x.
data(),r.data());
2039 vdSinh(static_cast<int>(x.
size()),x.
data(),r.data());
2046 vsTanh(static_cast<int>(x.
size()),x.
data(),r.data());
2053 vdTanh(static_cast<int>(x.
size()),x.
data(),r.data());
2059 template <
class E>
typename enable_if<is_expression<E>,
void >::T
2060 asg_div_v(
typename E::value_type *dt,
size_t sz,
const E& y)
2067 pow(
const E& x,
typename E::value_type y)
2073 template <
class E1,
class E2>
typename 2074 enable_if<one_is_expression<E1,E2>,
2076 pow(
const E1& x,
const E2& y)
2079 X(x.size()), Y(y.size()); X=x; Y=y;
2083 template <
class E>
typename 2086 template <
class E>
typename 2089 template <
class E>
typename 2092 template <
class E>
typename 2095 template <
class E>
typename 2098 template <
class E>
typename 2101 template <
class E>
typename 2104 template <
class E>
typename 2107 template <
class E>
typename 2110 template <
class E>
typename 2114 template <
class E1,
class E2>
typename 2116 atan2(
const E1& x,
const E2& y)
2122 template <
class E>
typename 2125 template <
class E>
typename 2128 template <
class E>
typename 2137 template <
class E>
typename 2143 for (
size_t i=0; i<cond.
size(); i++) ntrue+=cond[i];
2145 for (
size_t i=0, j=0; i<cond.
size(); i++)
2146 if (cond[i]) r[j++]=i;
2150 template <
class S>
typename 2152 pos(
const S& x,
dummy<1> d=1) {
return 0;}
2166 operator&&(
bool x,
const E& e)
2176 template <
class T,
class E>
2178 operator&&(T *x,
const E& e)
2179 {
return x!=NULL && e;}
2183 operator||(
bool x,
const E& e)
2200 typename E::value_type r;
2202 if (std::numeric_limits<typename E::value_type>::is_integer)
2203 r=std::numeric_limits<typename E::value_type>::min();
2205 r=-std::numeric_limits<typename E::value_type>::max();
2206 for (
size_t i=0; i<x.size(); i++)
2207 r = std::max(x[i],r);
2216 typename E::value_type r=std::numeric_limits<typename E::value_type>::max();
2217 for (
size_t i=0; i<x.size(); i++)
2218 r = std::min(x[i],r);
2225 typename result<typename E::value_type, typename E::value_type>::value_type
2229 typename result<typename E::value_type, typename E::value_type>::value_type
2231 for (
size_t i=0; i<x.size(); i++)
2236 template <
class E,
class M>
2238 typename result<typename E::value_type, typename E::value_type>::value_type
2240 sum(
const E& x,
const M& mask)
2242 typename result<typename E::value_type, typename E::value_type>::value_type
2244 for (
size_t i=0; i<x.size(); i++)
2245 if (mask[i]) r += x[i];
2254 typename E::value_type r=1;
2255 for (
size_t i=0; i<x.size(); i++)
2261 template <
class E,
class M>
2265 typename E::value_type r=1;
2266 for (
size_t i=0; i<x.size(); i++)
2267 if (mask[i]) r *= x[i];
2275 for (
size_t i=0; i<x.size(); i++)
2286 for (
size_t i=0; i<x.size(); i++)
2294 template <
class E1,
class E2,
class E3>
typename 2298 merge(
const E1& mask,
const E2& x,
const E3& y)
2300 conformance_check(mask,x);
2301 conformance_check(mask,y);
2303 for (
size_t i=0; i<mask.size(); i++)
2304 ret[i]= mask[i]?
at(x,i):
at(y,i);
2309 template <
class E1,
class E2>
typename 2313 pack(
const E1& e,
const E2& mask,
long ntrue=-1)
2315 assert(mask.size()==e.size());
2317 for (
size_t i=0, j=0; i<mask.size(); i++)
2318 if (mask[i]) r[j++]=e[i];
2323 template <
class E>
typename 2328 for (
size_t i=0, j=0; i<x.size(); i++)
2337 std::ostream& put(std::ostream& o,
const E& x)
2341 for (
size_t i=0; i<x.size()-1; i++)
2349 std::ostream& operator<<(std::ostream& o, const array<T>& x)
2353 template <
class T,
class Op>
2354 std::ostream& operator<<(std::ostream& o, const unop<T, Op>& x)
2357 template <
class E1,
class E2,
class Op>
2358 std::ostream& operator<<(std::ostream& o, const binop<E1,E2, Op>& x)
2363 std::istream&
get(std::istream& s, T& x)
2365 typename T::value_type v; x.resize(0);
2366 while (s>>v) {x<<=v;}
2371 std::istream& operator>>(std::istream& i,
array<T>& x)
2379 #pragma loop count(1000) 2381 #pragma vector aligned 2383 for (
int i=0; i<n; i++)
2400 for (
size_t i=0,p=0; i<x.
size(); i++)
2401 for (
int j=0; j<x[i]; j++,p++)
2429 enum array_dir_t {upwards, downwards};
2438 Cmp(
const array<T>& data,
bool fwd): data(data), fwd(fwd) {
2441 bool operator()(
const int& i,
const int& j)
2444 return data[i] < data[j];
2446 return data[j] < data[i];
2451 template <
class T>
typename 2453 rank(
const T& x,
enum array_dir_t dir=upwards)
2456 std::sort(cmp.ranks.begin(),cmp.ranks.end(),cmp);
2464 using array_ns::pcoord;
2466 extern urand array_urand;
2470 using ecolab::TCL_obj;
2482 pack(targ,desc,arg.
size());
2495 unpack(targ,desc,size);
2508 ecolab::TCL_obj_register(targ,desc,arg);
2519 static std::string name()
2520 {
return "ecolab::array<"+typeName<T>()+
">";}
Definition: arrays.h:1086
unop< E, Tanh< typename E::value_type > > tanh(const E &e)
Definition: arrays.h:952
binop< E1, E2, Pow< E1, E2 > > pow(const E1 &e1, const E2 &e2)
Definition: arrays.h:777
unop< E, Floor< typename E::value_type > > floor(const E &e)
Definition: arrays.h:1027
Definition: arrays.h:1066
enable_if< both_are_expressions< E1, E2 >, array< typename E1::value_type > >::T pack(const E1 &e, const E2 &mask, long ntrue=-1)
pack vector (remove elements where mask[i] is false
Definition: arrays.h:2313
unop< E, Acos< typename E::value_type > > acos(const E &e)
Definition: arrays.h:883
enable_if< one_is_expression< E1, E2 >, binop< E1, E2, Max< E1, E2 > > >::T max(const E1 &e1, const E2 &e2)
Definition: arrays.h:1079
enable_if< is_expression< E >, typename E::value_type >::T prod(const E &x)
product of a vector expression
Definition: arrays.h:2252
enable_if< is_scalar< scalar >, array & >::T operator-=(scalar x)
subtracting broadcast
Definition: arrays.h:1735
unop< E, Exp< typename E::value_type > > exp(const E &e)
Definition: arrays.h:792
enable_if< one_is_expression< E1, E2 >, binop< E1, E2, Min< E1, E2 > > >::T min(const E1 &e1, const E2 &e2)
Definition: arrays.h:1099
unop< E, Cosh< typename E::value_type > > cosh(const E &e)
Definition: arrays.h:939
unop< E, Log< typename E::value_type > > log(const E &e)
Definition: arrays.h:805
Namespace for array functionality.
size_t size() const
size of buffer
Definition: pack_base.h:154
enable_if< is_scalar< scalar >, array & >::T operator|=(scalar x)
bitwise or broadcast
Definition: arrays.h:1760
Definition: arrays.h:2432
E::value_type & at(E &x, size_t i, typename enable_if< is_expression< E >, int >::T dum=0)
Definition: arrays.h:335
void fillgrand(array< double > &x)
fill array with gaussian random numbers from
enable_if< is_scalar< scalar >, array & >::T operator/=(scalar x)
dividing broadcast
Definition: arrays.h:1745
Definition: classdesc.h:375
binop< E1, E2, Ldexp< E1, E2 > > ldexp(const E1 &e1, const E2 &e2)
Definition: arrays.h:1042
enable_if< is_expression< E1 >, array< typename result< E2, E3 >::value_type > >::T merge(const E1 &mask, const E2 &x, const E3 &y)
merge two vectors: r[i] = mask[i]? x[i]: y[i]
Definition: arrays.h:2298
void gspread(array< double > &a, const array< double > &s)
Additive process .
unop< E, Abs< typename E::value_type > > abs(const E &e)
Definition: arrays.h:992
unop< E, Asin< typename E::value_type > > asin(const E &e)
Definition: arrays.h:870
unop< E, Abs< typename E::value_type > > fabs(const E &e)
Definition: arrays.h:987
Definition: arrays.h:1006
void fillrand(array< double > &x)
fill array with uniformly random numbers from [0,1)
Definition: classdesc.h:623
void lgspread(array< double > &a, const array< double > &s)
Multiplicative process .
binop< E1, E2, Atan2< E1, E2 > > atan2(const E1 &e1, const E2 &e2)
Definition: arrays.h:911
enable_if< is_scalar< scalar >, array & >::T operator+=(scalar x)
summing broadcast
Definition: arrays.h:1730
bool eq(const E1 &e1, const E2 &e2)
Definition: arrays.h:747
unop< E, Sgn< typename E::value_type > > sign(const E &e)
Definition: arrays.h:1001
Definition: arrays.h:1049
Gaussian (normal) random generator.
Definition: random_basic.h:19
class to allow access to private members
Definition: classdesc_access.h:21
enable_if< is_expression< E >, size_t >::T len(const E &x, dummy< 0 > d=0)
Definition: arrays.h:359
enable_if< is_scalar< scalar >, array & >::T operator*=(scalar x)
multiplying broadcast
Definition: arrays.h:1740
enable_if< is_scalar< scalar >, array & >::T operator=(scalar x)
broadcast
Definition: arrays.h:1725
unop< E, Ceil< typename E::value_type > > ceil(const E &e)
Definition: arrays.h:1014
binop< E1, E2, Fmod< E1, E2 > > fmod(const E1 &e1, const E2 &e2)
Definition: arrays.h:1059
array< int > gen_index(const array< int > &x)
Definition: arrays.h:2397
E::value_type value_type
type of result
Definition: arrays.h:1220
void resize(size_t s, const V &val)
resize array to s elements, and initialise to val
Definition: arrays.h:1610
Definition: TCL_obj_stl.h:185
Definition: arrays.h:1019
class to allow access to private members
Definition: classdesc_access.h:22
bool all(const E &x)
true iff all elements of x are true
Definition: arrays.h:2284
enable_if< is_expression< T >, array< int > >::T rank(const T &x, enum array_dir_t dir=upwards)
rank elements
Definition: arrays.h:2453
void fill_unique_rand(array< int > &x, unsigned max)
fill with uniform numbers drawn from [0...max] without replacement
unop< E, Log10< typename E::value_type > > log10(const E &e)
Definition: arrays.h:818
unop< E, Tan< typename E::value_type > > tan(const E &e)
Definition: arrays.h:857
void fillprand(array< double > &x)
fill array with exponential random numbers
enable_if< is_scalar< scalar >, array & >::T operator &=(scalar x)
bitwise and broadcast
Definition: arrays.h:1755
enable_if< is_expression< I >, RVindex< unop, I > >::T operator[](const I &i) const
vector indexing
Definition: arrays.h:1228
enable_if< is_expression< I >, RVindex< binop, I > >::T operator[](const I &i) const
vector indexing
Definition: arrays.h:1278
unop< E, Sin< typename E::value_type > > sin(const E &e)
Definition: arrays.h:831
enable_if< is_expression< I >, RVindex< array, I > >::T operator[](const I &i) const
vector indexing
Definition: arrays.h:1622
Definition: TCL_obj_base.h:364
array< int > pcoord(int n)
[0...n-1]
Definition: arrays.h:2375
unop< E, Cos< typename E::value_type > > cos(const E &e)
Definition: arrays.h:844
unop< E, Sqrt< typename E::value_type > > sqrt(const E &e)
Definition: arrays.h:965
size_t size() const
number of elements
Definition: arrays.h:1766
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
Definition: pack_base.h:124
enable_if< is_expression< E >, typename result< typename E::value_type, typename E::value_type >::value_type >::T sum(const E &x)
sum of a vector expression
Definition: arrays.h:2227
unop< E, Sinh< typename E::value_type > > sinh(const E &e)
Definition: arrays.h:926
_OPENMP
Definition: accessor.h:16
enable_if< is_scalar< scalar >, array & >::T operator%=(scalar x)
remaindering broadcast
Definition: arrays.h:1750
TCL_obj descriptor object.
Definition: TCL_obj_base.h:327
Definition: arrays.h:1487
Definition: TCL_obj_base.h:27
void resize(size_t s)
resize array to s elements
Definition: arrays.h:1599
Definition: arrays.h:1032
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition: accessor.h:55
unop< E, Atan< typename E::value_type > > atan(const E &e)
Definition: arrays.h:896
Definition: random_basic.h:11
bool any(const E &x)
true iff any element x is true
Definition: arrays.h:2273
const T * data() const
obtain raw pointer to data
Definition: arrays.h:1770
enable_if< is_expression< E >, array< size_t > >::T enumerate(const E &x)
running sum of x considered as a boolean mask
Definition: arrays.h:2325
Op::value_type value_type
type of result
Definition: arrays.h:1243
T * data()
obtain raw pointer to data
Definition: arrays.h:1768