/[escript]/branches/schroedinger/escript/src/Data.h
ViewVC logotype

Contents of /branches/schroedinger/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1332 - (show annotations)
Tue Oct 23 03:28:51 2007 UTC (12 years ago) by matt
Original Path: trunk/escript/src/Data.h
File MIME type: text/plain
File size: 82298 byte(s)
Pow now uses the new binary function interface of C_TensorBinaryOperation.

1
2 /* $Id$ */
3
4 /*******************************************************
5 *
6 * Copyright 2003-2007 by ACceSS MNRF
7 * Copyright 2007 by University of Queensland
8 *
9 * http://esscc.uq.edu.au
10 * Primary Business: Queensland, Australia
11 * Licensed under the Open Software License version 3.0
12 * http://www.opensource.org/licenses/osl-3.0.php
13 *
14 *******************************************************/
15
16 /** \file Data.h */
17
18 #ifndef DATA_H
19 #define DATA_H
20 #include "system_dep.h"
21
22 #include "DataAbstract.h"
23 #include "DataAlgorithm.h"
24 #include "FunctionSpace.h"
25 #include "BinaryOp.h"
26 #include "UnaryOp.h"
27 #include "DataException.h"
28
29 extern "C" {
30 #include "DataC.h"
31 /* #include "paso/Paso.h" doesn't belong in this file...causes trouble for BruceFactory.cpp */
32 }
33
34 #include "esysmpi.h"
35 #include <string>
36 #include <algorithm>
37
38 #include <boost/shared_ptr.hpp>
39 #include <boost/python/object.hpp>
40 #include <boost/python/tuple.hpp>
41 #include <boost/python/numeric.hpp>
42
43 namespace escript {
44
45 //
46 // Forward declaration for various implementations of Data.
47 class DataConstant;
48 class DataTagged;
49 class DataExpanded;
50
51 /**
52 \brief
53 Data creates the appropriate Data object for the given construction
54 arguments.
55
56 Description:
57 Data is essentially a factory class which creates the appropriate Data
58 object for the given construction arguments. It retains control over
59 the object created for the lifetime of the object.
60 The type of Data object referred to may change during the lifetime of
61 the Data object.
62 */
63 class Data {
64
65 public:
66
67 // These typedefs allow function names to be cast to pointers
68 // to functions of the appropriate type when calling unaryOp etc.
69 typedef double (*UnaryDFunPtr)(double);
70 typedef double (*BinaryDFunPtr)(double,double);
71
72
73 /**
74 Constructors.
75 */
76
77 /**
78 \brief
79 Default constructor.
80 Creates a DataEmpty object.
81 */
82 ESCRIPT_DLL_API
83 Data();
84
85 /**
86 \brief
87 Copy constructor.
88 WARNING: Only performs a shallow copy.
89 */
90 ESCRIPT_DLL_API
91 Data(const Data& inData);
92
93 /**
94 \brief
95 Constructor from another Data object. If "what" is different from the
96 function space of inData the inData are tried to be interpolated to what,
97 otherwise a shallow copy of inData is returned.
98 */
99 ESCRIPT_DLL_API
100 Data(const Data& inData,
101 const FunctionSpace& what);
102
103 /**
104 \brief
105 Constructor which copies data from a DataArrayView.
106
107 \param value - Input - Data value for a single point.
108 \param what - Input - A description of what this data represents.
109 \param expanded - Input - Flag, if true fill the entire container with
110 the value. Otherwise a more efficient storage
111 mechanism will be used.
112 */
113 ESCRIPT_DLL_API
114 Data(const DataArrayView& value,
115 const FunctionSpace& what=FunctionSpace(),
116 bool expanded=false);
117
118 /**
119 \brief
120 Constructor which creates a Data from a DataArrayView shape.
121
122 \param value - Input - Single value applied to all Data.
123 \param dataPointShape - Input - The shape of each data point.
124 \param what - Input - A description of what this data represents.
125 \param expanded - Input - Flag, if true fill the entire container with
126 the given value. Otherwise a more efficient storage
127 mechanism will be used.
128 */
129 ESCRIPT_DLL_API
130 Data(double value,
131 const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),
132 const FunctionSpace& what=FunctionSpace(),
133 bool expanded=false);
134
135 /**
136 \brief
137 Constructor which performs a deep copy of a region from another Data object.
138
139 \param inData - Input - Input Data object.
140 \param region - Input - Region to copy.
141 */
142 ESCRIPT_DLL_API
143 Data(const Data& inData,
144 const DataArrayView::RegionType& region);
145
146 /**
147 \brief
148 Constructor which will create Tagged data if expanded is false.
149 No attempt is made to ensure the tag keys match the tag keys
150 within the function space.
151
152 \param tagKeys - Input - List of tag values.
153 \param values - Input - List of values, one for each tag.
154 \param defaultValue - Input - A default value, used if tag doesn't exist.
155 \param what - Input - A description of what this data represents.
156 \param expanded - Input - Flag, if true fill the entire container with
157 the appropriate values.
158 ==>*
159 */
160 ESCRIPT_DLL_API
161 Data(const DataTagged::TagListType& tagKeys,
162 const DataTagged::ValueListType& values,
163 const DataArrayView& defaultValue,
164 const FunctionSpace& what=FunctionSpace(),
165 bool expanded=false);
166
167 /**
168 \brief
169 Constructor which copies data from a python numarray.
170
171 \param value - Input - Data value for a single point.
172 \param what - Input - A description of what this data represents.
173 \param expanded - Input - Flag, if true fill the entire container with
174 the value. Otherwise a more efficient storage
175 mechanism will be used.
176 */
177 ESCRIPT_DLL_API
178 Data(const boost::python::numeric::array& value,
179 const FunctionSpace& what=FunctionSpace(),
180 bool expanded=false);
181
182 /**
183 \brief
184 Constructor which copies data from any object that can be converted into
185 a python numarray.
186
187 \param value - Input - Input data.
188 \param what - Input - A description of what this data represents.
189 \param expanded - Input - Flag, if true fill the entire container with
190 the value. Otherwise a more efficient storage
191 mechanism will be used.
192 */
193 ESCRIPT_DLL_API
194 Data(const boost::python::object& value,
195 const FunctionSpace& what=FunctionSpace(),
196 bool expanded=false);
197
198 /**
199 \brief
200 Constructor which creates a DataConstant.
201 Copies data from any object that can be converted
202 into a numarray. All other parameters are copied from other.
203
204 \param value - Input - Input data.
205 \param other - Input - contains all other parameters.
206 */
207 ESCRIPT_DLL_API
208 Data(const boost::python::object& value,
209 const Data& other);
210
211 /**
212 \brief
213 Constructor which creates a DataConstant of "shape" with constant value.
214 */
215 ESCRIPT_DLL_API
216 Data(double value,
217 const boost::python::tuple& shape=boost::python::make_tuple(),
218 const FunctionSpace& what=FunctionSpace(),
219 bool expanded=false);
220 /**
221 \brief
222 Destructor
223 */
224 ESCRIPT_DLL_API
225 ~Data();
226
227 /**
228 \brief
229 Perform a deep copy.
230 */
231 ESCRIPT_DLL_API
232 void
233 copy(const Data& other);
234
235 /**
236 Member access methods.
237 */
238
239 /**
240 \brief
241 switches on update protection
242
243 */
244 ESCRIPT_DLL_API
245 void
246 setProtection();
247
248 /**
249 \brief
250 Returns trueif the data object is protected against update
251
252 */
253 ESCRIPT_DLL_API
254 bool
255 isProtected() const;
256
257 /**
258 \brief
259 Return the values of a data point on this process
260 */
261 ESCRIPT_DLL_API
262 const boost::python::numeric::array
263 getValueOfDataPoint(int dataPointNo);
264
265 /**
266 \brief
267 sets the values of a data-point from a python object on this process
268 */
269 ESCRIPT_DLL_API
270 void
271 setValueOfDataPointToPyObject(int dataPointNo, const boost::python::object& py_object);
272
273 /**
274 \brief
275 sets the values of a data-point from a numarray object on this process
276 */
277 ESCRIPT_DLL_API
278 void
279 setValueOfDataPointToArray(int dataPointNo, const boost::python::numeric::array&);
280
281 /**
282 \brief
283 sets the values of a data-point on this process
284 */
285 ESCRIPT_DLL_API
286 void
287 setValueOfDataPoint(int dataPointNo, const double);
288
289 /**
290 \brief
291 Return the value of the specified data-point across all processors
292 */
293 ESCRIPT_DLL_API
294 const boost::python::numeric::array
295 getValueOfGlobalDataPoint(int procNo, int dataPointNo);
296
297 /**
298 \brief
299 Return the tag number associated with the given data-point.
300
301 The data-point number here corresponds to the data-point number in the
302 numarray returned by convertToNumArray.
303 */
304 ESCRIPT_DLL_API
305 int
306 getTagNumber(int dpno);
307
308 /**
309 \brief
310 Return the C wrapper for the Data object.
311 */
312 ESCRIPT_DLL_API
313 escriptDataC
314 getDataC();
315
316 /**
317 \brief
318 Return the C wrapper for the Data object - const version.
319 */
320 ESCRIPT_DLL_API
321 escriptDataC
322 getDataC() const;
323
324 /**
325 \brief
326 Write the data as a string.
327 */
328 ESCRIPT_DLL_API
329 inline
330 std::string
331 toString() const
332 {
333 return m_data->toString();
334 }
335
336 /**
337 \brief
338 Return the DataArrayView of the point data. This essentially contains
339 the shape information for each data point although it also may be used
340 to manipulate the point data.
341 */
342 ESCRIPT_DLL_API
343 inline
344 const DataArrayView&
345 getPointDataView() const
346 {
347 return m_data->getPointDataView();
348 }
349
350 /**
351 \brief
352 Whatever the current Data type make this into a DataExpanded.
353 */
354 ESCRIPT_DLL_API
355 void
356 expand();
357
358 /**
359 \brief
360 If possible convert this Data to DataTagged. This will only allow
361 Constant data to be converted to tagged. An attempt to convert
362 Expanded data to tagged will throw an exception.
363 ==>*
364 */
365 ESCRIPT_DLL_API
366 void
367 tag();
368
369 /**
370 \brief
371 Return true if this Data is expanded.
372 */
373 ESCRIPT_DLL_API
374 bool
375 isExpanded() const;
376
377 /**
378 \brief
379 Return true if this Data is tagged.
380 */
381 ESCRIPT_DLL_API
382 bool
383 isTagged() const;
384
385 /**
386 \brief
387 Return true if this Data is constant.
388 */
389 ESCRIPT_DLL_API
390 bool
391 isConstant() const;
392
393 /**
394 \brief
395 Return true if this Data is empty.
396 */
397 ESCRIPT_DLL_API
398 bool
399 isEmpty() const;
400
401 /**
402 \brief
403 Return the function space.
404 */
405 ESCRIPT_DLL_API
406 inline
407 const FunctionSpace&
408 getFunctionSpace() const
409 {
410 return m_data->getFunctionSpace();
411 }
412
413 /**
414 \brief
415 Return a copy of the function space.
416 */
417 ESCRIPT_DLL_API
418 const FunctionSpace
419 getCopyOfFunctionSpace() const;
420
421 /**
422 \brief
423 Return the domain.
424 */
425 ESCRIPT_DLL_API
426 inline
427 const AbstractDomain&
428 getDomain() const
429 {
430 return getFunctionSpace().getDomain();
431 }
432
433 /**
434 \brief
435 Return a copy of the domain.
436 */
437 ESCRIPT_DLL_API
438 const AbstractDomain
439 getCopyOfDomain() const;
440
441 /**
442 \brief
443 Return the rank of the point data.
444 */
445 ESCRIPT_DLL_API
446 inline
447 int
448 getDataPointRank() const
449 {
450 return m_data->getPointDataView().getRank();
451 }
452
453 /**
454 \brief
455 Return the number of data points
456 */
457 ESCRIPT_DLL_API
458 inline
459 int
460 getNumDataPoints() const
461 {
462 return getNumSamples() * getNumDataPointsPerSample();
463 }
464 /**
465 \brief
466 Return the number of samples.
467 */
468 ESCRIPT_DLL_API
469 inline
470 int
471 getNumSamples() const
472 {
473 return m_data->getNumSamples();
474 }
475
476 /**
477 \brief
478 Return the number of data points per sample.
479 */
480 ESCRIPT_DLL_API
481 inline
482 int
483 getNumDataPointsPerSample() const
484 {
485 return m_data->getNumDPPSample();
486 }
487 /**
488 \brief
489 dumps the object into a netCDF file
490 */
491 ESCRIPT_DLL_API
492 void
493 dump(const std::string fileName) const;
494 /**
495 \brief
496 Return the sample data for the given sample no. This is not the
497 preferred interface but is provided for use by C code.
498 \param sampleNo - Input - the given sample no.
499 */
500 ESCRIPT_DLL_API
501 inline
502 DataAbstract::ValueType::value_type*
503 getSampleData(DataAbstract::ValueType::size_type sampleNo)
504 {
505 return m_data->getSampleData(sampleNo);
506 }
507
508 /**
509 \brief
510 Return the sample data for the given tag. If an attempt is made to
511 access data that isn't tagged an exception will be thrown.
512 \param tag - Input - the tag key.
513 */
514 ESCRIPT_DLL_API
515 inline
516 DataAbstract::ValueType::value_type*
517 getSampleDataByTag(int tag)
518 {
519 return m_data->getSampleDataByTag(tag);
520 }
521
522 /**
523 \brief
524 Return a view into the data for the data point specified.
525 NOTE: Construction of the DataArrayView is a relatively expensive
526 operation.
527 \param sampleNo - Input -
528 \param dataPointNo - Input -
529 */
530 ESCRIPT_DLL_API
531 inline
532 DataArrayView
533 getDataPoint(int sampleNo,
534 int dataPointNo)
535 {
536 return m_data->getDataPoint(sampleNo,dataPointNo);
537 }
538
539 /**
540 \brief
541 Return a reference to the data point shape.
542 */
543 ESCRIPT_DLL_API
544 const DataArrayView::ShapeType&
545 getDataPointShape() const;
546
547 /**
548 \brief
549 Return the data point shape as a tuple of integers.
550 */
551 ESCRIPT_DLL_API
552 const boost::python::tuple
553 getShapeTuple() const;
554
555 /**
556 \brief
557 Return the size of the data point. It is the product of the
558 data point shape dimensions.
559 */
560 ESCRIPT_DLL_API
561 int
562 getDataPointSize() const;
563
564 /**
565 \brief
566 Return the number of doubles stored for this Data.
567 */
568 ESCRIPT_DLL_API
569 DataArrayView::ValueType::size_type
570 getLength() const;
571
572
573
574 /**
575 \brief
576 Assign the given value to the tag assocciated with name. Implicitly converts this
577 object to type DataTagged. Throws an exception if this object
578 cannot be converted to a DataTagged object or name cannot be mapped onto a tag key.
579 \param tagKey - Input - Integer key.
580 \param value - Input - Value to associate with given key.
581 ==>*
582 */
583 ESCRIPT_DLL_API
584 void
585 setTaggedValueByName(std::string name,
586 const boost::python::object& value);
587
588 /**
589 \brief
590 Assign the given value to the tag. Implicitly converts this
591 object to type DataTagged. Throws an exception if this object
592 cannot be converted to a DataTagged object.
593 \param tagKey - Input - Integer key.
594 \param value - Input - Value to associate with given key.
595 ==>*
596 */
597 ESCRIPT_DLL_API
598 void
599 setTaggedValue(int tagKey,
600 const boost::python::object& value);
601
602 /**
603 \brief
604 Assign the given value to the tag. Implicitly converts this
605 object to type DataTagged. Throws an exception if this object
606 cannot be converted to a DataTagged object.
607 \param tagKey - Input - Integer key.
608 \param value - Input - Value to associate with given key.
609 ==>*
610 */
611 ESCRIPT_DLL_API
612 void
613 setTaggedValueFromCPP(int tagKey,
614 const DataArrayView& value);
615
616 /**
617 \brief
618 Copy other Data object into this Data object where mask is positive.
619 */
620 ESCRIPT_DLL_API
621 void
622 copyWithMask(const Data& other,
623 const Data& mask);
624
625 /**
626 Data object operation methods and operators.
627 */
628
629 /**
630 \brief
631 set all values to zero
632 *
633 */
634 ESCRIPT_DLL_API
635 void
636 setToZero();
637
638 /**
639 \brief
640 Interpolates this onto the given functionspace and returns
641 the result as a Data object.
642 *
643 */
644 ESCRIPT_DLL_API
645 Data
646 interpolate(const FunctionSpace& functionspace) const;
647 /**
648 \brief
649 Calculates the gradient of the data at the data points of functionspace.
650 If functionspace is not present the function space of Function(getDomain()) is used.
651 *
652 */
653 ESCRIPT_DLL_API
654 Data
655 gradOn(const FunctionSpace& functionspace) const;
656
657 ESCRIPT_DLL_API
658 Data
659 grad() const;
660
661 /**
662 \brief
663 Calculate the integral over the function space domain.
664 *
665 */
666 ESCRIPT_DLL_API
667 boost::python::numeric::array
668 integrate() const;
669
670 /**
671 \brief
672 Returns 1./ Data object
673 *
674 */
675 ESCRIPT_DLL_API
676 Data
677 oneOver() const;
678 /**
679 \brief
680 Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
681 *
682 */
683 ESCRIPT_DLL_API
684 Data
685 wherePositive() const;
686
687 /**
688 \brief
689 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
690 *
691 */
692 ESCRIPT_DLL_API
693 Data
694 whereNegative() const;
695
696 /**
697 \brief
698 Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
699 *
700 */
701 ESCRIPT_DLL_API
702 Data
703 whereNonNegative() const;
704
705 /**
706 \brief
707 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
708 *
709 */
710 ESCRIPT_DLL_API
711 Data
712 whereNonPositive() const;
713
714 /**
715 \brief
716 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
717 *
718 */
719 ESCRIPT_DLL_API
720 Data
721 whereZero(double tol=0.0) const;
722
723 /**
724 \brief
725 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
726 *
727 */
728 ESCRIPT_DLL_API
729 Data
730 whereNonZero(double tol=0.0) const;
731
732 /**
733 \brief
734 Return the maximum absolute value of this Data object.
735 *
736 */
737 ESCRIPT_DLL_API
738 double
739 Lsup() const;
740
741 /**
742 \brief
743 Return the maximum value of this Data object.
744 *
745 */
746 ESCRIPT_DLL_API
747 double
748 sup() const;
749
750 /**
751 \brief
752 Return the minimum value of this Data object.
753 *
754 */
755 ESCRIPT_DLL_API
756 double
757 inf() const;
758
759 /**
760 \brief
761 Return the absolute value of each data point of this Data object.
762 *
763 */
764 ESCRIPT_DLL_API
765 Data
766 abs() const;
767
768 /**
769 \brief
770 Return the maximum value of each data point of this Data object.
771 *
772 */
773 ESCRIPT_DLL_API
774 Data
775 maxval() const;
776
777 /**
778 \brief
779 Return the minimum value of each data point of this Data object.
780 *
781 */
782 ESCRIPT_DLL_API
783 Data
784 minval() const;
785
786 /**
787 \brief
788 Return the (sample number, data-point number) of the data point with
789 the minimum value in this Data object.
790 */
791 ESCRIPT_DLL_API
792 const boost::python::tuple
793 minGlobalDataPoint() const;
794
795 ESCRIPT_DLL_API
796 void
797 calc_minGlobalDataPoint(int& ProcNo, int& DataPointNo) const;
798 /**
799 \brief
800 Return the sign of each data point of this Data object.
801 -1 for negative values, zero for zero values, 1 for positive values.
802 *
803 */
804 ESCRIPT_DLL_API
805 Data
806 sign() const;
807
808 /**
809 \brief
810 Return the symmetric part of a matrix which is half the matrix plus its transpose.
811 *
812 */
813 ESCRIPT_DLL_API
814 Data
815 symmetric() const;
816
817 /**
818 \brief
819 Return the nonsymmetric part of a matrix which is half the matrix minus its transpose.
820 *
821 */
822 ESCRIPT_DLL_API
823 Data
824 nonsymmetric() const;
825
826 /**
827 \brief
828 Return the trace of a matrix
829 *
830 */
831 ESCRIPT_DLL_API
832 Data
833 trace(int axis_offset) const;
834
835 /**
836 \brief
837 Transpose each data point of this Data object around the given axis.
838 *
839 */
840 ESCRIPT_DLL_API
841 Data
842 transpose(int axis_offset) const;
843
844 /**
845 \brief
846 Return the eigenvalues of the symmetric part at each data point of this Data object in increasing values.
847 Currently this function is restricted to rank 2, square shape, and dimension 3.
848 *
849 */
850 ESCRIPT_DLL_API
851 Data
852 eigenvalues() const;
853
854 /**
855 \brief
856 Return the eigenvalues and corresponding eigenvcetors of the symmetric part at each data point of this Data object.
857 the eigenvalues are ordered in increasing size where eigenvalues with relative difference less than
858 tol are treated as equal. The eigenvectors are orthogonal, normalized and the sclaed such that the
859 first non-zero entry is positive.
860 Currently this function is restricted to rank 2, square shape, and dimension 3
861 *
862 */
863 ESCRIPT_DLL_API
864 const boost::python::tuple
865 eigenvalues_and_eigenvectors(const double tol=1.e-12) const;
866
867 /**
868 \brief
869 swaps the components axis0 and axis1
870 *
871 */
872 ESCRIPT_DLL_API
873 Data
874 swapaxes(const int axis0, const int axis1) const;
875
876 /**
877 \brief
878 Return the error function erf of each data point of this Data object.
879 *
880 */
881 ESCRIPT_DLL_API
882 Data
883 erf() const;
884
885 /**
886 \brief
887 Return the sin of each data point of this Data object.
888 *
889 */
890 ESCRIPT_DLL_API
891 Data
892 sin() const;
893
894 /**
895 \brief
896 Return the cos of each data point of this Data object.
897 *
898 */
899 ESCRIPT_DLL_API
900 Data
901 cos() const;
902
903 /**
904 \brief
905 Return the tan of each data point of this Data object.
906 *
907 */
908 ESCRIPT_DLL_API
909 Data
910 tan() const;
911
912 /**
913 \brief
914 Return the asin of each data point of this Data object.
915 *
916 */
917 ESCRIPT_DLL_API
918 Data
919 asin() const;
920
921 /**
922 \brief
923 Return the acos of each data point of this Data object.
924 *
925 */
926 ESCRIPT_DLL_API
927 Data
928 acos() const;
929
930 /**
931 \brief
932 Return the atan of each data point of this Data object.
933 *
934 */
935 ESCRIPT_DLL_API
936 Data
937 atan() const;
938
939 /**
940 \brief
941 Return the sinh of each data point of this Data object.
942 *
943 */
944 ESCRIPT_DLL_API
945 Data
946 sinh() const;
947
948 /**
949 \brief
950 Return the cosh of each data point of this Data object.
951 *
952 */
953 ESCRIPT_DLL_API
954 Data
955 cosh() const;
956
957 /**
958 \brief
959 Return the tanh of each data point of this Data object.
960 *
961 */
962 ESCRIPT_DLL_API
963 Data
964 tanh() const;
965
966 /**
967 \brief
968 Return the asinh of each data point of this Data object.
969 *
970 */
971 ESCRIPT_DLL_API
972 Data
973 asinh() const;
974
975 /**
976 \brief
977 Return the acosh of each data point of this Data object.
978 *
979 */
980 ESCRIPT_DLL_API
981 Data
982 acosh() const;
983
984 /**
985 \brief
986 Return the atanh of each data point of this Data object.
987 *
988 */
989 ESCRIPT_DLL_API
990 Data
991 atanh() const;
992
993 /**
994 \brief
995 Return the log to base 10 of each data point of this Data object.
996 *
997 */
998 ESCRIPT_DLL_API
999 Data
1000 log10() const;
1001
1002 /**
1003 \brief
1004 Return the natural log of each data point of this Data object.
1005 *
1006 */
1007 ESCRIPT_DLL_API
1008 Data
1009 log() const;
1010
1011 /**
1012 \brief
1013 Return the exponential function of each data point of this Data object.
1014 *
1015 */
1016 ESCRIPT_DLL_API
1017 Data
1018 exp() const;
1019
1020 /**
1021 \brief
1022 Return the square root of each data point of this Data object.
1023 *
1024 */
1025 ESCRIPT_DLL_API
1026 Data
1027 sqrt() const;
1028
1029 /**
1030 \brief
1031 Return the negation of each data point of this Data object.
1032 *
1033 */
1034 ESCRIPT_DLL_API
1035 Data
1036 neg() const;
1037
1038 /**
1039 \brief
1040 Return the identity of each data point of this Data object.
1041 Simply returns this object unmodified.
1042 *
1043 */
1044 ESCRIPT_DLL_API
1045 Data
1046 pos() const;
1047
1048 /**
1049 \brief
1050 Return the given power of each data point of this Data object.
1051
1052 \param right Input - the power to raise the object to.
1053 *
1054 */
1055 ESCRIPT_DLL_API
1056 Data
1057 powD(const Data& right) const;
1058
1059 /**
1060 \brief
1061 Return the given power of each data point of this boost python object.
1062
1063 \param right Input - the power to raise the object to.
1064 *
1065 */
1066 ESCRIPT_DLL_API
1067 Data
1068 powO(const boost::python::object& right) const;
1069
1070 /**
1071 \brief
1072 Return the given power of each data point of this boost python object.
1073
1074 \param left Input - the bases
1075 *
1076 */
1077
1078 ESCRIPT_DLL_API
1079 Data
1080 rpowO(const boost::python::object& left) const;
1081
1082 /**
1083 \brief
1084 writes the object to a file in the DX file format
1085 */
1086 ESCRIPT_DLL_API
1087 void
1088 saveDX(std::string fileName) const;
1089
1090 /**
1091 \brief
1092 writes the object to a file in the VTK file format
1093 */
1094 ESCRIPT_DLL_API
1095 void
1096 saveVTK(std::string fileName) const;
1097
1098 /**
1099 \brief
1100 Overloaded operator +=
1101 \param right - Input - The right hand side.
1102 *
1103 */
1104 ESCRIPT_DLL_API
1105 Data& operator+=(const Data& right);
1106 ESCRIPT_DLL_API
1107 Data& operator+=(const boost::python::object& right);
1108
1109 ESCRIPT_DLL_API
1110 Data& operator=(const Data& other);
1111
1112 /**
1113 \brief
1114 Overloaded operator -=
1115 \param right - Input - The right hand side.
1116 *
1117 */
1118 ESCRIPT_DLL_API
1119 Data& operator-=(const Data& right);
1120 ESCRIPT_DLL_API
1121 Data& operator-=(const boost::python::object& right);
1122
1123 /**
1124 \brief
1125 Overloaded operator *=
1126 \param right - Input - The right hand side.
1127 *
1128 */
1129 ESCRIPT_DLL_API
1130 Data& operator*=(const Data& right);
1131 ESCRIPT_DLL_API
1132 Data& operator*=(const boost::python::object& right);
1133
1134 /**
1135 \brief
1136 Overloaded operator /=
1137 \param right - Input - The right hand side.
1138 *
1139 */
1140 ESCRIPT_DLL_API
1141 Data& operator/=(const Data& right);
1142 ESCRIPT_DLL_API
1143 Data& operator/=(const boost::python::object& right);
1144
1145 /**
1146 \brief
1147 Returns true if this can be interpolated to functionspace.
1148 */
1149 ESCRIPT_DLL_API
1150 bool
1151 probeInterpolation(const FunctionSpace& functionspace) const;
1152
1153 /**
1154 Data object slicing methods.
1155 */
1156
1157 /**
1158 \brief
1159 Returns a slice from this Data object.
1160
1161 /description
1162 Implements the [] get operator in python.
1163 Calls getSlice.
1164
1165 \param key - Input - python slice tuple specifying
1166 slice to return.
1167 */
1168 ESCRIPT_DLL_API
1169 Data
1170 getItem(const boost::python::object& key) const;
1171
1172 /**
1173 \brief
1174 Copies slice from value into this Data object.
1175
1176 Implements the [] set operator in python.
1177 Calls setSlice.
1178
1179 \param key - Input - python slice tuple specifying
1180 slice to copy from value.
1181 \param value - Input - Data object to copy from.
1182 */
1183 ESCRIPT_DLL_API
1184 void
1185 setItemD(const boost::python::object& key,
1186 const Data& value);
1187
1188 ESCRIPT_DLL_API
1189 void
1190 setItemO(const boost::python::object& key,
1191 const boost::python::object& value);
1192
1193 // These following public methods should be treated as private.
1194
1195 /**
1196 \brief
1197 Perform the given unary operation on every element of every data point in
1198 this Data object.
1199 */
1200 template <class UnaryFunction>
1201 ESCRIPT_DLL_API
1202 inline
1203 void
1204 unaryOp(UnaryFunction operation);
1205
1206 /**
1207 \brief
1208 Return a Data object containing the specified slice of
1209 this Data object.
1210 \param region - Input - Region to copy.
1211 *
1212 */
1213 ESCRIPT_DLL_API
1214 Data
1215 getSlice(const DataArrayView::RegionType& region) const;
1216
1217 /**
1218 \brief
1219 Copy the specified slice from the given value into this
1220 Data object.
1221 \param value - Input - Data to copy from.
1222 \param region - Input - Region to copy.
1223 *
1224 */
1225 ESCRIPT_DLL_API
1226 void
1227 setSlice(const Data& value,
1228 const DataArrayView::RegionType& region);
1229
1230 /**
1231 \brief
1232 Archive the current Data object to the given file.
1233 \param fileName - Input - file to archive to.
1234 */
1235 ESCRIPT_DLL_API
1236 void
1237 archiveData(const std::string fileName);
1238
1239 /**
1240 \brief
1241 Extract the Data object archived in the given file, overwriting
1242 the current Data object.
1243 Note - the current object must be of type DataEmpty.
1244 \param fileName - Input - file to extract from.
1245 \param fspace - Input - a suitable FunctionSpace descibing the data.
1246 */
1247 ESCRIPT_DLL_API
1248 void
1249 extractData(const std::string fileName,
1250 const FunctionSpace& fspace);
1251
1252
1253 /**
1254 \brief
1255 print the data values to stdout. Used for debugging
1256 */
1257 ESCRIPT_DLL_API
1258 void
1259 print(void);
1260
1261 /**
1262 \brief
1263 return the MPI rank number of the local data
1264 MPI_COMM_WORLD is assumed and the result of MPI_Comm_size()
1265 is returned
1266 */
1267 ESCRIPT_DLL_API
1268 int
1269 get_MPIRank(void) const;
1270
1271 /**
1272 \brief
1273 return the MPI rank number of the local data
1274 MPI_COMM_WORLD is assumed and the result of MPI_Comm_rank()
1275 is returned
1276 */
1277 ESCRIPT_DLL_API
1278 int
1279 get_MPISize(void) const;
1280
1281 /**
1282 \brief
1283 return the MPI rank number of the local data
1284 MPI_COMM_WORLD is assumed and returned.
1285 */
1286 ESCRIPT_DLL_API
1287 MPI_Comm
1288 get_MPIComm(void) const;
1289
1290 /**
1291 \brief
1292 return the object produced by the factory, which is a DataConstant or DataExpanded
1293 */
1294 ESCRIPT_DLL_API
1295 DataAbstract*
1296 borrowData(void) const;
1297
1298 protected:
1299
1300 private:
1301
1302 /**
1303 \brief
1304 Check *this and the right operand are compatible. Throws
1305 an exception if they aren't.
1306 \param right - Input - The right hand side.
1307 */
1308 inline
1309 void
1310 operandCheck(const Data& right) const
1311 {
1312 return m_data->operandCheck(*(right.m_data.get()));
1313 }
1314
1315 /**
1316 \brief
1317 Perform the specified reduction algorithm on every element of every data point in
1318 this Data object according to the given function and return the single value result.
1319 */
1320 template <class BinaryFunction>
1321 inline
1322 double
1323 algorithm(BinaryFunction operation,
1324 double initial_value) const;
1325
1326 /**
1327 \brief
1328 Reduce each data-point in this Data object using the given operation. Return a Data
1329 object with the same number of data-points, but with each data-point containing only
1330 one value - the result of the reduction operation on the corresponding data-point in
1331 this Data object
1332 */
1333 template <class BinaryFunction>
1334 inline
1335 Data
1336 dp_algorithm(BinaryFunction operation,
1337 double initial_value) const;
1338
1339 /**
1340 \brief
1341 Perform the given binary operation on all of the data's elements.
1342 The underlying type of the right hand side (right) determines the final
1343 type of *this after the operation. For example if the right hand side
1344 is expanded *this will be expanded if necessary.
1345 RHS is a Data object.
1346 */
1347 template <class BinaryFunction>
1348 inline
1349 void
1350 binaryOp(const Data& right,
1351 BinaryFunction operation);
1352
1353 /**
1354 \brief
1355 Convert the data type of the RHS to match this.
1356 \param right - Input - data type to match.
1357 */
1358 void
1359 typeMatchLeft(Data& right) const;
1360
1361 /**
1362 \brief
1363 Convert the data type of this to match the RHS.
1364 \param right - Input - data type to match.
1365 */
1366 void
1367 typeMatchRight(const Data& right);
1368
1369 /**
1370 \brief
1371 Construct a Data object of the appropriate type.
1372 */
1373 template <class IValueType>
1374 void
1375 initialise(const IValueType& value,
1376 const FunctionSpace& what,
1377 bool expanded);
1378
1379 //
1380 // flag to protect the data object against any update
1381 bool m_protected;
1382
1383 //
1384 // pointer to the actual data object
1385 boost::shared_ptr<DataAbstract> m_data;
1386
1387 };
1388
1389 template <class IValueType>
1390 void
1391 Data::initialise(const IValueType& value,
1392 const FunctionSpace& what,
1393 bool expanded)
1394 {
1395 //
1396 // Construct a Data object of the appropriate type.
1397 // Construct the object first as there seems to be a bug which causes
1398 // undefined behaviour if an exception is thrown during construction
1399 // within the shared_ptr constructor.
1400 if (expanded) {
1401 DataAbstract* temp=new DataExpanded(value,what);
1402 boost::shared_ptr<DataAbstract> temp_data(temp);
1403 m_data=temp_data;
1404 } else {
1405 DataAbstract* temp=new DataConstant(value,what);
1406 boost::shared_ptr<DataAbstract> temp_data(temp);
1407 m_data=temp_data;
1408 }
1409 }
1410
1411 /**
1412 Binary Data object operators.
1413 */
1414 inline double rpow(double x,double y)
1415 {
1416 return pow(y,x);
1417 }
1418
1419 /**
1420 \brief
1421 Operator+
1422 Takes two Data objects.
1423 */
1424 ESCRIPT_DLL_API Data operator+(const Data& left, const Data& right);
1425
1426 /**
1427 \brief
1428 Operator-
1429 Takes two Data objects.
1430 */
1431 ESCRIPT_DLL_API Data operator-(const Data& left, const Data& right);
1432
1433 /**
1434 \brief
1435 Operator*
1436 Takes two Data objects.
1437 */
1438 ESCRIPT_DLL_API Data operator*(const Data& left, const Data& right);
1439
1440 /**
1441 \brief
1442 Operator/
1443 Takes two Data objects.
1444 */
1445 ESCRIPT_DLL_API Data operator/(const Data& left, const Data& right);
1446
1447 /**
1448 \brief
1449 Operator+
1450 Takes LHS Data object and RHS python::object.
1451 python::object must be convertable to Data type.
1452 */
1453 ESCRIPT_DLL_API Data operator+(const Data& left, const boost::python::object& right);
1454
1455 /**
1456 \brief
1457 Operator-
1458 Takes LHS Data object and RHS python::object.
1459 python::object must be convertable to Data type.
1460 */
1461 ESCRIPT_DLL_API Data operator-(const Data& left, const boost::python::object& right);
1462
1463 /**
1464 \brief
1465 Operator*
1466 Takes LHS Data object and RHS python::object.
1467 python::object must be convertable to Data type.
1468 */
1469 ESCRIPT_DLL_API Data operator*(const Data& left, const boost::python::object& right);
1470
1471 /**
1472 \brief
1473 Operator/
1474 Takes LHS Data object and RHS python::object.
1475 python::object must be convertable to Data type.
1476 */
1477 ESCRIPT_DLL_API Data operator/(const Data& left, const boost::python::object& right);
1478
1479 /**
1480 \brief
1481 Operator+
1482 Takes LHS python::object and RHS Data object.
1483 python::object must be convertable to Data type.
1484 */
1485 ESCRIPT_DLL_API Data operator+(const boost::python::object& left, const Data& right);
1486
1487 /**
1488 \brief
1489 Operator-
1490 Takes LHS python::object and RHS Data object.
1491 python::object must be convertable to Data type.
1492 */
1493 ESCRIPT_DLL_API Data operator-(const boost::python::object& left, const Data& right);
1494
1495 /**
1496 \brief
1497 Operator*
1498 Takes LHS python::object and RHS Data object.
1499 python::object must be convertable to Data type.
1500 */
1501 ESCRIPT_DLL_API Data operator*(const boost::python::object& left, const Data& right);
1502
1503 /**
1504 \brief
1505 Operator/
1506 Takes LHS python::object and RHS Data object.
1507 python::object must be convertable to Data type.
1508 */
1509 ESCRIPT_DLL_API Data operator/(const boost::python::object& left, const Data& right);
1510
1511
1512
1513 /**
1514 \brief
1515 Output operator
1516 */
1517 ESCRIPT_DLL_API std::ostream& operator<<(std::ostream& o, const Data& data);
1518
1519 /**
1520 \brief
1521 Compute a tensor product of two Data objects
1522 \param arg0 - Input - Data object
1523 \param arg1 - Input - Data object
1524 \param axis_offset - Input - axis offset
1525 \param transpose - Input - 0: transpose neither, 1: transpose arg0, 2: transpose arg1
1526 */
1527 ESCRIPT_DLL_API
1528 Data
1529 C_GeneralTensorProduct(Data& arg0,
1530 Data& arg1,
1531 int axis_offset=0,
1532 int transpose=0);
1533
1534
1535 /**
1536 \brief
1537 Compute a tensor operation with two Data objects
1538 \param arg0 - Input - Data object
1539 \param arg1 - Input - Data object
1540 \param operation - Input - Binary op functor
1541 */
1542 template <typename BinaryFunction>
1543 ESCRIPT_DLL_API
1544 Data
1545 C_TensorBinaryOperation(Data const &arg0,
1546 Data const &arg1,
1547 BinaryFunction operation);
1548
1549 /**
1550 \brief
1551 Return true if operands are equivalent, else return false.
1552 NB: this operator does very little at this point, and isn't to
1553 be relied on. Requires further implementation.
1554 */
1555 // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);
1556
1557 /**
1558 \brief
1559 Perform the given binary operation with this and right as operands.
1560 Right is a Data object.
1561 */
1562 template <class BinaryFunction>
1563 inline
1564 void
1565 Data::binaryOp(const Data& right,
1566 BinaryFunction operation)
1567 {
1568 //
1569 // if this has a rank of zero promote it to the rank of the RHS
1570 if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1571 throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");
1572 }
1573 //
1574 // initially make the temporary a shallow copy
1575 Data tempRight(right);
1576 if (getFunctionSpace()!=right.getFunctionSpace()) {
1577 if (right.probeInterpolation(getFunctionSpace())) {
1578 //
1579 // an interpolation is required so create a new Data
1580 tempRight=Data(right,this->getFunctionSpace());
1581 } else if (probeInterpolation(right.getFunctionSpace())) {
1582 //
1583 // interpolate onto the RHS function space
1584 Data tempLeft(*this,right.getFunctionSpace());
1585 m_data=tempLeft.m_data;
1586 }
1587 }
1588 operandCheck(tempRight);
1589 //
1590 // ensure this has the right type for the RHS
1591 typeMatchRight(tempRight);
1592 //
1593 // Need to cast to the concrete types so that the correct binaryOp
1594 // is called.
1595 if (isExpanded()) {
1596 //
1597 // Expanded data will be done in parallel, the right hand side can be
1598 // of any data type
1599 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1600 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1601 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1602 } else if (isTagged()) {
1603 //
1604 // Tagged data is operated on serially, the right hand side can be
1605 // either DataConstant or DataTagged
1606 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1607 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1608 if (right.isTagged()) {
1609 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1610 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1611 escript::binaryOp(*leftC,*rightC,operation);
1612 } else {
1613 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1614 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1615 escript::binaryOp(*leftC,*rightC,operation);
1616 }
1617 } else if (isConstant()) {
1618 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1619 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1620 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1621 escript::binaryOp(*leftC,*rightC,operation);
1622 }
1623 }
1624
1625 /**
1626 \brief
1627 Perform the given unary operation on other and return the result.
1628 Given operation is performed on each element of each data point, thus
1629 argument object is a rank n Data object, and returned object is a rank n
1630 Data object.
1631 Calls Data::unaryOp.
1632 */
1633 template <class UnaryFunction>
1634 inline
1635 Data
1636 unaryOp(const Data& other,
1637 UnaryFunction operation)
1638 {
1639 Data result;
1640 result.copy(other);
1641 result.unaryOp(operation);
1642 return result;
1643 }
1644
1645 /**
1646 \brief
1647 Perform the given unary operation on this.
1648 Given operation is performed on each element of each data point.
1649 Calls escript::unaryOp.
1650 */
1651 template <class UnaryFunction>
1652 inline
1653 void
1654 Data::unaryOp(UnaryFunction operation)
1655 {
1656 if (isExpanded()) {
1657 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1658 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1659 escript::unaryOp(*leftC,operation);
1660 } else if (isTagged()) {
1661 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1662 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1663 escript::unaryOp(*leftC,operation);
1664 } else if (isConstant()) {
1665 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1666 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1667 escript::unaryOp(*leftC,operation);
1668 }
1669 }
1670
1671 /**
1672 \brief
1673 Perform the given Data object reduction algorithm on this and return the result.
1674 Given operation combines each element of each data point, thus argument
1675 object (*this) is a rank n Data object, and returned object is a scalar.
1676 Calls escript::algorithm.
1677 */
1678 template <class BinaryFunction>
1679 inline
1680 double
1681 Data::algorithm(BinaryFunction operation, double initial_value) const
1682 {
1683 if (isExpanded()) {
1684 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1685 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1686 return escript::algorithm(*leftC,operation,initial_value);
1687 } else if (isTagged()) {
1688 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1689 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1690 return escript::algorithm(*leftC,operation,initial_value);
1691 } else if (isConstant()) {
1692 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1693 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1694 return escript::algorithm(*leftC,operation,initial_value);
1695 }
1696 return 0;
1697 }
1698
1699 /**
1700 \brief
1701 Perform the given data point reduction algorithm on data and return the result.
1702 Given operation combines each element within each data point into a scalar,
1703 thus argument object is a rank n Data object, and returned object is a
1704 rank 0 Data object.
1705 Calls escript::dp_algorithm.
1706 */
1707 template <class BinaryFunction>
1708 inline
1709 Data
1710 Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1711 {
1712 if (isExpanded()) {
1713 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1714 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1715 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1716 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1717 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1718 escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1719 return result;
1720 } else if (isTagged()) {
1721 DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1722 DataArrayView::ShapeType viewShape;
1723 DataArrayView::ValueType viewData(1);
1724 viewData[0]=0;
1725 DataArrayView defaultValue(viewData,viewShape);
1726 DataTagged::TagListType keys;
1727 DataTagged::ValueListType values;
1728 DataTagged::DataMapType::const_iterator i;
1729 for (i=dataT->getTagLookup().begin();i!=dataT->getTagLookup().end();i++) {
1730 keys.push_back(i->first);
1731 values.push_back(defaultValue);
1732 }
1733 Data result(keys,values,defaultValue,getFunctionSpace());
1734 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1735 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1736 EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1737 escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1738 return result;
1739 } else if (isConstant()) {
1740 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1741 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1742 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1743 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1744 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1745 escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1746 return result;
1747 }
1748 Data falseRetVal; // to keep compiler quiet
1749 return falseRetVal;
1750 }
1751
1752 template <typename BinaryFunction>
1753 Data
1754 C_TensorBinaryOperation(Data const &arg_0,
1755 Data const &arg_1,
1756 BinaryFunction operation)
1757 {
1758 // Interpolate if necessary and find an appropriate function space
1759 Data arg_0_Z, arg_1_Z;
1760 if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {
1761 if (arg_0.probeInterpolation(arg_1.getFunctionSpace())) {
1762 arg_0_Z = arg_0.interpolate(arg_1.getFunctionSpace());
1763 arg_1_Z = Data(arg_1);
1764 }
1765 else if (arg_1.probeInterpolation(arg_0.getFunctionSpace())) {
1766 arg_1_Z=arg_1.interpolate(arg_0.getFunctionSpace());
1767 arg_0_Z =Data(arg_0);
1768 }
1769 else {
1770 throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible function spaces.");
1771 }
1772 } else {
1773 arg_0_Z = Data(arg_0);
1774 arg_1_Z = Data(arg_1);
1775 }
1776 // Get rank and shape of inputs
1777 int rank0 = arg_0_Z.getDataPointRank();
1778 int rank1 = arg_1_Z.getDataPointRank();
1779 DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();
1780 DataArrayView::ShapeType shape1 = arg_1_Z.getDataPointShape();
1781 int size0 = arg_0_Z.getDataPointSize();
1782 int size1 = arg_1_Z.getDataPointSize();
1783
1784 // Declare output Data object
1785 Data res;
1786
1787 if (shape0 == shape1) {
1788
1789 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
1790 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataConstant output
1791 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1792 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1793 double *ptr_2 = &((res.getPointDataView().getData())[0]);
1794 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1795 }
1796 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
1797
1798 // Prepare the DataConstant input
1799 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1800
1801 // Borrow DataTagged input from Data object
1802 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1803
1804 // Prepare a DataTagged output 2
1805 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataTagged output
1806 res.tag();
1807 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1808
1809 // Prepare offset into DataConstant
1810 int offset_0 = tmp_0->getPointOffset(0,0);
1811 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1812 // Get the views
1813 DataArrayView view_1 = tmp_1->getDefaultValue();
1814 DataArrayView view_2 = tmp_2->getDefaultValue();
1815 // Get the pointers to the actual data
1816 double *ptr_1 = &((view_1.getData())[0]);
1817 double *ptr_2 = &((view_2.getData())[0]);
1818 // Compute a result for the default
1819 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1820 // Compute a result for each tag
1821 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1822 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1823 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1824 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1825 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1826 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1827 double *ptr_1 = &view_1.getData(0);
1828 double *ptr_2 = &view_2.getData(0);
1829 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1830 }
1831
1832 }
1833 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
1834
1835 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1836 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
1837 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1838 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1839
1840 int sampleNo_1,dataPointNo_1;
1841 int numSamples_1 = arg_1_Z.getNumSamples();
1842 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
1843 int offset_0 = tmp_0->getPointOffset(0,0);
1844 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
1845 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
1846 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1847 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1848 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1849 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1850 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1851 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1852 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1853 }
1854 }
1855
1856 }
1857 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
1858
1859 // Borrow DataTagged input from Data object
1860 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1861
1862 // Prepare the DataConstant input
1863 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
1864
1865 // Prepare a DataTagged output 2
1866 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
1867 res.tag();
1868 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1869
1870 // Prepare offset into DataConstant
1871 int offset_1 = tmp_1->getPointOffset(0,0);
1872 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1873 // Get the views
1874 DataArrayView view_0 = tmp_0->getDefaultValue();
1875 DataArrayView view_2 = tmp_2->getDefaultValue();
1876 // Get the pointers to the actual data
1877 double *ptr_0 = &((view_0.getData())[0]);
1878 double *ptr_2 = &((view_2.getData())[0]);
1879 // Compute a result for the default
1880 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1881 // Compute a result for each tag
1882 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1883 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1884 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1885 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1886 DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1887 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1888 double *ptr_0 = &view_0.getData(0);
1889 double *ptr_2 = &view_2.getData(0);
1890 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1891 }
1892
1893 }
1894 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
1895
1896 // Borrow DataTagged input from Data object
1897 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1898
1899 // Borrow DataTagged input from Data object
1900 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1901
1902 // Prepare a DataTagged output 2
1903 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
1904 res.tag(); // DataTagged output
1905 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1906
1907 // Get the views
1908 DataArrayView view_0 = tmp_0->getDefaultValue();
1909 DataArrayView view_1 = tmp_1->getDefaultValue();
1910 DataArrayView view_2 = tmp_2->getDefaultValue();
1911 // Get the pointers to the actual data
1912 double *ptr_0 = &((view_0.getData())[0]);
1913 double *ptr_1 = &((view_1.getData())[0]);
1914 double *ptr_2 = &((view_2.getData())[0]);
1915 // Compute a result for the default
1916 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1917 // Merge the tags
1918 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1919 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1920 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1921 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1922 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
1923 }
1924 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1925 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
1926 }
1927 // Compute a result for each tag
1928 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1929 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1930 DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1931 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1932 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1933 double *ptr_0 = &view_0.getData(0);
1934 double *ptr_1 = &view_1.getData(0);
1935 double *ptr_2 = &view_2.getData(0);
1936 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1937 }
1938
1939 }
1940 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
1941
1942 // After finding a common function space above the two inputs have the same numSamples and num DPPS
1943 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1944 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
1945 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
1946 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1947
1948 int sampleNo_0,dataPointNo_0;
1949 int numSamples_0 = arg_0_Z.getNumSamples();
1950 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1951 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1952 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1953 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
1954 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1955 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1956 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
1957 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1958 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1959 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1960 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1961 }
1962 }
1963
1964 }
1965 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
1966
1967 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1968 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
1969 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
1970 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1971
1972 int sampleNo_0,dataPointNo_0;
1973 int numSamples_0 = arg_0_Z.getNumSamples();
1974 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
1975 int offset_1 = tmp_1->getPointOffset(0,0);
1976 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
1977 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
1978 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
1979 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
1980 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
1981 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1982 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1983 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1984 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1985 }
1986 }
1987
1988 }
1989 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
1990
1991 // After finding a common function space above the two inputs have the same numSamples and num DPPS
1992 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
1993 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
1994 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
1995 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
1996
1997 int sampleNo_0,dataPointNo_0;
1998 int numSamples_0 = arg_0_Z.getNumSamples();
1999 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2000 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2001 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2002 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2003 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2004 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2005 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2006 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2007 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2008 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2009 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2010 }
2011 }
2012
2013 }
2014 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2015
2016 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2017 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2018 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2019 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2020 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2021
2022 int sampleNo_0,dataPointNo_0;
2023 int numSamples_0 = arg_0_Z.getNumSamples();
2024 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2025 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2026 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2027 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2028 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2029 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2030 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2031 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2032 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2033 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2034 tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2035 }
2036 }
2037
2038 }
2039 else {
2040 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2041 }
2042
2043 } else if (0 == rank0) {
2044
2045 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
2046 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace()); // DataConstant output
2047 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2048 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
2049 double *ptr_2 = &((res.getPointDataView().getData())[0]);
2050 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2051 }
2052 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
2053
2054 // Prepare the DataConstant input
2055 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2056
2057 // Borrow DataTagged input from Data object
2058 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2059
2060 // Prepare a DataTagged output 2
2061 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace()); // DataTagged output
2062 res.tag();
2063 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2064
2065 // Prepare offset into DataConstant
2066 int offset_0 = tmp_0->getPointOffset(0,0);
2067 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2068 // Get the views
2069 DataArrayView view_1 = tmp_1->getDefaultValue();
2070 DataArrayView view_2 = tmp_2->getDefaultValue();
2071 // Get the pointers to the actual data
2072 double *ptr_1 = &((view_1.getData())[0]);
2073 double *ptr_2 = &((view_2.getData())[0]);
2074 // Compute a result for the default
2075 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2076 // Compute a result for each tag
2077 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2078 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2079 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2080 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2081 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2082 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2083 double *ptr_1 = &view_1.getData(0);
2084 double *ptr_2 = &view_2.getData(0);
2085 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2086 }
2087
2088 }
2089 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
2090
2091 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2092 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2093 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2094 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2095
2096 int sampleNo_1,dataPointNo_1;
2097 int numSamples_1 = arg_1_Z.getNumSamples();
2098 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2099 int offset_0 = tmp_0->getPointOffset(0,0);
2100 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2101 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2102 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2103 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2104 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2105 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2106 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2107 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2108 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2109
2110 }
2111 }
2112
2113 }
2114 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
2115
2116 // Borrow DataTagged input from Data object
2117 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2118
2119 // Prepare the DataConstant input
2120 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2121
2122 // Prepare a DataTagged output 2
2123 res = Data(0.0, shape1, arg_0_Z.getFunctionSpace()); // DataTagged output
2124 res.tag();
2125 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2126
2127 // Prepare offset into DataConstant
2128 int offset_1 = tmp_1->getPointOffset(0,0);
2129 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2130 // Get the views
2131 DataArrayView view_0 = tmp_0->getDefaultValue();
2132 DataArrayView view_2 = tmp_2->getDefaultValue();
2133 // Get the pointers to the actual data
2134 double *ptr_0 = &((view_0.getData())[0]);
2135 double *ptr_2 = &((view_2.getData())[0]);
2136 // Compute a result for the default
2137 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2138 // Compute a result for each tag
2139 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2140 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2141 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2142 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2143 DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2144 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2145 double *ptr_0 = &view_0.getData(0);
2146 double *ptr_2 = &view_2.getData(0);
2147 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2148 }
2149
2150 }
2151 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
2152
2153 // Borrow DataTagged input from Data object
2154 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2155
2156 // Borrow DataTagged input from Data object
2157 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2158
2159 // Prepare a DataTagged output 2
2160 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());
2161 res.tag(); // DataTagged output
2162 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2163
2164 // Get the views
2165 DataArrayView view_0 = tmp_0->getDefaultValue();
2166 DataArrayView view_1 = tmp_1->getDefaultValue();
2167 DataArrayView view_2 = tmp_2->getDefaultValue();
2168 // Get the pointers to the actual data
2169 double *ptr_0 = &((view_0.getData())[0]);
2170 double *ptr_1 = &((view_1.getData())[0]);
2171 double *ptr_2 = &((view_2.getData())[0]);
2172 // Compute a result for the default
2173 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2174 // Merge the tags
2175 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2176 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2177 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2178 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2179 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
2180 }
2181 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2182 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2183 }
2184 // Compute a result for each tag
2185 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2186 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2187 DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2188 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2189 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2190 double *ptr_0 = &view_0.getData(0);
2191 double *ptr_1 = &view_1.getData(0);
2192 double *ptr_2 = &view_2.getData(0);
2193 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2194 }
2195
2196 }
2197 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
2198
2199 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2200 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2201 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2202 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2203 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2204
2205 int sampleNo_0,dataPointNo_0;
2206 int numSamples_0 = arg_0_Z.getNumSamples();
2207 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2208 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2209 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2210 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2211 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2212 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2213 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2214 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2215 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2216 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2217 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2218 }
2219 }
2220
2221 }
2222 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2223
2224 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2225 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2226 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2227 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2228
2229 int sampleNo_0,dataPointNo_0;
2230 int numSamples_0 = arg_0_Z.getNumSamples();
2231 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2232 int offset_1 = tmp_1->getPointOffset(0,0);
2233 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2234 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2235 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2236 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2237 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2238 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2239 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2240 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2241 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2242 }
2243 }
2244
2245
2246 }
2247 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2248
2249 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2250 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2251 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2252 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2253 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2254
2255 int sampleNo_0,dataPointNo_0;
2256 int numSamples_0 = arg_0_Z.getNumSamples();
2257 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2258 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2259 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2260 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2261 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2262 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2263 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2264 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2265 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2266 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2267 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2268 }
2269 }
2270
2271 }
2272 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2273
2274 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2275 res = Data(0.0, shape1, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2276 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2277 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2278 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2279
2280 int sampleNo_0,dataPointNo_0;
2281 int numSamples_0 = arg_0_Z.getNumSamples();
2282 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2283 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2284 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2285 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2286 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2287 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2288 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2289 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2290 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2291 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2292 tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2293 }
2294 }
2295
2296 }
2297 else {
2298 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2299 }
2300
2301 } else if (0 == rank1) {
2302
2303 if (arg_0_Z.isConstant() && arg_1_Z.isConstant()) {
2304 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataConstant output
2305 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2306 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
2307 double *ptr_2 = &((res.getPointDataView().getData())[0]);
2308 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2309 }
2310 else if (arg_0_Z.isConstant() && arg_1_Z.isTagged()) {
2311
2312 // Prepare the DataConstant input
2313 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2314
2315 // Borrow DataTagged input from Data object
2316 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2317
2318 // Prepare a DataTagged output 2
2319 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace()); // DataTagged output
2320 res.tag();
2321 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2322
2323 // Prepare offset into DataConstant
2324 int offset_0 = tmp_0->getPointOffset(0,0);
2325 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2326 // Get the views
2327 DataArrayView view_1 = tmp_1->getDefaultValue();
2328 DataArrayView view_2 = tmp_2->getDefaultValue();
2329 // Get the pointers to the actual data
2330 double *ptr_1 = &((view_1.getData())[0]);
2331 double *ptr_2 = &((view_2.getData())[0]);
2332 // Compute a result for the default
2333 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2334 // Compute a result for each tag
2335 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2336 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2337 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2338 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2339 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2340 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2341 double *ptr_1 = &view_1.getData(0);
2342 double *ptr_2 = &view_2.getData(0);
2343 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2344 }
2345
2346 }
2347 else if (arg_0_Z.isConstant() && arg_1_Z.isExpanded()) {
2348
2349 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2350 DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0_Z.borrowData());
2351 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2352 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2353
2354 int sampleNo_1,dataPointNo_1;
2355 int numSamples_1 = arg_1_Z.getNumSamples();
2356 int numDataPointsPerSample_1 = arg_1_Z.getNumDataPointsPerSample();
2357 int offset_0 = tmp_0->getPointOffset(0,0);
2358 #pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static)
2359 for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) {
2360 for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2361 int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2362 int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2363 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2364 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2365 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2366 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2367 }
2368 }
2369
2370 }
2371 else if (arg_0_Z.isTagged() && arg_1_Z.isConstant()) {
2372
2373 // Borrow DataTagged input from Data object
2374 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2375
2376 // Prepare the DataConstant input
2377 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2378
2379 // Prepare a DataTagged output 2
2380 res = Data(0.0, shape0, arg_0_Z.getFunctionSpace()); // DataTagged output
2381 res.tag();
2382 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2383
2384 // Prepare offset into DataConstant
2385 int offset_1 = tmp_1->getPointOffset(0,0);
2386 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2387 // Get the views
2388 DataArrayView view_0 = tmp_0->getDefaultValue();
2389 DataArrayView view_2 = tmp_2->getDefaultValue();
2390 // Get the pointers to the actual data
2391 double *ptr_0 = &((view_0.getData())[0]);
2392 double *ptr_2 = &((view_2.getData())[0]);
2393 // Compute a result for the default
2394 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2395 // Compute a result for each tag
2396 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2397 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2398 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2399 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2400 DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2401 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2402 double *ptr_0 = &view_0.getData(0);
2403 double *ptr_2 = &view_2.getData(0);
2404 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2405 }
2406
2407 }
2408 else if (arg_0_Z.isTagged() && arg_1_Z.isTagged()) {
2409
2410 // Borrow DataTagged input from Data object
2411 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2412
2413 // Borrow DataTagged input from Data object
2414 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2415
2416 // Prepare a DataTagged output 2
2417 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());
2418 res.tag(); // DataTagged output
2419 DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2420
2421 // Get the views
2422 DataArrayView view_0 = tmp_0->getDefaultValue();
2423 DataArrayView view_1 = tmp_1->getDefaultValue();
2424 DataArrayView view_2 = tmp_2->getDefaultValue();
2425 // Get the pointers to the actual data
2426 double *ptr_0 = &((view_0.getData())[0]);
2427 double *ptr_1 = &((view_1.getData())[0]);
2428 double *ptr_2 = &((view_2.getData())[0]);
2429 // Compute a result for the default
2430 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2431 // Merge the tags
2432 DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2433 const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2434 const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2435 for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2436 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape
2437 }
2438 for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2439 tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());
2440 }
2441 // Compute a result for each tag
2442 const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2443 for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2444 DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2445 DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2446 DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2447 double *ptr_0 = &view_0.getData(0);
2448 double *ptr_1 = &view_1.getData(0);
2449 double *ptr_2 = &view_2.getData(0);
2450 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2451 }
2452
2453 }
2454 else if (arg_0_Z.isTagged() && arg_1_Z.isExpanded()) {
2455
2456 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2457 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2458 DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0_Z.borrowData());
2459 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2460 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2461
2462 int sampleNo_0,dataPointNo_0;
2463 int numSamples_0 = arg_0_Z.getNumSamples();
2464 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2465 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2466 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2467 int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2468 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2469 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2470 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2471 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2472 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2473 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2474 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2475 }
2476 }
2477
2478 }
2479 else if (arg_0_Z.isExpanded() && arg_1_Z.isConstant()) {
2480
2481 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2482 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2483 DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1_Z.borrowData());
2484 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2485
2486 int sampleNo_0,dataPointNo_0;
2487 int numSamples_0 = arg_0_Z.getNumSamples();
2488 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2489 int offset_1 = tmp_1->getPointOffset(0,0);
2490 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2491 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2492 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2493 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2494 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2495 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2496 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2497 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2498 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2499 }
2500 }
2501
2502
2503 }
2504 else if (arg_0_Z.isExpanded() && arg_1_Z.isTagged()) {
2505
2506 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2507 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2508 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2509 DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1_Z.borrowData());
2510 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2511
2512 int sampleNo_0,dataPointNo_0;
2513 int numSamples_0 = arg_0_Z.getNumSamples();
2514 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2515 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2516 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2517 int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2518 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2519 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2520 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2521 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2522 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2523 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2524 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2525 }
2526 }
2527
2528 }
2529 else if (arg_0_Z.isExpanded() && arg_1_Z.isExpanded()) {
2530
2531 // After finding a common function space above the two inputs have the same numSamples and num DPPS
2532 res = Data(0.0, shape0, arg_1_Z.getFunctionSpace(),true); // DataExpanded output
2533 DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0_Z.borrowData());
2534 DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1_Z.borrowData());
2535 DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(res.borrowData());
2536
2537 int sampleNo_0,dataPointNo_0;
2538 int numSamples_0 = arg_0_Z.getNumSamples();
2539 int numDataPointsPerSample_0 = arg_0_Z.getNumDataPointsPerSample();
2540 #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2541 for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2542 for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2543 int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2544 int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2545 int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2546 double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2547 double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2548 double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2549 tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2550 }
2551 }
2552
2553 }
2554 else {
2555 throw DataException("Error - C_TensorBinaryOperation: unknown combination of inputs");
2556 }
2557
2558 } else {
2559 throw DataException("Error - C_TensorBinaryOperation: arguments have incompatible shapes");
2560 }
2561
2562 return res;
2563 }
2564
2565 }
2566 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26