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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 104 - (show annotations)
Fri Dec 17 07:43:12 2004 UTC (14 years, 11 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 32398 byte(s)
*** empty log message ***

1 // $Id$
2 /*=============================================================================
3
4 ******************************************************************************
5 * *
6 * COPYRIGHT ACcESS 2004 - All Rights Reserved *
7 * *
8 * This software is the property of ACcESS. No part of this code *
9 * may be copied in any form or by any means without the expressed written *
10 * consent of ACcESS. Copying, use or modification of this software *
11 * by any unauthorised person is illegal unless that *
12 * person has a software license agreement with ACcESS. *
13 * *
14 ******************************************************************************
15
16 ******************************************************************************/
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/FunctionSpace.h"
24 #include "escript/Data/BinaryOp.h"
25 #include "escript/Data/UnaryOp.h"
26
27 extern "C" {
28 #include "escript/Data/DataC.h"
29 }
30
31 #include <iostream>
32 #include <string>
33 #include <memory>
34 #include <algorithm>
35
36 #include <boost/shared_ptr.hpp>
37 #include <boost/python/object.hpp>
38 #include <boost/python/list.hpp>
39 #include <boost/python/tuple.hpp>
40 #include <boost/python/numeric.hpp>
41
42 /**
43 \brief
44 Data is essentially a factory class which creates the appropriate Data
45 object for the given construction arguments. It retains control over
46 the object created for the lifetime of the object.
47 The type of Data object referred to may change during the lifetime of
48 the Data object.
49
50 Description:
51 Data is essentially a factory class which creates the appropriate Data
52 object for the given construction arguments. It retains control over
53 the object created for the lifetime of the object.
54 The type of Data object referred to may change during the lifetime of
55 the Data object.
56 */
57
58 namespace escript {
59
60 //
61 // Forward declaration for various implimentations of Data.
62 class DataEmpty;
63 class DataConstant;
64 class DataTagged;
65 class DataExpanded;
66
67 class Data {
68
69 public:
70
71 typedef double (*UnaryDFunPtr)(double);
72 typedef double (*BinaryDFunPtr)(double,double);
73
74 /**
75 Constructors.
76 */
77
78 /**
79 \brief
80 Default constructor.
81 Creates a DataEmpty object.
82 */
83 Data();
84
85 /**
86 \brief
87 Copy constructor.
88 WARNING: Only performs a shallow copy.
89 */
90 Data(const Data& inData);
91
92 /**
93 \brief
94 Constructor from another Data object. If "what" is different from the
95 function space of inData the inData are tried to be interpolated to what,
96 otherwise a shallow copy of inData is returned.
97 */
98 Data(const Data& inData,
99 const FunctionSpace& what);
100
101 /**
102 \brief
103 Constructor which copies data from a DataArrayView.
104
105 \param value - Input - Data value for a single point.
106 \param what - Input - A description of what this data represents.
107 \param expanded - Input - Flag, if true fill the entire container with
108 the value. Otherwise a more efficient storage
109 mechanism will be used.
110 */
111 Data(const DataArrayView& value,
112 const FunctionSpace& what=FunctionSpace(),
113 bool expanded=false);
114
115 /**
116 \brief
117 Constructor which creates a Data from a DataArrayView shape.
118
119 \param value - Input - Single value applied to all Data.
120 \param dataPointShape - Input - The shape of each data point.
121 \param what - Input - A description of what this data represents.
122 \param expanded - Input - Flag, if true fill the entire container with
123 the given value. Otherwise a more efficient storage
124 mechanism will be used.
125 */
126 Data(double value,
127 const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),
128 const FunctionSpace& what=FunctionSpace(),
129 bool expanded=false);
130
131 /**
132 \brief
133 Constructor which performs a deep copy of a region from another Data object.
134
135 \param inData - Input - Input Data object.
136 \param region - Input - Region to copy.
137 */
138 Data(const Data& inData,
139 const DataArrayView::RegionType& region);
140
141 /**
142 \brief
143 Constructor which will create Tagged data if expanded is false.
144 No attempt is made to ensure the tag keys match the tag keys
145 within the function space.
146
147 \param tagKeys - Input - List of tag values.
148 \param values - Input - List of values, one for each tag.
149 \param defaultValue - Input - A default value, used if tag doesn't exist.
150 \param what - Input - A description of what this data represents.
151 \param expanded - Input - Flag, if true fill the entire container with
152 the appropriate values.
153 */
154 Data(const DataTagged::TagListType& tagKeys,
155 const DataTagged::ValueListType& values,
156 const DataArrayView& defaultValue,
157 const FunctionSpace& what=FunctionSpace(),
158 bool expanded=false);
159
160 /**
161 \brief
162 Constructor which copies data from a python numarray.
163
164 \param value - Input - Data value for a single point.
165 \param what - Input - A description of what this data represents.
166 \param expanded - Input - Flag, if true fill the entire container with
167 the value. Otherwise a more efficient storage
168 mechanism will be used.
169 */
170 Data(const boost::python::numeric::array& value,
171 const FunctionSpace& what=FunctionSpace(),
172 bool expanded=false);
173
174 /**
175 \brief
176 Constructor which copies data from any object that can be converted into
177 a python numarray.
178
179 \param value - Input - Input data.
180 \param what - Input - A description of what this data represents.
181 \param expanded - Input - Flag, if true fill the entire container with
182 the value. Otherwise a more efficient storage
183 mechanism will be used.
184 */
185 Data(const boost::python::object& value,
186 const FunctionSpace& what=FunctionSpace(),
187 bool expanded=false);
188
189 /**
190 \brief
191 Constructor which creates a DataConstant.
192 Copies data from any object that can be converted
193 into a numarray. All other parameters are copied from other.
194
195 \param value - Input - Input data.
196 \param other - Input - contains all other parameters.
197 */
198 Data(const boost::python::object& value,
199 const Data& other);
200
201 /**
202 \brief
203 Constructor which creates a DataConstant of "shape" with constant value.
204 */
205 Data(double value,
206 const boost::python::tuple& shape=boost::python::make_tuple(),
207 const FunctionSpace& what=FunctionSpace(),
208 bool expanded=false);
209
210 /**
211 \brief
212 Perform a deep copy.
213 */
214 void
215 copy(const Data& other);
216
217 /**
218 Member access methods.
219 */
220
221 /**
222 \brief
223 Return the C wrapper for the Data object.
224 */
225 escriptDataC
226 getDataC();
227
228 /**
229 \brief
230 Return the C wrapper for the Data object - const version.
231 */
232 escriptDataC
233 getDataC() const;
234
235 /**
236 \brief
237 Write the data as a string.
238 */
239 inline
240 std::string
241 toString() const
242 {
243 return m_data->toString();
244 }
245
246 /**
247 \brief
248 Return the DataArrayView of the point data. This essentially contains
249 the shape information for each data point although it also may be used
250 to manipulate the point data.
251 */
252 inline
253 const DataArrayView&
254 getPointDataView() const
255 {
256 return m_data->getPointDataView();
257 }
258
259 /**
260 \brief
261 Whatever the current Data type make this into a DataExpanded.
262 */
263 void
264 expand();
265
266 /**
267 \brief
268 If possible convert this Data to DataTagged. This will only allow
269 Constant data to be converted to tagged. An attempt to convert
270 Expanded data to tagged will throw an exception.
271 */
272 void
273 tag();
274
275 /**
276 \brief
277 Return true if this Data is expanded.
278 */
279 bool
280 isExpanded() const;
281
282 /**
283 \brief
284 Return true if this Data is tagged.
285 */
286 bool
287 isTagged() const;
288
289 /**
290 \brief
291 Return true if this Data is constant.
292 */
293 bool
294 isConstant() const;
295
296 /**
297 \brief
298 Return true if this Data is empty.
299 */
300 bool
301 isEmpty() const;
302
303 /**
304 \brief
305 Return the function space.
306 */
307 inline
308 const FunctionSpace&
309 getFunctionSpace() const
310 {
311 return m_data->getFunctionSpace();
312 }
313
314 /**
315 \brief
316 Return a copy of the function space.
317 */
318 const FunctionSpace
319 getCopyOfFunctionSpace() const;
320
321 /**
322 \brief
323 Return the domain.
324 */
325 inline
326 const AbstractDomain&
327 getDomain() const
328 {
329 return getFunctionSpace().getDomain();
330 }
331
332 /**
333 \brief
334 Return a copy of the domain.
335 */
336 const AbstractDomain
337 getCopyOfDomain() const;
338
339 /**
340 \brief
341 Return the rank of the point data.
342 */
343 inline
344 int
345 getDataPointRank() const
346 {
347 return m_data->getPointDataView().getRank();
348 }
349
350 /**
351 \brief
352 Return the number of samples.
353 */
354 inline
355 int
356 getNumSamples() const
357 {
358 return m_data->getNumSamples();
359 }
360
361 /**
362 \brief
363 Return the number of data points per sample.
364 */
365 inline
366 int
367 getNumDataPointsPerSample() const
368 {
369 return m_data->getNumDPPSample();
370 }
371
372 /**
373 \brief
374 Return the sample data for the given sample no. This is not the
375 preferred interface but is provided for use by C code.
376 \param sampleNo - Input - the given sample no.
377 */
378 inline
379 DataAbstract::ValueType::value_type*
380 getSampleData(DataAbstract::ValueType::size_type sampleNo)
381 {
382 return m_data->getSampleData(sampleNo);
383 }
384
385 /**
386 \brief
387 Return the sample data for the given tag. If an attempt is made to
388 access data that isn't tagged an exception will be thrown.
389 \param tag - Input - the tag key.
390 */
391 inline
392 DataAbstract::ValueType::value_type*
393 getSampleDataByTag(int tag)
394 {
395 return m_data->getSampleDataByTag(tag);
396 }
397
398 /**
399 \brief
400 Return a view into the data for the data point specified.
401 NOTE: Construction of the DataArrayView is a relatively expensive
402 operation.
403 \param sampleNo - Input -
404 \param dataPointNo - Input -
405 */
406 inline
407 DataArrayView
408 getDataPoint(int sampleNo,
409 int dataPointNo)
410 {
411 return m_data->getDataPoint(sampleNo,dataPointNo);
412 }
413
414 /**
415 \brief
416 Return a reference to the data point shape.
417 */
418 const DataArrayView::ShapeType&
419 getDataPointShape() const;
420
421 /**
422 \brief
423 Return the data point shape as a tuple of integers.
424 */
425 boost::python::tuple
426 getShapeTuple() const;
427
428 /**
429 \brief
430 Return the size of the data point. It is the product of the
431 data point shape dimensions.
432 */
433 int
434 getDataPointSize() const;
435
436 /**
437 \brief
438 Return the number of doubles stored for this Data.
439 */
440 DataArrayView::ValueType::size_type
441 getLength() const;
442
443 /**
444 \brief
445 Assign the given value to the tag. Implicitly converts this
446 object to type DataTagged. Throws an exception if this object
447 cannot be converted to a DataTagged object.
448 \param tagKey - Input - Integer key.
449 \param value - Input - Value to associate with given key.
450 */
451 void
452 setTaggedValue(int tagKey,
453 const boost::python::object& value);
454
455 /**
456 \brief
457 Assign the given value to the tag. Implicitly converts this
458 object to type DataTagged. Throws an exception if this object
459 cannot be converted to a DataTagged object.
460 \param tagKey - Input - Integer key.
461 \param value - Input - Value to associate with given key.
462 Note: removed for now - this version not needed, and breaks escript.cpp
463 */
464 /*
465 void
466 setTaggedValue(int tagKey,
467 const DataArrayView& value);
468 */
469
470 /**
471 \brief
472 Copy other Data object into this Data object where mask is positive.
473 */
474 void
475 copyWithMask(const Data& other,
476 const Data& mask);
477
478 /**
479 Data object operation methods and operators.
480 */
481
482 /**
483 \brief
484 Interpolates this onto the given functionspace and returns
485 the result as a Data object.
486 */
487 Data
488 interpolate(const FunctionSpace& functionspace) const;
489
490 /**
491 \brief
492 Calculates the gradient of the data at the data points of functionspace.
493 If functionspace is not present the function space of Function(getDomain()) is used.
494 */
495 Data
496 gradOn(const FunctionSpace& functionspace) const;
497
498 Data
499 grad() const;
500
501 /**
502 \brief
503 Calculate the integral over the function space domain.
504 */
505 boost::python::numeric::array
506 integrate() const;
507
508 /**
509 \brief
510 Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
511 */
512 Data
513 wherePositive() const;
514
515 /**
516 \brief
517 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
518 */
519 Data
520 whereNegative() const;
521
522 /**
523 \brief
524 Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
525 */
526 Data
527 whereNonNegative() const;
528
529 /**
530 \brief
531 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
532 */
533 Data
534 whereNonPositive() const;
535
536 /**
537 \brief
538 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
539 */
540 Data
541 whereZero() const;
542
543 /**
544 \brief
545 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
546 */
547 Data
548 whereNonZero() const;
549
550 /**
551 \brief
552 Return the sin of each data point of this Data object.
553 */
554 Data
555 sin() const;
556
557 /**
558 \brief
559 Return the cos of each data point of this Data object.
560 */
561 Data
562 cos() const;
563
564 /**
565 \brief
566 Return the tan of each data point of this Data object.
567 */
568 Data
569 tan() const;
570
571 /**
572 \brief
573 Return the log to base 10 of each data point of this Data object.
574 */
575 Data
576 log() const;
577
578 /**
579 \brief
580 Return the natural log of each data point of this Data object.
581 */
582 Data
583 ln() const;
584
585 /**
586 \brief
587 Return the maximum absolute value of this Data object.
588 */
589 double
590 Lsup() const;
591
592 /**
593 \brief
594 Return the maximum value of this Data object.
595 */
596 double
597 sup() const;
598
599 /**
600 \brief
601 Return the minimum value of this Data object.
602 */
603 double
604 inf() const;
605
606 /**
607 \brief
608 Return the absolute value of each data point of this Data object.
609 */
610 Data
611 abs() const;
612
613 /**
614 \brief
615 Return the maximum value of each data point of this Data object.
616 */
617 Data
618 maxval() const;
619
620 /**
621 \brief
622 Return the minimum value of each data point of this Data object.
623 */
624 Data
625 minval() const;
626
627 /**
628 \brief
629 Return the length of each data point of this Data object.
630 sqrt(sum(A[i,j,k,l]^2))
631 */
632 Data
633 length() const;
634
635 /**
636 \brief
637 Return the sign of each data point of this Data object.
638 -1 for negative values, zero for zero values, 1 for positive values.
639 */
640 Data
641 sign() const;
642
643 /**
644 \transpose
645 Transpose each data point of this Data object around the given axis.
646 */
647 Data
648 transpose(int axis) const;
649
650 /**
651 \trace
652 Calculate the trace of each data point of this Data object.
653 sum(A[i,i,i,i])
654 */
655 Data
656 trace() const;
657
658 /**
659 \exp
660 Return the exponential function of each data point of this Data object.
661 */
662 Data
663 exp() const;
664
665 /**
666 \sqrt
667 Return the square root of each data point of this Data object.
668 */
669 Data
670 sqrt() const;
671
672 /**
673 \brief
674 Return the given power of each data point of this Data object.
675 */
676 Data
677 powD(const Data& right) const;
678
679 Data
680 powO(const boost::python::object& right) const;
681
682 /**
683 \brief
684 writes the object to a file in the DX file format
685 */
686 void
687 saveDX(std::string fileName) const;
688
689 /**
690 \brief
691 Return the negation of each data point of this Data object.
692 */
693 Data
694 neg() const;
695
696 /**
697 \brief
698 Return the identity of each data point of this Data object.
699 Simply returns this object unmodified.
700 */
701 Data
702 pos() const;
703
704 /**
705 \brief
706 Overloaded operator +=
707 \param right - Input - The right hand side.
708 */
709 Data& operator+=(const Data& right);
710 Data& operator+=(const boost::python::object& right);
711
712 /**
713 \brief
714 Overloaded operator -=
715 \param right - Input - The right hand side.
716 */
717 Data& operator-=(const Data& right);
718 Data& operator-=(const boost::python::object& right);
719
720 /**
721 \brief
722 Overloaded operator *=
723 \param right - Input - The right hand side.
724 */
725 Data& operator*=(const Data& right);
726 Data& operator*=(const boost::python::object& right);
727
728 /**
729 \brief
730 Overloaded operator /=
731 \param right - Input - The right hand side.
732 */
733 Data& operator/=(const Data& right);
734 Data& operator/=(const boost::python::object& right);
735
736 /**
737 \brief
738 Returns true if this can be interpolated to functionspace.
739 */
740 bool
741 probeInterpolation(const FunctionSpace& functionspace) const;
742
743 /**
744 Data object slicing methods.
745 */
746
747 /**
748 \brief
749 Returns a slice from this Data object.
750
751 /description
752 Implements the [] get operator in python.
753 Calls getSlice.
754
755 \param key - Input - python slice tuple specifying
756 slice to return.
757 */
758 Data
759 getItem(const boost::python::object& key) const;
760
761 /**
762 \brief
763 Copies slice from value into this Data object.
764
765 \description
766 Implements the [] set operator in python.
767 Calls setSlice.
768
769 \param key - Input - python slice tuple specifying
770 slice to copy from value.
771 \param value - Input - Data object to copy from.
772 */
773 void
774 setItemD(const boost::python::object& key,
775 const Data& value);
776
777 void
778 setItemO(const boost::python::object& key,
779 const boost::python::object& value);
780
781 // These following public methods should be treated as private.
782
783 /**
784 \brief
785 Perform the given unary operation on every element of every data point in
786 this Data object.
787 */
788 template <class UnaryFunction>
789 inline
790 void
791 unaryOp(UnaryFunction operation);
792
793 /**
794 \brief
795 Return a Data object containing the specified slice of
796 this Data object.
797 \param region - Input - Region to copy.
798 */
799 Data
800 getSlice(const DataArrayView::RegionType& region) const;
801
802 /**
803 \brief
804 Copy the specified slice from the given value into this
805 Data object.
806 \param value - Input - Data to copy from.
807 \param region - Input - Region to copy.
808 */
809 void
810 setSlice(const Data& value,
811 const DataArrayView::RegionType& region);
812
813 protected:
814
815 private:
816
817 /**
818 \brief
819 Check *this and the right operand are compatible. Throws
820 an exception if they aren't.
821 \param right - Input - The right hand side.
822 */
823 inline
824 void
825 operandCheck(const Data& right) const
826 {
827 return m_data->operandCheck(*(right.m_data.get()));
828 }
829
830 /**
831 \brief
832 Perform the specified reduction algorithm on every element of every data point in
833 this Data object and return the single double value result.
834 */
835 template <class UnaryFunction>
836 inline
837 double
838 algorithm(UnaryFunction operation) const;
839
840 /**
841 \brief
842 Perform the given binary operation on all of the data's elements.
843 The underlying type of the right hand side (right) determines the final
844 type of *this after the operation. For example if the right hand side
845 is expanded *this will be expanded if necessary.
846 RHS is a Data object.
847 */
848 template <class BinaryFunction>
849 inline
850 void
851 binaryOp(const Data& right,
852 BinaryFunction operation);
853
854 /**
855 \brief
856 Perform the given binary operation on all of the data's elements.
857 RHS is a boost::python object.
858 */
859 template <class BinaryFunction>
860 inline
861 void
862 binaryOp(const boost::python::object& right,
863 BinaryFunction operation);
864
865 /**
866 \brief
867 Convert the data type of the RHS to match this.
868 \param right - Input - data type to match.
869 */
870 void
871 typeMatchLeft(Data& right) const;
872
873 /**
874 \brief
875 Convert the data type of this to match the RHS.
876 \param right - Input - data type to match.
877 */
878 void
879 typeMatchRight(const Data& right);
880
881 /**
882 \brief
883 Construct a Data object of the appropriate type.
884 */
885 template <class IValueType>
886 void
887 initialise(const IValueType& value,
888 const FunctionSpace& what,
889 bool expanded);
890
891 /**
892 \brief
893 Reshape the data point if the data point is currently rank 0.
894 Will throw an exception if the data points are not rank 0.
895 The original data point value is used for all values of the new
896 data point.
897 */
898 void
899 reshapeDataPoint(const DataArrayView::ShapeType& shape);
900
901 //
902 // pointer to the actual data object
903 boost::shared_ptr<DataAbstract> m_data;
904
905 };
906
907 template <class IValueType>
908 void
909 Data::initialise(const IValueType& value,
910 const FunctionSpace& what,
911 bool expanded)
912 {
913 //
914 // Construct a Data object of the appropriate type.
915 // Construct the object first as there seems to be a bug which causes
916 // undefined behaviour if an exception is thrown during construction
917 // within the shared_ptr constructor.
918 if (expanded) {
919 DataAbstract* temp=new DataExpanded(value,what);
920 boost::shared_ptr<DataAbstract> temp_data(temp);
921 m_data=temp_data;
922 } else {
923 DataAbstract* temp=new DataConstant(value,what);
924 boost::shared_ptr<DataAbstract> temp_data(temp);
925 m_data=temp_data;
926 }
927 }
928
929 /**
930 Binary Data object operators.
931 */
932
933 /**
934 \brief
935 Operator+
936 Takes two Data objects.
937 */
938 Data operator+(const Data& left, const Data& right);
939
940 /**
941 \brief
942 Operator-
943 Takes two Data objects.
944 */
945 Data operator-(const Data& left, const Data& right);
946
947 /**
948 \brief
949 Operator*
950 Takes two Data objects.
951 */
952 Data operator*(const Data& left, const Data& right);
953
954 /**
955 \brief
956 Operator/
957 Takes two Data objects.
958 */
959 Data operator/(const Data& left, const Data& right);
960
961 /**
962 \brief
963 Operator+
964 Takes LHS Data object and RHS python::object.
965 python::object must be convertable to Data type.
966 */
967 Data operator+(const Data& left, const boost::python::object& right);
968
969 /**
970 \brief
971 Operator-
972 Takes LHS Data object and RHS python::object.
973 python::object must be convertable to Data type.
974 */
975 Data operator-(const Data& left, const boost::python::object& right);
976
977 /**
978 \brief
979 Operator*
980 Takes LHS Data object and RHS python::object.
981 python::object must be convertable to Data type.
982 */
983 Data operator*(const Data& left, const boost::python::object& right);
984
985 /**
986 \brief
987 Operator/
988 Takes LHS Data object and RHS python::object.
989 python::object must be convertable to Data type.
990 */
991 Data operator/(const Data& left, const boost::python::object& right);
992
993 /**
994 \brief
995 Operator+
996 Takes LHS python::object and RHS Data object.
997 python::object must be convertable to Data type.
998 */
999 Data operator+(const boost::python::object& left, const Data& right);
1000
1001 /**
1002 \brief
1003 Operator-
1004 Takes LHS python::object and RHS Data object.
1005 python::object must be convertable to Data type.
1006 */
1007 Data operator-(const boost::python::object& left, const Data& right);
1008
1009 /**
1010 \brief
1011 Operator*
1012 Takes LHS python::object and RHS Data object.
1013 python::object must be convertable to Data type.
1014 */
1015 Data operator*(const boost::python::object& left, const Data& right);
1016
1017 /**
1018 \brief
1019 Operator/
1020 Takes LHS python::object and RHS Data object.
1021 python::object must be convertable to Data type.
1022 */
1023 Data operator/(const boost::python::object& left, const Data& right);
1024
1025 /**
1026 \brief
1027 Output operator
1028 */
1029 std::ostream& operator<<(std::ostream& o, const Data& data);
1030
1031 /**
1032 \brief
1033 Return true if operands are equivalent, else return false.
1034 NB: this operator does very little at this point, and isn't to
1035 be relied on. Requires further implementation.
1036 */
1037 //bool operator==(const Data& left, const Data& right);
1038
1039 /**
1040 \brief
1041 Perform the given binary operation with this and right as operands.
1042 Right is a Data object.
1043 */
1044 template <class BinaryFunction>
1045 inline
1046 void
1047 Data::binaryOp(const Data& right,
1048 BinaryFunction operation)
1049 {
1050 //
1051 // if this has a rank of zero promote it to the rank of the RHS
1052 if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1053 reshapeDataPoint(right.getPointDataView().getShape());
1054 }
1055 //
1056 // initially make the temporary a shallow copy
1057 Data tempRight(right);
1058 if (getFunctionSpace()!=right.getFunctionSpace()) {
1059 if (right.probeInterpolation(getFunctionSpace())) {
1060 //
1061 // an interpolation is required so create a new Data
1062 tempRight=Data(right,this->getFunctionSpace());
1063 } else if (probeInterpolation(right.getFunctionSpace())) {
1064 //
1065 // interpolate onto the RHS function space
1066 Data tempLeft(*this,right.getFunctionSpace());
1067 m_data=tempLeft.m_data;
1068 }
1069 }
1070 operandCheck(tempRight);
1071 //
1072 // ensure this has the right type for the RHS
1073 typeMatchRight(tempRight);
1074 //
1075 // Need to cast to the concrete types so that the correct binaryOp
1076 // is called.
1077 if (isExpanded()) {
1078 //
1079 // Expanded data will be done in parallel, the right hand side can be
1080 // of any data type
1081 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1082 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1083 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1084 } else if (isTagged()) {
1085 //
1086 // Tagged data is operated on serially, the right hand side can be
1087 // either DataConstant or DataTagged
1088 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1089 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1090 if (right.isTagged()) {
1091 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1092 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1093 escript::binaryOp(*leftC,*rightC,operation);
1094 } else {
1095 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1096 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1097 escript::binaryOp(*leftC,*rightC,operation);
1098 }
1099 } else if (isConstant()) {
1100 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1101 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1102 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1103 escript::binaryOp(*leftC,*rightC,operation);
1104 }
1105 }
1106
1107 /**
1108 \brief
1109 Perform the given binary operation with this and right as operands.
1110 Right is a boost::python object.
1111 */
1112 template <class BinaryFunction>
1113 inline
1114 void
1115 Data::binaryOp(const boost::python::object& right,
1116 BinaryFunction operation)
1117 {
1118 DataArray temp(right);
1119 //
1120 // if this has a rank of zero promote it to the rank of the RHS.
1121 if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1122 reshapeDataPoint(temp.getView().getShape());
1123 }
1124 //
1125 // Always allow scalar values for the RHS but check other shapes
1126 if (temp.getView().getRank()!=0) {
1127 if (!getPointDataView().checkShape(temp.getView().getShape())) {
1128 throw DataException(getPointDataView().createShapeErrorMessage(
1129 "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1130 }
1131 }
1132 if (isExpanded()) {
1133 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1134 EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1135 escript::binaryOp(*leftC,temp.getView(),operation);
1136 } else if (isTagged()) {
1137 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1138 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1139 escript::binaryOp(*leftC,temp.getView(),operation);
1140 } else if (isConstant()) {
1141 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1142 EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1143 escript::binaryOp(*leftC,temp.getView(),operation);
1144 }
1145 }
1146
1147 /**
1148 \brief
1149 Perform the given unary operation on other and return the result.
1150 Given operation is performed on each element of each data point, thus
1151 argument object is a rank n Data object, and returned object is a rank n
1152 Data object.
1153 Calls Data::unaryOp.
1154 */
1155 template <class UnaryFunction>
1156 inline
1157 Data
1158 unaryOp(const Data& other,
1159 UnaryFunction operation)
1160 {
1161 Data result;
1162 result.copy(other);
1163 result.unaryOp(operation);
1164 return result;
1165 }
1166
1167 /**
1168 \brief
1169 Perform the given unary operation on this.
1170 Given operation is performed on each element of each data point.
1171 Calls escript::unaryOp.
1172 */
1173 template <class UnaryFunction>
1174 inline
1175 void
1176 Data::unaryOp(UnaryFunction operation)
1177 {
1178 if (isExpanded()) {
1179 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1180 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1181 escript::unaryOp(*leftC,operation);
1182 } else if (isTagged()) {
1183 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1184 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1185 escript::unaryOp(*leftC,operation);
1186 } else if (isConstant()) {
1187 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1188 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1189 escript::unaryOp(*leftC,operation);
1190 }
1191 }
1192
1193 /**
1194 \brief
1195 Perform the given Data object reduction algorithm on this and return the result.
1196 Given operation combines each element of each data point, thus argument
1197 object (*this) is a rank n Data object, and returned object is a scalar.
1198 Calls escript::algorithm.
1199 */
1200 template <class UnaryFunction>
1201 inline
1202 double
1203 Data::algorithm(UnaryFunction operation) const
1204 {
1205 if (isExpanded()) {
1206 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1207 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1208 return escript::algorithm(*leftC,operation);
1209 } else if (isTagged()) {
1210 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1211 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1212 return escript::algorithm(*leftC,operation);
1213 } else if (isConstant()) {
1214 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1215 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1216 return escript::algorithm(*leftC,operation);
1217 }
1218 return 0;
1219 }
1220
1221 /**
1222 \brief
1223 Perform the given data point reduction algorithm on data and return the result.
1224 Given operation combines each element within each data point into a scalar,
1225 thus argument object is a rank n Data object, and returned object is a
1226 rank 0 Data object.
1227 Calls escript::dp_algorithm.
1228 */
1229 template <class UnaryFunction>
1230 inline
1231 Data
1232 dp_algorithm(const Data& data,
1233 UnaryFunction operation)
1234 {
1235 Data result(0,DataArrayView::ShapeType(),data.getFunctionSpace(),data.isExpanded());
1236 if (data.isExpanded()) {
1237 DataExpanded* dataE=dynamic_cast<DataExpanded*>(data.m_data.get());
1238 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1239 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1240 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1241 escript::dp_algorithm(*dataE,*resultE,operation);
1242 } else if (data.isTagged()) {
1243 DataTagged* dataT=dynamic_cast<DataTagged*>(data.m_data.get());
1244 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1245 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1246 EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1247 escript::dp_algorithm(*dataT,*resultT,operation);
1248 } else if (data.isConstant()) {
1249 DataConstant* dataC=dynamic_cast<DataConstant*>(data.m_data.get());
1250 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1251 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1252 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1253 escript::dp_algorithm(*dataC,*resultC,operation);
1254 }
1255 return result;
1256 }
1257
1258 }
1259 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26