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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 150 - (show annotations)
Thu Sep 15 03:44:45 2005 UTC (13 years, 11 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 37898 byte(s)
Merge of development branch dev-02 back to main trunk on 2005-09-15

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 /**
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 length of each data point of this Data object.
705 sqrt(sum(A[i,j,k,l]^2))
706 *
707 */
708 Data
709 length() const;
710
711 /**
712 \brief
713 Return the sign of each data point of this Data object.
714 -1 for negative values, zero for zero values, 1 for positive values.
715 *
716 */
717 Data
718 sign() const;
719
720 /**
721 \brief
722 Transpose each data point of this Data object around the given axis.
723 --* not implemented yet *--
724 *
725 */
726 Data
727 transpose(int axis) const;
728
729 /**
730 \brief
731 Calculate the trace of each data point of this Data object.
732 sum(A[i,i,i,i])
733 *
734 */
735 Data
736 trace() const;
737
738 /**
739 \brief
740 Return the sin of each data point of this Data object.
741 *
742 */
743 Data
744 sin() const;
745
746 /**
747 \brief
748 Return the cos of each data point of this Data object.
749 *
750 */
751 Data
752 cos() const;
753
754 /**
755 \brief
756 Return the tan of each data point of this Data object.
757 *
758 */
759 Data
760 tan() const;
761
762 /**
763 \brief
764 Return the asin of each data point of this Data object.
765 *
766 */
767 Data
768 asin() const;
769
770 /**
771 \brief
772 Return the acos of each data point of this Data object.
773 *
774 */
775 Data
776 acos() const;
777
778 /**
779 \brief
780 Return the atan of each data point of this Data object.
781 *
782 */
783 Data
784 atan() const;
785
786 /**
787 \brief
788 Return the sinh of each data point of this Data object.
789 *
790 */
791 Data
792 sinh() const;
793
794 /**
795 \brief
796 Return the cosh of each data point of this Data object.
797 *
798 */
799 Data
800 cosh() const;
801
802 /**
803 \brief
804 Return the tanh of each data point of this Data object.
805 *
806 */
807 Data
808 tanh() const;
809
810 /**
811 \brief
812 Return the asinh of each data point of this Data object.
813 *
814 */
815 Data
816 asinh() const;
817
818 /**
819 \brief
820 Return the acosh of each data point of this Data object.
821 *
822 */
823 Data
824 acosh() const;
825
826 /**
827 \brief
828 Return the atanh of each data point of this Data object.
829 *
830 */
831 Data
832 atanh() const;
833
834 /**
835 \brief
836 Return the log to base 10 of each data point of this Data object.
837 *
838 */
839 Data
840 log() const;
841
842 /**
843 \brief
844 Return the natural log of each data point of this Data object.
845 *
846 */
847 Data
848 ln() const;
849
850 /**
851 \brief
852 Return the exponential function of each data point of this Data object.
853 *
854 */
855 Data
856 exp() const;
857
858 /**
859 \brief
860 Return the square root of each data point of this Data object.
861 *
862 */
863 Data
864 sqrt() const;
865
866 /**
867 \brief
868 Return the negation of each data point of this Data object.
869 *
870 */
871 Data
872 neg() const;
873
874 /**
875 \brief
876 Return the identity of each data point of this Data object.
877 Simply returns this object unmodified.
878 *
879 */
880 Data
881 pos() const;
882
883 /**
884 \brief
885 Return the given power of each data point of this Data object.
886
887 \param right Input - the power to raise the object to.
888 *
889 */
890 Data
891 powD(const Data& right) const;
892
893 /**
894 \brief
895 Return the given power of each data point of this boost python object.
896
897 \param right Input - the power to raise the object to.
898 *
899 */
900 Data
901 powO(const boost::python::object& right) const;
902
903 /**
904 \brief
905 writes the object to a file in the DX file format
906 */
907 void
908 saveDX(std::string fileName) const;
909
910 /**
911 \brief
912 writes the object to a file in the VTK file format
913 */
914 void
915 saveVTK(std::string fileName) const;
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 Overloaded operator /=
947 \param right - Input - The right hand side.
948 *
949 */
950 Data& operator/=(const Data& right);
951 Data& operator/=(const boost::python::object& right);
952
953 /**
954 \brief
955 Returns true if this can be interpolated to functionspace.
956 */
957 bool
958 probeInterpolation(const FunctionSpace& functionspace) const;
959
960 /**
961 Data object slicing methods.
962 */
963
964 /**
965 \brief
966 Returns a slice from this Data object.
967
968 /description
969 Implements the [] get operator in python.
970 Calls getSlice.
971
972 \param key - Input - python slice tuple specifying
973 slice to return.
974 */
975 Data
976 getItem(const boost::python::object& key) const;
977
978 /**
979 \brief
980 Copies slice from value into this Data object.
981
982 Implements the [] set operator in python.
983 Calls setSlice.
984
985 \param key - Input - python slice tuple specifying
986 slice to copy from value.
987 \param value - Input - Data object to copy from.
988 */
989 void
990 setItemD(const boost::python::object& key,
991 const Data& value);
992
993 void
994 setItemO(const boost::python::object& key,
995 const boost::python::object& value);
996
997 // These following public methods should be treated as private.
998
999 /**
1000 \brief
1001 Perform the given unary operation on every element of every data point in
1002 this Data object.
1003 */
1004 template <class UnaryFunction>
1005 inline
1006 void
1007 unaryOp(UnaryFunction operation);
1008
1009 /**
1010 \brief
1011 Return a Data object containing the specified slice of
1012 this Data object.
1013 \param region - Input - Region to copy.
1014 *
1015 */
1016 Data
1017 getSlice(const DataArrayView::RegionType& region) const;
1018
1019 /**
1020 \brief
1021 Copy the specified slice from the given value into this
1022 Data object.
1023 \param value - Input - Data to copy from.
1024 \param region - Input - Region to copy.
1025 *
1026 */
1027 void
1028 setSlice(const Data& value,
1029 const DataArrayView::RegionType& region);
1030
1031 /**
1032 \brief
1033 Archive the current Data object to the given file.
1034 \param fileName - Input - file to archive to.
1035 */
1036 void
1037 archiveData(const std::string fileName);
1038
1039 /**
1040 \brief
1041 Extract the Data object archived in the given file, overwriting
1042 the current Data object.
1043 Note - the current object must be of type DataEmpty.
1044 \param fileName - Input - file to extract from.
1045 \param fspace - Input - a suitable FunctionSpace descibing the data.
1046 */
1047 void
1048 extractData(const std::string fileName,
1049 const FunctionSpace& fspace);
1050
1051 protected:
1052
1053 private:
1054
1055 /**
1056 \brief
1057 Check *this and the right operand are compatible. Throws
1058 an exception if they aren't.
1059 \param right - Input - The right hand side.
1060 */
1061 inline
1062 void
1063 operandCheck(const Data& right) const
1064 {
1065 return m_data->operandCheck(*(right.m_data.get()));
1066 }
1067
1068 /**
1069 \brief
1070 Perform the specified reduction algorithm on every element of every data point in
1071 this Data object according to the given function and return the single value result.
1072 */
1073 template <class BinaryFunction>
1074 inline
1075 double
1076 algorithm(BinaryFunction operation,
1077 double initial_value) const;
1078
1079 /**
1080 \brief
1081 Reduce each data-point in this Data object using the given operation. Return a Data
1082 object with the same number of data-points, but with each data-point containing only
1083 one value - the result of the reduction operation on the corresponding data-point in
1084 this Data object
1085 */
1086 template <class BinaryFunction>
1087 inline
1088 Data
1089 dp_algorithm(BinaryFunction operation,
1090 double initial_value) const;
1091
1092 /**
1093 \brief
1094 Perform the given binary operation on all of the data's elements.
1095 The underlying type of the right hand side (right) determines the final
1096 type of *this after the operation. For example if the right hand side
1097 is expanded *this will be expanded if necessary.
1098 RHS is a Data object.
1099 */
1100 template <class BinaryFunction>
1101 inline
1102 void
1103 binaryOp(const Data& right,
1104 BinaryFunction operation);
1105
1106 /**
1107 \brief
1108 Perform the given binary operation on all of the data's elements.
1109 RHS is a boost::python object.
1110 */
1111 template <class BinaryFunction>
1112 inline
1113 void
1114 binaryOp(const boost::python::object& right,
1115 BinaryFunction operation);
1116
1117 /**
1118 \brief
1119 Convert the data type of the RHS to match this.
1120 \param right - Input - data type to match.
1121 */
1122 void
1123 typeMatchLeft(Data& right) const;
1124
1125 /**
1126 \brief
1127 Convert the data type of this to match the RHS.
1128 \param right - Input - data type to match.
1129 */
1130 void
1131 typeMatchRight(const Data& right);
1132
1133 /**
1134 \brief
1135 Construct a Data object of the appropriate type.
1136 */
1137 template <class IValueType>
1138 void
1139 initialise(const IValueType& value,
1140 const FunctionSpace& what,
1141 bool expanded);
1142
1143 /**
1144 \brief
1145 Reshape the data point if the data point is currently rank 0.
1146 Will throw an exception if the data points are not rank 0.
1147 The original data point value is used for all values of the new
1148 data point.
1149 */
1150 void
1151 reshapeDataPoint(const DataArrayView::ShapeType& shape);
1152
1153 //
1154 // pointer to the actual data object
1155 boost::shared_ptr<DataAbstract> m_data;
1156
1157 //
1158 // pointer to the internal profiling data
1159 struct profDataEntry *profData;
1160
1161 };
1162
1163 template <class IValueType>
1164 void
1165 Data::initialise(const IValueType& value,
1166 const FunctionSpace& what,
1167 bool expanded)
1168 {
1169 //
1170 // Construct a Data object of the appropriate type.
1171 // Construct the object first as there seems to be a bug which causes
1172 // undefined behaviour if an exception is thrown during construction
1173 // within the shared_ptr constructor.
1174 if (expanded) {
1175 DataAbstract* temp=new DataExpanded(value,what);
1176 boost::shared_ptr<DataAbstract> temp_data(temp);
1177 m_data=temp_data;
1178 } else {
1179 DataAbstract* temp=new DataConstant(value,what);
1180 boost::shared_ptr<DataAbstract> temp_data(temp);
1181 m_data=temp_data;
1182 }
1183 }
1184
1185 /**
1186 Binary Data object operators.
1187 */
1188
1189 /**
1190 \brief
1191 Operator+
1192 Takes two Data objects.
1193 */
1194 Data operator+(const Data& left, const Data& right);
1195
1196 /**
1197 \brief
1198 Operator-
1199 Takes two Data objects.
1200 */
1201 Data operator-(const Data& left, const Data& right);
1202
1203 /**
1204 \brief
1205 Operator*
1206 Takes two Data objects.
1207 */
1208 Data operator*(const Data& left, const Data& right);
1209
1210 /**
1211 \brief
1212 Operator/
1213 Takes two Data objects.
1214 */
1215 Data operator/(const Data& left, const Data& right);
1216
1217 /**
1218 \brief
1219 Operator+
1220 Takes LHS Data object and RHS python::object.
1221 python::object must be convertable to Data type.
1222 */
1223 Data operator+(const Data& left, const boost::python::object& right);
1224
1225 /**
1226 \brief
1227 Operator-
1228 Takes LHS Data object and RHS python::object.
1229 python::object must be convertable to Data type.
1230 */
1231 Data operator-(const Data& left, const boost::python::object& right);
1232
1233 /**
1234 \brief
1235 Operator*
1236 Takes LHS Data object and RHS python::object.
1237 python::object must be convertable to Data type.
1238 */
1239 Data operator*(const Data& left, const boost::python::object& right);
1240
1241 /**
1242 \brief
1243 Operator/
1244 Takes LHS Data object and RHS python::object.
1245 python::object must be convertable to Data type.
1246 */
1247 Data operator/(const Data& left, const boost::python::object& right);
1248
1249 /**
1250 \brief
1251 Operator+
1252 Takes LHS python::object and RHS Data object.
1253 python::object must be convertable to Data type.
1254 */
1255 Data operator+(const boost::python::object& left, const Data& right);
1256
1257 /**
1258 \brief
1259 Operator-
1260 Takes LHS python::object and RHS Data object.
1261 python::object must be convertable to Data type.
1262 */
1263 Data operator-(const boost::python::object& left, const Data& right);
1264
1265 /**
1266 \brief
1267 Operator*
1268 Takes LHS python::object and RHS Data object.
1269 python::object must be convertable to Data type.
1270 */
1271 Data operator*(const boost::python::object& left, const Data& right);
1272
1273 /**
1274 \brief
1275 Operator/
1276 Takes LHS python::object and RHS Data object.
1277 python::object must be convertable to Data type.
1278 */
1279 Data operator/(const boost::python::object& left, const Data& right);
1280
1281 /**
1282 \brief
1283 Output operator
1284 */
1285 std::ostream& operator<<(std::ostream& o, const Data& data);
1286
1287 /**
1288 \brief
1289 Return true if operands are equivalent, else return false.
1290 NB: this operator does very little at this point, and isn't to
1291 be relied on. Requires further implementation.
1292 */
1293 //bool operator==(const Data& left, const Data& right);
1294
1295 /**
1296 \brief
1297 Perform the given binary operation with this and right as operands.
1298 Right is a Data object.
1299 */
1300 template <class BinaryFunction>
1301 inline
1302 void
1303 Data::binaryOp(const Data& right,
1304 BinaryFunction operation)
1305 {
1306 //
1307 // if this has a rank of zero promote it to the rank of the RHS
1308 if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1309 reshapeDataPoint(right.getPointDataView().getShape());
1310 }
1311 //
1312 // initially make the temporary a shallow copy
1313 Data tempRight(right);
1314 if (getFunctionSpace()!=right.getFunctionSpace()) {
1315 if (right.probeInterpolation(getFunctionSpace())) {
1316 //
1317 // an interpolation is required so create a new Data
1318 tempRight=Data(right,this->getFunctionSpace());
1319 } else if (probeInterpolation(right.getFunctionSpace())) {
1320 //
1321 // interpolate onto the RHS function space
1322 Data tempLeft(*this,right.getFunctionSpace());
1323 m_data=tempLeft.m_data;
1324 }
1325 }
1326 operandCheck(tempRight);
1327 //
1328 // ensure this has the right type for the RHS
1329 typeMatchRight(tempRight);
1330 //
1331 // Need to cast to the concrete types so that the correct binaryOp
1332 // is called.
1333 if (isExpanded()) {
1334 //
1335 // Expanded data will be done in parallel, the right hand side can be
1336 // of any data type
1337 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1338 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1339 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1340 } else if (isTagged()) {
1341 //
1342 // Tagged data is operated on serially, the right hand side can be
1343 // either DataConstant or DataTagged
1344 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1345 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1346 if (right.isTagged()) {
1347 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1348 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1349 escript::binaryOp(*leftC,*rightC,operation);
1350 } else {
1351 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1352 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1353 escript::binaryOp(*leftC,*rightC,operation);
1354 }
1355 } else if (isConstant()) {
1356 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1357 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1358 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1359 escript::binaryOp(*leftC,*rightC,operation);
1360 }
1361 }
1362
1363 /**
1364 \brief
1365 Perform the given binary operation with this and right as operands.
1366 Right is a boost::python object.
1367 */
1368 template <class BinaryFunction>
1369 inline
1370 void
1371 Data::binaryOp(const boost::python::object& right,
1372 BinaryFunction operation)
1373 {
1374 DataArray temp(right);
1375 //
1376 // if this has a rank of zero promote it to the rank of the RHS.
1377 if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1378 reshapeDataPoint(temp.getView().getShape());
1379 }
1380 //
1381 // Always allow scalar values for the RHS but check other shapes
1382 if (temp.getView().getRank()!=0) {
1383 if (!getPointDataView().checkShape(temp.getView().getShape())) {
1384 throw DataException(getPointDataView().createShapeErrorMessage(
1385 "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1386 }
1387 }
1388 if (isExpanded()) {
1389 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1390 EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1391 escript::binaryOp(*leftC,temp.getView(),operation);
1392 } else if (isTagged()) {
1393 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1394 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1395 escript::binaryOp(*leftC,temp.getView(),operation);
1396 } else if (isConstant()) {
1397 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1398 EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1399 escript::binaryOp(*leftC,temp.getView(),operation);
1400 }
1401 }
1402
1403 /**
1404 \brief
1405 Perform the given unary operation on other and return the result.
1406 Given operation is performed on each element of each data point, thus
1407 argument object is a rank n Data object, and returned object is a rank n
1408 Data object.
1409 Calls Data::unaryOp.
1410 */
1411 template <class UnaryFunction>
1412 inline
1413 Data
1414 unaryOp(const Data& other,
1415 UnaryFunction operation)
1416 {
1417 Data result;
1418 result.copy(other);
1419 result.unaryOp(operation);
1420 return result;
1421 }
1422
1423 /**
1424 \brief
1425 Perform the given unary operation on this.
1426 Given operation is performed on each element of each data point.
1427 Calls escript::unaryOp.
1428 */
1429 template <class UnaryFunction>
1430 inline
1431 void
1432 Data::unaryOp(UnaryFunction operation)
1433 {
1434 if (isExpanded()) {
1435 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1436 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1437 escript::unaryOp(*leftC,operation);
1438 } else if (isTagged()) {
1439 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1440 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1441 escript::unaryOp(*leftC,operation);
1442 } else if (isConstant()) {
1443 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1444 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1445 escript::unaryOp(*leftC,operation);
1446 }
1447 }
1448
1449 /**
1450 \brief
1451 Perform the given Data object reduction algorithm on this and return the result.
1452 Given operation combines each element of each data point, thus argument
1453 object (*this) is a rank n Data object, and returned object is a scalar.
1454 Calls escript::algorithm.
1455 */
1456 template <class BinaryFunction>
1457 inline
1458 double
1459 Data::algorithm(BinaryFunction operation, double initial_value) const
1460 {
1461 if (isExpanded()) {
1462 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1463 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1464 return escript::algorithm(*leftC,operation,initial_value);
1465 } else if (isTagged()) {
1466 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1467 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1468 return escript::algorithm(*leftC,operation,initial_value);
1469 } else if (isConstant()) {
1470 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1471 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1472 return escript::algorithm(*leftC,operation,initial_value);
1473 }
1474 return 0;
1475 }
1476
1477 /**
1478 \brief
1479 Perform the given data point reduction algorithm on data and return the result.
1480 Given operation combines each element within each data point into a scalar,
1481 thus argument object is a rank n Data object, and returned object is a
1482 rank 0 Data object.
1483 Calls escript::dp_algorithm.
1484 */
1485 template <class BinaryFunction>
1486 inline
1487 Data
1488 Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1489 {
1490 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1491 if (isExpanded()) {
1492 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1493 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1494 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1495 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1496 escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1497 } else if (isTagged()) {
1498 DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1499 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1500 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1501 EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1502 escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1503 } else if (isConstant()) {
1504 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1505 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1506 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1507 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1508 escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1509 }
1510 return result;
1511 }
1512
1513 }
1514 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26