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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26