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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26