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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26