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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1952 - (hide annotations)
Thu Oct 30 06:16:00 2008 UTC (11 years, 3 months ago) by jfenwick
File MIME type: text/plain
File size: 88577 byte(s)
Fixed /* in a comment.
The rank of a datapoint is now an unsigned int.

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26