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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26