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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26