LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
operators.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008, 2009, 2010, 2011 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 #ifndef NDARRAY_operators_h_INCLUDED
24 #define NDARRAY_operators_h_INCLUDED
25 
30 #include "ndarray/Array.h"
31 #include <boost/call_traits.hpp>
32 #include <boost/functional.hpp>
33 #include <boost/utility/enable_if.hpp>
34 
35 #include "ndarray/detail/UnaryOp.h"
37 #include "ndarray/types.h"
38 
39 namespace ndarray {
40 
42 namespace detail {
43 
50 template <typename A, typename B>
51 struct PromotingBinaryFunction {
52  typedef A ElementA;
53  typedef B ElementB;
54  typedef A first_argument_type;
55  typedef B second_argument_type;
56  typedef typename boost::call_traits<A>::param_type ParamA;
57  typedef typename boost::call_traits<B>::param_type ParamB;
58  typedef typename Promote<A,B>::Type result_type;
59 };
60 
67 template <typename A, typename B>
68 struct BinaryPredicate {
69  typedef A ElementA;
70  typedef B ElementB;
71  typedef A first_argument_type;
72  typedef B second_argument_type;
73  typedef typename boost::call_traits<A>::param_type ParamA;
74  typedef typename boost::call_traits<B>::param_type ParamB;
75  typedef bool result_type;
76 };
77 
84 template <typename Derived>
85 struct AdaptableFunctionTag {
86 
87  template <typename OperandB, typename A>
88  struct ScalarExpr {
89  typedef typename Derived::template ScalarFunction<
90  A, typename ExpressionTraits<OperandB>::Element
91  > BinaryFunction;
92  typedef boost::binder1st<BinaryFunction> Bound;
93  static Bound bind(A const & scalar) {
94  return Bound(BinaryFunction(),scalar);
95  }
96  };
97 
98  template <typename OperandA, typename B>
99  struct ExprScalar {
100  typedef typename Derived::template ScalarFunction<
101  typename ExpressionTraits<OperandA>::Element, B
102  > BinaryFunction;
103  typedef boost::binder2nd<BinaryFunction> Bound;
104  static Bound bind(B const & scalar) {
105  return Bound(BinaryFunction(),scalar);
106  }
107  };
108 
109  template <typename OperandA, typename OperandB>
110  struct ExprExpr {
111  typedef typename Derived::template ScalarFunction<
112  typename ExpressionTraits<OperandA>::Element,
113  typename ExpressionTraits<OperandB>::Element
114  > BinaryFunction;
115  };
116 
117 };
118 
124 template <typename T>
125 struct BitwiseNot {
126  typedef T argument_type;
127  typedef T result_type;
128 
129  result_type operator()(argument_type arg) const { return ~arg; }
130 };
131 
132 
133  struct PlusTag : public AdaptableFunctionTag<PlusTag> {
134  template <typename A, typename B>
135  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
136  typename PromotingBinaryFunction<A,B>::result_type operator()(
137  typename PromotingBinaryFunction<A,B>::ParamA a,
138  typename PromotingBinaryFunction<A,B>::ParamB b
139  ) const {
140  return a + b;
141  }
142  };
143  };
144 
145  struct MinusTag : public AdaptableFunctionTag<MinusTag> {
146  template <typename A, typename B>
147  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
148  typename PromotingBinaryFunction<A,B>::result_type operator()(
149  typename PromotingBinaryFunction<A,B>::ParamA a,
150  typename PromotingBinaryFunction<A,B>::ParamB b
151  ) const {
152  return a - b;
153  }
154  };
155  };
156 
157  struct MultipliesTag : public AdaptableFunctionTag<MultipliesTag> {
158  template <typename A, typename B>
159  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
160  typename PromotingBinaryFunction<A,B>::result_type operator()(
161  typename PromotingBinaryFunction<A,B>::ParamA a,
162  typename PromotingBinaryFunction<A,B>::ParamB b
163  ) const {
164  return a * b;
165  }
166  };
167  };
168 
169  struct DividesTag : public AdaptableFunctionTag<DividesTag> {
170  template <typename A, typename B>
171  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
172  typename PromotingBinaryFunction<A,B>::result_type operator()(
173  typename PromotingBinaryFunction<A,B>::ParamA a,
174  typename PromotingBinaryFunction<A,B>::ParamB b
175  ) const {
176  return a / b;
177  }
178  };
179  };
180 
181  struct ModulusTag : public AdaptableFunctionTag<ModulusTag> {
182  template <typename A, typename B>
183  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
184  typename PromotingBinaryFunction<A,B>::result_type operator()(
185  typename PromotingBinaryFunction<A,B>::ParamA a,
186  typename PromotingBinaryFunction<A,B>::ParamB b
187  ) const {
188  return a % b;
189  }
190  };
191  };
192 
193  struct BitwiseXorTag : public AdaptableFunctionTag<BitwiseXorTag> {
194  template <typename A, typename B>
195  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
196  typename PromotingBinaryFunction<A,B>::result_type operator()(
197  typename PromotingBinaryFunction<A,B>::ParamA a,
198  typename PromotingBinaryFunction<A,B>::ParamB b
199  ) const {
200  return a ^ b;
201  }
202  };
203  };
204 
205  struct BitwiseOrTag : public AdaptableFunctionTag<BitwiseOrTag> {
206  template <typename A, typename B>
207  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
208  typename PromotingBinaryFunction<A,B>::result_type operator()(
209  typename PromotingBinaryFunction<A,B>::ParamA a,
210  typename PromotingBinaryFunction<A,B>::ParamB b
211  ) const {
212  return a | b;
213  }
214  };
215  };
216 
217  struct BitwiseAndTag : public AdaptableFunctionTag<BitwiseAndTag> {
218  template <typename A, typename B>
219  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
220  typename PromotingBinaryFunction<A,B>::result_type operator()(
221  typename PromotingBinaryFunction<A,B>::ParamA a,
222  typename PromotingBinaryFunction<A,B>::ParamB b
223  ) const {
224  return a & b;
225  }
226  };
227  };
228 
229  struct BitwiseLeftShiftTag : public AdaptableFunctionTag<BitwiseLeftShiftTag> {
230  template <typename A, typename B>
231  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
232  typename PromotingBinaryFunction<A,B>::result_type operator()(
233  typename PromotingBinaryFunction<A,B>::ParamA a,
234  typename PromotingBinaryFunction<A,B>::ParamB b
235  ) const {
236  return a << b;
237  }
238  };
239  };
240 
241  struct BitwiseRightShiftTag : public AdaptableFunctionTag<BitwiseRightShiftTag> {
242  template <typename A, typename B>
243  struct ScalarFunction : public PromotingBinaryFunction<A,B> {
244  typename PromotingBinaryFunction<A,B>::result_type operator()(
245  typename PromotingBinaryFunction<A,B>::ParamA a,
246  typename PromotingBinaryFunction<A,B>::ParamB b
247  ) const {
248  return a >> b;
249  }
250  };
251  };
252 
253 
254  struct EqualToTag : public AdaptableFunctionTag<EqualToTag> {
255  template <typename A, typename B>
256  struct ScalarFunction : public BinaryPredicate<A,B> {
257  typename BinaryPredicate<A,B>::result_type operator()(
258  typename BinaryPredicate<A,B>::ParamA a,
259  typename BinaryPredicate<A,B>::ParamB b
260  ) const {
261  return a == b;
262  }
263  };
264  };
265 
266  struct NotEqualToTag : public AdaptableFunctionTag<NotEqualToTag> {
267  template <typename A, typename B>
268  struct ScalarFunction : public BinaryPredicate<A,B> {
269  typename BinaryPredicate<A,B>::result_type operator()(
270  typename BinaryPredicate<A,B>::ParamA a,
271  typename BinaryPredicate<A,B>::ParamB b
272  ) const {
273  return a != b;
274  }
275  };
276  };
277 
278  struct LessTag : public AdaptableFunctionTag<LessTag> {
279  template <typename A, typename B>
280  struct ScalarFunction : public BinaryPredicate<A,B> {
281  typename BinaryPredicate<A,B>::result_type operator()(
282  typename BinaryPredicate<A,B>::ParamA a,
283  typename BinaryPredicate<A,B>::ParamB b
284  ) const {
285  return a < b;
286  }
287  };
288  };
289 
290  struct GreaterTag : public AdaptableFunctionTag<GreaterTag> {
291  template <typename A, typename B>
292  struct ScalarFunction : public BinaryPredicate<A,B> {
293  typename BinaryPredicate<A,B>::result_type operator()(
294  typename BinaryPredicate<A,B>::ParamA a,
295  typename BinaryPredicate<A,B>::ParamB b
296  ) const {
297  return a > b;
298  }
299  };
300  };
301 
302  struct LessEqualTag : public AdaptableFunctionTag<LessEqualTag> {
303  template <typename A, typename B>
304  struct ScalarFunction : public BinaryPredicate<A,B> {
305  typename BinaryPredicate<A,B>::result_type operator()(
306  typename BinaryPredicate<A,B>::ParamA a,
307  typename BinaryPredicate<A,B>::ParamB b
308  ) const {
309  return a <= b;
310  }
311  };
312  };
313 
314  struct GreaterEqualTag : public AdaptableFunctionTag<GreaterEqualTag> {
315  template <typename A, typename B>
316  struct ScalarFunction : public BinaryPredicate<A,B> {
317  typename BinaryPredicate<A,B>::result_type operator()(
318  typename BinaryPredicate<A,B>::ParamA a,
319  typename BinaryPredicate<A,B>::ParamB b
320  ) const {
321  return a >= b;
322  }
323  };
324  };
325 
326  struct LogicalAnd : public AdaptableFunctionTag<LogicalAnd> {
327  template <typename A, typename B>
328  struct ScalarFunction : public BinaryPredicate<A,B> {
329  typename BinaryPredicate<A,B>::result_type operator()(
330  typename BinaryPredicate<A,B>::ParamA a,
331  typename BinaryPredicate<A,B>::ParamB b
332  ) const {
333  return a && b;
334  }
335  };
336  };
337 
338  struct LogicalOr : public AdaptableFunctionTag<LogicalOr> {
339  template <typename A, typename B>
340  struct ScalarFunction : public BinaryPredicate<A,B> {
341  typename BinaryPredicate<A,B>::result_type operator()(
342  typename BinaryPredicate<A,B>::ParamA a,
343  typename BinaryPredicate<A,B>::ParamB b
344  ) const {
345  return a || b;
346  }
347  };
348  };
349 
350 } // namespace detail
352 
355 
356  template <typename Operand, typename Scalar>
357 #ifndef DOXYGEN
358  typename boost::enable_if<
359  typename ExpressionTraits<Scalar>::IsScalar,
360  detail::UnaryOpExpression< Operand, typename detail::PlusTag::template ExprScalar<Operand,Scalar>::Bound >
361  >::type
362 #else
363  <unspecified-expression-type>
364 #endif
365  operator+(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
366  return vectorize(detail::PlusTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
367  }
368 
369  template <typename Operand, typename Scalar>
370 #ifndef DOXYGEN
371  typename boost::enable_if<
372  typename ExpressionTraits<Scalar>::IsScalar,
373  detail::UnaryOpExpression< Operand, typename detail::PlusTag::template ScalarExpr<Operand,Scalar>::Bound >
374  >::type
375 #else
376  <unspecified-expression-type>
377 #endif
378  operator+(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
379  return vectorize(detail::PlusTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
380  }
381 
382  template <typename Operand1, typename Operand2>
383 #ifndef DOXYGEN
384  detail::BinaryOpExpression<
385  Operand1, Operand2,
386  typename detail::PlusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
387  >
388 #else
389  <unspecified-expression-type>
390 #endif
391  operator+(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
392  return vectorize(
393  typename detail::PlusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
394  operand1,
395  operand2
396  );
397  }
398 
399  template <typename Operand, typename Scalar>
400 #ifndef DOXYGEN
401  typename boost::enable_if<
402  typename ExpressionTraits<Scalar>::IsScalar,
403  detail::UnaryOpExpression< Operand, typename detail::MinusTag::template ExprScalar<Operand,Scalar>::Bound >
404  >::type
405 #else
406  <unspecified-expression-type>
407 #endif
408  operator-(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
409  return vectorize(detail::MinusTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
410  }
411 
412  template <typename Operand, typename Scalar>
413 #ifndef DOXYGEN
414  typename boost::enable_if<
415  typename ExpressionTraits<Scalar>::IsScalar,
416  detail::UnaryOpExpression< Operand, typename detail::MinusTag::template ScalarExpr<Operand,Scalar>::Bound >
417  >::type
418 #else
419  <unspecified-expression-type>
420 #endif
421  operator-(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
422  return vectorize(detail::MinusTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
423  }
424 
425  template <typename Operand1, typename Operand2>
426 #ifndef DOXYGEN
427  detail::BinaryOpExpression<
428  Operand1, Operand2,
429  typename detail::MinusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
430  >
431 #else
432  <unspecified-expression-type>
433 #endif
434  operator-(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
435  return vectorize(
436  typename detail::MinusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
437  operand1,
438  operand2
439  );
440  }
441 
442  template <typename Operand, typename Scalar>
443 #ifndef DOXYGEN
444  typename boost::enable_if<
445  typename ExpressionTraits<Scalar>::IsScalar,
446  detail::UnaryOpExpression< Operand, typename detail::MultipliesTag::template ExprScalar<Operand,Scalar>::Bound >
447  >::type
448 #else
449  <unspecified-expression-type>
450 #endif
451  operator*(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
452  return vectorize(detail::MultipliesTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
453  }
454 
455  template <typename Operand, typename Scalar>
456 #ifndef DOXYGEN
457  typename boost::enable_if<
458  typename ExpressionTraits<Scalar>::IsScalar,
459  detail::UnaryOpExpression< Operand, typename detail::MultipliesTag::template ScalarExpr<Operand,Scalar>::Bound >
460  >::type
461 #else
462  <unspecified-expression-type>
463 #endif
464  operator*(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
465  return vectorize(detail::MultipliesTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
466  }
467 
468  template <typename Operand1, typename Operand2>
469 #ifndef DOXYGEN
470  detail::BinaryOpExpression<
471  Operand1, Operand2,
472  typename detail::MultipliesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
473  >
474 #else
475  <unspecified-expression-type>
476 #endif
477  operator*(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
478  return vectorize(
479  typename detail::MultipliesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
480  operand1,
481  operand2
482  );
483  }
484 
485  template <typename Operand, typename Scalar>
486 #ifndef DOXYGEN
487  typename boost::enable_if<
488  typename ExpressionTraits<Scalar>::IsScalar,
489  detail::UnaryOpExpression< Operand, typename detail::DividesTag::template ExprScalar<Operand,Scalar>::Bound >
490  >::type
491 #else
492  <unspecified-expression-type>
493 #endif
494  operator/(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
495  return vectorize(detail::DividesTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
496  }
497 
498  template <typename Operand, typename Scalar>
499 #ifndef DOXYGEN
500  typename boost::enable_if<
501  typename ExpressionTraits<Scalar>::IsScalar,
502  detail::UnaryOpExpression< Operand, typename detail::DividesTag::template ScalarExpr<Operand,Scalar>::Bound >
503  >::type
504 #else
505  <unspecified-expression-type>
506 #endif
507  operator/(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
508  return vectorize(detail::DividesTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
509  }
510 
511  template <typename Operand1, typename Operand2>
512 #ifndef DOXYGEN
513  detail::BinaryOpExpression<
514  Operand1, Operand2,
515  typename detail::DividesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
516  >
517 #else
518  <unspecified-expression-type>
519 #endif
520  operator/(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
521  return vectorize(
522  typename detail::DividesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
523  operand1,
524  operand2
525  );
526  }
527 
528  template <typename Operand, typename Scalar>
529 #ifndef DOXYGEN
530  typename boost::enable_if<
531  typename ExpressionTraits<Scalar>::IsScalar,
532  detail::UnaryOpExpression< Operand, typename detail::ModulusTag::template ExprScalar<Operand,Scalar>::Bound >
533  >::type
534 #else
535  <unspecified-expression-type>
536 #endif
537  operator%(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
538  return vectorize(detail::ModulusTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
539  }
540 
541  template <typename Operand, typename Scalar>
542 #ifndef DOXYGEN
543  typename boost::enable_if<
544  typename ExpressionTraits<Scalar>::IsScalar,
545  detail::UnaryOpExpression< Operand, typename detail::ModulusTag::template ScalarExpr<Operand,Scalar>::Bound >
546  >::type
547 #else
548  <unspecified-expression-type>
549 #endif
550  operator%(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
551  return vectorize(detail::ModulusTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
552  }
553 
554  template <typename Operand1, typename Operand2>
555 #ifndef DOXYGEN
556  detail::BinaryOpExpression<
557  Operand1, Operand2,
558  typename detail::ModulusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
559  >
560 #else
561  <unspecified-expression-type>
562 #endif
563  operator%(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
564  return vectorize(
565  typename detail::ModulusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
566  operand1,
567  operand2
568  );
569  }
570 
571  template <typename Operand, typename Scalar>
572 #ifndef DOXYGEN
573  typename boost::enable_if<
574  typename ExpressionTraits<Scalar>::IsScalar,
575  detail::UnaryOpExpression< Operand, typename detail::BitwiseXorTag::template ExprScalar<Operand,Scalar>::Bound >
576  >::type
577 #else
578  <unspecified-expression-type>
579 #endif
580  operator^(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
581  return vectorize(detail::BitwiseXorTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
582  }
583 
584  template <typename Operand, typename Scalar>
585 #ifndef DOXYGEN
586  typename boost::enable_if<
587  typename ExpressionTraits<Scalar>::IsScalar,
588  detail::UnaryOpExpression< Operand, typename detail::BitwiseXorTag::template ScalarExpr<Operand,Scalar>::Bound >
589  >::type
590 #else
591  <unspecified-expression-type>
592 #endif
593  operator^(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
594  return vectorize(detail::BitwiseXorTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
595  }
596 
597  template <typename Operand1, typename Operand2>
598 #ifndef DOXYGEN
599  detail::BinaryOpExpression<
600  Operand1, Operand2,
601  typename detail::BitwiseXorTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
602  >
603 #else
604  <unspecified-expression-type>
605 #endif
606  operator^(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
607  return vectorize(
608  typename detail::BitwiseXorTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
609  operand1,
610  operand2
611  );
612  }
613 
614  template <typename Operand, typename Scalar>
615 #ifndef DOXYGEN
616  typename boost::enable_if<
617  typename ExpressionTraits<Scalar>::IsScalar,
618  detail::UnaryOpExpression< Operand, typename detail::BitwiseOrTag::template ExprScalar<Operand,Scalar>::Bound >
619  >::type
620 #else
621  <unspecified-expression-type>
622 #endif
623  operator|(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
624  return vectorize(detail::BitwiseOrTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
625  }
626 
627  template <typename Operand, typename Scalar>
628 #ifndef DOXYGEN
629  typename boost::enable_if<
630  typename ExpressionTraits<Scalar>::IsScalar,
631  detail::UnaryOpExpression< Operand, typename detail::BitwiseOrTag::template ScalarExpr<Operand,Scalar>::Bound >
632  >::type
633 #else
634  <unspecified-expression-type>
635 #endif
636  operator|(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
637  return vectorize(detail::BitwiseOrTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
638  }
639 
640  template <typename Operand1, typename Operand2>
641 #ifndef DOXYGEN
642  detail::BinaryOpExpression<
643  Operand1, Operand2,
644  typename detail::BitwiseOrTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
645  >
646 #else
647  <unspecified-expression-type>
648 #endif
649  operator|(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
650  return vectorize(
651  typename detail::BitwiseOrTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
652  operand1,
653  operand2
654  );
655  }
656 
657  template <typename Operand, typename Scalar>
658 #ifndef DOXYGEN
659  typename boost::enable_if<
660  typename ExpressionTraits<Scalar>::IsScalar,
661  detail::UnaryOpExpression< Operand, typename detail::BitwiseAndTag::template ExprScalar<Operand,Scalar>::Bound >
662  >::type
663 #else
664  <unspecified-expression-type>
665 #endif
666  operator&(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
667  return vectorize(detail::BitwiseAndTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
668  }
669 
670  template <typename Operand, typename Scalar>
671 #ifndef DOXYGEN
672  typename boost::enable_if<
673  typename ExpressionTraits<Scalar>::IsScalar,
674  detail::UnaryOpExpression< Operand, typename detail::BitwiseAndTag::template ScalarExpr<Operand,Scalar>::Bound >
675  >::type
676 #else
677  <unspecified-expression-type>
678 #endif
679  operator&(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
680  return vectorize(detail::BitwiseAndTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
681  }
682 
683  template <typename Operand1, typename Operand2>
684 #ifndef DOXYGEN
685  detail::BinaryOpExpression<
686  Operand1, Operand2,
687  typename detail::BitwiseAndTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
688  >
689 #else
690  <unspecified-expression-type>
691 #endif
692  operator&(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
693  return vectorize(
694  typename detail::BitwiseAndTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
695  operand1,
696  operand2
697  );
698  }
699 
700  template <typename Operand, typename Scalar>
701 #ifndef DOXYGEN
702  typename boost::enable_if<
703  typename ExpressionTraits<Scalar>::IsScalar,
704  detail::UnaryOpExpression< Operand, typename detail::BitwiseLeftShiftTag::template ExprScalar<Operand,Scalar>::Bound >
705  >::type
706 #else
707  <unspecified-expression-type>
708 #endif
709  operator<<(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
710  return vectorize(detail::BitwiseLeftShiftTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
711  }
712 
713  template <typename Operand, typename Scalar>
714 #ifndef DOXYGEN
715  typename boost::enable_if<
716  typename ExpressionTraits<Scalar>::IsScalar,
717  detail::UnaryOpExpression< Operand, typename detail::BitwiseLeftShiftTag::template ScalarExpr<Operand,Scalar>::Bound >
718  >::type
719 #else
720  <unspecified-expression-type>
721 #endif
722  operator<<(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
723  return vectorize(detail::BitwiseLeftShiftTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
724  }
725 
726  template <typename Operand1, typename Operand2>
727 #ifndef DOXYGEN
728  detail::BinaryOpExpression<
729  Operand1, Operand2,
730  typename detail::BitwiseLeftShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
731  >
732 #else
733  <unspecified-expression-type>
734 #endif
735  operator<<(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
736  return vectorize(
737  typename detail::BitwiseLeftShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
738  operand1,
739  operand2
740  );
741  }
742 
743  template <typename Operand, typename Scalar>
744 #ifndef DOXYGEN
745  typename boost::enable_if<
746  typename ExpressionTraits<Scalar>::IsScalar,
747  detail::UnaryOpExpression< Operand, typename detail::BitwiseRightShiftTag::template ExprScalar<Operand,Scalar>::Bound >
748  >::type
749 #else
750  <unspecified-expression-type>
751 #endif
752  operator>>(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
753  return vectorize(detail::BitwiseRightShiftTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
754  }
755 
756  template <typename Operand, typename Scalar>
757 #ifndef DOXYGEN
758  typename boost::enable_if<
759  typename ExpressionTraits<Scalar>::IsScalar,
760  detail::UnaryOpExpression< Operand, typename detail::BitwiseRightShiftTag::template ScalarExpr<Operand,Scalar>::Bound >
761  >::type
762 #else
763  <unspecified-expression-type>
764 #endif
765  operator>>(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
766  return vectorize(detail::BitwiseRightShiftTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
767  }
768 
769  template <typename Operand1, typename Operand2>
770 #ifndef DOXYGEN
771  detail::BinaryOpExpression<
772  Operand1, Operand2,
773  typename detail::BitwiseRightShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
774  >
775 #else
776  <unspecified-expression-type>
777 #endif
778  operator>>(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
779  return vectorize(
780  typename detail::BitwiseRightShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
781  operand1,
782  operand2
783  );
784  }
785 
786 
787  template <typename Operand, typename Scalar>
788 #ifndef DOXYGEN
789  typename boost::enable_if<
790  typename ExpressionTraits<Scalar>::IsScalar,
791  detail::UnaryOpExpression< Operand, typename detail::EqualToTag::template ExprScalar<Operand,Scalar>::Bound >
792  >::type
793 #else
794  <unspecified-expression-type>
795 #endif
796  equal(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
797  return vectorize(detail::EqualToTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
798  }
799 
800  template <typename Operand, typename Scalar>
801 #ifndef DOXYGEN
802  typename boost::enable_if<
803  typename ExpressionTraits<Scalar>::IsScalar,
804  detail::UnaryOpExpression< Operand, typename detail::EqualToTag::template ScalarExpr<Operand,Scalar>::Bound >
805  >::type
806 #else
807  <unspecified-expression-type>
808 #endif
809  equal(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
810  return vectorize(detail::EqualToTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
811  }
812 
813  template <typename Operand1, typename Operand2>
814 #ifndef DOXYGEN
815  detail::BinaryOpExpression<
816  Operand1, Operand2,
817  typename detail::EqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
818  >
819 #else
820  <unspecified-expression-type>
821 #endif
822  equal(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
823  return vectorize(
824  typename detail::EqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
825  operand1,
826  operand2
827  );
828  }
829 
830  template <typename Operand, typename Scalar>
831 #ifndef DOXYGEN
832  typename boost::enable_if<
833  typename ExpressionTraits<Scalar>::IsScalar,
834  detail::UnaryOpExpression< Operand, typename detail::NotEqualToTag::template ExprScalar<Operand,Scalar>::Bound >
835  >::type
836 #else
837  <unspecified-expression-type>
838 #endif
839  not_equal(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
840  return vectorize(detail::NotEqualToTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
841  }
842 
843  template <typename Operand, typename Scalar>
844 #ifndef DOXYGEN
845  typename boost::enable_if<
846  typename ExpressionTraits<Scalar>::IsScalar,
847  detail::UnaryOpExpression< Operand, typename detail::NotEqualToTag::template ScalarExpr<Operand,Scalar>::Bound >
848  >::type
849 #else
850  <unspecified-expression-type>
851 #endif
852  not_equal(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
853  return vectorize(detail::NotEqualToTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
854  }
855 
856  template <typename Operand1, typename Operand2>
857 #ifndef DOXYGEN
858  detail::BinaryOpExpression<
859  Operand1, Operand2,
860  typename detail::NotEqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
861  >
862 #else
863  <unspecified-expression-type>
864 #endif
865  not_equal(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
866  return vectorize(
867  typename detail::NotEqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
868  operand1,
869  operand2
870  );
871  }
872 
873  template <typename Operand, typename Scalar>
874 #ifndef DOXYGEN
875  typename boost::enable_if<
876  typename ExpressionTraits<Scalar>::IsScalar,
877  detail::UnaryOpExpression< Operand, typename detail::LessTag::template ExprScalar<Operand,Scalar>::Bound >
878  >::type
879 #else
880  <unspecified-expression-type>
881 #endif
882  less(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
883  return vectorize(detail::LessTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
884  }
885 
886  template <typename Operand, typename Scalar>
887 #ifndef DOXYGEN
888  typename boost::enable_if<
889  typename ExpressionTraits<Scalar>::IsScalar,
890  detail::UnaryOpExpression< Operand, typename detail::LessTag::template ScalarExpr<Operand,Scalar>::Bound >
891  >::type
892 #else
893  <unspecified-expression-type>
894 #endif
895  less(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
896  return vectorize(detail::LessTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
897  }
898 
899  template <typename Operand1, typename Operand2>
900 #ifndef DOXYGEN
901  detail::BinaryOpExpression<
902  Operand1, Operand2,
903  typename detail::LessTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
904  >
905 #else
906  <unspecified-expression-type>
907 #endif
908  less(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
909  return vectorize(
910  typename detail::LessTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
911  operand1,
912  operand2
913  );
914  }
915 
916  template <typename Operand, typename Scalar>
917 #ifndef DOXYGEN
918  typename boost::enable_if<
919  typename ExpressionTraits<Scalar>::IsScalar,
920  detail::UnaryOpExpression< Operand, typename detail::GreaterTag::template ExprScalar<Operand,Scalar>::Bound >
921  >::type
922 #else
923  <unspecified-expression-type>
924 #endif
925  greater(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
926  return vectorize(detail::GreaterTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
927  }
928 
929  template <typename Operand, typename Scalar>
930 #ifndef DOXYGEN
931  typename boost::enable_if<
932  typename ExpressionTraits<Scalar>::IsScalar,
933  detail::UnaryOpExpression< Operand, typename detail::GreaterTag::template ScalarExpr<Operand,Scalar>::Bound >
934  >::type
935 #else
936  <unspecified-expression-type>
937 #endif
938  greater(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
939  return vectorize(detail::GreaterTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
940  }
941 
942  template <typename Operand1, typename Operand2>
943 #ifndef DOXYGEN
944  detail::BinaryOpExpression<
945  Operand1, Operand2,
946  typename detail::GreaterTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
947  >
948 #else
949  <unspecified-expression-type>
950 #endif
951  greater(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
952  return vectorize(
953  typename detail::GreaterTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
954  operand1,
955  operand2
956  );
957  }
958 
959  template <typename Operand, typename Scalar>
960 #ifndef DOXYGEN
961  typename boost::enable_if<
962  typename ExpressionTraits<Scalar>::IsScalar,
963  detail::UnaryOpExpression< Operand, typename detail::LessEqualTag::template ExprScalar<Operand,Scalar>::Bound >
964  >::type
965 #else
966  <unspecified-expression-type>
967 #endif
968  less_equal(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
969  return vectorize(detail::LessEqualTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
970  }
971 
972  template <typename Operand, typename Scalar>
973 #ifndef DOXYGEN
974  typename boost::enable_if<
975  typename ExpressionTraits<Scalar>::IsScalar,
976  detail::UnaryOpExpression< Operand, typename detail::LessEqualTag::template ScalarExpr<Operand,Scalar>::Bound >
977  >::type
978 #else
979  <unspecified-expression-type>
980 #endif
981  less_equal(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
982  return vectorize(detail::LessEqualTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
983  }
984 
985  template <typename Operand1, typename Operand2>
986 #ifndef DOXYGEN
987  detail::BinaryOpExpression<
988  Operand1, Operand2,
989  typename detail::LessEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
990  >
991 #else
992  <unspecified-expression-type>
993 #endif
994  less_equal(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
995  return vectorize(
996  typename detail::LessEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
997  operand1,
998  operand2
999  );
1000  }
1001 
1002  template <typename Operand, typename Scalar>
1003 #ifndef DOXYGEN
1004  typename boost::enable_if<
1005  typename ExpressionTraits<Scalar>::IsScalar,
1006  detail::UnaryOpExpression< Operand, typename detail::GreaterEqualTag::template ExprScalar<Operand,Scalar>::Bound >
1007  >::type
1008 #else
1009  <unspecified-expression-type>
1010 #endif
1011  great_equal(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
1012  return vectorize(detail::GreaterEqualTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
1013  }
1014 
1015  template <typename Operand, typename Scalar>
1016 #ifndef DOXYGEN
1017  typename boost::enable_if<
1018  typename ExpressionTraits<Scalar>::IsScalar,
1019  detail::UnaryOpExpression< Operand, typename detail::GreaterEqualTag::template ScalarExpr<Operand,Scalar>::Bound >
1020  >::type
1021 #else
1022  <unspecified-expression-type>
1023 #endif
1024  great_equal(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
1025  return vectorize(detail::GreaterEqualTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
1026  }
1027 
1028  template <typename Operand1, typename Operand2>
1029 #ifndef DOXYGEN
1030  detail::BinaryOpExpression<
1031  Operand1, Operand2,
1032  typename detail::GreaterEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
1033  >
1034 #else
1035  <unspecified-expression-type>
1036 #endif
1037  great_equal(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
1038  return vectorize(
1039  typename detail::GreaterEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1040  operand1,
1041  operand2
1042  );
1043  }
1044 
1045  template <typename Operand, typename Scalar>
1046 #ifndef DOXYGEN
1047  typename boost::enable_if<
1048  typename ExpressionTraits<Scalar>::IsScalar,
1049  detail::UnaryOpExpression< Operand, typename detail::LogicalAnd::template ExprScalar<Operand,Scalar>::Bound >
1050  >::type
1051 #else
1052  <unspecified-expression-type>
1053 #endif
1054  logical_and(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
1055  return vectorize(detail::LogicalAnd::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
1056  }
1057 
1058  template <typename Operand, typename Scalar>
1059 #ifndef DOXYGEN
1060  typename boost::enable_if<
1061  typename ExpressionTraits<Scalar>::IsScalar,
1062  detail::UnaryOpExpression< Operand, typename detail::LogicalAnd::template ScalarExpr<Operand,Scalar>::Bound >
1063  >::type
1064 #else
1065  <unspecified-expression-type>
1066 #endif
1067  logical_and(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
1068  return vectorize(detail::LogicalAnd::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
1069  }
1070 
1071  template <typename Operand1, typename Operand2>
1072 #ifndef DOXYGEN
1073  detail::BinaryOpExpression<
1074  Operand1, Operand2,
1075  typename detail::LogicalAnd::template ExprExpr<Operand1,Operand2>::BinaryFunction
1076  >
1077 #else
1078  <unspecified-expression-type>
1079 #endif
1080  logical_and(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
1081  return vectorize(
1082  typename detail::LogicalAnd::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1083  operand1,
1084  operand2
1085  );
1086  }
1087 
1088  template <typename Operand, typename Scalar>
1089 #ifndef DOXYGEN
1090  typename boost::enable_if<
1091  typename ExpressionTraits<Scalar>::IsScalar,
1092  detail::UnaryOpExpression< Operand, typename detail::LogicalOr::template ExprScalar<Operand,Scalar>::Bound >
1093  >::type
1094 #else
1095  <unspecified-expression-type>
1096 #endif
1097  logical_or(ExpressionBase<Operand> const & operand, Scalar const & scalar) {
1098  return vectorize(detail::LogicalOr::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
1099  }
1100 
1101  template <typename Operand, typename Scalar>
1102 #ifndef DOXYGEN
1103  typename boost::enable_if<
1104  typename ExpressionTraits<Scalar>::IsScalar,
1105  detail::UnaryOpExpression< Operand, typename detail::LogicalOr::template ScalarExpr<Operand,Scalar>::Bound >
1106  >::type
1107 #else
1108  <unspecified-expression-type>
1109 #endif
1110  logical_or(Scalar const & scalar, ExpressionBase<Operand> const & operand) {
1111  return vectorize(detail::LogicalOr::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
1112  }
1113 
1114  template <typename Operand1, typename Operand2>
1115 #ifndef DOXYGEN
1116  detail::BinaryOpExpression<
1117  Operand1, Operand2,
1118  typename detail::LogicalOr::template ExprExpr<Operand1,Operand2>::BinaryFunction
1119  >
1120 #else
1121  <unspecified-expression-type>
1122 #endif
1123  logical_or(ExpressionBase<Operand1> const & operand1, ExpressionBase<Operand2> const & operand2) {
1124  return vectorize(
1125  typename detail::LogicalOr::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1126  operand1,
1127  operand2
1128  );
1129  }
1130 
1131 
1132  template <typename Operand>
1133 #ifndef DOXYGEN
1134  detail::UnaryOpExpression< Operand, std::negate<typename ExpressionTraits<Operand>::Element> >
1135 #else
1136  <unspecified-expression-type>
1137 #endif
1139  return vectorize(std::negate<typename ExpressionTraits<Operand>::Element>(),operand);
1140  }
1141 
1142  template <typename Operand>
1143 #ifndef DOXYGEN
1144  detail::UnaryOpExpression< Operand, std::logical_not<typename ExpressionTraits<Operand>::Element> >
1145 #else
1146  <unspecified-expression-type>
1147 #endif
1150  }
1151 
1152  template <typename Operand>
1153 #ifndef DOXYGEN
1154  detail::UnaryOpExpression< Operand, detail::BitwiseNot<typename ExpressionTraits<Operand>::Element> >
1155 #else
1156  <unspecified-expression-type>
1157 #endif
1159  return vectorize(detail::BitwiseNot<typename ExpressionTraits<Operand>::Element>(),operand);
1160  }
1162 
1163 template <typename Scalar>
1164 inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar, bool>::type
1165 any(Scalar const & scalar) {
1166  return bool(scalar);
1167 }
1168 
1174 template <typename Derived>
1175 inline bool
1177  typename Derived::Iterator const i_end = expr.end();
1178  for (typename Derived::Iterator i = expr.begin(); i != i_end; ++i) {
1179  if (any(*i)) return true;
1180  }
1181  return false;
1182 }
1183 
1184 template <typename Scalar>
1185 inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar, bool>::type
1186 all(Scalar const & scalar) {
1187  return bool(scalar);
1188 }
1189 
1195 template <typename Derived>
1196 inline bool
1198  typename Derived::Iterator const i_end = expr.end();
1199  for (typename Derived::Iterator i = expr.begin(); i != i_end; ++i) {
1200  if (!all(*i)) return false;
1201  }
1202  return true;
1203 }
1204 
1205 template <typename Scalar1, typename Scalar2>
1206 inline typename boost::enable_if<
1207  boost::mpl::and_<
1208  typename ExpressionTraits<Scalar1>::IsScalar,
1209  typename ExpressionTraits<Scalar2>::IsScalar
1210  >,
1211  bool
1212 >::type
1213 allclose(Scalar1 const & scalar1, Scalar2 const & scalar2, double tol=1E-8) {
1215  return func(scalar1, scalar2);
1216 }
1217 
1218 template <typename Scalar, typename Derived>
1219 inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar,bool>::type
1220 allclose(Scalar const & scalar, ExpressionBase<Derived> const & expr, double tol=1E-8) {
1222  typename Derived::Iterator const i_end = expr.end();
1223  for (typename Derived::Iterator i = expr.begin(); i != i_end; ++i) {
1224  if (!allclose(scalar, *i, tol)) return false;
1225  }
1226  return true;
1227 }
1228 
1229 template <typename Scalar, typename Derived>
1230 inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar,bool>::type
1231 allclose(ExpressionBase<Derived> const & expr, Scalar const & scalar, double tol=1E-8) {
1232  return allclose(scalar, expr, tol);
1233 }
1234 
1235 template <typename Derived1, typename Derived2>
1236 inline bool
1237 allclose(ExpressionBase<Derived1> const & expr1, ExpressionBase<Derived2> const & expr2, double tol=1E-8) {
1238  typename Derived1::Iterator const i_end = expr1.end();
1239  typename Derived1::Iterator i = expr1.begin();
1240  typename Derived2::Iterator j = expr2.begin();
1241  for (; i != i_end; ++i, ++j) {
1242  if (!allclose(*i, *j, tol)) return false;
1243  }
1244  return true;
1245 }
1246 
1247 
1248 template <typename Scalar>
1249 inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar, Scalar>::type
1250 sum(Scalar const & scalar) { return scalar; }
1251 
1252 
1258 template <typename Derived>
1259 inline typename Derived::Element
1261  typename Derived::Iterator const i_end = expr.end();
1262  typename Derived::Element total = static_cast<typename Derived::Element>(0);
1263  for (typename Derived::Iterator i = expr.begin(); i != i_end; ++i) {
1264  total += sum(*i);
1265  }
1266  return total;
1267 }
1268 
1269 
1270 } // namespace ndarray
1271 
1272 #endif // !NDARRAY_operators_h_INCLUDED
boost::enable_if< boost::mpl::and_< typename ExpressionTraits< Scalar1 >::IsScalar, typename ExpressionTraits< Scalar2 >::IsScalar >, bool >::type allclose(Scalar1 const &scalar1, Scalar2 const &scalar2, double tol=1E-8)
Definition: operators.h:1213
< unspecified-expression-type > operator-(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:408
< unspecified-expression-type > not_equal(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:839
< unspecified-expression-type > less(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:882
< unspecified-expression-type > logical_and(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:1054
< unspecified-expression-type > operator~(ExpressionBase< Operand > const &operand)
Definition: operators.h:1158
< unspecified-expression-type > operator/(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:494
< unspecified-expression-type > less_equal(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:968
< unspecified-expression-type > greater(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:925
< unspecified-expression-type > operator+(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:365
Definitions for Array.
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, bool >::type all(Scalar const &scalar)
Definition: operators.h:1186
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, Scalar >::type sum(Scalar const &scalar)
Definition: operators.h:1250
Binary predicate for floating point equality comparison with tolerance.
Definition: types.h:149
Lazy binary expression templates.
Numeric type traits.
< unspecified-expression-type > great_equal(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:1011
Traits for expressions.
< unspecified-expression-type > operator*(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:451
Lazy unary expression templates.
< unspecified-expression-type > operator^(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:580
< unspecified-expression-type > operator%(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:537
UnaryFunction::result_type vectorize(UnaryFunction const &functor, Scalar const &scalar)
Apply a non-mutating unary function object to a scalar.
Definition: vectorize.h:85
Iterator begin() const
Return an Iterator to the beginning of the expression.
< unspecified-expression-type > equal(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:796
< unspecified-expression-type > logical_not(ExpressionBase< Operand > const &operand)
Definition: operators.h:1148
< unspecified-expression-type > logical_or(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:1097
Iterator end() const
Return an Iterator to one past the end of the expression.
< unspecified-expression-type > operator&(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:666
afw::table::Key< double > b
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, bool >::type any(Scalar const &scalar)
Definition: operators.h:1165
< unspecified-expression-type > operator|(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:623
< unspecified-expression-type > operator>>(ExpressionBase< Operand > const &operand, Scalar const &scalar)
Definition: operators.h:752
CRTP base class for all multidimensional expressions.