/[escript]/trunk/escript/src/Data.h
ViewVC logotype

Annotation of /trunk/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26