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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26