/[escript]/branches/schroedinger/escript/src/Data.h
ViewVC logotype

Annotation of /branches/schroedinger/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26