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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26