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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26