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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1872 - (hide annotations)
Mon Oct 13 00:18:55 2008 UTC (11 years, 4 months ago) by jfenwick
File MIME type: text/plain
File size: 88617 byte(s)
Closing the moreshared branch

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26