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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1712 - (show annotations)
Wed Aug 20 05:04:28 2008 UTC (10 years, 9 months ago) by jfenwick
File MIME type: text/plain
File size: 89004 byte(s)
Branch commit.

Finished first pass of Data.h - There is still a constructor which takes 
a DataArrayView as a parameter. Apart from that, there are no direct 
references to DataArrayView.

DataTagged has a new constructor for copying just the tags from an 
existing object.
DataTypes:: now has a scalarShape constant (to avoid creating one 
everytime you create a scalar).



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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26