/[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 121 - (show annotations)
Fri May 6 04:26:16 2005 UTC (14 years, 5 months ago) by jgs
Original Path: trunk/esys2/escript/src/Data/Data.h
File MIME type: text/plain
File size: 35766 byte(s)
Merge of development branch back to main trunk on 2005-05-06

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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26