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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26