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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 104 - (hide annotations)
Fri Dec 17 07:43:12 2004 UTC (14 years, 5 months ago) by jgs
File MIME type: text/plain
File size: 32398 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 jgs 104 writes the object to a file in the DX file format
685     */
686     void
687     saveDX(std::string fileName) const;
688    
689     /**
690     \brief
691 jgs 102 Return the negation of each data point of this Data object.
692     */
693     Data
694     neg() const;
695    
696     /**
697     \brief
698     Return the identity of each data point of this Data object.
699     Simply returns this object unmodified.
700     */
701     Data
702     pos() const;
703    
704     /**
705     \brief
706     Overloaded operator +=
707     \param right - Input - The right hand side.
708     */
709     Data& operator+=(const Data& right);
710     Data& operator+=(const boost::python::object& right);
711    
712     /**
713     \brief
714     Overloaded operator -=
715     \param right - Input - The right hand side.
716     */
717     Data& operator-=(const Data& right);
718     Data& operator-=(const boost::python::object& right);
719    
720     /**
721     \brief
722     Overloaded operator *=
723     \param right - Input - The right hand side.
724     */
725     Data& operator*=(const Data& right);
726     Data& operator*=(const boost::python::object& right);
727    
728     /**
729     \brief
730     Overloaded operator /=
731     \param right - Input - The right hand side.
732     */
733     Data& operator/=(const Data& right);
734     Data& operator/=(const boost::python::object& right);
735    
736     /**
737     \brief
738 jgs 94 Returns true if this can be interpolated to functionspace.
739     */
740     bool
741     probeInterpolation(const FunctionSpace& functionspace) const;
742    
743     /**
744 jgs 102 Data object slicing methods.
745     */
746    
747     /**
748 jgs 94 \brief
749 jgs 102 Returns a slice from this Data object.
750    
751     /description
752     Implements the [] get operator in python.
753     Calls getSlice.
754    
755     \param key - Input - python slice tuple specifying
756     slice to return.
757 jgs 94 */
758 jgs 102 Data
759     getItem(const boost::python::object& key) const;
760    
761     /**
762     \brief
763     Copies slice from value into this Data object.
764    
765     \description
766     Implements the [] set operator in python.
767     Calls setSlice.
768    
769     \param key - Input - python slice tuple specifying
770     slice to copy from value.
771     \param value - Input - Data object to copy from.
772     */
773 jgs 94 void
774 jgs 102 setItemD(const boost::python::object& key,
775     const Data& value);
776 jgs 94
777 jgs 102 void
778     setItemO(const boost::python::object& key,
779     const boost::python::object& value);
780    
781     // These following public methods should be treated as private.
782    
783 jgs 94 /**
784     \brief
785 jgs 102 Perform the given unary operation on every element of every data point in
786     this Data object.
787 jgs 94 */
788 jgs 102 template <class UnaryFunction>
789     inline
790 jgs 94 void
791 jgs 102 unaryOp(UnaryFunction operation);
792    
793     /**
794     \brief
795     Return a Data object containing the specified slice of
796     this Data object.
797     \param region - Input - Region to copy.
798 jgs 94 */
799 jgs 102 Data
800     getSlice(const DataArrayView::RegionType& region) const;
801 jgs 94
802 jgs 102 /**
803     \brief
804     Copy the specified slice from the given value into this
805     Data object.
806     \param value - Input - Data to copy from.
807     \param region - Input - Region to copy.
808     */
809     void
810     setSlice(const Data& value,
811     const DataArrayView::RegionType& region);
812    
813     protected:
814    
815 jgs 94 private:
816    
817     /**
818     \brief
819 jgs 102 Check *this and the right operand are compatible. Throws
820     an exception if they aren't.
821     \param right - Input - The right hand side.
822     */
823     inline
824     void
825     operandCheck(const Data& right) const
826     {
827     return m_data->operandCheck(*(right.m_data.get()));
828     }
829    
830     /**
831     \brief
832     Perform the specified reduction algorithm on every element of every data point in
833     this Data object and return the single double value result.
834     */
835     template <class UnaryFunction>
836     inline
837     double
838     algorithm(UnaryFunction operation) const;
839    
840     /**
841     \brief
842     Perform the given binary operation on all of the data's elements.
843     The underlying type of the right hand side (right) determines the final
844     type of *this after the operation. For example if the right hand side
845     is expanded *this will be expanded if necessary.
846     RHS is a Data object.
847     */
848     template <class BinaryFunction>
849     inline
850     void
851     binaryOp(const Data& right,
852     BinaryFunction operation);
853    
854     /**
855     \brief
856     Perform the given binary operation on all of the data's elements.
857     RHS is a boost::python object.
858     */
859     template <class BinaryFunction>
860     inline
861     void
862     binaryOp(const boost::python::object& right,
863     BinaryFunction operation);
864    
865     /**
866     \brief
867     Convert the data type of the RHS to match this.
868     \param right - Input - data type to match.
869     */
870     void
871     typeMatchLeft(Data& right) const;
872    
873     /**
874     \brief
875     Convert the data type of this to match the RHS.
876     \param right - Input - data type to match.
877     */
878     void
879     typeMatchRight(const Data& right);
880    
881     /**
882     \brief
883 jgs 94 Construct a Data object of the appropriate type.
884     */
885     template <class IValueType>
886     void
887     initialise(const IValueType& value,
888     const FunctionSpace& what,
889     bool expanded);
890    
891     /**
892     \brief
893     Reshape the data point if the data point is currently rank 0.
894     Will throw an exception if the data points are not rank 0.
895     The original data point value is used for all values of the new
896     data point.
897     */
898     void
899     reshapeDataPoint(const DataArrayView::ShapeType& shape);
900    
901     //
902 jgs 102 // pointer to the actual data object
903 jgs 94 boost::shared_ptr<DataAbstract> m_data;
904    
905     };
906    
907     template <class IValueType>
908     void
909     Data::initialise(const IValueType& value,
910     const FunctionSpace& what,
911     bool expanded)
912     {
913     //
914     // Construct a Data object of the appropriate type.
915     // Construct the object first as there seems to be a bug which causes
916     // undefined behaviour if an exception is thrown during construction
917     // within the shared_ptr constructor.
918     if (expanded) {
919     DataAbstract* temp=new DataExpanded(value,what);
920 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
921     m_data=temp_data;
922 jgs 94 } else {
923     DataAbstract* temp=new DataConstant(value,what);
924 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
925     m_data=temp_data;
926 jgs 94 }
927     }
928    
929 jgs 102 /**
930     Binary Data object operators.
931     */
932 jgs 94
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 two Data objects.
958     */
959     Data operator/(const Data& left, const Data& right);
960    
961     /**
962     \brief
963     Operator+
964     Takes LHS Data object and RHS python::object.
965     python::object must be convertable to Data type.
966     */
967     Data operator+(const Data& left, const boost::python::object& right);
968    
969     /**
970     \brief
971     Operator-
972     Takes LHS Data object and RHS python::object.
973     python::object must be convertable to Data type.
974     */
975     Data operator-(const Data& left, const boost::python::object& right);
976    
977     /**
978     \brief
979     Operator*
980     Takes LHS Data object and RHS python::object.
981     python::object must be convertable to Data type.
982     */
983     Data operator*(const Data& left, const boost::python::object& right);
984    
985     /**
986     \brief
987     Operator/
988     Takes LHS Data object and RHS python::object.
989     python::object must be convertable to Data type.
990     */
991     Data operator/(const Data& left, const boost::python::object& right);
992    
993     /**
994     \brief
995     Operator+
996     Takes LHS python::object and RHS Data object.
997     python::object must be convertable to Data type.
998     */
999     Data operator+(const boost::python::object& left, const Data& right);
1000    
1001     /**
1002     \brief
1003     Operator-
1004     Takes LHS python::object and RHS Data object.
1005     python::object must be convertable to Data type.
1006     */
1007     Data operator-(const boost::python::object& left, const Data& right);
1008    
1009     /**
1010     \brief
1011     Operator*
1012     Takes LHS python::object and RHS Data object.
1013     python::object must be convertable to Data type.
1014     */
1015     Data operator*(const boost::python::object& left, const Data& right);
1016    
1017     /**
1018     \brief
1019     Operator/
1020     Takes LHS python::object and RHS Data object.
1021     python::object must be convertable to Data type.
1022     */
1023     Data operator/(const boost::python::object& left, const Data& right);
1024    
1025     /**
1026     \brief
1027     Output operator
1028     */
1029     std::ostream& operator<<(std::ostream& o, const Data& data);
1030    
1031     /**
1032     \brief
1033     Return true if operands are equivalent, else return false.
1034     NB: this operator does very little at this point, and isn't to
1035     be relied on. Requires further implementation.
1036     */
1037 jgs 102 //bool operator==(const Data& left, const Data& right);
1038 jgs 94
1039 jgs 102 /**
1040     \brief
1041     Perform the given binary operation with this and right as operands.
1042     Right is a Data object.
1043     */
1044 jgs 94 template <class BinaryFunction>
1045     inline
1046     void
1047     Data::binaryOp(const Data& right,
1048     BinaryFunction operation)
1049     {
1050     //
1051     // if this has a rank of zero promote it to the rank of the RHS
1052     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1053     reshapeDataPoint(right.getPointDataView().getShape());
1054     }
1055     //
1056     // initially make the temporary a shallow copy
1057     Data tempRight(right);
1058     if (getFunctionSpace()!=right.getFunctionSpace()) {
1059     if (right.probeInterpolation(getFunctionSpace())) {
1060     //
1061     // an interpolation is required so create a new Data
1062     tempRight=Data(right,this->getFunctionSpace());
1063     } else if (probeInterpolation(right.getFunctionSpace())) {
1064     //
1065     // interpolate onto the RHS function space
1066     Data tempLeft(*this,right.getFunctionSpace());
1067     m_data=tempLeft.m_data;
1068     }
1069     }
1070     operandCheck(tempRight);
1071     //
1072     // ensure this has the right type for the RHS
1073 jgs 102 typeMatchRight(tempRight);
1074 jgs 94 //
1075     // Need to cast to the concrete types so that the correct binaryOp
1076     // is called.
1077     if (isExpanded()) {
1078     //
1079     // Expanded data will be done in parallel, the right hand side can be
1080     // of any data type
1081     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1082     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1083     escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1084     } else if (isTagged()) {
1085     //
1086     // Tagged data is operated on serially, the right hand side can be
1087     // either DataConstant or DataTagged
1088     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1089     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1090     if (right.isTagged()) {
1091     DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1092     EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1093     escript::binaryOp(*leftC,*rightC,operation);
1094     } else {
1095     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1096     EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1097     escript::binaryOp(*leftC,*rightC,operation);
1098     }
1099 jgs 102 } else if (isConstant()) {
1100 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1101     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1102     EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1103     escript::binaryOp(*leftC,*rightC,operation);
1104     }
1105     }
1106    
1107 jgs 102 /**
1108     \brief
1109     Perform the given binary operation with this and right as operands.
1110     Right is a boost::python object.
1111     */
1112 jgs 94 template <class BinaryFunction>
1113     inline
1114     void
1115     Data::binaryOp(const boost::python::object& right,
1116     BinaryFunction operation)
1117     {
1118     DataArray temp(right);
1119     //
1120     // if this has a rank of zero promote it to the rank of the RHS.
1121     if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1122     reshapeDataPoint(temp.getView().getShape());
1123     }
1124     //
1125     // Always allow scalar values for the RHS but check other shapes
1126     if (temp.getView().getRank()!=0) {
1127     if (!getPointDataView().checkShape(temp.getView().getShape())) {
1128     throw DataException(getPointDataView().createShapeErrorMessage(
1129     "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1130     }
1131     }
1132     if (isExpanded()) {
1133     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1134     EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1135     escript::binaryOp(*leftC,temp.getView(),operation);
1136     } else if (isTagged()) {
1137     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1138     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1139     escript::binaryOp(*leftC,temp.getView(),operation);
1140 jgs 102 } else if (isConstant()) {
1141 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1142     EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1143     escript::binaryOp(*leftC,temp.getView(),operation);
1144     }
1145     }
1146    
1147 jgs 102 /**
1148     \brief
1149     Perform the given unary operation on other and return the result.
1150     Given operation is performed on each element of each data point, thus
1151     argument object is a rank n Data object, and returned object is a rank n
1152     Data object.
1153     Calls Data::unaryOp.
1154     */
1155 jgs 94 template <class UnaryFunction>
1156     inline
1157 jgs 102 Data
1158     unaryOp(const Data& other,
1159     UnaryFunction operation)
1160     {
1161     Data result;
1162     result.copy(other);
1163     result.unaryOp(operation);
1164     return result;
1165     }
1166    
1167     /**
1168     \brief
1169     Perform the given unary operation on this.
1170     Given operation is performed on each element of each data point.
1171     Calls escript::unaryOp.
1172     */
1173     template <class UnaryFunction>
1174     inline
1175 jgs 94 void
1176     Data::unaryOp(UnaryFunction operation)
1177     {
1178     if (isExpanded()) {
1179     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1180     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1181     escript::unaryOp(*leftC,operation);
1182     } else if (isTagged()) {
1183     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1184     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1185     escript::unaryOp(*leftC,operation);
1186 jgs 102 } else if (isConstant()) {
1187 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1188     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1189     escript::unaryOp(*leftC,operation);
1190     }
1191     }
1192    
1193 jgs 102 /**
1194     \brief
1195     Perform the given Data object reduction algorithm on this and return the result.
1196     Given operation combines each element of each data point, thus argument
1197     object (*this) is a rank n Data object, and returned object is a scalar.
1198     Calls escript::algorithm.
1199     */
1200 jgs 94 template <class UnaryFunction>
1201     inline
1202     double
1203     Data::algorithm(UnaryFunction operation) const
1204     {
1205     if (isExpanded()) {
1206     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1207     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1208     return escript::algorithm(*leftC,operation);
1209 jgs 102 } else if (isTagged()) {
1210 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1211     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1212     return escript::algorithm(*leftC,operation);
1213 jgs 102 } else if (isConstant()) {
1214 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1215     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1216     return escript::algorithm(*leftC,operation);
1217     }
1218 jgs 102 return 0;
1219 jgs 94 }
1220    
1221 jgs 102 /**
1222     \brief
1223     Perform the given data point reduction algorithm on data and return the result.
1224     Given operation combines each element within each data point into a scalar,
1225     thus argument object is a rank n Data object, and returned object is a
1226     rank 0 Data object.
1227     Calls escript::dp_algorithm.
1228     */
1229 jgs 94 template <class UnaryFunction>
1230     inline
1231     Data
1232 jgs 102 dp_algorithm(const Data& data,
1233     UnaryFunction operation)
1234 jgs 94 {
1235 jgs 102 Data result(0,DataArrayView::ShapeType(),data.getFunctionSpace(),data.isExpanded());
1236     if (data.isExpanded()) {
1237     DataExpanded* dataE=dynamic_cast<DataExpanded*>(data.m_data.get());
1238     DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1239     EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1240     EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1241     escript::dp_algorithm(*dataE,*resultE,operation);
1242     } else if (data.isTagged()) {
1243     DataTagged* dataT=dynamic_cast<DataTagged*>(data.m_data.get());
1244     DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1245     EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1246     EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1247     escript::dp_algorithm(*dataT,*resultT,operation);
1248     } else if (data.isConstant()) {
1249     DataConstant* dataC=dynamic_cast<DataConstant*>(data.m_data.get());
1250     DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1251     EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1252     EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1253     escript::dp_algorithm(*dataC,*resultC,operation);
1254     }
1255 jgs 94 return result;
1256     }
1257    
1258     }
1259     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26