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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26