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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26