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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 122 - (show annotations)
Thu Jun 9 05:38: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: 35806 byte(s)
Merge of development branch back to main trunk on 2005-06-09

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26