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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 480 - (hide annotations)
Wed Feb 1 05:15:12 2006 UTC (13 years, 4 months ago) by jgs
File MIME type: text/plain
File size: 37587 byte(s)
rationalise #includes and forward declarations

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26