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

Annotation of /branches/windows_from_1383_trunk/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 119 - (hide annotations)
Tue Apr 12 04:45:05 2005 UTC (14 years, 8 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 jgs 94 // $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 jgs 108 #include "escript/Data/DataException.h"
27 jgs 94
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 jgs 110 // These typedefs allow function names to be cast to pointers
73     // to functions of the appropriate type when calling unaryOp etc.
74 jgs 94 typedef double (*UnaryDFunPtr)(double);
75     typedef double (*BinaryDFunPtr)(double,double);
76    
77     /**
78 jgs 102 Constructors.
79     */
80    
81     /**
82 jgs 94 \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 jgs 102 function space of inData the inData are tried to be interpolated to what,
99 jgs 94 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 jgs 102 Perform a deep copy.
216 jgs 94 */
217     void
218 jgs 102 copy(const Data& other);
219 jgs 94
220     /**
221 jgs 102 Member access methods.
222 jgs 94 */
223    
224     /**
225     \brief
226 jgs 117 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 jgs 94 Return the C wrapper for the Data object.
234     */
235 jgs 102 escriptDataC
236     getDataC();
237 jgs 94
238     /**
239     \brief
240     Return the C wrapper for the Data object - const version.
241     */
242 jgs 102 escriptDataC
243     getDataC() const;
244 jgs 94
245     /**
246     \brief
247     Write the data as a string.
248     */
249 jgs 102 inline
250     std::string
251     toString() const
252     {
253     return m_data->toString();
254     }
255 jgs 94
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 jgs 102 Whatever the current Data type make this into a DataExpanded.
272 jgs 94 */
273     void
274     expand();
275    
276     /**
277     \brief
278 jgs 102 If possible convert this Data to DataTagged. This will only allow
279 jgs 94 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 jgs 102 Return true if this Data is constant.
302 jgs 94 */
303     bool
304 jgs 102 isConstant() const;
305 jgs 94
306     /**
307     \brief
308 jgs 102 Return true if this Data is empty.
309 jgs 94 */
310     bool
311 jgs 102 isEmpty() const;
312 jgs 94
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 jgs 102 Return the number of samples.
363 jgs 94 */
364     inline
365     int
366 jgs 102 getNumSamples() const
367 jgs 94 {
368 jgs 102 return m_data->getNumSamples();
369 jgs 94 }
370    
371     /**
372     \brief
373 jgs 102 Return the number of data points per sample.
374 jgs 94 */
375 jgs 102 inline
376 jgs 94 int
377 jgs 102 getNumDataPointsPerSample() const
378     {
379     return m_data->getNumDPPSample();
380     }
381 jgs 94
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 jgs 102 inline
389 jgs 94 DataAbstract::ValueType::value_type*
390 jgs 102 getSampleData(DataAbstract::ValueType::size_type sampleNo)
391     {
392     return m_data->getSampleData(sampleNo);
393     }
394 jgs 94
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 jgs 102 inline
402 jgs 94 DataAbstract::ValueType::value_type*
403 jgs 102 getSampleDataByTag(int tag)
404     {
405     return m_data->getSampleDataByTag(tag);
406     }
407 jgs 94
408     /**
409     \brief
410 jgs 110 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 jgs 94 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 jgs 102 Return the data point shape as a tuple of integers.
473 jgs 94 */
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 jgs 102 Return the number of doubles stored for this Data.
488 jgs 94 */
489     DataArrayView::ValueType::size_type
490     getLength() const;
491    
492     /**
493     \brief
494 jgs 102 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 jgs 94 */
500 jgs 102 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 jgs 94 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 jgs 102 Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
567 jgs 94 */
568     Data
569 jgs 102 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 jgs 94 whereNonNegative() const;
577    
578     /**
579     \brief
580 jgs 102 Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
581 jgs 94 */
582     Data
583 jgs 102 whereNonPositive() const;
584 jgs 94
585     /**
586     \brief
587 jgs 102 Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
588 jgs 94 */
589     Data
590     whereZero() const;
591    
592     /**
593     \brief
594 jgs 102 Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
595 jgs 94 */
596     Data
597 jgs 102 whereNonZero() const;
598    
599     /**
600     \brief
601     Return the sin of each data point of this Data object.
602     */
603     Data
604 jgs 94 sin() const;
605    
606     /**
607     \brief
608 jgs 102 Return the cos of each data point of this Data object.
609 jgs 94 */
610     Data
611     cos() const;
612    
613     /**
614     \brief
615 jgs 102 Return the tan of each data point of this Data object.
616 jgs 94 */
617     Data
618     tan() const;
619    
620     /**
621     \brief
622 jgs 102 Return the log to base 10 of each data point of this Data object.
623 jgs 94 */
624     Data
625     log() const;
626    
627     /**
628     \brief
629 jgs 102 Return the natural log of each data point of this Data object.
630 jgs 94 */
631     Data
632     ln() const;
633    
634     /**
635     \brief
636 jgs 102 Return the maximum absolute value of this Data object.
637 jgs 94 */
638 jgs 102 double
639     Lsup() const;
640 jgs 94
641     /**
642     \brief
643 jgs 117 Return the minimum absolute value of this Data object.
644     */
645     double
646     Linf() const;
647    
648     /**
649     \brief
650 jgs 102 Return the maximum value of this Data object.
651 jgs 94 */
652 jgs 102 double
653     sup() const;
654 jgs 94
655     /**
656     \brief
657 jgs 102 Return the minimum value of this Data object.
658 jgs 94 */
659     double
660 jgs 102 inf() const;
661 jgs 94
662     /**
663     \brief
664 jgs 102 Return the absolute value of each data point of this Data object.
665 jgs 94 */
666 jgs 102 Data
667     abs() const;
668 jgs 94
669     /**
670     \brief
671 jgs 102 Return the maximum value of each data point of this Data object.
672 jgs 94 */
673 jgs 102 Data
674     maxval() const;
675 jgs 94
676     /**
677     \brief
678 jgs 102 Return the minimum value of each data point of this Data object.
679 jgs 94 */
680     Data
681 jgs 102 minval() const;
682 jgs 94
683     /**
684     \brief
685 jgs 102 Return the length of each data point of this Data object.
686     sqrt(sum(A[i,j,k,l]^2))
687 jgs 94 */
688 jgs 102 Data
689     length() const;
690 jgs 94
691     /**
692     \brief
693 jgs 102 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 jgs 94 */
696 jgs 102 Data
697     sign() const;
698 jgs 94
699     /**
700 jgs 102 \transpose
701     Transpose each data point of this Data object around the given axis.
702 jgs 106 --* not implemented yet *--
703 jgs 102 */
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 jgs 94 \brief
731 jgs 102 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 jgs 104 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 jgs 110 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 jgs 102 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 jgs 94 Returns true if this can be interpolated to functionspace.
803     */
804     bool
805     probeInterpolation(const FunctionSpace& functionspace) const;
806    
807     /**
808 jgs 102 Data object slicing methods.
809     */
810    
811     /**
812 jgs 94 \brief
813 jgs 102 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 jgs 94 */
822 jgs 102 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 jgs 94 void
838 jgs 102 setItemD(const boost::python::object& key,
839     const Data& value);
840 jgs 94
841 jgs 102 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 jgs 94 /**
848     \brief
849 jgs 102 Perform the given unary operation on every element of every data point in
850     this Data object.
851 jgs 94 */
852 jgs 102 template <class UnaryFunction>
853     inline
854 jgs 94 void
855 jgs 102 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 jgs 94 */
863 jgs 102 Data
864     getSlice(const DataArrayView::RegionType& region) const;
865 jgs 94
866 jgs 102 /**
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 jgs 119 /**
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 jgs 102 protected:
898    
899 jgs 94 private:
900    
901     /**
902     \brief
903 jgs 102 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 jgs 113 this Data object according to the given function and return the single value result.
918 jgs 102 */
919     template <class UnaryFunction>
920     inline
921     double
922     algorithm(UnaryFunction operation) const;
923    
924 jgs 113 /**
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 jgs 106 template <class UnaryFunction>
932     inline
933     Data
934     dp_algorithm(UnaryFunction operation) const;
935    
936 jgs 102 /**
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 jgs 94 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 jgs 102 // pointer to the actual data object
999 jgs 94 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 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1017     m_data=temp_data;
1018 jgs 94 } else {
1019     DataAbstract* temp=new DataConstant(value,what);
1020 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1021     m_data=temp_data;
1022 jgs 94 }
1023     }
1024    
1025 jgs 102 /**
1026     Binary Data object operators.
1027     */
1028 jgs 94
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 jgs 102 //bool operator==(const Data& left, const Data& right);
1134 jgs 94
1135 jgs 102 /**
1136     \brief
1137     Perform the given binary operation with this and right as operands.
1138     Right is a Data object.
1139     */
1140 jgs 94 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 jgs 102 typeMatchRight(tempRight);
1170 jgs 94 //
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 jgs 102 } else if (isConstant()) {
1196 jgs 94 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 jgs 102 /**
1204     \brief
1205     Perform the given binary operation with this and right as operands.
1206     Right is a boost::python object.
1207     */
1208 jgs 94 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 jgs 102 } else if (isConstant()) {
1237 jgs 94 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 jgs 102 /**
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 jgs 94 template <class UnaryFunction>
1252     inline
1253 jgs 102 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 jgs 94 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 jgs 102 } else if (isConstant()) {
1283 jgs 94 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 jgs 102 /**
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 jgs 94 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 jgs 102 } else if (isTagged()) {
1306 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1307     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1308     return escript::algorithm(*leftC,operation);
1309 jgs 102 } else if (isConstant()) {
1310 jgs 94 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 jgs 102 return 0;
1315 jgs 94 }
1316    
1317 jgs 102 /**
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 jgs 94 template <class UnaryFunction>
1326     inline
1327     Data
1328 jgs 106 Data::dp_algorithm(UnaryFunction operation) const
1329 jgs 94 {
1330 jgs 106 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1331     if (isExpanded()) {
1332     DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1333 jgs 102 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 jgs 106 } else if (isTagged()) {
1338     DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1339 jgs 102 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 jgs 106 } else if (isConstant()) {
1344     DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1345 jgs 102 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 jgs 94 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