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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 108 - (hide annotations)
Thu Jan 27 06:21:59 2005 UTC (14 years, 7 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 32508 byte(s)
*** empty log message ***

1 jgs 94 // $Id$
2     /*=============================================================================
3    
4     ******************************************************************************
5     * *
6     * COPYRIGHT ACcESS 2004 - All Rights Reserved *
7     * *
8     * This software is the property of ACcESS. No part of this code *
9     * may be copied in any form or by any means without the expressed written *
10     * consent of ACcESS. Copying, use or modification of this software *
11     * by any unauthorised person is illegal unless that *
12     * person has a software license agreement with ACcESS. *
13     * *
14     ******************************************************************************
15    
16     ******************************************************************************/
17    
18     #ifndef DATA_H
19     #define DATA_H
20    
21     #include "escript/Data/DataAbstract.h"
22     #include "escript/Data/DataTagged.h"
23     #include "escript/Data/FunctionSpace.h"
24     #include "escript/Data/BinaryOp.h"
25     #include "escript/Data/UnaryOp.h"
26 jgs 108 #include "escript/Data/DataException.h"
27 jgs 94
28     extern "C" {
29     #include "escript/Data/DataC.h"
30     }
31    
32     #include <iostream>
33     #include <string>
34     #include <memory>
35     #include <algorithm>
36    
37     #include <boost/shared_ptr.hpp>
38     #include <boost/python/object.hpp>
39     #include <boost/python/list.hpp>
40     #include <boost/python/tuple.hpp>
41     #include <boost/python/numeric.hpp>
42    
43     /**
44     \brief
45     Data is essentially a factory class which creates the appropriate Data
46     object for the given construction arguments. It retains control over
47     the object created for the lifetime of the object.
48     The type of Data object referred to may change during the lifetime of
49     the Data object.
50    
51     Description:
52     Data is essentially a factory class which creates the appropriate Data
53     object for the given construction arguments. It retains control over
54     the object created for the lifetime of the object.
55     The type of Data object referred to may change during the lifetime of
56     the Data object.
57     */
58    
59     namespace escript {
60    
61     //
62     // Forward declaration for various implimentations of Data.
63     class DataEmpty;
64     class DataConstant;
65     class DataTagged;
66     class DataExpanded;
67    
68     class Data {
69    
70     public:
71    
72     typedef double (*UnaryDFunPtr)(double);
73     typedef double (*BinaryDFunPtr)(double,double);
74    
75     /**
76 jgs 102 Constructors.
77     */
78    
79     /**
80 jgs 94 \brief
81     Default constructor.
82     Creates a DataEmpty object.
83     */
84     Data();
85    
86     /**
87     \brief
88     Copy constructor.
89     WARNING: Only performs a shallow copy.
90     */
91     Data(const Data& inData);
92    
93     /**
94     \brief
95     Constructor from another Data object. If "what" is different from the
96 jgs 102 function space of inData the inData are tried to be interpolated to what,
97 jgs 94 otherwise a shallow copy of inData is returned.
98     */
99     Data(const Data& inData,
100     const FunctionSpace& what);
101    
102     /**
103     \brief
104     Constructor which copies data from a DataArrayView.
105    
106     \param value - Input - Data value for a single point.
107     \param what - Input - A description of what this data represents.
108     \param expanded - Input - Flag, if true fill the entire container with
109     the value. Otherwise a more efficient storage
110     mechanism will be used.
111     */
112     Data(const DataArrayView& value,
113     const FunctionSpace& what=FunctionSpace(),
114     bool expanded=false);
115    
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     Data(double value,
128     const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),
129     const FunctionSpace& what=FunctionSpace(),
130     bool expanded=false);
131    
132     /**
133     \brief
134     Constructor which performs a deep copy of a region from another Data object.
135    
136     \param inData - Input - Input Data object.
137     \param region - Input - Region to copy.
138     */
139     Data(const Data& inData,
140     const DataArrayView::RegionType& region);
141    
142     /**
143     \brief
144     Constructor which will create Tagged data if expanded is false.
145     No attempt is made to ensure the tag keys match the tag keys
146     within the function space.
147    
148     \param tagKeys - Input - List of tag values.
149     \param values - Input - List of values, one for each tag.
150     \param defaultValue - Input - A default value, used if tag doesn't exist.
151     \param what - Input - A description of what this data represents.
152     \param expanded - Input - Flag, if true fill the entire container with
153     the appropriate values.
154     */
155     Data(const DataTagged::TagListType& tagKeys,
156     const DataTagged::ValueListType& values,
157     const DataArrayView& defaultValue,
158     const FunctionSpace& what=FunctionSpace(),
159     bool expanded=false);
160    
161     /**
162     \brief
163     Constructor which copies data from a python numarray.
164    
165     \param value - Input - Data value for a single point.
166     \param what - Input - A description of what this data represents.
167     \param expanded - Input - Flag, if true fill the entire container with
168     the value. Otherwise a more efficient storage
169     mechanism will be used.
170     */
171     Data(const boost::python::numeric::array& value,
172     const FunctionSpace& what=FunctionSpace(),
173     bool expanded=false);
174    
175     /**
176     \brief
177     Constructor which copies data from any object that can be converted into
178     a python numarray.
179    
180     \param value - Input - Input data.
181     \param what - Input - A description of what this data represents.
182     \param expanded - Input - Flag, if true fill the entire container with
183     the value. Otherwise a more efficient storage
184     mechanism will be used.
185     */
186     Data(const boost::python::object& value,
187     const FunctionSpace& what=FunctionSpace(),
188     bool expanded=false);
189    
190     /**
191     \brief
192     Constructor which creates a DataConstant.
193     Copies data from any object that can be converted
194     into a numarray. All other parameters are copied from other.
195    
196     \param value - Input - Input data.
197     \param other - Input - contains all other parameters.
198     */
199     Data(const boost::python::object& value,
200     const Data& other);
201    
202     /**
203     \brief
204     Constructor which creates a DataConstant of "shape" with constant value.
205     */
206     Data(double value,
207     const boost::python::tuple& shape=boost::python::make_tuple(),
208     const FunctionSpace& what=FunctionSpace(),
209     bool expanded=false);
210    
211     /**
212     \brief
213 jgs 102 Perform a deep copy.
214 jgs 94 */
215     void
216 jgs 102 copy(const Data& other);
217 jgs 94
218     /**
219 jgs 102 Member access methods.
220 jgs 94 */
221    
222     /**
223     \brief
224     Return the C wrapper for the Data object.
225     */
226 jgs 102 escriptDataC
227     getDataC();
228 jgs 94
229     /**
230     \brief
231     Return the C wrapper for the Data object - const version.
232     */
233 jgs 102 escriptDataC
234     getDataC() const;
235 jgs 94
236     /**
237     \brief
238     Write the data as a string.
239     */
240 jgs 102 inline
241     std::string
242     toString() const
243     {
244     return m_data->toString();
245     }
246 jgs 94
247     /**
248     \brief
249     Return the DataArrayView of the point data. This essentially contains
250     the shape information for each data point although it also may be used
251     to manipulate the point data.
252     */
253     inline
254     const DataArrayView&
255     getPointDataView() const
256     {
257     return m_data->getPointDataView();
258     }
259    
260     /**
261     \brief
262 jgs 102 Whatever the current Data type make this into a DataExpanded.
263 jgs 94 */
264     void
265     expand();
266    
267     /**
268     \brief
269 jgs 102 If possible convert this Data to DataTagged. This will only allow
270 jgs 94 Constant data to be converted to tagged. An attempt to convert
271     Expanded data to tagged will throw an exception.
272     */
273     void
274     tag();
275    
276     /**
277     \brief
278     Return true if this Data is expanded.
279     */
280     bool
281     isExpanded() const;
282    
283     /**
284     \brief
285     Return true if this Data is tagged.
286     */
287     bool
288     isTagged() const;
289    
290     /**
291     \brief
292 jgs 102 Return true if this Data is constant.
293 jgs 94 */
294     bool
295 jgs 102 isConstant() const;
296 jgs 94
297     /**
298     \brief
299 jgs 102 Return true if this Data is empty.
300 jgs 94 */
301     bool
302 jgs 102 isEmpty() const;
303 jgs 94
304     /**
305     \brief
306     Return the function space.
307     */
308     inline
309     const FunctionSpace&
310     getFunctionSpace() const
311     {
312     return m_data->getFunctionSpace();
313     }
314    
315     /**
316     \brief
317     Return a copy of the function space.
318     */
319     const FunctionSpace
320     getCopyOfFunctionSpace() const;
321    
322     /**
323     \brief
324     Return the domain.
325     */
326     inline
327     const AbstractDomain&
328     getDomain() const
329     {
330     return getFunctionSpace().getDomain();
331     }
332    
333     /**
334     \brief
335     Return a copy of the domain.
336     */
337     const AbstractDomain
338     getCopyOfDomain() const;
339    
340     /**
341     \brief
342     Return the rank of the point data.
343     */
344     inline
345     int
346     getDataPointRank() const
347     {
348     return m_data->getPointDataView().getRank();
349     }
350    
351     /**
352     \brief
353 jgs 102 Return the number of samples.
354 jgs 94 */
355     inline
356     int
357 jgs 102 getNumSamples() const
358 jgs 94 {
359 jgs 102 return m_data->getNumSamples();
360 jgs 94 }
361    
362     /**
363     \brief
364 jgs 102 Return the number of data points per sample.
365 jgs 94 */
366 jgs 102 inline
367 jgs 94 int
368 jgs 102 getNumDataPointsPerSample() const
369     {
370     return m_data->getNumDPPSample();
371     }
372 jgs 94
373     /**
374     \brief
375     Return the sample data for the given sample no. This is not the
376     preferred interface but is provided for use by C code.
377     \param sampleNo - Input - the given sample no.
378     */
379 jgs 102 inline
380 jgs 94 DataAbstract::ValueType::value_type*
381 jgs 102 getSampleData(DataAbstract::ValueType::size_type sampleNo)
382     {
383     return m_data->getSampleData(sampleNo);
384     }
385 jgs 94
386     /**
387     \brief
388     Return the sample data for the given tag. If an attempt is made to
389     access data that isn't tagged an exception will be thrown.
390     \param tag - Input - the tag key.
391     */
392 jgs 102 inline
393 jgs 94 DataAbstract::ValueType::value_type*
394 jgs 102 getSampleDataByTag(int tag)
395     {
396     return m_data->getSampleDataByTag(tag);
397     }
398 jgs 94
399     /**
400     \brief
401     Return a view into the data for the data point specified.
402     NOTE: Construction of the DataArrayView is a relatively expensive
403     operation.
404     \param sampleNo - Input -
405     \param dataPointNo - Input -
406     */
407     inline
408     DataArrayView
409     getDataPoint(int sampleNo,
410     int dataPointNo)
411     {
412     return m_data->getDataPoint(sampleNo,dataPointNo);
413     }
414    
415     /**
416     \brief
417     Return a reference to the data point shape.
418     */
419     const DataArrayView::ShapeType&
420     getDataPointShape() const;
421    
422     /**
423     \brief
424 jgs 102 Return the data point shape as a tuple of integers.
425 jgs 94 */
426     boost::python::tuple
427     getShapeTuple() const;
428    
429     /**
430     \brief
431     Return the size of the data point. It is the product of the
432     data point shape dimensions.
433     */
434     int
435     getDataPointSize() const;
436    
437     /**
438     \brief
439 jgs 102 Return the number of doubles stored for this Data.
440 jgs 94 */
441     DataArrayView::ValueType::size_type
442     getLength() const;
443    
444     /**
445     \brief
446 jgs 102 Assign the given value to the tag. Implicitly converts this
447     object to type DataTagged. Throws an exception if this object
448     cannot be converted to a DataTagged object.
449     \param tagKey - Input - Integer key.
450     \param value - Input - Value to associate with given key.
451 jgs 94 */
452 jgs 102 void
453     setTaggedValue(int tagKey,
454     const boost::python::object& value);
455    
456     /**
457     \brief
458     Assign the given value to the tag. Implicitly converts this
459     object to type DataTagged. Throws an exception if this object
460     cannot be converted to a DataTagged object.
461     \param tagKey - Input - Integer key.
462     \param value - Input - Value to associate with given key.
463     Note: removed for now - this version not needed, and breaks escript.cpp
464     */
465     /*
466     void
467     setTaggedValue(int tagKey,
468     const DataArrayView& value);
469     */
470    
471     /**
472     \brief
473     Copy other Data object into this Data object where mask is positive.
474     */
475     void
476     copyWithMask(const Data& other,
477     const Data& mask);
478    
479     /**
480     Data object operation methods and operators.
481     */
482    
483     /**
484     \brief
485     Interpolates this onto the given functionspace and returns
486     the result as a Data object.
487     */
488 jgs 94 Data
489     interpolate(const FunctionSpace& functionspace) const;
490    
491     /**
492     \brief
493     Calculates the gradient of the data at the data points of functionspace.
494     If functionspace is not present the function space of Function(getDomain()) is used.
495     */
496     Data
497     gradOn(const FunctionSpace& functionspace) const;
498    
499     Data
500     grad() const;
501    
502     /**
503     \brief
504     Calculate the integral over the function space domain.
505     */
506     boost::python::numeric::array
507     integrate() const;
508    
509     /**
510     \brief
511     Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
512     */
513     Data
514     wherePositive() const;
515    
516     /**
517     \brief
518 jgs 102 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
519 jgs 94 */
520     Data
521 jgs 102 whereNegative() const;
522    
523     /**
524     \brief
525     Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
526     */
527     Data
528 jgs 94 whereNonNegative() const;
529    
530     /**
531     \brief
532 jgs 102 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
533 jgs 94 */
534     Data
535 jgs 102 whereNonPositive() const;
536 jgs 94
537     /**
538     \brief
539 jgs 102 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
540 jgs 94 */
541     Data
542     whereZero() const;
543    
544     /**
545     \brief
546 jgs 102 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
547 jgs 94 */
548     Data
549 jgs 102 whereNonZero() const;
550    
551     /**
552     \brief
553     Return the sin of each data point of this Data object.
554     */
555     Data
556 jgs 94 sin() const;
557    
558     /**
559     \brief
560 jgs 102 Return the cos of each data point of this Data object.
561 jgs 94 */
562     Data
563     cos() const;
564    
565     /**
566     \brief
567 jgs 102 Return the tan of each data point of this Data object.
568 jgs 94 */
569     Data
570     tan() const;
571    
572     /**
573     \brief
574 jgs 102 Return the log to base 10 of each data point of this Data object.
575 jgs 94 */
576     Data
577     log() const;
578    
579     /**
580     \brief
581 jgs 102 Return the natural log of each data point of this Data object.
582 jgs 94 */
583     Data
584     ln() const;
585    
586     /**
587     \brief
588 jgs 102 Return the maximum absolute value of this Data object.
589 jgs 94 */
590 jgs 102 double
591     Lsup() const;
592 jgs 94
593     /**
594     \brief
595 jgs 102 Return the maximum value of this Data object.
596 jgs 94 */
597 jgs 102 double
598     sup() const;
599 jgs 94
600     /**
601     \brief
602 jgs 102 Return the minimum value of this Data object.
603 jgs 94 */
604     double
605 jgs 102 inf() const;
606 jgs 94
607     /**
608     \brief
609 jgs 102 Return the absolute value of each data point of this Data object.
610 jgs 94 */
611 jgs 102 Data
612     abs() const;
613 jgs 94
614     /**
615     \brief
616 jgs 102 Return the maximum value of each data point of this Data object.
617 jgs 94 */
618 jgs 102 Data
619     maxval() const;
620 jgs 94
621     /**
622     \brief
623 jgs 102 Return the minimum value of each data point of this Data object.
624 jgs 94 */
625     Data
626 jgs 102 minval() const;
627 jgs 94
628     /**
629     \brief
630 jgs 102 Return the length of each data point of this Data object.
631     sqrt(sum(A[i,j,k,l]^2))
632 jgs 94 */
633 jgs 102 Data
634     length() const;
635 jgs 94
636     /**
637     \brief
638 jgs 102 Return the sign of each data point of this Data object.
639     -1 for negative values, zero for zero values, 1 for positive values.
640 jgs 94 */
641 jgs 102 Data
642     sign() const;
643 jgs 94
644     /**
645 jgs 102 \transpose
646     Transpose each data point of this Data object around the given axis.
647 jgs 106 --* not implemented yet *--
648 jgs 102 */
649     Data
650     transpose(int axis) const;
651    
652     /**
653     \trace
654     Calculate the trace of each data point of this Data object.
655     sum(A[i,i,i,i])
656     */
657     Data
658     trace() const;
659    
660     /**
661     \exp
662     Return the exponential function of each data point of this Data object.
663     */
664     Data
665     exp() const;
666    
667     /**
668     \sqrt
669     Return the square root of each data point of this Data object.
670     */
671     Data
672     sqrt() const;
673    
674     /**
675 jgs 94 \brief
676 jgs 102 Return the given power of each data point of this Data object.
677     */
678     Data
679     powD(const Data& right) const;
680    
681     Data
682     powO(const boost::python::object& right) const;
683    
684     /**
685     \brief
686 jgs 104 writes the object to a file in the DX file format
687     */
688     void
689     saveDX(std::string fileName) const;
690    
691     /**
692     \brief
693 jgs 102 Return the negation of each data point of this Data object.
694     */
695     Data
696     neg() const;
697    
698     /**
699     \brief
700     Return the identity of each data point of this Data object.
701     Simply returns this object unmodified.
702     */
703     Data
704     pos() const;
705    
706     /**
707     \brief
708     Overloaded operator +=
709     \param right - Input - The right hand side.
710     */
711     Data& operator+=(const Data& right);
712     Data& operator+=(const boost::python::object& right);
713    
714     /**
715     \brief
716     Overloaded operator -=
717     \param right - Input - The right hand side.
718     */
719     Data& operator-=(const Data& right);
720     Data& operator-=(const boost::python::object& right);
721    
722     /**
723     \brief
724     Overloaded operator *=
725     \param right - Input - The right hand side.
726     */
727     Data& operator*=(const Data& right);
728     Data& operator*=(const boost::python::object& right);
729    
730     /**
731     \brief
732     Overloaded operator /=
733     \param right - Input - The right hand side.
734     */
735     Data& operator/=(const Data& right);
736     Data& operator/=(const boost::python::object& right);
737    
738     /**
739     \brief
740 jgs 94 Returns true if this can be interpolated to functionspace.
741     */
742     bool
743     probeInterpolation(const FunctionSpace& functionspace) const;
744    
745     /**
746 jgs 102 Data object slicing methods.
747     */
748    
749     /**
750 jgs 94 \brief
751 jgs 102 Returns a slice from this Data object.
752    
753     /description
754     Implements the [] get operator in python.
755     Calls getSlice.
756    
757     \param key - Input - python slice tuple specifying
758     slice to return.
759 jgs 94 */
760 jgs 102 Data
761     getItem(const boost::python::object& key) const;
762    
763     /**
764     \brief
765     Copies slice from value into this Data object.
766    
767     \description
768     Implements the [] set operator in python.
769     Calls setSlice.
770    
771     \param key - Input - python slice tuple specifying
772     slice to copy from value.
773     \param value - Input - Data object to copy from.
774     */
775 jgs 94 void
776 jgs 102 setItemD(const boost::python::object& key,
777     const Data& value);
778 jgs 94
779 jgs 102 void
780     setItemO(const boost::python::object& key,
781     const boost::python::object& value);
782    
783     // These following public methods should be treated as private.
784    
785 jgs 94 /**
786     \brief
787 jgs 102 Perform the given unary operation on every element of every data point in
788     this Data object.
789 jgs 94 */
790 jgs 102 template <class UnaryFunction>
791     inline
792 jgs 94 void
793 jgs 102 unaryOp(UnaryFunction operation);
794    
795     /**
796     \brief
797     Return a Data object containing the specified slice of
798     this Data object.
799     \param region - Input - Region to copy.
800 jgs 94 */
801 jgs 102 Data
802     getSlice(const DataArrayView::RegionType& region) const;
803 jgs 94
804 jgs 102 /**
805     \brief
806     Copy the specified slice from the given value into this
807     Data object.
808     \param value - Input - Data to copy from.
809     \param region - Input - Region to copy.
810     */
811     void
812     setSlice(const Data& value,
813     const DataArrayView::RegionType& region);
814    
815     protected:
816    
817 jgs 94 private:
818    
819     /**
820     \brief
821 jgs 102 Check *this and the right operand are compatible. Throws
822     an exception if they aren't.
823     \param right - Input - The right hand side.
824     */
825     inline
826     void
827     operandCheck(const Data& right) const
828     {
829     return m_data->operandCheck(*(right.m_data.get()));
830     }
831    
832     /**
833     \brief
834     Perform the specified reduction algorithm on every element of every data point in
835     this Data object and return the single double value result.
836     */
837     template <class UnaryFunction>
838     inline
839     double
840     algorithm(UnaryFunction operation) const;
841    
842 jgs 106 template <class UnaryFunction>
843     inline
844     Data
845     dp_algorithm(UnaryFunction operation) const;
846    
847 jgs 102 /**
848     \brief
849     Perform the given binary operation on all of the data's elements.
850     The underlying type of the right hand side (right) determines the final
851     type of *this after the operation. For example if the right hand side
852     is expanded *this will be expanded if necessary.
853     RHS is a Data object.
854     */
855     template <class BinaryFunction>
856     inline
857     void
858     binaryOp(const Data& right,
859     BinaryFunction operation);
860    
861     /**
862     \brief
863     Perform the given binary operation on all of the data's elements.
864     RHS is a boost::python object.
865     */
866     template <class BinaryFunction>
867     inline
868     void
869     binaryOp(const boost::python::object& right,
870     BinaryFunction operation);
871    
872     /**
873     \brief
874     Convert the data type of the RHS to match this.
875     \param right - Input - data type to match.
876     */
877     void
878     typeMatchLeft(Data& right) const;
879    
880     /**
881     \brief
882     Convert the data type of this to match the RHS.
883     \param right - Input - data type to match.
884     */
885     void
886     typeMatchRight(const Data& right);
887    
888     /**
889     \brief
890 jgs 94 Construct a Data object of the appropriate type.
891     */
892     template <class IValueType>
893     void
894     initialise(const IValueType& value,
895     const FunctionSpace& what,
896     bool expanded);
897    
898     /**
899     \brief
900     Reshape the data point if the data point is currently rank 0.
901     Will throw an exception if the data points are not rank 0.
902     The original data point value is used for all values of the new
903     data point.
904     */
905     void
906     reshapeDataPoint(const DataArrayView::ShapeType& shape);
907    
908     //
909 jgs 102 // pointer to the actual data object
910 jgs 94 boost::shared_ptr<DataAbstract> m_data;
911    
912     };
913    
914     template <class IValueType>
915     void
916     Data::initialise(const IValueType& value,
917     const FunctionSpace& what,
918     bool expanded)
919     {
920     //
921     // Construct a Data object of the appropriate type.
922     // Construct the object first as there seems to be a bug which causes
923     // undefined behaviour if an exception is thrown during construction
924     // within the shared_ptr constructor.
925     if (expanded) {
926     DataAbstract* temp=new DataExpanded(value,what);
927 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
928     m_data=temp_data;
929 jgs 94 } else {
930     DataAbstract* temp=new DataConstant(value,what);
931 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
932     m_data=temp_data;
933 jgs 94 }
934     }
935    
936 jgs 102 /**
937     Binary Data object operators.
938     */
939 jgs 94
940     /**
941     \brief
942     Operator+
943     Takes two Data objects.
944     */
945     Data operator+(const Data& left, const Data& right);
946    
947     /**
948     \brief
949     Operator-
950     Takes two Data objects.
951     */
952     Data operator-(const Data& left, const Data& right);
953    
954     /**
955     \brief
956     Operator*
957     Takes two Data objects.
958     */
959     Data operator*(const Data& left, const Data& right);
960    
961     /**
962     \brief
963     Operator/
964     Takes two Data objects.
965     */
966     Data operator/(const Data& left, const Data& right);
967    
968     /**
969     \brief
970     Operator+
971     Takes LHS Data object and RHS python::object.
972     python::object must be convertable to Data type.
973     */
974     Data operator+(const Data& left, const boost::python::object& right);
975    
976     /**
977     \brief
978     Operator-
979     Takes LHS Data object and RHS python::object.
980     python::object must be convertable to Data type.
981     */
982     Data operator-(const Data& left, const boost::python::object& right);
983    
984     /**
985     \brief
986     Operator*
987     Takes LHS Data object and RHS python::object.
988     python::object must be convertable to Data type.
989     */
990     Data operator*(const Data& left, const boost::python::object& right);
991    
992     /**
993     \brief
994     Operator/
995     Takes LHS Data object and RHS python::object.
996     python::object must be convertable to Data type.
997     */
998     Data operator/(const Data& left, const boost::python::object& right);
999    
1000     /**
1001     \brief
1002     Operator+
1003     Takes LHS python::object and RHS Data object.
1004     python::object must be convertable to Data type.
1005     */
1006     Data operator+(const boost::python::object& left, const Data& right);
1007    
1008     /**
1009     \brief
1010     Operator-
1011     Takes LHS python::object and RHS Data object.
1012     python::object must be convertable to Data type.
1013     */
1014     Data operator-(const boost::python::object& left, const Data& right);
1015    
1016     /**
1017     \brief
1018     Operator*
1019     Takes LHS python::object and RHS Data object.
1020     python::object must be convertable to Data type.
1021     */
1022     Data operator*(const boost::python::object& left, const Data& right);
1023    
1024     /**
1025     \brief
1026     Operator/
1027     Takes LHS python::object and RHS Data object.
1028     python::object must be convertable to Data type.
1029     */
1030     Data operator/(const boost::python::object& left, const Data& right);
1031    
1032     /**
1033     \brief
1034     Output operator
1035     */
1036     std::ostream& operator<<(std::ostream& o, const Data& data);
1037    
1038     /**
1039     \brief
1040     Return true if operands are equivalent, else return false.
1041     NB: this operator does very little at this point, and isn't to
1042     be relied on. Requires further implementation.
1043     */
1044 jgs 102 //bool operator==(const Data& left, const Data& right);
1045 jgs 94
1046 jgs 102 /**
1047     \brief
1048     Perform the given binary operation with this and right as operands.
1049     Right is a Data object.
1050     */
1051 jgs 94 template <class BinaryFunction>
1052     inline
1053     void
1054     Data::binaryOp(const Data& right,
1055     BinaryFunction operation)
1056     {
1057     //
1058     // if this has a rank of zero promote it to the rank of the RHS
1059     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1060     reshapeDataPoint(right.getPointDataView().getShape());
1061     }
1062     //
1063     // initially make the temporary a shallow copy
1064     Data tempRight(right);
1065     if (getFunctionSpace()!=right.getFunctionSpace()) {
1066     if (right.probeInterpolation(getFunctionSpace())) {
1067     //
1068     // an interpolation is required so create a new Data
1069     tempRight=Data(right,this->getFunctionSpace());
1070     } else if (probeInterpolation(right.getFunctionSpace())) {
1071     //
1072     // interpolate onto the RHS function space
1073     Data tempLeft(*this,right.getFunctionSpace());
1074     m_data=tempLeft.m_data;
1075     }
1076     }
1077     operandCheck(tempRight);
1078     //
1079     // ensure this has the right type for the RHS
1080 jgs 102 typeMatchRight(tempRight);
1081 jgs 94 //
1082     // Need to cast to the concrete types so that the correct binaryOp
1083     // is called.
1084     if (isExpanded()) {
1085     //
1086     // Expanded data will be done in parallel, the right hand side can be
1087     // of any data type
1088     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1089     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1090     escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1091     } else if (isTagged()) {
1092     //
1093     // Tagged data is operated on serially, the right hand side can be
1094     // either DataConstant or DataTagged
1095     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1096     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1097     if (right.isTagged()) {
1098     DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1099     EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1100     escript::binaryOp(*leftC,*rightC,operation);
1101     } else {
1102     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1103     EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1104     escript::binaryOp(*leftC,*rightC,operation);
1105     }
1106 jgs 102 } else if (isConstant()) {
1107 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1108     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1109     EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1110     escript::binaryOp(*leftC,*rightC,operation);
1111     }
1112     }
1113    
1114 jgs 102 /**
1115     \brief
1116     Perform the given binary operation with this and right as operands.
1117     Right is a boost::python object.
1118     */
1119 jgs 94 template <class BinaryFunction>
1120     inline
1121     void
1122     Data::binaryOp(const boost::python::object& right,
1123     BinaryFunction operation)
1124     {
1125     DataArray temp(right);
1126     //
1127     // if this has a rank of zero promote it to the rank of the RHS.
1128     if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1129     reshapeDataPoint(temp.getView().getShape());
1130     }
1131     //
1132     // Always allow scalar values for the RHS but check other shapes
1133     if (temp.getView().getRank()!=0) {
1134     if (!getPointDataView().checkShape(temp.getView().getShape())) {
1135     throw DataException(getPointDataView().createShapeErrorMessage(
1136     "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1137     }
1138     }
1139     if (isExpanded()) {
1140     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1141     EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1142     escript::binaryOp(*leftC,temp.getView(),operation);
1143     } else if (isTagged()) {
1144     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1145     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1146     escript::binaryOp(*leftC,temp.getView(),operation);
1147 jgs 102 } else if (isConstant()) {
1148 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1149     EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1150     escript::binaryOp(*leftC,temp.getView(),operation);
1151     }
1152     }
1153    
1154 jgs 102 /**
1155     \brief
1156     Perform the given unary operation on other and return the result.
1157     Given operation is performed on each element of each data point, thus
1158     argument object is a rank n Data object, and returned object is a rank n
1159     Data object.
1160     Calls Data::unaryOp.
1161     */
1162 jgs 94 template <class UnaryFunction>
1163     inline
1164 jgs 102 Data
1165     unaryOp(const Data& other,
1166     UnaryFunction operation)
1167     {
1168     Data result;
1169     result.copy(other);
1170     result.unaryOp(operation);
1171     return result;
1172     }
1173    
1174     /**
1175     \brief
1176     Perform the given unary operation on this.
1177     Given operation is performed on each element of each data point.
1178     Calls escript::unaryOp.
1179     */
1180     template <class UnaryFunction>
1181     inline
1182 jgs 94 void
1183     Data::unaryOp(UnaryFunction operation)
1184     {
1185     if (isExpanded()) {
1186     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1187     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1188     escript::unaryOp(*leftC,operation);
1189     } else if (isTagged()) {
1190     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1191     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1192     escript::unaryOp(*leftC,operation);
1193 jgs 102 } else if (isConstant()) {
1194 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1195     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1196     escript::unaryOp(*leftC,operation);
1197     }
1198     }
1199    
1200 jgs 102 /**
1201     \brief
1202     Perform the given Data object reduction algorithm on this and return the result.
1203     Given operation combines each element of each data point, thus argument
1204     object (*this) is a rank n Data object, and returned object is a scalar.
1205     Calls escript::algorithm.
1206     */
1207 jgs 94 template <class UnaryFunction>
1208     inline
1209     double
1210     Data::algorithm(UnaryFunction operation) const
1211     {
1212     if (isExpanded()) {
1213     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1214     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1215     return escript::algorithm(*leftC,operation);
1216 jgs 102 } else if (isTagged()) {
1217 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1218     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1219     return escript::algorithm(*leftC,operation);
1220 jgs 102 } else if (isConstant()) {
1221 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1222     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1223     return escript::algorithm(*leftC,operation);
1224     }
1225 jgs 102 return 0;
1226 jgs 94 }
1227    
1228 jgs 102 /**
1229     \brief
1230     Perform the given data point reduction algorithm on data and return the result.
1231     Given operation combines each element within each data point into a scalar,
1232     thus argument object is a rank n Data object, and returned object is a
1233     rank 0 Data object.
1234     Calls escript::dp_algorithm.
1235     */
1236 jgs 94 template <class UnaryFunction>
1237     inline
1238     Data
1239 jgs 106 Data::dp_algorithm(UnaryFunction operation) const
1240 jgs 94 {
1241 jgs 106 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1242     if (isExpanded()) {
1243     DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1244 jgs 102 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1245     EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1246     EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1247     escript::dp_algorithm(*dataE,*resultE,operation);
1248 jgs 106 } else if (isTagged()) {
1249     DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1250 jgs 102 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1251     EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1252     EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1253     escript::dp_algorithm(*dataT,*resultT,operation);
1254 jgs 106 } else if (isConstant()) {
1255     DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1256 jgs 102 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1257     EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1258     EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1259     escript::dp_algorithm(*dataC,*resultC,operation);
1260     }
1261 jgs 94 return result;
1262     }
1263    
1264     }
1265     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26