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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 155 - (show annotations)
Wed Nov 9 02:02:19 2005 UTC (14 years ago) by jgs
Original Path: trunk/escript/src/Data/Data.h
File MIME type: text/plain
File size: 37948 byte(s)
move all directories from trunk/esys2 into trunk and remove esys2

1 // $Id$
2 /*
3 ******************************************************************************
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 */
15
16 /** \file Data.h */
17
18 #ifndef DATA_H
19 #define DATA_H
20
21 #include "escript/Data/DataAbstract.h"
22 #include "escript/Data/DataTagged.h"
23 #include "escript/Data/DataAlgorithm.h"
24 #include "escript/Data/FunctionSpace.h"
25 #include "escript/Data/BinaryOp.h"
26 #include "escript/Data/UnaryOp.h"
27 #include "escript/Data/DataException.h"
28
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 namespace escript {
45
46 //
47 // Forward declaration for various implementations of Data.
48 class DataEmpty;
49 class DataConstant;
50 class DataTagged;
51 class DataExpanded;
52
53 /**
54 \brief
55 Data creates the appropriate Data object for the given construction
56 arguments.
57
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 // These typedefs allow function names to be cast to pointers
70 // to functions of the appropriate type when calling unaryOp etc.
71 typedef double (*UnaryDFunPtr)(double);
72 typedef double (*BinaryDFunPtr)(double,double);
73
74 /**
75 Constructors.
76 */
77
78 /**
79 \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 function space of inData the inData are tried to be interpolated to what,
96 otherwise a shallow copy of inData is returned.
97 */
98 Data(const Data& inData,
99 const FunctionSpace& what);
100
101 /**
102 \brief
103 Constructor which copies data from a DataArrayView.
104
105 \param value - Input - Data value for a single point.
106 \param what - Input - A description of what this data represents.
107 \param expanded - Input - Flag, if true fill the entire container with
108 the value. Otherwise a more efficient storage
109 mechanism will be used.
110 */
111 Data(const DataArrayView& value,
112 const FunctionSpace& what=FunctionSpace(),
113 bool expanded=false);
114
115 /**
116 \brief
117 Constructor which creates a Data from a DataArrayView shape.
118
119 \param value - Input - Single value applied to all Data.
120 \param dataPointShape - Input - The shape of each data point.
121 \param what - Input - A description of what this data represents.
122 \param expanded - Input - Flag, if true fill the entire container with
123 the given value. Otherwise a more efficient storage
124 mechanism will be used.
125 */
126 Data(double value,
127 const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),
128 const FunctionSpace& what=FunctionSpace(),
129 bool expanded=false);
130
131 /**
132 \brief
133 Constructor which performs a deep copy of a region from another Data object.
134
135 \param inData - Input - Input Data object.
136 \param region - Input - Region to copy.
137 */
138 Data(const Data& inData,
139 const DataArrayView::RegionType& region);
140
141 /**
142 \brief
143 Constructor which will create Tagged data if expanded is false.
144 No attempt is made to ensure the tag keys match the tag keys
145 within the function space.
146
147 \param tagKeys - Input - List of tag values.
148 \param values - Input - List of values, one for each tag.
149 \param defaultValue - Input - A default value, used if tag doesn't exist.
150 \param what - Input - A description of what this data represents.
151 \param expanded - Input - Flag, if true fill the entire container with
152 the appropriate values.
153 */
154 Data(const DataTagged::TagListType& tagKeys,
155 const DataTagged::ValueListType& values,
156 const DataArrayView& defaultValue,
157 const FunctionSpace& what=FunctionSpace(),
158 bool expanded=false);
159
160 /**
161 \brief
162 Constructor which copies data from a python numarray.
163
164 \param value - Input - Data value for a single point.
165 \param what - Input - A description of what this data represents.
166 \param expanded - Input - Flag, if true fill the entire container with
167 the value. Otherwise a more efficient storage
168 mechanism will be used.
169 */
170 Data(const boost::python::numeric::array& value,
171 const FunctionSpace& what=FunctionSpace(),
172 bool expanded=false);
173
174 /**
175 \brief
176 Constructor which copies data from any object that can be converted into
177 a python numarray.
178
179 \param value - Input - Input data.
180 \param what - Input - A description of what this data represents.
181 \param expanded - Input - Flag, if true fill the entire container with
182 the value. Otherwise a more efficient storage
183 mechanism will be used.
184 */
185 Data(const boost::python::object& value,
186 const FunctionSpace& what=FunctionSpace(),
187 bool expanded=false);
188
189 /**
190 \brief
191 Constructor which creates a DataConstant.
192 Copies data from any object that can be converted
193 into a numarray. All other parameters are copied from other.
194
195 \param value - Input - Input data.
196 \param other - Input - contains all other parameters.
197 */
198 Data(const boost::python::object& value,
199 const Data& other);
200
201 /**
202 \brief
203 Constructor which creates a DataConstant of "shape" with constant value.
204 */
205 Data(double value,
206 const boost::python::tuple& shape=boost::python::make_tuple(),
207 const FunctionSpace& what=FunctionSpace(),
208 bool expanded=false);
209 /**
210 \brief
211 Destructor
212 */
213 ~Data();
214
215 /**
216 \brief
217 Perform a deep copy.
218 */
219 void
220 copy(const Data& other);
221
222 /**
223 Member access methods.
224 */
225
226 /**
227 \brief
228 Return the values of all data-points as a single python numarray object.
229 */
230 const boost::python::numeric::array
231 convertToNumArray();
232
233 /**
234 \brief
235 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 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 Return the C wrapper for the Data object.
268 */
269 escriptDataC
270 getDataC();
271
272 /**
273 \brief
274 Return the C wrapper for the Data object - const version.
275 */
276 escriptDataC
277 getDataC() const;
278
279 /**
280 \brief
281 Write the data as a string.
282 */
283 inline
284 std::string
285 toString() const
286 {
287 return m_data->toString();
288 }
289
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 Whatever the current Data type make this into a DataExpanded.
306 */
307 void
308 expand();
309
310 /**
311 \brief
312 If possible convert this Data to DataTagged. This will only allow
313 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 Return true if this Data is constant.
336 */
337 bool
338 isConstant() const;
339
340 /**
341 \brief
342 Return true if this Data is empty.
343 */
344 bool
345 isEmpty() const;
346
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 Return the number of samples.
397 */
398 inline
399 int
400 getNumSamples() const
401 {
402 return m_data->getNumSamples();
403 }
404
405 /**
406 \brief
407 Return the number of data points per sample.
408 */
409 inline
410 int
411 getNumDataPointsPerSample() const
412 {
413 return m_data->getNumDPPSample();
414 }
415
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 inline
423 DataAbstract::ValueType::value_type*
424 getSampleData(DataAbstract::ValueType::size_type sampleNo)
425 {
426 return m_data->getSampleData(sampleNo);
427 }
428
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 inline
436 DataAbstract::ValueType::value_type*
437 getSampleDataByTag(int tag)
438 {
439 return m_data->getSampleDataByTag(tag);
440 }
441
442 /**
443 \brief
444 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 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 Return the data point shape as a tuple of integers.
507 */
508 const boost::python::tuple
509 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 Return the number of doubles stored for this Data.
522 */
523 DataArrayView::ValueType::size_type
524 getLength() const;
525
526 /**
527 \brief
528 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 */
534 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 setTaggedValueFromCPP(int tagKey,
548 const DataArrayView& value);
549
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 *
567 */
568 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 *
576 */
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 *
587 */
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 *
595 */
596 Data
597 wherePositive() const;
598
599 /**
600 \brief
601 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
602 *
603 */
604 Data
605 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 *
611 */
612 Data
613 whereNonNegative() const;
614
615 /**
616 \brief
617 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
618 *
619 */
620 Data
621 whereNonPositive() const;
622
623 /**
624 \brief
625 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
626 *
627 */
628 Data
629 whereZero() const;
630
631 /**
632 \brief
633 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
634 *
635 */
636 Data
637 whereNonZero() const;
638
639 /**
640 \brief
641 Return the maximum absolute value of this Data object.
642 *
643 */
644 double
645 Lsup() const;
646
647 /**
648 \brief
649 Return the minimum absolute value of this Data object.
650 *
651 */
652 double
653 Linf() const;
654
655 /**
656 \brief
657 Return the maximum value of this Data object.
658 *
659 */
660 double
661 sup() const;
662
663 /**
664 \brief
665 Return the minimum value of this Data object.
666 *
667 */
668 double
669 inf() const;
670
671 /**
672 \brief
673 Return the absolute value of each data point of this Data object.
674 *
675 */
676 Data
677 abs() const;
678
679 /**
680 \brief
681 Return the maximum value of each data point of this Data object.
682 *
683 */
684 Data
685 maxval() const;
686
687 /**
688 \brief
689 Return the minimum value of each data point of this Data object.
690 *
691 */
692 Data
693 minval() const;
694
695 /**
696 \brief
697 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 void
704 calc_mindp(int& SampleNo,
705 int& DataPointNo) const;
706
707 /**
708 \brief
709 Return the length of each data point of this Data object.
710 sqrt(sum(A[i,j,k,l]^2))
711 *
712 */
713 Data
714 length() const;
715
716 /**
717 \brief
718 Return the sign of each data point of this Data object.
719 -1 for negative values, zero for zero values, 1 for positive values.
720 *
721 */
722 Data
723 sign() const;
724
725 /**
726 \brief
727 Transpose each data point of this Data object around the given axis.
728 --* not implemented yet *--
729 *
730 */
731 Data
732 transpose(int axis) const;
733
734 /**
735 \brief
736 Calculate the trace of each data point of this Data object.
737 sum(A[i,i,i,i])
738 *
739 */
740 Data
741 trace() const;
742
743 /**
744 \brief
745 Return the sin of each data point of this Data object.
746 *
747 */
748 Data
749 sin() const;
750
751 /**
752 \brief
753 Return the cos of each data point of this Data object.
754 *
755 */
756 Data
757 cos() const;
758
759 /**
760 \brief
761 Return the tan of each data point of this Data object.
762 *
763 */
764 Data
765 tan() const;
766
767 /**
768 \brief
769 Return the asin of each data point of this Data object.
770 *
771 */
772 Data
773 asin() const;
774
775 /**
776 \brief
777 Return the acos of each data point of this Data object.
778 *
779 */
780 Data
781 acos() const;
782
783 /**
784 \brief
785 Return the atan of each data point of this Data object.
786 *
787 */
788 Data
789 atan() const;
790
791 /**
792 \brief
793 Return the sinh of each data point of this Data object.
794 *
795 */
796 Data
797 sinh() const;
798
799 /**
800 \brief
801 Return the cosh of each data point of this Data object.
802 *
803 */
804 Data
805 cosh() const;
806
807 /**
808 \brief
809 Return the tanh of each data point of this Data object.
810 *
811 */
812 Data
813 tanh() const;
814
815 /**
816 \brief
817 Return the asinh of each data point of this Data object.
818 *
819 */
820 Data
821 asinh() const;
822
823 /**
824 \brief
825 Return the acosh of each data point of this Data object.
826 *
827 */
828 Data
829 acosh() const;
830
831 /**
832 \brief
833 Return the atanh of each data point of this Data object.
834 *
835 */
836 Data
837 atanh() const;
838
839 /**
840 \brief
841 Return the log to base 10 of each data point of this Data object.
842 *
843 */
844 Data
845 log() const;
846
847 /**
848 \brief
849 Return the natural log of each data point of this Data object.
850 *
851 */
852 Data
853 ln() const;
854
855 /**
856 \brief
857 Return the exponential function of each data point of this Data object.
858 *
859 */
860 Data
861 exp() const;
862
863 /**
864 \brief
865 Return the square root of each data point of this Data object.
866 *
867 */
868 Data
869 sqrt() const;
870
871 /**
872 \brief
873 Return the negation of each data point of this Data object.
874 *
875 */
876 Data
877 neg() const;
878
879 /**
880 \brief
881 Return the identity of each data point of this Data object.
882 Simply returns this object unmodified.
883 *
884 */
885 Data
886 pos() const;
887
888 /**
889 \brief
890 Return the given power of each data point of this Data object.
891
892 \param right Input - the power to raise the object to.
893 *
894 */
895 Data
896 powD(const Data& right) const;
897
898 /**
899 \brief
900 Return the given power of each data point of this boost python object.
901
902 \param right Input - the power to raise the object to.
903 *
904 */
905 Data
906 powO(const boost::python::object& right) const;
907
908 /**
909 \brief
910 writes the object to a file in the DX file format
911 */
912 void
913 saveDX(std::string fileName) const;
914
915 /**
916 \brief
917 writes the object to a file in the VTK file format
918 */
919 void
920 saveVTK(std::string fileName) const;
921
922 /**
923 \brief
924 Overloaded operator +=
925 \param right - Input - The right hand side.
926 *
927 */
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 *
936 */
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 *
945 */
946 Data& operator*=(const Data& right);
947 Data& operator*=(const boost::python::object& right);
948
949 /**
950 \brief
951 Overloaded operator /=
952 \param right - Input - The right hand side.
953 *
954 */
955 Data& operator/=(const Data& right);
956 Data& operator/=(const boost::python::object& right);
957
958 /**
959 \brief
960 Returns true if this can be interpolated to functionspace.
961 */
962 bool
963 probeInterpolation(const FunctionSpace& functionspace) const;
964
965 /**
966 Data object slicing methods.
967 */
968
969 /**
970 \brief
971 Returns a slice from this Data object.
972
973 /description
974 Implements the [] get operator in python.
975 Calls getSlice.
976
977 \param key - Input - python slice tuple specifying
978 slice to return.
979 */
980 Data
981 getItem(const boost::python::object& key) const;
982
983 /**
984 \brief
985 Copies slice from value into this Data object.
986
987 Implements the [] set operator in python.
988 Calls setSlice.
989
990 \param key - Input - python slice tuple specifying
991 slice to copy from value.
992 \param value - Input - Data object to copy from.
993 */
994 void
995 setItemD(const boost::python::object& key,
996 const Data& value);
997
998 void
999 setItemO(const boost::python::object& key,
1000 const boost::python::object& value);
1001
1002 // These following public methods should be treated as private.
1003
1004 /**
1005 \brief
1006 Perform the given unary operation on every element of every data point in
1007 this Data object.
1008 */
1009 template <class UnaryFunction>
1010 inline
1011 void
1012 unaryOp(UnaryFunction operation);
1013
1014 /**
1015 \brief
1016 Return a Data object containing the specified slice of
1017 this Data object.
1018 \param region - Input - Region to copy.
1019 *
1020 */
1021 Data
1022 getSlice(const DataArrayView::RegionType& region) const;
1023
1024 /**
1025 \brief
1026 Copy the specified slice from the given value into this
1027 Data object.
1028 \param value - Input - Data to copy from.
1029 \param region - Input - Region to copy.
1030 *
1031 */
1032 void
1033 setSlice(const Data& value,
1034 const DataArrayView::RegionType& region);
1035
1036 /**
1037 \brief
1038 Archive the current Data object to the given file.
1039 \param fileName - Input - file to archive to.
1040 */
1041 void
1042 archiveData(const std::string fileName);
1043
1044 /**
1045 \brief
1046 Extract the Data object archived in the given file, overwriting
1047 the current Data object.
1048 Note - the current object must be of type DataEmpty.
1049 \param fileName - Input - file to extract from.
1050 \param fspace - Input - a suitable FunctionSpace descibing the data.
1051 */
1052 void
1053 extractData(const std::string fileName,
1054 const FunctionSpace& fspace);
1055
1056 protected:
1057
1058 private:
1059
1060 /**
1061 \brief
1062 Check *this and the right operand are compatible. Throws
1063 an exception if they aren't.
1064 \param right - Input - The right hand side.
1065 */
1066 inline
1067 void
1068 operandCheck(const Data& right) const
1069 {
1070 return m_data->operandCheck(*(right.m_data.get()));
1071 }
1072
1073 /**
1074 \brief
1075 Perform the specified reduction algorithm on every element of every data point in
1076 this Data object according to the given function and return the single value result.
1077 */
1078 template <class BinaryFunction>
1079 inline
1080 double
1081 algorithm(BinaryFunction operation,
1082 double initial_value) const;
1083
1084 /**
1085 \brief
1086 Reduce each data-point in this Data object using the given operation. Return a Data
1087 object with the same number of data-points, but with each data-point containing only
1088 one value - the result of the reduction operation on the corresponding data-point in
1089 this Data object
1090 */
1091 template <class BinaryFunction>
1092 inline
1093 Data
1094 dp_algorithm(BinaryFunction operation,
1095 double initial_value) const;
1096
1097 /**
1098 \brief
1099 Perform the given binary operation on all of the data's elements.
1100 The underlying type of the right hand side (right) determines the final
1101 type of *this after the operation. For example if the right hand side
1102 is expanded *this will be expanded if necessary.
1103 RHS is a Data object.
1104 */
1105 template <class BinaryFunction>
1106 inline
1107 void
1108 binaryOp(const Data& right,
1109 BinaryFunction operation);
1110
1111 /**
1112 \brief
1113 Perform the given binary operation on all of the data's elements.
1114 RHS is a boost::python object.
1115 */
1116 template <class BinaryFunction>
1117 inline
1118 void
1119 binaryOp(const boost::python::object& right,
1120 BinaryFunction operation);
1121
1122 /**
1123 \brief
1124 Convert the data type of the RHS to match this.
1125 \param right - Input - data type to match.
1126 */
1127 void
1128 typeMatchLeft(Data& right) const;
1129
1130 /**
1131 \brief
1132 Convert the data type of this to match the RHS.
1133 \param right - Input - data type to match.
1134 */
1135 void
1136 typeMatchRight(const Data& right);
1137
1138 /**
1139 \brief
1140 Construct a Data object of the appropriate type.
1141 */
1142 template <class IValueType>
1143 void
1144 initialise(const IValueType& value,
1145 const FunctionSpace& what,
1146 bool expanded);
1147
1148 /**
1149 \brief
1150 Reshape the data point if the data point is currently rank 0.
1151 Will throw an exception if the data points are not rank 0.
1152 The original data point value is used for all values of the new
1153 data point.
1154 */
1155 void
1156 reshapeDataPoint(const DataArrayView::ShapeType& shape);
1157
1158 //
1159 // pointer to the actual data object
1160 boost::shared_ptr<DataAbstract> m_data;
1161
1162 //
1163 // pointer to the internal profiling data
1164 struct profDataEntry *profData;
1165
1166 };
1167
1168 template <class IValueType>
1169 void
1170 Data::initialise(const IValueType& value,
1171 const FunctionSpace& what,
1172 bool expanded)
1173 {
1174 //
1175 // Construct a Data object of the appropriate type.
1176 // Construct the object first as there seems to be a bug which causes
1177 // undefined behaviour if an exception is thrown during construction
1178 // within the shared_ptr constructor.
1179 if (expanded) {
1180 DataAbstract* temp=new DataExpanded(value,what);
1181 boost::shared_ptr<DataAbstract> temp_data(temp);
1182 m_data=temp_data;
1183 } else {
1184 DataAbstract* temp=new DataConstant(value,what);
1185 boost::shared_ptr<DataAbstract> temp_data(temp);
1186 m_data=temp_data;
1187 }
1188 }
1189
1190 /**
1191 Binary Data object operators.
1192 */
1193
1194 /**
1195 \brief
1196 Operator+
1197 Takes two Data objects.
1198 */
1199 Data operator+(const Data& left, const Data& right);
1200
1201 /**
1202 \brief
1203 Operator-
1204 Takes two Data objects.
1205 */
1206 Data operator-(const Data& left, const Data& right);
1207
1208 /**
1209 \brief
1210 Operator*
1211 Takes two Data objects.
1212 */
1213 Data operator*(const Data& left, const Data& right);
1214
1215 /**
1216 \brief
1217 Operator/
1218 Takes two Data objects.
1219 */
1220 Data operator/(const Data& left, const Data& right);
1221
1222 /**
1223 \brief
1224 Operator+
1225 Takes LHS Data object and RHS python::object.
1226 python::object must be convertable to Data type.
1227 */
1228 Data operator+(const Data& left, const boost::python::object& 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 python::object and RHS Data object.
1258 python::object must be convertable to Data type.
1259 */
1260 Data operator+(const boost::python::object& left, const Data& 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 Output operator
1289 */
1290 std::ostream& operator<<(std::ostream& o, const Data& data);
1291
1292 /**
1293 \brief
1294 Return true if operands are equivalent, else return false.
1295 NB: this operator does very little at this point, and isn't to
1296 be relied on. Requires further implementation.
1297 */
1298 //bool operator==(const Data& left, const Data& right);
1299
1300 /**
1301 \brief
1302 Perform the given binary operation with this and right as operands.
1303 Right is a Data object.
1304 */
1305 template <class BinaryFunction>
1306 inline
1307 void
1308 Data::binaryOp(const Data& right,
1309 BinaryFunction operation)
1310 {
1311 //
1312 // if this has a rank of zero promote it to the rank of the RHS
1313 if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1314 reshapeDataPoint(right.getPointDataView().getShape());
1315 }
1316 //
1317 // initially make the temporary a shallow copy
1318 Data tempRight(right);
1319 if (getFunctionSpace()!=right.getFunctionSpace()) {
1320 if (right.probeInterpolation(getFunctionSpace())) {
1321 //
1322 // an interpolation is required so create a new Data
1323 tempRight=Data(right,this->getFunctionSpace());
1324 } else if (probeInterpolation(right.getFunctionSpace())) {
1325 //
1326 // interpolate onto the RHS function space
1327 Data tempLeft(*this,right.getFunctionSpace());
1328 m_data=tempLeft.m_data;
1329 }
1330 }
1331 operandCheck(tempRight);
1332 //
1333 // ensure this has the right type for the RHS
1334 typeMatchRight(tempRight);
1335 //
1336 // Need to cast to the concrete types so that the correct binaryOp
1337 // is called.
1338 if (isExpanded()) {
1339 //
1340 // Expanded data will be done in parallel, the right hand side can be
1341 // of any data type
1342 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1343 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1344 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1345 } else if (isTagged()) {
1346 //
1347 // Tagged data is operated on serially, the right hand side can be
1348 // either DataConstant or DataTagged
1349 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1350 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1351 if (right.isTagged()) {
1352 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1353 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1354 escript::binaryOp(*leftC,*rightC,operation);
1355 } else {
1356 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1357 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1358 escript::binaryOp(*leftC,*rightC,operation);
1359 }
1360 } else if (isConstant()) {
1361 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1362 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1363 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1364 escript::binaryOp(*leftC,*rightC,operation);
1365 }
1366 }
1367
1368 /**
1369 \brief
1370 Perform the given binary operation with this and right as operands.
1371 Right is a boost::python object.
1372 */
1373 template <class BinaryFunction>
1374 inline
1375 void
1376 Data::binaryOp(const boost::python::object& right,
1377 BinaryFunction operation)
1378 {
1379 DataArray temp(right);
1380 //
1381 // if this has a rank of zero promote it to the rank of the RHS.
1382 if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1383 reshapeDataPoint(temp.getView().getShape());
1384 }
1385 //
1386 // Always allow scalar values for the RHS but check other shapes
1387 if (temp.getView().getRank()!=0) {
1388 if (!getPointDataView().checkShape(temp.getView().getShape())) {
1389 throw DataException(getPointDataView().createShapeErrorMessage(
1390 "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1391 }
1392 }
1393 if (isExpanded()) {
1394 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1395 EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1396 escript::binaryOp(*leftC,temp.getView(),operation);
1397 } else if (isTagged()) {
1398 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1399 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1400 escript::binaryOp(*leftC,temp.getView(),operation);
1401 } else if (isConstant()) {
1402 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1403 EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1404 escript::binaryOp(*leftC,temp.getView(),operation);
1405 }
1406 }
1407
1408 /**
1409 \brief
1410 Perform the given unary operation on other and return the result.
1411 Given operation is performed on each element of each data point, thus
1412 argument object is a rank n Data object, and returned object is a rank n
1413 Data object.
1414 Calls Data::unaryOp.
1415 */
1416 template <class UnaryFunction>
1417 inline
1418 Data
1419 unaryOp(const Data& other,
1420 UnaryFunction operation)
1421 {
1422 Data result;
1423 result.copy(other);
1424 result.unaryOp(operation);
1425 return result;
1426 }
1427
1428 /**
1429 \brief
1430 Perform the given unary operation on this.
1431 Given operation is performed on each element of each data point.
1432 Calls escript::unaryOp.
1433 */
1434 template <class UnaryFunction>
1435 inline
1436 void
1437 Data::unaryOp(UnaryFunction operation)
1438 {
1439 if (isExpanded()) {
1440 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1441 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1442 escript::unaryOp(*leftC,operation);
1443 } else if (isTagged()) {
1444 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1445 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1446 escript::unaryOp(*leftC,operation);
1447 } else if (isConstant()) {
1448 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1449 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1450 escript::unaryOp(*leftC,operation);
1451 }
1452 }
1453
1454 /**
1455 \brief
1456 Perform the given Data object reduction algorithm on this and return the result.
1457 Given operation combines each element of each data point, thus argument
1458 object (*this) is a rank n Data object, and returned object is a scalar.
1459 Calls escript::algorithm.
1460 */
1461 template <class BinaryFunction>
1462 inline
1463 double
1464 Data::algorithm(BinaryFunction operation, double initial_value) const
1465 {
1466 if (isExpanded()) {
1467 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1468 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1469 return escript::algorithm(*leftC,operation,initial_value);
1470 } else if (isTagged()) {
1471 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1472 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1473 return escript::algorithm(*leftC,operation,initial_value);
1474 } else if (isConstant()) {
1475 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1476 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1477 return escript::algorithm(*leftC,operation,initial_value);
1478 }
1479 return 0;
1480 }
1481
1482 /**
1483 \brief
1484 Perform the given data point reduction algorithm on data and return the result.
1485 Given operation combines each element within each data point into a scalar,
1486 thus argument object is a rank n Data object, and returned object is a
1487 rank 0 Data object.
1488 Calls escript::dp_algorithm.
1489 */
1490 template <class BinaryFunction>
1491 inline
1492 Data
1493 Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1494 {
1495 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1496 if (isExpanded()) {
1497 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1498 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1499 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1500 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1501 escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1502 } else if (isTagged()) {
1503 DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1504 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1505 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1506 EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1507 escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1508 } else if (isConstant()) {
1509 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1510 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1511 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1512 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1513 escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1514 }
1515 return result;
1516 }
1517
1518 }
1519 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26