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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26