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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1864 - (hide annotations)
Thu Oct 9 03:09:30 2008 UTC (11 years ago) by jfenwick
File MIME type: text/plain
File size: 88392 byte(s)
Branch commit
It compiles but doesn't do much.


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26