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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 615 - (hide annotations)
Wed Mar 22 02:12:00 2006 UTC (13 years, 3 months ago) by elspeth
File MIME type: text/plain
File size: 38877 byte(s)
More copyright information.

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 jgs 571 wherePositive(double tol=0.0) 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 jgs 571 whereNegative(double tol=0.0) 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 jgs 571 whereNonNegative(double tol=0.0) 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 jgs 571 whereNonPositive(double tol=0.0) 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     writes the object to a file in the DX file format
919 jgs 104 */
920     void
921     saveDX(std::string fileName) const;
922    
923     /**
924 jgs 123 \brief
925     writes the object to a file in the VTK file format
926 jgs 110 */
927     void
928     saveVTK(std::string fileName) const;
929    
930     /**
931 jgs 102 \brief
932     Overloaded operator +=
933     \param right - Input - The right hand side.
934 jgs 123 *
935 jgs 102 */
936     Data& operator+=(const Data& right);
937     Data& operator+=(const boost::python::object& right);
938    
939     /**
940     \brief
941     Overloaded operator -=
942     \param right - Input - The right hand side.
943 jgs 123 *
944 jgs 102 */
945     Data& operator-=(const Data& right);
946     Data& operator-=(const boost::python::object& right);
947    
948     /**
949     \brief
950     Overloaded operator *=
951     \param right - Input - The right hand side.
952 jgs 123 *
953 jgs 102 */
954     Data& operator*=(const Data& right);
955     Data& operator*=(const boost::python::object& right);
956    
957     /**
958     \brief
959     Overloaded operator /=
960     \param right - Input - The right hand side.
961 jgs 123 *
962 jgs 102 */
963     Data& operator/=(const Data& right);
964     Data& operator/=(const boost::python::object& right);
965    
966     /**
967     \brief
968 jgs 94 Returns true if this can be interpolated to functionspace.
969     */
970     bool
971     probeInterpolation(const FunctionSpace& functionspace) const;
972    
973     /**
974 jgs 102 Data object slicing methods.
975     */
976    
977     /**
978 jgs 94 \brief
979 jgs 102 Returns a slice from this Data object.
980    
981     /description
982     Implements the [] get operator in python.
983     Calls getSlice.
984    
985     \param key - Input - python slice tuple specifying
986     slice to return.
987 jgs 94 */
988 jgs 102 Data
989     getItem(const boost::python::object& key) const;
990    
991     /**
992     \brief
993     Copies slice from value into this Data object.
994    
995     Implements the [] set operator in python.
996     Calls setSlice.
997    
998     \param key - Input - python slice tuple specifying
999     slice to copy from value.
1000     \param value - Input - Data object to copy from.
1001     */
1002 jgs 94 void
1003 jgs 102 setItemD(const boost::python::object& key,
1004     const Data& value);
1005 jgs 94
1006 jgs 102 void
1007     setItemO(const boost::python::object& key,
1008     const boost::python::object& value);
1009    
1010     // These following public methods should be treated as private.
1011    
1012 jgs 94 /**
1013     \brief
1014 jgs 102 Perform the given unary operation on every element of every data point in
1015     this Data object.
1016 jgs 94 */
1017 jgs 102 template <class UnaryFunction>
1018     inline
1019 jgs 94 void
1020 jgs 102 unaryOp(UnaryFunction operation);
1021    
1022     /**
1023     \brief
1024     Return a Data object containing the specified slice of
1025     this Data object.
1026     \param region - Input - Region to copy.
1027 jgs 123 *
1028 jgs 94 */
1029 jgs 102 Data
1030     getSlice(const DataArrayView::RegionType& region) const;
1031 jgs 94
1032 jgs 102 /**
1033     \brief
1034     Copy the specified slice from the given value into this
1035     Data object.
1036     \param value - Input - Data to copy from.
1037     \param region - Input - Region to copy.
1038 jgs 123 *
1039 jgs 102 */
1040     void
1041     setSlice(const Data& value,
1042     const DataArrayView::RegionType& region);
1043    
1044 jgs 119 /**
1045     \brief
1046     Archive the current Data object to the given file.
1047     \param fileName - Input - file to archive to.
1048     */
1049     void
1050     archiveData(const std::string fileName);
1051    
1052     /**
1053     \brief
1054     Extract the Data object archived in the given file, overwriting
1055     the current Data object.
1056     Note - the current object must be of type DataEmpty.
1057     \param fileName - Input - file to extract from.
1058 jgs 121 \param fspace - Input - a suitable FunctionSpace descibing the data.
1059 jgs 119 */
1060     void
1061     extractData(const std::string fileName,
1062     const FunctionSpace& fspace);
1063    
1064 jgs 102 protected:
1065    
1066 jgs 94 private:
1067    
1068     /**
1069     \brief
1070 jgs 102 Check *this and the right operand are compatible. Throws
1071     an exception if they aren't.
1072     \param right - Input - The right hand side.
1073     */
1074     inline
1075     void
1076     operandCheck(const Data& right) const
1077     {
1078     return m_data->operandCheck(*(right.m_data.get()));
1079     }
1080    
1081     /**
1082     \brief
1083     Perform the specified reduction algorithm on every element of every data point in
1084 jgs 113 this Data object according to the given function and return the single value result.
1085 jgs 102 */
1086 jgs 147 template <class BinaryFunction>
1087 jgs 102 inline
1088     double
1089 jgs 147 algorithm(BinaryFunction operation,
1090     double initial_value) const;
1091 jgs 102
1092 jgs 113 /**
1093     \brief
1094     Reduce each data-point in this Data object using the given operation. Return a Data
1095     object with the same number of data-points, but with each data-point containing only
1096     one value - the result of the reduction operation on the corresponding data-point in
1097     this Data object
1098     */
1099 jgs 147 template <class BinaryFunction>
1100 jgs 106 inline
1101     Data
1102 jgs 147 dp_algorithm(BinaryFunction operation,
1103     double initial_value) const;
1104 jgs 106
1105 jgs 102 /**
1106     \brief
1107     Perform the given binary operation on all of the data's elements.
1108     The underlying type of the right hand side (right) determines the final
1109     type of *this after the operation. For example if the right hand side
1110     is expanded *this will be expanded if necessary.
1111     RHS is a Data object.
1112     */
1113     template <class BinaryFunction>
1114     inline
1115     void
1116     binaryOp(const Data& right,
1117     BinaryFunction operation);
1118    
1119     /**
1120     \brief
1121     Perform the given binary operation on all of the data's elements.
1122     RHS is a boost::python object.
1123     */
1124     template <class BinaryFunction>
1125     inline
1126     void
1127     binaryOp(const boost::python::object& right,
1128     BinaryFunction operation);
1129    
1130     /**
1131     \brief
1132     Convert the data type of the RHS to match this.
1133     \param right - Input - data type to match.
1134     */
1135     void
1136     typeMatchLeft(Data& right) const;
1137    
1138     /**
1139     \brief
1140     Convert the data type of this to match the RHS.
1141     \param right - Input - data type to match.
1142     */
1143     void
1144     typeMatchRight(const Data& right);
1145    
1146     /**
1147     \brief
1148 jgs 94 Construct a Data object of the appropriate type.
1149     */
1150     template <class IValueType>
1151     void
1152     initialise(const IValueType& value,
1153     const FunctionSpace& what,
1154     bool expanded);
1155    
1156     /**
1157     \brief
1158     Reshape the data point if the data point is currently rank 0.
1159     Will throw an exception if the data points are not rank 0.
1160     The original data point value is used for all values of the new
1161     data point.
1162     */
1163     void
1164     reshapeDataPoint(const DataArrayView::ShapeType& shape);
1165    
1166     //
1167 jgs 102 // pointer to the actual data object
1168 jgs 94 boost::shared_ptr<DataAbstract> m_data;
1169    
1170 jgs 123 //
1171     // pointer to the internal profiling data
1172     struct profDataEntry *profData;
1173    
1174 jgs 94 };
1175    
1176     template <class IValueType>
1177     void
1178     Data::initialise(const IValueType& value,
1179     const FunctionSpace& what,
1180     bool expanded)
1181     {
1182     //
1183     // Construct a Data object of the appropriate type.
1184     // Construct the object first as there seems to be a bug which causes
1185     // undefined behaviour if an exception is thrown during construction
1186     // within the shared_ptr constructor.
1187     if (expanded) {
1188     DataAbstract* temp=new DataExpanded(value,what);
1189 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1190     m_data=temp_data;
1191 jgs 94 } else {
1192     DataAbstract* temp=new DataConstant(value,what);
1193 jgs 102 boost::shared_ptr<DataAbstract> temp_data(temp);
1194     m_data=temp_data;
1195 jgs 94 }
1196     }
1197    
1198 jgs 102 /**
1199     Binary Data object operators.
1200     */
1201 jgs 94
1202     /**
1203     \brief
1204     Operator+
1205     Takes two Data objects.
1206     */
1207     Data operator+(const Data& left, const Data& right);
1208    
1209     /**
1210     \brief
1211     Operator-
1212     Takes two Data objects.
1213     */
1214     Data operator-(const Data& left, const Data& right);
1215    
1216     /**
1217     \brief
1218     Operator*
1219     Takes two Data objects.
1220     */
1221     Data operator*(const Data& left, const Data& right);
1222    
1223     /**
1224     \brief
1225     Operator/
1226     Takes two Data objects.
1227     */
1228     Data operator/(const Data& left, const Data& right);
1229    
1230     /**
1231     \brief
1232     Operator+
1233     Takes LHS Data object and RHS python::object.
1234     python::object must be convertable to Data type.
1235     */
1236     Data operator+(const Data& left, const boost::python::object& right);
1237    
1238     /**
1239     \brief
1240     Operator-
1241     Takes LHS Data object and RHS python::object.
1242     python::object must be convertable to Data type.
1243     */
1244     Data operator-(const Data& left, const boost::python::object& right);
1245    
1246     /**
1247     \brief
1248     Operator*
1249     Takes LHS Data object and RHS python::object.
1250     python::object must be convertable to Data type.
1251     */
1252     Data operator*(const Data& left, const boost::python::object& right);
1253    
1254     /**
1255     \brief
1256     Operator/
1257     Takes LHS Data object and RHS python::object.
1258     python::object must be convertable to Data type.
1259     */
1260     Data operator/(const Data& left, const boost::python::object& right);
1261    
1262     /**
1263     \brief
1264     Operator+
1265     Takes LHS python::object and RHS Data object.
1266     python::object must be convertable to Data type.
1267     */
1268     Data operator+(const boost::python::object& left, const Data& right);
1269    
1270     /**
1271     \brief
1272     Operator-
1273     Takes LHS python::object and RHS Data object.
1274     python::object must be convertable to Data type.
1275     */
1276     Data operator-(const boost::python::object& left, const Data& right);
1277    
1278     /**
1279     \brief
1280     Operator*
1281     Takes LHS python::object and RHS Data object.
1282     python::object must be convertable to Data type.
1283     */
1284     Data operator*(const boost::python::object& left, const Data& right);
1285    
1286     /**
1287     \brief
1288     Operator/
1289     Takes LHS python::object and RHS Data object.
1290     python::object must be convertable to Data type.
1291     */
1292     Data operator/(const boost::python::object& left, const Data& right);
1293    
1294     /**
1295     \brief
1296     Output operator
1297     */
1298     std::ostream& operator<<(std::ostream& o, const Data& data);
1299    
1300     /**
1301     \brief
1302     Return true if operands are equivalent, else return false.
1303     NB: this operator does very little at this point, and isn't to
1304     be relied on. Requires further implementation.
1305     */
1306 jgs 102 //bool operator==(const Data& left, const Data& right);
1307 jgs 94
1308 jgs 102 /**
1309     \brief
1310     Perform the given binary operation with this and right as operands.
1311     Right is a Data object.
1312     */
1313 jgs 94 template <class BinaryFunction>
1314     inline
1315     void
1316     Data::binaryOp(const Data& right,
1317     BinaryFunction operation)
1318     {
1319     //
1320     // if this has a rank of zero promote it to the rank of the RHS
1321     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {
1322     reshapeDataPoint(right.getPointDataView().getShape());
1323     }
1324     //
1325     // initially make the temporary a shallow copy
1326     Data tempRight(right);
1327     if (getFunctionSpace()!=right.getFunctionSpace()) {
1328     if (right.probeInterpolation(getFunctionSpace())) {
1329     //
1330     // an interpolation is required so create a new Data
1331     tempRight=Data(right,this->getFunctionSpace());
1332     } else if (probeInterpolation(right.getFunctionSpace())) {
1333     //
1334     // interpolate onto the RHS function space
1335     Data tempLeft(*this,right.getFunctionSpace());
1336     m_data=tempLeft.m_data;
1337     }
1338     }
1339     operandCheck(tempRight);
1340     //
1341     // ensure this has the right type for the RHS
1342 jgs 102 typeMatchRight(tempRight);
1343 jgs 94 //
1344     // Need to cast to the concrete types so that the correct binaryOp
1345     // is called.
1346     if (isExpanded()) {
1347     //
1348     // Expanded data will be done in parallel, the right hand side can be
1349     // of any data type
1350     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1351     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1352     escript::binaryOp(*leftC,*(tempRight.m_data.get()),operation);
1353     } else if (isTagged()) {
1354     //
1355     // Tagged data is operated on serially, the right hand side can be
1356     // either DataConstant or DataTagged
1357     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1358     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1359     if (right.isTagged()) {
1360     DataTagged* rightC=dynamic_cast<DataTagged*>(tempRight.m_data.get());
1361     EsysAssert((rightC!=0), "Programming error - casting to DataTagged.");
1362     escript::binaryOp(*leftC,*rightC,operation);
1363     } else {
1364     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1365     EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1366     escript::binaryOp(*leftC,*rightC,operation);
1367     }
1368 jgs 102 } else if (isConstant()) {
1369 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1370     DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1371     EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
1372     escript::binaryOp(*leftC,*rightC,operation);
1373     }
1374     }
1375    
1376 jgs 102 /**
1377     \brief
1378     Perform the given binary operation with this and right as operands.
1379     Right is a boost::python object.
1380     */
1381 jgs 94 template <class BinaryFunction>
1382     inline
1383     void
1384     Data::binaryOp(const boost::python::object& right,
1385     BinaryFunction operation)
1386     {
1387     DataArray temp(right);
1388     //
1389     // if this has a rank of zero promote it to the rank of the RHS.
1390     if (getPointDataView().getRank()==0 && temp.getView().getRank()!=0) {
1391     reshapeDataPoint(temp.getView().getShape());
1392     }
1393     //
1394     // Always allow scalar values for the RHS but check other shapes
1395     if (temp.getView().getRank()!=0) {
1396     if (!getPointDataView().checkShape(temp.getView().getShape())) {
1397     throw DataException(getPointDataView().createShapeErrorMessage(
1398     "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1399     }
1400     }
1401     if (isExpanded()) {
1402     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1403     EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1404     escript::binaryOp(*leftC,temp.getView(),operation);
1405     } else if (isTagged()) {
1406     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1407     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1408     escript::binaryOp(*leftC,temp.getView(),operation);
1409 jgs 102 } else if (isConstant()) {
1410 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1411     EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1412     escript::binaryOp(*leftC,temp.getView(),operation);
1413     }
1414     }
1415    
1416 jgs 102 /**
1417     \brief
1418     Perform the given unary operation on other and return the result.
1419     Given operation is performed on each element of each data point, thus
1420     argument object is a rank n Data object, and returned object is a rank n
1421     Data object.
1422     Calls Data::unaryOp.
1423     */
1424 jgs 94 template <class UnaryFunction>
1425     inline
1426 jgs 102 Data
1427     unaryOp(const Data& other,
1428     UnaryFunction operation)
1429     {
1430     Data result;
1431     result.copy(other);
1432     result.unaryOp(operation);
1433     return result;
1434     }
1435    
1436     /**
1437     \brief
1438     Perform the given unary operation on this.
1439     Given operation is performed on each element of each data point.
1440     Calls escript::unaryOp.
1441     */
1442     template <class UnaryFunction>
1443     inline
1444 jgs 94 void
1445     Data::unaryOp(UnaryFunction operation)
1446     {
1447     if (isExpanded()) {
1448     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1449     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1450     escript::unaryOp(*leftC,operation);
1451     } else if (isTagged()) {
1452     DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1453     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1454     escript::unaryOp(*leftC,operation);
1455 jgs 102 } else if (isConstant()) {
1456 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1457     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1458     escript::unaryOp(*leftC,operation);
1459     }
1460     }
1461    
1462 jgs 102 /**
1463     \brief
1464     Perform the given Data object reduction algorithm on this and return the result.
1465     Given operation combines each element of each data point, thus argument
1466     object (*this) is a rank n Data object, and returned object is a scalar.
1467     Calls escript::algorithm.
1468     */
1469 jgs 147 template <class BinaryFunction>
1470 jgs 94 inline
1471     double
1472 jgs 147 Data::algorithm(BinaryFunction operation, double initial_value) const
1473 jgs 94 {
1474     if (isExpanded()) {
1475     DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1476     EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1477 jgs 147 return escript::algorithm(*leftC,operation,initial_value);
1478 jgs 102 } else if (isTagged()) {
1479 jgs 94 DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1480     EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1481 jgs 147 return escript::algorithm(*leftC,operation,initial_value);
1482 jgs 102 } else if (isConstant()) {
1483 jgs 94 DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1484     EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1485 jgs 147 return escript::algorithm(*leftC,operation,initial_value);
1486 jgs 94 }
1487 jgs 102 return 0;
1488 jgs 94 }
1489    
1490 jgs 102 /**
1491     \brief
1492     Perform the given data point reduction algorithm on data and return the result.
1493     Given operation combines each element within each data point into a scalar,
1494     thus argument object is a rank n Data object, and returned object is a
1495     rank 0 Data object.
1496     Calls escript::dp_algorithm.
1497     */
1498 jgs 147 template <class BinaryFunction>
1499 jgs 94 inline
1500     Data
1501 jgs 147 Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1502 jgs 94 {
1503 jgs 106 if (isExpanded()) {
1504 jgs 559 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1505 jgs 106 DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1506 jgs 102 DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1507     EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1508     EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1509 jgs 147 escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1510 jgs 559 return result;
1511 jgs 106 } else if (isTagged()) {
1512     DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1513 jgs 562 DataArrayView::ShapeType viewShape;
1514     DataArrayView::ValueType viewData(1);
1515     viewData[0]=0;
1516     DataArrayView defaultValue(viewData,viewShape);
1517 jgs 559 DataTagged::TagListType keys;
1518 jgs 562 DataTagged::ValueListType values;
1519 jgs 559 DataTagged::DataMapType::const_iterator i;
1520     for (i=dataT->getTagLookup().begin();i!=dataT->getTagLookup().end();i++) {
1521     keys.push_back(i->first);
1522 jgs 562 values.push_back(defaultValue);
1523 jgs 559 }
1524     Data result(keys,values,defaultValue,getFunctionSpace());
1525 jgs 102 DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1526     EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1527     EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1528 jgs 147 escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1529 jgs 559 return result;
1530 jgs 106 } else if (isConstant()) {
1531 jgs 559 Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1532 jgs 106 DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1533 jgs 102 DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1534     EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1535     EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1536 jgs 147 escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1537 jgs 559 return result;
1538 jgs 102 }
1539 jgs 559 Data falseRetVal; // to keep compiler quiet
1540     return falseRetVal;
1541 jgs 94 }
1542    
1543     }
1544     #endif

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26