1/*
2 * Point_operators.hpp
3 *
4 * Created on: Jun 14, 2016
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_SPACE_SHAPE_POINT_OPERATORS_HPP_
9#define OPENFPM_DATA_SRC_SPACE_SHAPE_POINT_OPERATORS_HPP_
10
11#include "util/multi_array_openfpm/array_openfpm.hpp"
12
13template<unsigned int dim ,typename T> class Point;
14
15#define POINT_SUM 1
16#define POINT_SUB 2
17#define POINT_MUL 3
18#define POINT_DIV 4
19#define POINT_MUL_POINT 5
20#define POINT_NORM 6
21#define POINT_NORM2 7
22
23// Functions
24
25#define POINT_ABS 8
26#define POINT_EXP 9
27#define POINT_EXP2 10
28#define POINT_EXPM1 11
29#define POINT_LOG 12
30#define POINT_LOG10 13
31#define POINT_LOG2 14
32#define POINT_LOG1P 15
33#define POINT_SQRT 17
34#define POINT_CBRT 18
35#define POINT_SIN 19
36#define POINT_COS 20
37#define POINT_TAN 21
38#define POINT_ASIN 22
39#define POINT_ACOS 23
40#define POINT_ATAN 24
41#define POINT_SINH 25
42#define POINT_COSH 26
43#define POINT_TANH 27
44#define POINT_ASINH 28
45#define POINT_ACOSH 29
46#define POINT_ATANH 30
47#define POINT_ERF 31
48#define POINT_ERFC 32
49#define POINT_TGAMMA 33
50#define POINT_LGAMMA 34
51#define POINT_CEIL 35
52#define POINT_FLOOR 36
53#define POINT_TRUNC 37
54#define POINT_ROUND 38
55#define POINT_NEARBYINT 39
56#define POINT_RINT 40
57#define POINT_SUB_UNI 41
58
59/////////////////// Best cast rules ////////////////////////
60
61template<typename source1, typename source2>
62struct best_conv
63{
64 typedef source1 type;
65};
66
67
68template<typename source2>
69struct best_conv<int,source2>
70{
71 typedef source2 type;
72};
73
74template<typename source2>
75struct best_conv<long int,source2>
76{
77 typedef source2 type;
78};
79
80template<typename source2>
81struct best_conv<unsigned int,source2>
82{
83 typedef source2 type;
84};
85
86template<typename source2>
87struct best_conv<unsigned long int,source2>
88{
89 typedef source2 type;
90};
91
92template<typename source1>
93struct best_conv<source1,int>
94{
95 typedef source1 type;
96};
97
98template<typename source1>
99struct best_conv<source1,long int>
100{
101 typedef source1 type;
102};
103
104template<typename source1>
105struct best_conv<source1,unsigned int>
106{
107 typedef source1 type;
108};
109
110template<typename source1>
111struct best_conv<source1,unsigned long int>
112{
113 typedef source1 type;
114};
115
116///////////////////////////////////////////////////////////////
117
118constexpr unsigned int max_expr(unsigned int dim1, unsigned int dim2)
119{
120 return (dim1 > dim2)?dim1:dim2;
121}
122
123/*! \brief It return the dimansionality of the operation given the dimensionality of the 2 operators
124 *
125 * this is the default that return 3
126 *
127 * \tparam op1_dim dimansionality operator1
128 * \tparam op2_dim dimensionality operator2
129 * \tparam op operation
130 *
131 */
132template <unsigned int op1_dim, unsigned int op2_dim, unsigned int op>
133struct r_type_dim
134{
135 //! bigger vector determine the size of the expression
136 enum
137 {
138 value = max_expr(op1_dim,op2_dim),
139 };
140};
141
142//! scalar + scalar = scalar
143template <>
144struct r_type_dim<1,1,POINT_SUM>
145{
146 //! scalar
147 enum
148 {
149 value = 1,
150 };
151};
152
153//! scalar - scalar = scalar
154template <>
155struct r_type_dim<1,1,POINT_SUB>
156{
157 //! scalar
158 enum
159 {
160 value = 1,
161 };
162};
163
164//! Point * Point = scalar
165template <unsigned int op1_dim, unsigned int op2_dim>
166struct r_type_dim<op1_dim,op2_dim,POINT_MUL_POINT>
167{
168 //! scalar
169 enum
170 {
171 value = 1,
172 };
173};
174
175//! scalar * scalar = scalar
176template <>
177struct r_type_dim<1,1,POINT_MUL>
178{
179 //! scalar
180 enum
181 {
182 value = 1,
183 };
184};
185
186//! scalar / scalar = scalar
187template <>
188struct r_type_dim<1,1,POINT_DIV>
189{
190 //! scalar
191 enum
192 {
193 value = 1,
194 };
195};
196
197/*! \brief Return type of the expression
198 *
199 * \tparam r dimension of the return type
200 * \tparam orig original type
201 *
202 */
203template <unsigned int r, typename orig>
204struct r_type_p
205{
206 //! meta-function return orig or the expression produce a vector
207 typedef orig type;
208};
209
210/*! \brief Return type of the expression
211 *
212 * \tparam orig original type
213 *
214 */
215template <typename orig>
216struct r_type_p<1,orig>
217{
218 //! meta-function return a scalar or the expression produce a scalar
219 typedef typename orig::coord_type type;
220};
221
222
223/*! \brief Main class that encapsulate a constant number used in a point expression
224 *
225 *
226 */
227template<typename T>
228class point_expression
229{
230 //! constant
231 T d;
232
233public:
234
235 //! indicate that init must be called before value
236 typedef int has_init;
237
238 //! indicate that this class encapsulate an expression
239 typedef int is_expression;
240
241 //! this operation produce a vector as result of size dims
242 static const unsigned int nvals = 1;
243
244 /*! \brief constructor from a value
245 *
246 * \param d value
247 *
248 */
249 __device__ __host__ inline point_expression(T & d)
250 :d(d)
251 {}
252
253 /*! \brief This function must be called before value
254 *
255 * it calculate the scalar product before return the values
256 *
257 */
258 __device__ __host__ inline void init() const
259 {
260 }
261
262 /*! \brief Evaluate the expression
263 *
264 * \param k coordinate to evaluate
265 *
266 * \return It just return the velue set in the constructor
267 *
268 */
269 __device__ __host__ inline T value(const size_t k) const
270 {
271 return d;
272 }
273};
274
275
276
277/*! \brief Unknown operation specialization
278 *
279 * \tparam orig original type
280 * \tparam exp1 expression1
281 * \tparam exp2 expression2
282 * \tparam op operation
283 *
284 */
285template <typename orig, typename exp1, typename exp2, unsigned int op>
286class point_expression_op
287{
288
289};
290
291/*! \brief Sum operation
292 *
293 * \tparam orig original type
294 * \tparam exp1 expression1
295 * \tparam exp2 expression2
296 *
297 */
298template <typename orig, typename exp1, typename exp2>
299class point_expression_op<orig,exp1,exp2,POINT_SUM>
300{
301 //! first expression
302 const exp1 o1;
303 //! second expression
304 const exp2 o2;
305
306public:
307
308 //! original type of the point expression
309 typedef orig orig_type;
310
311 //! indicate that this class encapsulate an expression
312 typedef int is_expression;
313
314 //! indicate that init must be called before value
315 typedef int has_init;
316
317 //! return type of the expression
318 typedef typename r_type_p<r_type_dim<exp1::nvals,exp2::nvals,POINT_SUM>::value,orig >::type return_type;
319
320 //! this operation produce a vector as result of size dims
321 static const unsigned int nvals = r_type_dim<exp1::nvals,exp2::nvals,POINT_SUM>::value;
322
323 /*! \brief Constructor from 2 point expressions
324 *
325 * \param o1 expression1
326 * \param o2 expression2
327 *
328 */
329 __device__ __host__ inline point_expression_op(const exp1 & o1, const exp2 & o2)
330 :o1(o1),o2(o2)
331 {}
332
333 /*! \brief This function must be called before value
334 *
335 * it calculate the scalar product before return the values
336 *
337 */
338 __device__ __host__ inline void init() const
339 {
340 o1.init();
341 o2.init();
342 }
343
344 /*! \brief Evaluate the expression at coordinate k
345 *
346 * \param k coordinate
347 *
348 * \return the value of the expression for the coordinate k
349 *
350 */
351 template<typename r_type=typename best_conv<typename std::remove_reference<decltype(o1.value(0))>::type,
352 typename std::remove_reference<decltype(o2.value(0))>::type>::type >
353 __device__ __host__ inline r_type value(size_t k) const
354 {
355 return o1.value(k) + o2.value(k);
356 }
357
358 /*! \brief conversion of the class to double or float or ...
359 *
360 *
361 */
362 template<typename T, typename test=typename boost::disable_if_c< std::is_same<T,orig>::value || exp1::nvals != 1 || exp2::nvals != 1 >::type >
363 __device__ __host__ inline operator T() const
364 {
365 init();
366 return o1.value(0) + o2.value(0);
367 }
368};
369
370/*! \brief Subtraction operation
371 *
372 * \tparam exp1 expression1
373 * \tparam exp2 expression2
374 *
375 */
376template <typename orig,typename exp1, typename exp2>
377class point_expression_op<orig, exp1,exp2,POINT_SUB>
378{
379 //! expression 1
380 const exp1 o1;
381 //! expression 2
382 const exp2 o2;
383
384public:
385
386 //! Original type
387 typedef orig orig_type;
388
389 //! indicate that init must be called before value
390 typedef int has_init;
391
392 //! indicate that this class encapsulate an expression
393 typedef int is_expression;
394
395 //! return type of the expression
396 typedef orig return_type;
397
398 //! this operation produce a vector as result of size dims
399 static const unsigned int nvals = r_type_dim<exp1::nvals,exp2::nvals,POINT_SUB>::value;
400
401 /*! \brief constructor from 2 expressions
402 *
403 * \param o1 expression1
404 * \param o2 expression2
405 *
406 */
407 __device__ __host__ inline point_expression_op(const exp1 & o1, const exp2 & o2)
408 :o1(o1),o2(o2)
409 {}
410
411 /*! \brief This function must be called before value
412 *
413 * it calculate the scalar product before return the values
414 *
415 */
416 __device__ __host__ inline void init() const
417 {
418 o1.init();
419 o2.init();
420 }
421
422 /*! \brief Evaluate the expression at coordinate k
423 *
424 * \param k coordinate
425 *
426 * \return the evaluate expression at coordinate k
427 *
428 */
429 template<typename r_type=typename best_conv<typename std::remove_reference<decltype(o1.value(0))>::type,
430 typename std::remove_reference<decltype(o2.value(0))>::type>::type >
431 __device__ __host__ inline r_type value(size_t k) const
432 {
433 return o1.value(k) - o2.value(k);
434 }
435
436 /*! \brief conversion of the class to double or float or ...
437 *
438 *
439 */
440 template<typename T, typename test=typename boost::disable_if_c< std::is_same<T,orig>::value || exp1::nvals != 1 || exp2::nvals != 1 >::type >
441 __device__ __host__ operator T() const
442 {
443 init();
444 return o1.value(0) - o2.value(0);
445 }
446};
447
448/*! \brief expression that subtract two points
449 *
450 * \tparam orig original vector
451 * \tparam exp1 expression 1
452 * \tparam exp2 expression 2
453 *
454 */
455template <typename orig, typename exp1, typename exp2>
456class point_expression_op<orig,exp1,exp2, POINT_SUB_UNI >
457{
458 //! expression
459 const exp1 o1;
460
461 //! scalar value produced by the expression
462 mutable typename orig::coord_type scal;
463
464public:
465
466 //! original type
467 typedef orig orig_type;
468
469 //! indicate that is an expression
470 typedef int is_expression;
471
472 //! indicate that this class has an init function
473 typedef int has_init;
474
475 //! return type of the expression evaluation
476 typedef typename orig::coord_type return_type;
477
478 //! result dimensionality of this expression
479 static const unsigned int nvals = exp1::nvals;
480
481 /*! constructor from expression
482 *
483 * \param o1 expression1
484 *
485 */
486 __device__ __host__ inline point_expression_op(const exp1 & o1)
487 :o1(o1),scal(0.0)
488 {}
489
490 //! initialize the the expression
491 __device__ __host__ inline void init() const
492 {
493 o1.init();
494 }
495
496 /*! \brief evaluate the expression
497 *
498 * \param k evaluate in k
499 *
500 * \return the result
501 *
502 */
503 template<typename r_type=typename std::remove_reference<decltype(o1.value(0))>::type >
504 __device__ __host__ inline r_type value(size_t k) const
505 {
506 return -(o1.value(k));
507 }
508
509 //! casting to a type T
510 template <typename T, typename check = typename std::enable_if<!std::is_same<T,orig>::value >::type >
511 __device__ __host__ operator T() const
512 {
513 init();
514 return -(o1.value(0));
515 }
516};
517
518
519/*! \brief Multiplication operation
520 *
521 * \tparam orig original type
522 * \tparam exp1 expression1
523 * \tparam exp2 expression2
524 * \tparam op operation
525 *
526 */
527template <typename orig, typename exp1, typename exp2>
528class point_expression_op<orig,exp1,exp2,POINT_MUL_POINT>
529{
530 //! first expression
531 const exp1 o1;
532 //! second expression
533 const exp2 o2;
534
535 //! the expression produce a scalar
536 mutable typename std::remove_const<typename orig::coord_type>::type scal;
537
538public:
539
540 //! base type of the expression
541 typedef orig orig_type;
542
543 //! indicate that init must be called before value
544 typedef int has_init;
545
546 //! indicate that this class encapsulate an expression
547 typedef int is_expression;
548
549 //! return type of the expression
550 typedef typename orig::coord_type return_type;
551
552 //! this operation produce a scalar as result
553 static const unsigned int nvals = 1;
554
555 /*! \brief constructor from 2 expressions
556 *
557 * \param o1 expression 1
558 * \param o2 expression 2
559 *
560 */
561 __device__ __host__ inline point_expression_op(const exp1 & o1, const exp2 & o2)
562 :o1(o1),o2(o2),scal(0.0)
563 {}
564
565 /*! \brief This function must be called before value
566 *
567 * it calculate the scalar product before return the values
568 *
569 */
570 __device__ __host__ inline void init() const
571 {
572 o1.init();
573 o2.init();
574
575 for (size_t i = 0 ; i < orig::dims ; i++)
576 scal += o1.value(i) * o2.value(i);
577 }
578
579 /*! \brief Evaluate the expression
580 *
581 * \param k where to evaluate the expression
582 *
583 * \return the expression value
584 *
585 */
586 template<typename r_type=typename best_conv<typename std::remove_reference<decltype(o1.value(0))>::type,
587 typename std::remove_reference<decltype(o2.value(0))>::type>::type >
588 __device__ __host__ inline r_type value(size_t k) const
589 {
590 return scal;
591 }
592
593 //! cast to other type
594 template<typename T, typename test=typename boost::disable_if_c< std::is_same<T,orig>::value >::type >
595 __device__ __host__ operator T() const
596 {
597 init();
598 return scal;
599 }
600};
601
602
603/*! \brief Multiplication operation
604 *
605 * \tparam orig original type
606 * \tparam exp1 expression1
607 * \tparam exp2 expression2
608 *
609 */
610template <typename orig, typename exp1, typename exp2>
611class point_expression_op<orig,exp1,exp2,POINT_MUL>
612{
613 //! expression 1
614 const exp1 o1;
615 //! expression 2
616 const exp2 o2;
617
618public:
619
620 //! origin type
621 typedef orig orig_type;
622
623 //! indicate that init must be called before value
624 typedef int has_init;
625
626 //! indicate that this class encapsulate an expression
627 typedef int is_expression;
628
629 //! return type of the expression
630 typedef orig return_type;
631
632 //! this operation produce a vector as result of size dims
633 static const unsigned int nvals = r_type_dim<exp1::nvals,exp2::nvals,POINT_MUL>::value;
634
635 /*! \brief constructor from 2 expression
636 *
637 * \param o1 expression 1
638 * \param o2 expression 2
639 *
640 */
641 __device__ __host__ inline point_expression_op(const exp1 & o1, const exp2 & o2)
642 :o1(o1),o2(o2)
643 {}
644
645 /*! \brief This function must be called before value
646 *
647 * it calculate the scalar product before return the values
648 *
649 */
650 __device__ __host__ inline void init() const
651 {
652 o1.init();
653 o2.init();
654 }
655
656 /*! \brief Evaluate the expression
657 *
658 * \param key where to evaluate the expression
659 *
660 */
661 template<typename r_type=typename best_conv<typename std::remove_reference<decltype(o1.value(0))>::type,
662 typename std::remove_reference<decltype(o2.value(0))>::type>::type >
663 __device__ __host__ inline r_type value(size_t k) const
664 {
665 return o1.value(k) * o2.value(k);
666 }
667
668 /*! \brief conversion of the class to double or float or ...
669 *
670 *
671 */
672 template<typename T, typename test=typename boost::disable_if_c< std::is_same<T,orig>::value || exp1::nvals != 1 || exp2::nvals != 1 >::type >
673 __device__ __host__ operator T() const
674 {
675 init();
676 return o1.value(0) * o2.value(0);
677 }
678
679};
680
681/*! \brief Division operation
682 *
683 * \tparam exp1 expression1
684 * \tparam exp2 expression2
685 *
686 */
687template <typename orig, typename exp1, typename exp2>
688class point_expression_op<orig,exp1,exp2,POINT_DIV>
689{
690 //! expression 1
691 const exp1 o1;
692 //! expression 2
693 const exp2 o2;
694
695public:
696
697 //! original type
698 typedef orig orig_type;
699
700 //! indicate that this class encapsulate an expression
701 typedef int is_expression;
702
703 //! indicate that init must be called before value
704 typedef int has_init;
705
706 //! return type of the expression
707 typedef orig return_type;
708
709 //! this operation produce a vector as result of size dims
710 static const unsigned int nvals = r_type_dim<exp1::nvals,exp2::nvals,POINT_DIV>::value;
711
712 /*! \brief constructor from expression 1 and expression 2
713 *
714 * \param o1 expression 1
715 * \param o2 expression 2
716 *
717 */
718 __device__ __host__ inline point_expression_op(const exp1 & o1, const exp2 & o2)
719 :o1(o1),o2(o2)
720 {}
721
722 /*! \brief This function must be called before value
723 *
724 * it calculate the scalar product before return the values
725 *
726 */
727 __device__ __host__ inline void init() const
728 {
729 o1.init();
730 o2.init();
731 }
732
733 /*! \brief Evaluate the expression
734 *
735 * \param k where to evaluate the expression
736 *
737 * \return the value of the expression
738 *
739 */
740 template<typename r_type=typename best_conv<typename std::remove_reference<decltype(o1.value(0))>::type,
741 typename std::remove_reference<decltype(o2.value(0))>::type>::type >
742 __device__ __host__ inline r_type value(size_t k) const
743 {
744 return o1.value(k) / o2.value(k);
745 }
746
747
748 /*! \brief conversion of the class to double or float or ...
749 *
750 *
751 */
752 template<typename T, typename test=typename boost::disable_if_c< std::is_same<T,orig>::value || exp1::nvals != 1 || exp2::nvals != 1 >::type > __device__ __host__ operator T() const
753 {
754 init();
755 return o1.value(0) / o2.value(0);
756 }
757};
758
759/*! \brief Transform an array into a point expression
760 *
761 * \param array
762 *
763 * \return an object that can be used into an expression
764 *
765 */
766template<unsigned int dim, typename T> __device__ __host__ point_expression<T[dim]> getExprL(T (& a)[dim])
767{
768 return point_expression<T[dim]>(a);
769}
770
771/*! \brief Transform an array into a point expression
772 *
773 * \param array
774 *
775 * \return an object that can be used into an expression
776 *
777 */
778template<unsigned int dim, typename T> __device__ __host__ point_expression<const T[dim]> getExprR(T (& a)[dim])
779{
780 return point_expression<const T[dim]>(a);
781}
782
783template<unsigned int dim, typename T>
784struct ger
785{
786 template<typename vmpl> __device__ __host__
787 __device__ __host__ static point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>
788 getExprR(const openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl> & a)
789 {
790 return point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>(a);
791 }
792
793 __device__ __host__ static point_expression<const T[dim]>
794 getExprR(T (& a)[dim])
795 {
796 return point_expression<const T[dim]>(a);
797 }
798
799 template<typename vmpl> __device__ __host__
800 __device__ __host__ static point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>
801 getExprL(const openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl> & a)
802 {
803 return point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>(a);
804 }
805
806 __device__ __host__ static point_expression<T[dim]>
807 getExprL(T (& a)[dim])
808 {
809 return point_expression<T[dim]>(a);
810 }
811};
812
813
814/*! \brief MACRO that define operator for point template expression parsing
815 *
816 *
817 */
818
819#define CREATE_POINT_OPERATOR(operator_name,OP_ID) \
820\
821\
822template<unsigned int dim, typename T>\
823__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<const T[dim]>,OP_ID>\
824operator_name(const Point<dim,T> & va, const point_expression<const T[(unsigned int)dim]> & vb)\
825{\
826 point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<const T[dim]>,OP_ID> exp_sum(va,vb);\
827\
828 return exp_sum;\
829}\
830\
831template<unsigned int dim, typename T, typename vmpl>\
832__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,OP_ID>\
833operator_name(const Point<dim,T> & va, const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & vb)\
834{\
835 point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,OP_ID> exp_sum(va,vb);\
836\
837 return exp_sum;\
838}\
839\
840template<unsigned int dim, typename T>\
841__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<const T[dim]>,Point<dim,T>,OP_ID>\
842operator_name(const point_expression<const T[(unsigned int)dim]> & va, const Point<dim,T> & vb)\
843{\
844 point_expression_op<Point<dim,T>,point_expression<const T[dim]>,Point<dim,T>,OP_ID> exp_sum(va,vb);\
845\
846 return exp_sum;\
847}\
848\
849template<unsigned int dim, typename T, typename vmpl>\
850__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,Point<dim,T>,OP_ID>\
851operator_name(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va,\
852 const Point<dim,T> & vb)\
853{\
854 point_expression_op<Point<dim,T>,point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,Point<dim,T>,OP_ID> exp_sum(va,vb);\
855\
856 return exp_sum;\
857}\
858\
859template<unsigned int dim, typename T>\
860__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<const T[dim]>,point_expression<double>,OP_ID>\
861operator_name(const point_expression<const T[dim]> & va, double d)\
862{\
863 point_expression_op<Point<dim,T>,point_expression<const T[dim]>,point_expression<double>,OP_ID> exp_sum(va,point_expression<double>(d));\
864\
865 return exp_sum;\
866}\
867\
868template<typename T, typename vmpl>\
869__device__ __host__ inline point_expression_op<Point<subar_dim<vmpl>::type::value,T>,\
870 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
871 point_expression<double>,\
872 OP_ID>\
873operator_name(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va, double d)\
874{\
875 point_expression_op<Point<subar_dim<vmpl>::type::value,T>,\
876 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
877 point_expression<double>,\
878 OP_ID>\
879 exp_sum(va,point_expression<double>(d));\
880\
881 return exp_sum;\
882}\
883\
884template<unsigned int dim, typename T>\
885__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<double>,point_expression<const T[dim]>,OP_ID>\
886operator_name(double d, const point_expression<const T[dim]> & va)\
887{\
888 point_expression_op<Point<dim,T>,point_expression<double>,point_expression<const T[dim]>,OP_ID> exp_sum(point_expression<double>(d),va);\
889\
890 return exp_sum;\
891}\
892\
893template<typename T, typename vmpl>\
894__device__ __host__ inline point_expression_op<Point<subar_dim<vmpl>::type::value,T>,\
895 point_expression<double>,\
896 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
897 OP_ID>\
898operator_name(double d, const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va)\
899{\
900 point_expression_op<Point<subar_dim<vmpl>::type::value,T>,\
901 point_expression<double>,\
902 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
903 OP_ID>\
904 exp_sum(point_expression<double>(d),va);\
905\
906 return exp_sum;\
907}\
908\
909template<unsigned int dim, typename T>\
910__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<const T[dim]>,point_expression<const T[dim]>,OP_ID>\
911operator_name(const point_expression<const T[dim]> & va, const point_expression<const T[dim]> & vb)\
912{\
913 point_expression_op<Point<dim,T>,point_expression<const T[dim]>,point_expression<const T[dim]>,OP_ID> exp_sum(va,vb);\
914\
915 return exp_sum;\
916}\
917\
918template<typename T, typename vmpl>\
919__device__ __host__ inline point_expression_op<Point<subar_dim<vmpl>::type::value,T>,\
920 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
921 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
922 OP_ID>\
923operator_name(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va,\
924 const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & vb)\
925{\
926 point_expression_op<Point<subar_dim<vmpl>::type::value,T>,\
927 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
928 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
929 OP_ID> exp_sum(va,vb);\
930\
931 return exp_sum;\
932}\
933\
934template<unsigned int dim, typename T>\
935__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<const T[dim]>,point_expression<T[dim]>,OP_ID>\
936operator_name(const point_expression<const T[dim]> & va, const point_expression<T[dim]> & vb)\
937{\
938 point_expression_op<Point<dim,T>,point_expression<const T[dim]>,point_expression<T[dim]>,OP_ID> exp_sum(va,vb);\
939\
940 return exp_sum;\
941}\
942\
943template<typename orig, typename exp1 , typename exp2, unsigned int op1, unsigned int dim, typename T>\
944__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T[dim]>,OP_ID>\
945operator_name(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression<T[dim]> & vb)\
946{\
947 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T[dim]>,OP_ID> exp_sum(va,vb);\
948\
949 return exp_sum;\
950}\
951\
952template<typename orig, typename exp1 , typename exp2, unsigned int op1, typename T, typename vmpl>\
953__device__ __host__ inline point_expression_op<orig,\
954 point_expression_op<orig,exp1,exp2,op1>,\
955 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
956 OP_ID>\
957operator_name(const point_expression_op<orig,exp1,exp2,op1> & va,\
958 const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & vb)\
959{\
960 point_expression_op<orig,\
961 point_expression_op<orig,exp1,exp2,op1>,\
962 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
963 OP_ID> exp_sum(va,vb);\
964\
965 return exp_sum;\
966}\
967\
968template<typename orig, typename exp1 , typename exp2, unsigned int op1, unsigned int dim, typename T>\
969__device__ __host__ inline point_expression_op<orig,point_expression<T[dim]>,point_expression_op<orig,exp1,exp2,op1>,OP_ID>\
970operator_name(const point_expression<T[dim]> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)\
971{\
972 point_expression_op<orig,point_expression<T[dim]>,point_expression_op<orig,exp1,exp2,op1>,OP_ID> exp_sum(va,vb);\
973\
974 return exp_sum;\
975}\
976\
977template<typename orig, typename exp1 , typename exp2, unsigned int op1, typename T, typename vmpl>\
978__device__ __host__ inline point_expression_op<orig,\
979 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
980 point_expression_op<orig,exp1,exp2,op1>,\
981 OP_ID>\
982operator_name(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va,\
983 const point_expression_op<orig,exp1,exp2,op1> & vb)\
984{\
985 point_expression_op<orig,\
986 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,\
987 point_expression_op<orig,exp1,exp2,op1>,\
988 OP_ID> exp_sum(va,vb);\
989\
990 return exp_sum;\
991}\
992\
993\
994template<unsigned int dim, typename T>\
995__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,Point<dim,T>,OP_ID>\
996operator_name(const Point<dim,T> & va, const Point<dim,T> & vb)\
997{\
998 point_expression_op<Point<dim,T>,Point<dim,T>,Point<dim,T>,OP_ID> exp_sum(va,vb);\
999\
1000 return exp_sum;\
1001}\
1002\
1003template<typename orig, typename exp1 , typename exp2, unsigned int op1, unsigned int dim, typename T>\
1004__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,OP_ID>\
1005operator_name(const point_expression_op<orig,exp1,exp2,op1> & va, const Point<dim,T> & vb)\
1006{\
1007 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,OP_ID> exp_sum(va,vb);\
1008\
1009 return exp_sum;\
1010}\
1011\
1012template<typename orig,typename exp1 , typename exp2, unsigned int op1, unsigned int dim, typename T>\
1013__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,OP_ID>\
1014operator_name(const Point<dim,T> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)\
1015{\
1016 point_expression_op<Point<dim,T>,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,OP_ID> exp_sum(va,vb);\
1017\
1018 return exp_sum;\
1019}\
1020\
1021template<typename orig, typename exp1 , typename exp2, unsigned int op1, typename T>\
1022__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T>,OP_ID>\
1023operator_name(const point_expression_op<orig,exp1,exp2,op1> & va, T d)\
1024{\
1025 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T>,OP_ID> exp_sum(va,d);\
1026\
1027 return exp_sum;\
1028}\
1029\
1030template<typename orig,typename exp1 , typename exp2, unsigned int op1, typename T>\
1031__device__ __host__ inline point_expression_op<orig,point_expression<T>,point_expression_op<orig,exp1,exp2,op1>,OP_ID>\
1032operator_name(T d, const point_expression_op<orig,exp1,exp2,op1> & vb)\
1033{\
1034 point_expression_op<orig,point_expression<T>,point_expression_op<orig,exp1,exp2,op1>,OP_ID> exp_sum(d,vb);\
1035\
1036 return exp_sum;\
1037}\
1038\
1039template<typename orig,typename exp1 , typename exp2, unsigned int op1, typename exp3 , typename exp4, unsigned int op2>\
1040__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,OP_ID>\
1041operator_name(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression_op<orig,exp3,exp4,op2> & vb)\
1042{\
1043 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,OP_ID> exp_sum(va,vb);\
1044\
1045 return exp_sum;\
1046}\
1047\
1048template<unsigned int dim , typename T, typename check=typename std::enable_if< !std::is_same<T,double>::value >::type >\
1049__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<T>,OP_ID>\
1050operator_name(const Point<dim,T> & va, T d)\
1051{\
1052 point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<T>,OP_ID> exp_sum(va,point_expression<T>(d));\
1053\
1054 return exp_sum;\
1055}\
1056\
1057template<unsigned int dim , typename T>\
1058__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<double>,OP_ID>\
1059operator_name(const Point<dim,T> & va, double d)\
1060{\
1061 point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<double>,OP_ID> exp_sum(va,point_expression<double>(d));\
1062\
1063 return exp_sum;\
1064}\
1065\
1066template<unsigned int dim , typename T, typename check=typename std::enable_if< !std::is_same<T,double>::value >::type >\
1067__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<T>,Point<dim,T>,OP_ID>\
1068operator_name(T d, const Point<dim,T> & vb)\
1069{\
1070 point_expression_op<Point<dim,T>,point_expression<T>,Point<dim,T>,OP_ID> exp_sum(point_expression<T>(d),vb);\
1071\
1072 return exp_sum;\
1073}\
1074\
1075template<unsigned int dim, typename T, typename check=typename std::enable_if< !std::is_same<T,double>::value >::type>\
1076__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<T[dim]>,Point<dim,T>,OP_ID>\
1077operator_name(T (& d)[dim], const Point<dim,T> & vb)\
1078{\
1079 point_expression_op<Point<dim,T>,point_expression<T[dim]>,Point<dim,T>,OP_ID> exp_sum(point_expression<T[dim]>(d),vb);\
1080\
1081 return exp_sum;\
1082}\
1083\
1084template<unsigned int dim , typename T>\
1085__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<double>,Point<dim,T>,OP_ID>\
1086operator_name(double d, const Point<dim,T> & vb)\
1087{\
1088 point_expression_op<Point<dim,T>,point_expression<double>,Point<dim,T>,OP_ID> exp_sum(point_expression<double>(d),vb);\
1089\
1090 return exp_sum;\
1091}\
1092\
1093template<typename orig, typename exp1 , typename exp2, unsigned int op1, typename T, typename check=typename std::enable_if< !std::is_same<T,double>::value >::type >\
1094__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T>,OP_ID>\
1095operator_name(const point_expression_op<orig,exp1,exp2,op1> & va, T d)\
1096{\
1097 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T>,OP_ID> exp_sum(va,point_expression<T>(d));\
1098\
1099 return exp_sum;\
1100}\
1101\
1102template<typename orig, typename exp1 , typename exp2, unsigned int op1, typename T>\
1103__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<double>,OP_ID>\
1104operator_name(const point_expression_op<orig,exp1,exp2,op1> & va, double d)\
1105{\
1106 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<double>,OP_ID> exp_sum(va,point_expression<double>(d));\
1107\
1108 return exp_sum;\
1109}
1110
1111
1112CREATE_POINT_OPERATOR(operator+,POINT_SUM)
1113CREATE_POINT_OPERATOR(operator-,POINT_SUB)
1114CREATE_POINT_OPERATOR(operator/,POINT_DIV)
1115
1116/* \brief sum two points expression
1117 *
1118 * \param va point expression one
1119 * \param vb point expression two
1120 *
1121 * \return an object that encapsulate the expression
1122 *
1123 */
1124template<typename orig, typename exp1 , typename exp2, unsigned int op1, typename T, typename check=typename std::enable_if< ! std::is_same<T,orig>::value >::type >
1125__device__ __host__ inline T &
1126operator+=(T & d, const point_expression_op<orig,exp1,exp2,op1> & va)
1127{
1128 va.init();
1129 d += va.value(0);
1130
1131 return d;
1132}
1133
1134
1135
1136/* \brief sum two points expression
1137 *
1138 * \param va point expression one
1139 * \param vb point expression two
1140 *
1141 * \return an object that encapsulate the expression
1142 *
1143 */
1144template<typename orig, typename exp1 , typename exp2, unsigned int op1, typename T>
1145__device__ __host__ inline T &
1146operator+=(orig & d, const point_expression_op<orig,exp1,exp2,op1> & va)
1147{
1148 va.init();
1149
1150 d = d + va;
1151
1152 return d;
1153}
1154
1155/* \brief minus points expression
1156 *
1157 * \param va point expression one
1158 *
1159 * \return an object that encapsulate the expression
1160 *
1161 */
1162template<typename orig, typename exp1, typename exp2, unsigned int op1>
1163__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,void, POINT_SUB_UNI >
1164operator-(const point_expression_op<orig,exp1,exp2,op1> & va)
1165{
1166 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,void,POINT_SUB_UNI> exp_sum(va);
1167
1168 return exp_sum;
1169}
1170
1171/* \brief minus points expression
1172 *
1173 * \param va point expression one
1174 *
1175 * \return an object that encapsulate the expression
1176 *
1177 */
1178template<unsigned int dim, typename T>
1179__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,void, POINT_SUB_UNI >
1180operator-(const Point<dim,T> & va)
1181{
1182 point_expression_op<Point<dim,T>,Point<dim,T>,void,POINT_SUB_UNI> exp_sum(va);
1183
1184 return exp_sum;
1185}
1186
1187
1188///////////////////// DEFINITION OF THE OPERATOR* (Note * is scalar product) ////////////////
1189///////////////////// This is the reason why we do not use CREATE_POINT_OPERATOR ////////////
1190///////////////// Template expression parsing ///////////////////////////////////////////////
1191
1192
1193template<unsigned int dim, typename T>
1194__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<T[dim]>,point_expression<double>,POINT_MUL>
1195operator*(const point_expression<T[dim]> & va, double d)
1196{
1197 point_expression_op<Point<dim,T>,point_expression<T[dim]>,point_expression<double>,POINT_MUL> exp_sum(va,point_expression<double>(d));
1198
1199 return exp_sum;
1200}
1201
1202template<typename T, typename vmpl>
1203__device__ __host__ inline point_expression_op<Point<subar_dim<vmpl>::type::value,T>,
1204 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1205 point_expression<double>,
1206 POINT_MUL>
1207operator*(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va,
1208 double d)
1209{
1210 point_expression_op<Point<subar_dim<vmpl>::type::value,T>,
1211 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1212 point_expression<double>,
1213 POINT_MUL> exp_sum(va,point_expression<double>(d));
1214
1215 return exp_sum;
1216}
1217
1218template<unsigned int dim, typename T>
1219__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<double>,point_expression<T[dim]>,POINT_MUL>
1220operator*(double d,
1221 const point_expression<T[dim]> & va)
1222{
1223 point_expression_op<Point<dim,T>,point_expression<double>,point_expression<T[dim]>,POINT_MUL> exp_sum(point_expression<double>(d),va);
1224
1225 return exp_sum;
1226}
1227
1228template<typename T, typename vmpl>
1229__device__ __host__ inline point_expression_op<Point<subar_dim<vmpl>::type::value,T>,
1230 point_expression<double>,
1231 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1232 POINT_MUL>
1233operator*(double d,
1234 const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va)
1235{
1236 point_expression_op<Point<subar_dim<vmpl>::type::value,T>,
1237 point_expression<double>,
1238 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1239 POINT_MUL> exp_sum(point_expression<double>(d),va);
1240
1241 return exp_sum;
1242}
1243
1244template<unsigned int dim, typename T>
1245__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<T[dim]>,point_expression<T[dim]>,POINT_MUL_POINT>
1246operator*(const point_expression<T[dim]> & va, const point_expression<T[dim]> & vb)
1247{
1248 point_expression_op<Point<dim,T>,point_expression<T[dim]>,point_expression<T[dim]>,POINT_MUL_POINT> exp_sum(va,vb);
1249
1250 return exp_sum;
1251}
1252
1253template<typename T, typename vmpl>
1254__device__ __host__ inline point_expression_op<Point<subar_dim<vmpl>::type::value,T>,
1255 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1256 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1257 POINT_MUL_POINT>
1258operator*(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va,
1259 const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & vb)
1260{
1261 point_expression_op<Point<subar_dim<vmpl>::type::value,T>,
1262 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1263 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1264 POINT_MUL_POINT> exp_sum(va,vb);
1265
1266 return exp_sum;
1267}
1268
1269template<unsigned int dim, typename T, typename check=typename std::enable_if< !std::is_same<T,double>::value >::type>
1270__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<T>,Point<dim,T>,POINT_MUL>
1271operator*(T d, const Point<dim,T> & vb)
1272{
1273 point_expression_op<Point<dim,T>,point_expression<T>,Point<dim,T>,POINT_MUL> exp_sum(point_expression<T>(d),vb);
1274
1275 return exp_sum;
1276}
1277
1278////////////////////// point_expression_op first operand cases ////////////////////////
1279
1280template<typename orig,
1281 typename exp1 ,
1282 typename exp2,
1283 unsigned int op1,
1284 unsigned int dim,
1285 typename T,
1286 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == dim >::type >
1287__device__ __host__ inline point_expression_op<orig,
1288 point_expression_op<orig,exp1,exp2,op1>,
1289 point_expression<T[dim]>,
1290 POINT_MUL_POINT>
1291operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression<T[dim]> & vb)
1292{
1293 point_expression_op<orig,
1294 point_expression_op<orig,exp1,exp2,op1>,
1295 point_expression<T[dim]>,
1296 POINT_MUL_POINT> exp_sum(va,vb);
1297
1298 return exp_sum;
1299}
1300
1301template<typename orig,
1302 typename exp1 ,
1303 typename exp2,
1304 unsigned int op1,
1305 typename T,
1306 typename vmpl,
1307 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == subar_dim<vmpl>::type::value >::type >
1308__device__ __host__ inline point_expression_op<orig,
1309 point_expression_op<orig,exp1,exp2,op1>,
1310 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1311 POINT_MUL_POINT>
1312operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & vb)
1313{
1314 point_expression_op<orig,
1315 point_expression_op<orig,exp1,exp2,op1>,
1316 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1317 POINT_MUL_POINT> exp_sum(va,vb);
1318
1319 return exp_sum;
1320}
1321
1322template<typename orig,
1323 typename exp1 ,
1324 typename exp2,
1325 unsigned int op1,
1326 unsigned int dim,
1327 typename T,
1328 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == 1 >::type >
1329__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T[dim]>,POINT_MUL>
1330operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression<T[dim]> & vb)
1331{
1332 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T[dim]>,POINT_MUL> exp_sum(va,vb);
1333
1334 return exp_sum;
1335}
1336
1337template<typename orig,
1338 typename exp1 ,
1339 typename exp2,
1340 unsigned int op1,
1341 typename T,
1342 typename vmpl,
1343 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == 1 >::type >
1344__device__ __host__ inline point_expression_op<orig,
1345 point_expression_op<orig,exp1,exp2,op1>,
1346 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1347 POINT_MUL>
1348operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & vb)
1349{
1350 point_expression_op<orig,
1351 point_expression_op<orig,exp1,exp2,op1>,
1352 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1353 POINT_MUL> exp_sum(va,vb);
1354
1355 return exp_sum;
1356}
1357
1358////////////////////// point_expression_op second operand cases ////////////////////////
1359
1360template<typename orig,
1361 typename exp1,
1362 typename exp2,
1363 unsigned int op1,
1364 unsigned int dim,
1365 typename T,
1366 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == dim >::type >
1367__device__ __host__ inline point_expression_op<orig,point_expression<T[dim]>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL_POINT>
1368operator*(const point_expression<T[dim]> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)
1369{
1370 point_expression_op<orig,point_expression<T[dim]>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL_POINT> exp_sum(va,vb);
1371
1372 return exp_sum;
1373}
1374
1375template<typename orig,
1376 typename exp1,
1377 typename exp2,
1378 unsigned int op1,
1379 typename T,
1380 typename vmpl,
1381 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == subar_dim<vmpl>::type::value >::type >
1382__device__ __host__ inline point_expression_op<orig,
1383 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1384 point_expression_op<orig,exp1,exp2,op1>,
1385 POINT_MUL_POINT>
1386operator*(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)
1387{
1388 point_expression_op<orig,
1389 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1390 point_expression_op<orig,exp1,exp2,op1>,
1391 POINT_MUL_POINT> exp_sum(va,vb);
1392
1393 return exp_sum;
1394}
1395
1396template<typename orig,
1397 typename exp1,
1398 typename exp2,
1399 unsigned int op1,
1400 unsigned int dim,
1401 typename T,
1402 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == 1 >::type >
1403__device__ __host__ inline point_expression_op<orig,point_expression<T[dim]>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL>
1404operator*(const point_expression<T[dim]> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)
1405{
1406 point_expression_op<orig,point_expression<T[dim]>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL> exp_sum(va,vb);
1407
1408 return exp_sum;
1409}
1410
1411template<typename orig,
1412 typename exp1,
1413 typename exp2,
1414 unsigned int op1,
1415 typename T,
1416 typename vmpl,
1417 typename sfinae = typename std::enable_if< point_expression_op<orig,exp1,exp2,op1>::nvals == 1 >::type >
1418__device__ __host__ inline point_expression_op<orig,
1419 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1420 point_expression_op<orig,exp1,exp2,op1>,
1421 POINT_MUL>
1422operator*(const point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)
1423{
1424 point_expression_op<orig,
1425 point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>,
1426 point_expression_op<orig,exp1,exp2,op1>,
1427 POINT_MUL> exp_sum(va,vb);
1428
1429 return exp_sum;
1430}
1431
1432////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1433
1434/* \brief Multiply two points expression
1435 *
1436 * \param va vector expression one
1437 * \param vb vector expression two
1438 *
1439 * \return an object that encapsulate the expression
1440 *
1441 */
1442template<unsigned int dim, typename T>
1443__device__ __host__ inline point_expression_op<Point<dim,T>,point_expression<double>,Point<dim,T>,POINT_MUL>
1444operator*(double d, const Point<dim,T> & vb)
1445{
1446 point_expression_op<Point<dim,T>,point_expression<double>,Point<dim,T>,POINT_MUL> exp_sum(point_expression<double>(d),vb);
1447
1448 return exp_sum;
1449}
1450
1451/* \brief Multiply two points expression
1452 *
1453 * \param va point expression one
1454 * \param vb point expression two
1455 *
1456 * \return an object that encapsulate the expression
1457 *
1458 */
1459template<unsigned int dim, typename T, typename check=typename std::enable_if< !std::is_same<T,double>::value >::type >
1460__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<T>,POINT_MUL>
1461operator*(const Point<dim,T> & va, T d)
1462{
1463 point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<T>,POINT_MUL> exp_sum(va,point_expression<T>(d));
1464
1465 return exp_sum;
1466}
1467
1468/* \brief Multiply two points expression
1469 *
1470 * \param va point expression one
1471 * \param vb point expression two
1472 *
1473 * \return an object that encapsulate the expression
1474 *
1475 */
1476template<unsigned int dim, typename T>
1477__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<double>,POINT_MUL>
1478operator*(const Point<dim,T> & va, double d)
1479{
1480 point_expression_op<Point<dim,T>,Point<dim,T>,point_expression<double>,POINT_MUL> exp_sum(va,point_expression<double>(d));
1481
1482 return exp_sum;
1483}
1484
1485/* \brief Multiply two points expression
1486 *
1487 * \param va point expression one
1488 * \param vb point expression two
1489 *
1490 * \return an object that encapsulate the expression
1491 *
1492 */
1493template<unsigned int dim, typename T>
1494__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,Point<dim,T>,POINT_MUL_POINT>
1495operator*(const Point<dim,T> & va, const Point<dim,T> & vb)
1496{
1497 point_expression_op<Point<dim,T>,Point<dim,T>,Point<dim,T>,POINT_MUL_POINT> exp_sum(va,vb);
1498
1499 return exp_sum;
1500}
1501
1502/* \brief Multiply two points expression
1503 *
1504 * \param va point expression one
1505 * \param vb point expression two
1506 *
1507 * \return an object that encapsulate the expression
1508 *
1509 */
1510template<typename orig,
1511 unsigned int dim,
1512 typename T,
1513 typename exp1,
1514 typename exp2,
1515 unsigned int op1,
1516 typename sfinae = typename std::enable_if<point_expression_op<orig,exp1,exp2,op1>::nvals != 1>::type >
1517__device__ __host__ inline point_expression_op<orig,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL_POINT>
1518operator*(const Point<dim,T> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)
1519{
1520 point_expression_op<orig,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL_POINT> exp_sum(va,vb);
1521
1522 return exp_sum;
1523}
1524
1525/* \brief Multiply two points expression
1526 *
1527 * \param va point expression one
1528 * \param vb point expression two
1529 *
1530 * \return an object that encapsulate the expression
1531 *
1532 */
1533template<typename orig,
1534 unsigned int dim,
1535 typename T,
1536 typename exp1,
1537 typename exp2,
1538 unsigned int op1,
1539 typename sfinae = typename std::enable_if<point_expression_op<orig,exp1,exp2,op1>::nvals == 1>::type >
1540__device__ __host__ inline point_expression_op<orig,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL>
1541operator*(const Point<dim,T> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)
1542{
1543 point_expression_op<orig,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL> exp_sum(va,vb);
1544
1545 return exp_sum;
1546}
1547
1548/* \brief Multiply two points expression
1549 *
1550 * \param va point expression one
1551 * \param vb point expression two
1552 *
1553 * \return an object that encapsulate the expression
1554 *
1555 */
1556template<typename orig,
1557 unsigned int dim,
1558 typename T,
1559 typename exp1,
1560 typename exp2,
1561 unsigned int op1,
1562 typename sfinae = typename std::enable_if<point_expression_op<orig,exp1,exp2,op1>::nvals != 1>::type >
1563__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,POINT_MUL_POINT>
1564operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const Point<dim,T> & vb)
1565{
1566 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,POINT_MUL_POINT> exp_sum(va,vb);
1567
1568 return exp_sum;
1569}
1570
1571/* \brief Multiply two points expression
1572 *
1573 * \param va point expression one
1574 * \param vb point expression two
1575 *
1576 * \return an object that encapsulate the expression
1577 *
1578 */
1579template<typename orig,
1580 unsigned int dim,
1581 typename T,
1582 typename exp1,
1583 typename exp2,
1584 unsigned int op1,
1585 typename check = typename std::enable_if<point_expression_op<orig,exp1,exp2,op1>::nvals == 1>::type >
1586__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,POINT_MUL>
1587operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const Point<dim,T> & vb)
1588{
1589 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,POINT_MUL> exp_sum(va,vb);
1590
1591 return exp_sum;
1592}
1593
1594/* \brief Multiply a point expression with a number
1595 *
1596 * \param d number
1597 * \param vb point expression
1598 *
1599 * \return an object that encapsulate the expression
1600 *
1601 */
1602template<typename orig, typename T, typename exp1, typename exp2, unsigned int op1>
1603__device__ __host__ inline point_expression_op<orig,point_expression<T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL>
1604operator*(T d, const point_expression_op<orig,exp1,exp2,op1> & vb)
1605{
1606 point_expression_op<orig,point_expression<T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL> exp_sum(point_expression<T>(d),vb);
1607
1608 return exp_sum;
1609}
1610
1611
1612/* \brief Multiply two points expression
1613 *
1614 * \param va point expression one
1615 * \param d constant value
1616 *
1617 * \return an object that encapsulate the expression
1618 *
1619 */
1620template<typename orig, typename exp1, typename exp2, unsigned int op1, typename T>
1621__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T>,POINT_MUL>
1622operator*(const point_expression_op<orig,exp1,exp2,op1> & va, T d)
1623{
1624 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression<T>,POINT_MUL> exp_sum(va,point_expression<T>(d));
1625
1626 return exp_sum;
1627}
1628
1629
1630/* \brief Multiply two points expression
1631 *
1632 * \param va point expression one
1633 * \param vb point expression two
1634 *
1635 * \return an object that encapsulate the expression
1636 *
1637 */
1638template<typename orig,
1639 typename exp1,
1640 typename exp2,
1641 unsigned int op1,
1642 typename exp3 ,
1643 typename exp4,
1644 unsigned int op2,
1645 typename check = typename std::enable_if<point_expression_op<orig,exp1,exp2,op1>::nvals != 1 && point_expression_op<orig,exp3,exp4,op2>::nvals != 1>::type >
1646__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,POINT_MUL_POINT>
1647operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression_op<orig,exp3,exp4,op2> & vb)
1648{
1649 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,POINT_MUL_POINT> exp_sum(va,vb);
1650
1651 return exp_sum;
1652}
1653
1654/* \brief Multiply two points expression
1655 *
1656 * \param va point expression one
1657 * \param vb point expression two
1658 *
1659 * \return an object that encapsulate the expression
1660 *
1661 */
1662template<typename orig,
1663 typename exp1,
1664 typename exp2,
1665 unsigned int op1,
1666 typename exp3 ,
1667 typename exp4,
1668 unsigned int op2,
1669 typename check = typename std::enable_if<point_expression_op<orig,exp1,exp2,op1>::nvals == 1 || point_expression_op<orig,exp3,exp4,op2>::nvals == 1 >::type >
1670inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,POINT_MUL>
1671operator*(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression_op<orig,exp3,exp4,op2> & vb)
1672{
1673 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,POINT_MUL> exp_sum(va,vb);
1674
1675 return exp_sum;
1676}
1677
1678////////////////////////////// Point wise multiplication ///////////////////////
1679
1680/* \brief Multiply two points expression
1681 *
1682 * \param va point expression one
1683 * \param vb point expression two
1684 *
1685 * \return an object that encapsulate the expression
1686 *
1687 */
1688template<unsigned int dim, typename T>
1689__device__ __host__ inline point_expression_op<Point<dim,T>,Point<dim,T>,Point<dim,T>,POINT_MUL>
1690pmul(const Point<dim,T> & va, const Point<dim,T> & vb)
1691{
1692 point_expression_op<Point<dim,T>,Point<dim,T>,Point<dim,T>,POINT_MUL> exp_sum(va,vb);
1693
1694 return exp_sum;
1695}
1696
1697/* \brief Multiply two points expression
1698 *
1699 * \param va point expression one
1700 * \param vb point expression two
1701 *
1702 * \return an object that encapsulate the expression
1703 *
1704 */
1705template<typename orig, unsigned int dim, typename T, typename exp1, typename exp2, unsigned int op1>
1706__device__ __host__ inline point_expression_op<orig,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL>
1707pmul(const Point<dim,T> & va, const point_expression_op<orig,exp1,exp2,op1> & vb)
1708{
1709 point_expression_op<orig,Point<dim,T>,point_expression_op<orig,exp1,exp2,op1>,POINT_MUL> exp_sum(va,vb);
1710
1711 return exp_sum;
1712}
1713
1714/* \brief Multiply two points expression
1715 *
1716 * \param va point expression one
1717 * \param vb point expression two
1718 *
1719 * \return an object that encapsulate the expression
1720 *
1721 */
1722template<typename orig,unsigned int dim, typename T, typename exp1, typename exp2, unsigned int op1>
1723__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,POINT_MUL>
1724pmul(const point_expression_op<orig,exp1,exp2,op1> & va, const Point<dim,T> & vb)
1725{
1726 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,Point<dim,T>,POINT_MUL> exp_sum(va,vb);
1727
1728 return exp_sum;
1729}
1730
1731/* \brief Multiply two points expression
1732 *
1733 * \param va point expression one
1734 * \param vb point expression two
1735 *
1736 * \return an object that encapsulate the expression
1737 *
1738 */
1739template<typename orig, typename exp1, typename exp2, unsigned int op1, typename exp3 , typename exp4, unsigned int op2>
1740__device__ __host__ inline point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,POINT_MUL>
1741pmul(const point_expression_op<orig,exp1,exp2,op1> & va, const point_expression_op<orig,exp3,exp4,op2> & vb)
1742{
1743 point_expression_op<orig,point_expression_op<orig,exp1,exp2,op1>,point_expression_op<orig,exp3,exp4,op2>,POINT_MUL> exp_sum(va,vb);
1744
1745 return exp_sum;
1746}
1747
1748
1749/*! \brief Specialization for an array of dimension dim as expression
1750 *
1751 * \tparam T type of the array
1752 * \tparam dim dimensionality of the array
1753 *
1754 */
1755template<typename T, unsigned int dim>
1756class point_expression<T[dim]>
1757{
1758 //! array of dimension dim
1759 T (& d)[dim];
1760
1761public:
1762
1763 //! indicate that init must be called before value
1764 typedef int has_init;
1765
1766 //! indicate that this class encapsulate an expression
1767 typedef int is_expression;
1768
1769 //! this operation produce a vector as result of size dims
1770 static const unsigned int nvals = dim;
1771
1772 /*! \brief constructor from an array
1773 *
1774 * \param d array of dimension dim
1775 *
1776 */
1777 inline point_expression(T (& d)[dim])
1778 :d(d)
1779 {
1780 }
1781
1782 /*! \brief Operator= for point expression
1783 *
1784 * \tparam orig origin type
1785 * \tparam exp1 expression 1
1786 * \tparam exp2 expression 2
1787 * \tparam op operation
1788 *
1789 * \param point expression
1790 *
1791 * \return a point expression
1792 *
1793 */
1794 template<typename orig, typename exp1, typename exp2, unsigned int op>
1795 __device__ __host__ point_expression<T[dim]> & operator=(const point_expression_op<orig,exp1,exp2,op> & p_exp)
1796 {
1797 p_exp.init();
1798
1799 for (size_t i = 0; i < dim ; i++)
1800 {d[i] = p_exp.value(i);}
1801
1802 return *this;
1803 }
1804
1805 /*! \brief Operator= for point expression
1806 *
1807 * \param point expression
1808 *
1809 * \return a point expression
1810 *
1811 */
1812 template<typename T_>
1813 __device__ __host__ point_expression<T[dim]> & operator=(const point_expression<T_> & p_exp)
1814 {
1815 p_exp.init();
1816
1817 for (size_t i = 0; i < dim ; i++)
1818 {d[i] = p_exp.value(i);}
1819
1820 return *this;
1821 }
1822
1823 /*! \brief This function must be called before value
1824 *
1825 * it calculate the scalar product before return the values
1826 *
1827 */
1828 __device__ __host__ inline void init() const
1829 {
1830 }
1831
1832 /*! \brief Evaluate the expression at coordinate k
1833 *
1834 * It just return the value set in the constructor
1835 *
1836 * \param k coordinate
1837 *
1838 * \return the value
1839 *
1840 */
1841 __device__ __host__ inline T value(const size_t k) const
1842 {
1843 return d[k];
1844 }
1845};
1846
1847
1848/*! \brief Specialization for a const array of dimension dim
1849 *
1850 * \tparam T type of the array
1851 * \tparam dim dimensionality of the array
1852 *
1853 */
1854template<typename T, unsigned int dim>
1855class point_expression<const T[dim]>
1856{
1857 //! array of dimensions dim
1858 const T (& d)[dim];
1859
1860public:
1861
1862 //! indicate that init must be called before value
1863 typedef int has_init;
1864
1865 //! indicate that this class encapsulate an expression
1866 typedef int is_expression;
1867
1868 //! this operation produce a vector as result of size dims
1869 static const unsigned int nvals = dim;
1870
1871 /*! \brief construct from an array of dimension dim
1872 *
1873 * \param d array
1874 *
1875 */
1876 __device__ __host__ inline point_expression(const T (& d)[dim])
1877 :d(d)
1878 {
1879 }
1880
1881 /*! \brief This function must be called before value
1882 *
1883 * it calculate the scalar product before return the values
1884 *
1885 */
1886 __device__ __host__ inline void init() const
1887 {
1888 }
1889
1890 /*! \brief Evaluate the expression at coordinate k
1891 *
1892 * It just return the value set in the constructor
1893 *
1894 * \param k coordinate
1895 *
1896 * \return the value
1897 *
1898 */
1899 __device__ __host__ inline T value(const size_t k) const
1900 {
1901 return d[k];
1902 }
1903};
1904
1905/*! \brief Specialization for a const array of dimension dim
1906 *
1907 * \tparam T type of the array
1908 * \tparam dim dimensionality of the array
1909 *
1910 */
1911template<typename T, typename vmpl>
1912class point_expression<openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl>>
1913{
1914 //! array view of dimension dim
1915 const openfpm::detail::multi_array::const_sub_array_openfpm<T,1,vmpl,const T *> d;
1916
1917public:
1918
1919 //! indicate that init must be called before value
1920 typedef int has_init;
1921
1922 //! indicate that this class encapsulate an expression
1923 typedef int is_expression;
1924
1925 //! this operation produce a vector as result of size dims
1926 static const unsigned int nvals = subar_dim<vmpl>::type::value;
1927
1928 /*! \brief construct from an array of dimension dim
1929 *
1930 * \param d array
1931 *
1932 */
1933 __device__ __host__ inline point_expression(const openfpm::detail::multi_array::sub_array_openfpm<T,1,vmpl> & d)
1934 :d(d.origin(),d.strides())
1935 {
1936 }
1937
1938 /*! \brief This function must be called before value
1939 *
1940 * it calculate the scalar product before return the values
1941 *
1942 */
1943 __device__ __host__ inline void init() const
1944 {
1945 }
1946
1947 /*! \brief Evaluate the expression at coordinate k
1948 *
1949 * It just return the value set in the constructor
1950 *
1951 * \param k coordinate
1952 *
1953 * \return the value
1954 *
1955 */
1956 __device__ __host__ inline T value(const size_t k) const
1957 {
1958 return d[k];
1959 }
1960};
1961
1962#include "Point_operators_functions.hpp"
1963
1964#endif /* OPENFPM_DATA_SRC_SPACE_SHAPE_POINT_OPERATORS_HPP_ */
1965