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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 119 - (show annotations)
Tue Apr 12 04:45:05 2005 UTC (14 years, 6 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 35328 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 /**
878 \brief
879 Archive the current Data object to the given file.
880 \param fileName - Input - file to archive to.
881 */
882 void
883 archiveData(const std::string fileName);
884
885 /**
886 \brief
887 Extract the Data object archived in the given file, overwriting
888 the current Data object.
889 Note - the current object must be of type DataEmpty.
890 \param fileName - Input - file to extract from.
891 \param what - Input - a suitable FunctionSpace descibing the data.
892 */
893 void
894 extractData(const std::string fileName,
895 const FunctionSpace& fspace);
896
897 protected:
898
899 private:
900
901 /**
902 \brief
903 Check *this and the right operand are compatible. Throws
904 an exception if they aren't.
905 \param right - Input - The right hand side.
906 */
907 inline
908 void
909 operandCheck(const Data& right) const
910 {
911 return m_data->operandCheck(*(right.m_data.get()));
912 }
913
914 /**
915 \brief
916 Perform the specified reduction algorithm on every element of every data point in
917 this Data object according to the given function and return the single value result.
918 */
919 template <class UnaryFunction>
920 inline
921 double
922 algorithm(UnaryFunction operation) const;
923
924 /**
925 \brief
926 Reduce each data-point in this Data object using the given operation. Return a Data
927 object with the same number of data-points, but with each data-point containing only
928 one value - the result of the reduction operation on the corresponding data-point in
929 this Data object
930 */
931 template <class UnaryFunction>
932 inline
933 Data
934 dp_algorithm(UnaryFunction operation) const;
935
936 /**
937 \brief
938 Perform the given binary operation on all of the data's elements.
939 The underlying type of the right hand side (right) determines the final
940 type of *this after the operation. For example if the right hand side
941 is expanded *this will be expanded if necessary.
942 RHS is a Data object.
943 */
944 template <class BinaryFunction>
945 inline
946 void
947 binaryOp(const Data& right,
948 BinaryFunction operation);
949
950 /**
951 \brief
952 Perform the given binary operation on all of the data's elements.
953 RHS is a boost::python object.
954 */
955 template <class BinaryFunction>
956 inline
957 void
958 binaryOp(const boost::python::object& right,
959 BinaryFunction operation);
960
961 /**
962 \brief
963 Convert the data type of the RHS to match this.
964 \param right - Input - data type to match.
965 */
966 void
967 typeMatchLeft(Data& right) const;
968
969 /**
970 \brief
971 Convert the data type of this to match the RHS.
972 \param right - Input - data type to match.
973 */
974 void
975 typeMatchRight(const Data& right);
976
977 /**
978 \brief
979 Construct a Data object of the appropriate type.
980 */
981 template <class IValueType>
982 void
983 initialise(const IValueType& value,
984 const FunctionSpace& what,
985 bool expanded);
986
987 /**
988 \brief
989 Reshape the data point if the data point is currently rank 0.
990 Will throw an exception if the data points are not rank 0.
991 The original data point value is used for all values of the new
992 data point.
993 */
994 void
995 reshapeDataPoint(const DataArrayView::ShapeType& shape);
996
997 //
998 // pointer to the actual data object
999 boost::shared_ptr<DataAbstract> m_data;
1000
1001 };
1002
1003 template <class IValueType>
1004 void
1005 Data::initialise(const IValueType& value,
1006 const FunctionSpace& what,
1007 bool expanded)
1008 {
1009 //
1010 // Construct a Data object of the appropriate type.
1011 // Construct the object first as there seems to be a bug which causes
1012 // undefined behaviour if an exception is thrown during construction
1013 // within the shared_ptr constructor.
1014 if (expanded) {
1015 DataAbstract* temp=new DataExpanded(value,what);
1016 boost::shared_ptr<DataAbstract> temp_data(temp);
1017 m_data=temp_data;
1018 } else {
1019 DataAbstract* temp=new DataConstant(value,what);
1020 boost::shared_ptr<DataAbstract> temp_data(temp);
1021 m_data=temp_data;
1022 }
1023 }
1024
1025 /**
1026 Binary Data object operators.
1027 */
1028
1029 /**
1030 \brief
1031 Operator+
1032 Takes two Data objects.
1033 */
1034 Data operator+(const Data& left, const Data& right);
1035
1036 /**
1037 \brief
1038 Operator-
1039 Takes two Data objects.
1040 */
1041 Data operator-(const Data& left, const Data& right);
1042
1043 /**
1044 \brief
1045 Operator*
1046 Takes two Data objects.
1047 */
1048 Data operator*(const Data& left, const Data& right);
1049
1050 /**
1051 \brief
1052 Operator/
1053 Takes two Data objects.
1054 */
1055 Data operator/(const Data& left, const Data& right);
1056
1057 /**
1058 \brief
1059 Operator+
1060 Takes LHS Data object and RHS python::object.
1061 python::object must be convertable to Data type.
1062 */
1063 Data operator+(const Data& left, const boost::python::object& right);
1064
1065 /**
1066 \brief
1067 Operator-
1068 Takes LHS Data object and RHS python::object.
1069 python::object must be convertable to Data type.
1070 */
1071 Data operator-(const Data& left, const boost::python::object& right);
1072
1073 /**
1074 \brief
1075 Operator*
1076 Takes LHS Data object and RHS python::object.
1077 python::object must be convertable to Data type.
1078 */
1079 Data operator*(const Data& left, const boost::python::object& right);
1080
1081 /**
1082 \brief
1083 Operator/
1084 Takes LHS Data object and RHS python::object.
1085 python::object must be convertable to Data type.
1086 */
1087 Data operator/(const Data& left, const boost::python::object& right);
1088
1089 /**
1090 \brief
1091 Operator+
1092 Takes LHS python::object and RHS Data object.
1093 python::object must be convertable to Data type.
1094 */
1095 Data operator+(const boost::python::object& left, const Data& right);
1096
1097 /**
1098 \brief
1099 Operator-
1100 Takes LHS python::object and RHS Data object.
1101 python::object must be convertable to Data type.
1102 */
1103 Data operator-(const boost::python::object& left, const Data& right);
1104
1105 /**
1106 \brief
1107 Operator*
1108 Takes LHS python::object and RHS Data object.
1109 python::object must be convertable to Data type.
1110 */
1111 Data operator*(const boost::python::object& left, const Data& right);
1112
1113 /**
1114 \brief
1115 Operator/
1116 Takes LHS python::object and RHS Data object.
1117 python::object must be convertable to Data type.
1118 */
1119 Data operator/(const boost::python::object& left, const Data& right);
1120
1121 /**
1122 \brief
1123 Output operator
1124 */
1125 std::ostream& operator<<(std::ostream& o, const Data& data);
1126
1127 /**
1128 \brief
1129 Return true if operands are equivalent, else return false.
1130 NB: this operator does very little at this point, and isn't to
1131 be relied on. Requires further implementation.
1132 */
1133 //bool operator==(const Data& left, const Data& right);
1134
1135 /**
1136 \brief
1137 Perform the given binary operation with this and right as operands.
1138 Right is a Data object.
1139 */
1140 template <class BinaryFunction>
1141 inline
1142 void
1143 Data::binaryOp(const Data& right,
1144 BinaryFunction operation)
1145 {
1146 //
1147 // if this has a rank of zero promote it to the rank of the RHS
1148 if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1149 reshapeDataPoint(right.getPointDataView().getShape());
1150 }
1151 //
1152 // initially make the temporary a shallow copy
1153 Data tempRight(right);
1154 if (getFunctionSpace()!=right.getFunctionSpace()) {
1155 if (right.probeInterpolation(getFunctionSpace())) {
1156 //
1157 // an interpolation is required so create a new Data
1158 tempRight=Data(right,this->getFunctionSpace());
1159 } else if (probeInterpolation(right.getFunctionSpace())) {
1160 //
1161 // interpolate onto the RHS function space
1162 Data tempLeft(*this,right.getFunctionSpace());
1163 m_data=tempLeft.m_data;
1164 }
1165 }
1166 operandCheck(tempRight);
1167 //
1168 // ensure this has the right type for the RHS
1169 typeMatchRight(tempRight);
1170 //
1171 // Need to cast to the concrete types so that the correct binaryOp
1172 // is called.
1173 if (isExpanded()) {
1174 //
1175 // Expanded data will be done in parallel, the right hand side can be
1176 // of any data type
1177 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1178 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1179 escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1180 } else if (isTagged()) {
1181 //
1182 // Tagged data is operated on serially, the right hand side can be
1183 // either DataConstant or DataTagged
1184 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1185 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1186 if (right.isTagged()) {
1187 DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1188 EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1189 escript::binaryOp(*leftC,*rightC,operation);
1190 } else {
1191 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1192 EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1193 escript::binaryOp(*leftC,*rightC,operation);
1194 }
1195 } else if (isConstant()) {
1196 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1197 DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1198 EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1199 escript::binaryOp(*leftC,*rightC,operation);
1200 }
1201 }
1202
1203 /**
1204 \brief
1205 Perform the given binary operation with this and right as operands.
1206 Right is a boost::python object.
1207 */
1208 template <class BinaryFunction>
1209 inline
1210 void
1211 Data::binaryOp(const boost::python::object& right,
1212 BinaryFunction operation)
1213 {
1214 DataArray temp(right);
1215 //
1216 // if this has a rank of zero promote it to the rank of the RHS.
1217 if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1218 reshapeDataPoint(temp.getView().getShape());
1219 }
1220 //
1221 // Always allow scalar values for the RHS but check other shapes
1222 if (temp.getView().getRank()!=0) {
1223 if (!getPointDataView().checkShape(temp.getView().getShape())) {
1224 throw DataException(getPointDataView().createShapeErrorMessage(
1225 "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1226 }
1227 }
1228 if (isExpanded()) {
1229 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1230 EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1231 escript::binaryOp(*leftC,temp.getView(),operation);
1232 } else if (isTagged()) {
1233 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1234 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1235 escript::binaryOp(*leftC,temp.getView(),operation);
1236 } else if (isConstant()) {
1237 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1238 EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1239 escript::binaryOp(*leftC,temp.getView(),operation);
1240 }
1241 }
1242
1243 /**
1244 \brief
1245 Perform the given unary operation on other and return the result.
1246 Given operation is performed on each element of each data point, thus
1247 argument object is a rank n Data object, and returned object is a rank n
1248 Data object.
1249 Calls Data::unaryOp.
1250 */
1251 template <class UnaryFunction>
1252 inline
1253 Data
1254 unaryOp(const Data& other,
1255 UnaryFunction operation)
1256 {
1257 Data result;
1258 result.copy(other);
1259 result.unaryOp(operation);
1260 return result;
1261 }
1262
1263 /**
1264 \brief
1265 Perform the given unary operation on this.
1266 Given operation is performed on each element of each data point.
1267 Calls escript::unaryOp.
1268 */
1269 template <class UnaryFunction>
1270 inline
1271 void
1272 Data::unaryOp(UnaryFunction operation)
1273 {
1274 if (isExpanded()) {
1275 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1276 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1277 escript::unaryOp(*leftC,operation);
1278 } else if (isTagged()) {
1279 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1280 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1281 escript::unaryOp(*leftC,operation);
1282 } else if (isConstant()) {
1283 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1284 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1285 escript::unaryOp(*leftC,operation);
1286 }
1287 }
1288
1289 /**
1290 \brief
1291 Perform the given Data object reduction algorithm on this and return the result.
1292 Given operation combines each element of each data point, thus argument
1293 object (*this) is a rank n Data object, and returned object is a scalar.
1294 Calls escript::algorithm.
1295 */
1296 template <class UnaryFunction>
1297 inline
1298 double
1299 Data::algorithm(UnaryFunction operation) const
1300 {
1301 if (isExpanded()) {
1302 DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1303 EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1304 return escript::algorithm(*leftC,operation);
1305 } else if (isTagged()) {
1306 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1307 EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1308 return escript::algorithm(*leftC,operation);
1309 } else if (isConstant()) {
1310 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1311 EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1312 return escript::algorithm(*leftC,operation);
1313 }
1314 return 0;
1315 }
1316
1317 /**
1318 \brief
1319 Perform the given data point reduction algorithm on data and return the result.
1320 Given operation combines each element within each data point into a scalar,
1321 thus argument object is a rank n Data object, and returned object is a
1322 rank 0 Data object.
1323 Calls escript::dp_algorithm.
1324 */
1325 template <class UnaryFunction>
1326 inline
1327 Data
1328 Data::dp_algorithm(UnaryFunction operation) const
1329 {
1330 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1331 if (isExpanded()) {
1332 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1333 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1334 EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1335 EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1336 escript::dp_algorithm(*dataE,*resultE,operation);
1337 } else if (isTagged()) {
1338 DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1339 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1340 EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1341 EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1342 escript::dp_algorithm(*dataT,*resultT,operation);
1343 } else if (isConstant()) {
1344 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1345 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1346 EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1347 EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1348 escript::dp_algorithm(*dataC,*resultC,operation);
1349 }
1350 return result;
1351 }
1352
1353 }
1354 #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26