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

Diff of /temp/escript/src/Data.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 94 by jgs, Wed Oct 27 00:45:54 2004 UTC revision 149 by jgs, Thu Sep 1 03:31:39 2005 UTC
# Line 1  Line 1 
1  // $Id$  // $Id$
2  /*=============================================================================  /*
   
3   ******************************************************************************   ******************************************************************************
4   *                                                                            *   *                                                                            *
5   *       COPYRIGHT ACcESS 2004 -  All Rights Reserved                         *   *       COPYRIGHT ACcESS 2004 -  All Rights Reserved                         *
# Line 12  Line 11 
11   * person has a software license agreement with ACcESS.                       *   * person has a software license agreement with ACcESS.                       *
12   *                                                                            *   *                                                                            *
13   ******************************************************************************   ******************************************************************************
14    */
15    
16  ******************************************************************************/  /** \file Data.h */
17    
18  #ifndef DATA_H  #ifndef DATA_H
19  #define DATA_H  #define DATA_H
20    
21  #include "escript/Data/DataAbstract.h"  #include "escript/Data/DataAbstract.h"
22  #include "escript/Data/DataTagged.h"  #include "escript/Data/DataTagged.h"
23    #include "escript/Data/DataAlgorithm.h"
24  #include "escript/Data/FunctionSpace.h"  #include "escript/Data/FunctionSpace.h"
25  #include "escript/Data/BinaryOp.h"  #include "escript/Data/BinaryOp.h"
26  #include "escript/Data/UnaryOp.h"  #include "escript/Data/UnaryOp.h"
27    #include "escript/Data/DataException.h"
28    
29  extern "C" {  extern "C" {
30  #include "escript/Data/DataC.h"  #include "escript/Data/DataC.h"
# Line 39  extern "C" { Line 41  extern "C" {
41  #include <boost/python/tuple.hpp>  #include <boost/python/tuple.hpp>
42  #include <boost/python/numeric.hpp>  #include <boost/python/numeric.hpp>
43    
44    namespace escript {
45    
46    //
47    // Forward declaration for various implementations of Data.
48    class DataEmpty;
49    class DataConstant;
50    class DataTagged;
51    class DataExpanded;
52    
53  /**  /**
54     \brief     \brief
55     Data is essentially a factory class which creates the appropriate Data     Data creates the appropriate Data object for the given construction
56     object for the given construction arguments. It retains control over     arguments.
    the object created for the lifetime of the object.  
    The type of Data object referred to may change during the lifetime of  
    the Data object.  
57    
58     Description:     Description:
59     Data is essentially a factory class which creates the appropriate Data     Data is essentially a factory class which creates the appropriate Data
# Line 54  extern "C" { Line 62  extern "C" {
62     The type of Data object referred to may change during the lifetime of     The type of Data object referred to may change during the lifetime of
63     the Data object.     the Data object.
64  */  */
   
 namespace escript {  
   
 //  
 // Forward declaration for various implimentations of Data.  
 class DataEmpty;  
 class DataConstant;  
 class DataTagged;  
 class DataExpanded;  
   
65  class Data {  class Data {
66    
67    public:    public:
68    
69      // These typedefs allow function names to be cast to pointers
70      // to functions of the appropriate type when calling unaryOp etc.
71    typedef double (*UnaryDFunPtr)(double);    typedef double (*UnaryDFunPtr)(double);
72    typedef double (*BinaryDFunPtr)(double,double);    typedef double (*BinaryDFunPtr)(double,double);
73    
74    /**    /**
75         Constructors.
76      */
77    
78      /**
79       \brief       \brief
80       Default constructor.       Default constructor.
81       Creates a DataEmpty object.       Creates a DataEmpty object.
# Line 88  class Data { Line 92  class Data {
92    /**    /**
93       \brief       \brief
94       Constructor from another Data object. If "what" is different from the       Constructor from another Data object. If "what" is different from the
95       function space of inData the inData are tried to be interpolated to what       function space of inData the inData are tried to be interpolated to what,
96       otherwise a shallow copy of inData is returned.       otherwise a shallow copy of inData is returned.
97    */    */
98    Data(const Data& inData,    Data(const Data& inData,
# Line 205  class Data { Line 209  class Data {
209    
210    /**    /**
211       \brief       \brief
212       Perform the specified algorithm on the Data and return result.       Perform a deep copy.
   */  
   template <class UnaryFunction>  
   inline double  
   algorithm(UnaryFunction operation) const;  
   
   /**  
      \brief  
      Perform the given unary operation on all of the data's elements.  
213    */    */
   template <class UnaryFunction>  
214    void    void
215    unaryOp(UnaryFunction operation);    copy(const Data& other);
216    
217    /**    /**
218       \brief       Member access methods.
      Perform the given binary operation on all of the data's elements.  
      The underlying type of the right hand side (right) determines the final  
      type of *this after the operation. For example if the right hand side  
      is expanded *this will be expanded if necessary.  
219    */    */
   template <class BinaryFunction>  
   void  
   binaryOp(const Data& right,  
            BinaryFunction operation);  
220    
221    /**    /**
222       \brief       \brief
223       Perform the given binary operation on all of the data's elements.       Return the values of all data-points as a single python numarray object.
224    */    */
225    template <class BinaryFunction>    const boost::python::numeric::array
226    void    convertToNumArray();
   binaryOp(const boost::python::object& right,  
            BinaryFunction operation);  
227    
228    /**    /**
229       \brief       \brief
230       Overloaded operator +=       Return the values of all data-points for the given sample as a single python numarray object.
      \param right - Input - The right hand side.  
231    */    */
232    Data& operator+=(const Data& right);    const boost::python::numeric::array
233    Data& operator+=(const boost::python::object& right);    convertToNumArrayFromSampleNo(int sampleNo);
234    
235    /**    /**
236       \brief       \brief
237       Overloaded operator -=       Return the value of the specified data-point as a single python numarray object.
      \param right - Input - The right hand side.  
238    */    */
239    Data& operator-=(const Data& right);    const boost::python::numeric::array
240    Data& operator-=(const boost::python::object& right);    convertToNumArrayFromDPNo(int sampleNo,
241                                int dataPointNo);
242    
243   /**    /**
      \brief  
      Overloaded operator *=  
      \param right - Input - The right hand side.  
   */  
   Data& operator*=(const Data& right);  
   Data& operator*=(const boost::python::object& right);  
   
  /**  
244       \brief       \brief
245       Overloaded operator /=       Fills the expanded Data object from values of a python numarray object.
      \param right - Input - The right hand side.  
246    */    */
247    Data& operator/=(const Data& right);    void
248    Data& operator/=(const boost::python::object& right);    fillFromNumArray(const boost::python::numeric::array);
249    
250    /**    /**
251       \brief       \brief
252       Return the power of Data.       Return the tag number associated with the given data-point.
253    
254         The data-point number here corresponds to the data-point number in the
255         numarray returned by convertToNumArray.
256    */    */
257    Data powD(const Data& right) const;    int
258    Data powO(const boost::python::object& right) const;    getTagNumber(int dpno);
259    
260    /**    /**
261       \brief       \brief
262       Return the C wrapper for the Data object.       Return the C wrapper for the Data object.
263    */    */
264    escriptDataC getDataC();    escriptDataC
265      getDataC();
266    
267    /**    /**
268       \brief       \brief
269       Return the C wrapper for the Data object - const version.       Return the C wrapper for the Data object - const version.
270    */    */
271    escriptDataC getDataC() const;    escriptDataC
272      getDataC() const;
273    
274    /**    /**
275       \brief       \brief
276       Write the data as a string.       Write the data as a string.
277    */    */
278    std::string toString() const;    inline
279      std::string
280      toString() const
281      {
282        return m_data->toString();
283      }
284    
285    /**    /**
286       \brief       \brief
# Line 312  class Data { Line 297  class Data {
297    
298    /**    /**
299       \brief       \brief
300       Perform a deep copy.       Whatever the current Data type make this into a DataExpanded.
   */  
   void  
   copy(const Data& other);  
   
   /**  
     \brief  
     Copy other Data object into this Data object where mask is positive.  
   */  
   void  
   copyWithMask(const Data& other,  
                const Data& mask);  
   
   /**  
      \brief  
      Whatever the current Data type make it expanded.  
301    */    */
302    void    void
303    expand();    expand();
304    
305    /**    /**
306       \brief       \brief
307       If possible convert the Data type to tagged. This will only allow       If possible convert this Data to DataTagged. This will only allow
308       Constant data to be converted to tagged. An attempt to convert       Constant data to be converted to tagged. An attempt to convert
309       Expanded data to tagged will throw an exception.       Expanded data to tagged will throw an exception.
310    */    */
# Line 357  class Data { Line 327  class Data {
327    
328    /**    /**
329       \brief       \brief
330       Return true if this Data is empty.       Return true if this Data is constant.
331    */    */
332    bool    bool
333    isEmpty() const;    isConstant() const;
334    
335    /**    /**
336       \brief       \brief
337       Return true if this Data is constant.       Return true if this Data is empty.
338    */    */
339    bool    bool
340    isConstant() const;    isEmpty() const;
341    
342    /**    /**
343       \brief       \brief
# Line 418  class Data { Line 388  class Data {
388    
389    /**    /**
390       \brief       \brief
391       Return the number of data points per sample.       Return the number of samples.
392    */    */
393    inline    inline
394    int    int
395    getNumDataPointsPerSample() const    getNumSamples() const
396    {    {
397      return m_data->getNumDPPSample();      return m_data->getNumSamples();
398    }    }
399    
400    /**    /**
401       \brief       \brief
402       Return the number of samples.       Return the number of data points per sample.
403    */    */
404      inline
405    int    int
406    getNumSamples() const;    getNumDataPointsPerSample() const
407      {
408    /**      return m_data->getNumDPPSample();
409       \brief    }
      Check *this and the right operand are compatible. Throws  
      an exception if they aren't.  
      \param right - Input - The right hand side.  
   */  
   void  
   operandCheck(const Data& right) const;  
410    
411    /**    /**
412       \brief       \brief
# Line 449  class Data { Line 414  class Data {
414       preferred interface but is provided for use by C code.       preferred interface but is provided for use by C code.
415       \param sampleNo - Input - the given sample no.       \param sampleNo - Input - the given sample no.
416    */    */
417      inline
418    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
419    getSampleData(DataAbstract::ShapeType::size_type sampleNo);    getSampleData(DataAbstract::ValueType::size_type sampleNo)
420      {
421        return m_data->getSampleData(sampleNo);
422      }
423    
424    /**    /**
425       \brief       \brief
# Line 458  class Data { Line 427  class Data {
427       access data that isn't tagged an exception will be thrown.       access data that isn't tagged an exception will be thrown.
428       \param tag - Input - the tag key.       \param tag - Input - the tag key.
429    */    */
430      inline
431    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
432    getSampleDataByTag(int tag);    getSampleDataByTag(int tag)
433      {
434        return m_data->getSampleDataByTag(tag);
435      }
436    
437      /**
438         \brief
439         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       \brief
# Line 486  class Data { Line 498  class Data {
498    
499    /**    /**
500       \brief       \brief
501       Return data point shape as a tuple of integers:       Return the data point shape as a tuple of integers.
502    */    */
503    boost::python::tuple    const boost::python::tuple
504    getShapeTuple() const;    getShapeTuple() const;
505    
506    /**    /**
# Line 501  class Data { Line 513  class Data {
513    
514    /**    /**
515       \brief       \brief
516       Return the number of doubles stored for Data.       Return the number of doubles stored for this Data.
517    */    */
518    DataArrayView::ValueType::size_type    DataArrayView::ValueType::size_type
519    getLength() const;    getLength() const;
520    
521    /**    /**
522       \brief       \brief
523       Interpolates this onto the given functionspace and returns the result as a Data object.       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      */
529      void
530      setTaggedValue(int tagKey,
531                     const boost::python::object& value);
532    
533      /**
534         \brief
535         Assign the given value to the tag. Implicitly converts this
536         object to type DataTagged. Throws an exception if this object
537         cannot be converted to a DataTagged object.
538         \param tagKey - Input - Integer key.
539         \param value - Input - Value to associate with given key.
540      */
541      void
542      setTaggedValueFromCPP(int tagKey,
543                            const DataArrayView& value);
544    
545      /**
546        \brief
547        Copy other Data object into this Data object where mask is positive.
548      */
549      void
550      copyWithMask(const Data& other,
551                   const Data& mask);
552    
553      /**
554         Data object operation methods and operators.
555      */
556    
557      /**
558         \brief
559         Interpolates this onto the given functionspace and returns
560         the result as a Data object.
561         *
562    */    */
563    Data    Data
564    interpolate(const FunctionSpace& functionspace) const;    interpolate(const FunctionSpace& functionspace) const;
# Line 517  class Data { Line 567  class Data {
567       \brief       \brief
568       Calculates the gradient of the data at the data points of functionspace.       Calculates the gradient of the data at the data points of functionspace.
569       If functionspace is not present the function space of Function(getDomain()) is used.       If functionspace is not present the function space of Function(getDomain()) is used.
570         *
571    */    */
572    Data    Data
573    gradOn(const FunctionSpace& functionspace) const;    gradOn(const FunctionSpace& functionspace) const;
# Line 527  class Data { Line 578  class Data {
578    /**    /**
579       \brief       \brief
580       Calculate the integral over the function space domain.       Calculate the integral over the function space domain.
581         *
582    */    */
583    boost::python::numeric::array    boost::python::numeric::array
584    integrate() const;    integrate() const;
# Line 534  class Data { Line 586  class Data {
586    /**    /**
587       \brief       \brief
588       Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.       Return a Data with a 1 for +ive values and a 0 for 0 or -ive values.
589         *
590    */    */
591    Data    Data
592    wherePositive() const;    wherePositive() const;
593    
594    /**    /**
595       \brief       \brief
596       Return a Data with a 1 for +ive values and a 0 for -ive values.       Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.
597         *
598      */
599      Data
600      whereNegative() const;
601    
602      /**
603         \brief
604         Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
605         *
606    */    */
607    Data    Data
608    whereNonNegative() const;    whereNonNegative() const;
609    
610    /**    /**
611       \brief       \brief
612       Return a Data with a 1 for -ive values and a 0 for +ive or 0 values.       Return a Data with a 1 for -ive or 0 values and a 0 for +ive values.
613         *
614    */    */
615    Data    Data
616    whereNegative() const;    whereNonPositive() const;
617    
618    /**    /**
619       \brief       \brief
620       Return a Data with a 1 for 0 values a 0 for +ive or -ive.       Return a Data with a 1 for 0 values and a 0 for +ive or -ive values.
621         *
622    */    */
623    Data    Data
624    whereZero() const;    whereZero() const;
625    
626    /**    /**
627       \brief       \brief
628       Return the sin of Data.       Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
629         *
630      */
631      Data
632      whereNonZero() const;
633    
634      /**
635         \brief
636         Return the maximum absolute value of this Data object.
637         *
638      */
639      double
640      Lsup() const;
641    
642      /**
643         \brief
644         Return the minimum absolute value of this Data object.
645         *
646      */
647      double
648      Linf() const;
649    
650      /**
651         \brief
652         Return the maximum value of this Data object.
653         *
654      */
655      double
656      sup() const;
657    
658      /**
659         \brief
660         Return the minimum value of this Data object.
661         *
662      */
663      double
664      inf() const;
665    
666      /**
667         \brief
668         Return the absolute value of each data point of this Data object.
669         *
670      */
671      Data
672      abs() const;
673    
674      /**
675         \brief
676         Return the maximum value of each data point of this Data object.
677         *
678      */
679      Data
680      maxval() const;
681    
682      /**
683         \brief
684         Return the minimum value of each data point of this Data object.
685         *
686      */
687      Data
688      minval() const;
689    
690      /**
691         \brief
692         Return the (sample number, data-point number) of the data point with
693         the minimum value in this Data object.
694      */
695      const boost::python::tuple
696      mindp() const;
697    
698      void
699      calc_mindp(int& SampleNo,
700                 int& DataPointNo) const;
701    
702      /**
703         \brief
704         Return the length of each data point of this Data object.
705         sqrt(sum(A[i,j,k,l]^2))
706         *
707      */
708      Data
709      length() const;
710    
711      /**
712         \brief
713         Return the sign of each data point of this Data object.
714         -1 for negative values, zero for zero values, 1 for positive values.
715         *
716      */
717      Data
718      sign() const;
719    
720      /**
721         \brief
722         Transpose each data point of this Data object around the given axis.
723         --* not implemented yet *--
724         *
725      */
726      Data
727      transpose(int axis) const;
728    
729      /**
730         \brief
731         Calculate the trace of each data point of this Data object.
732         sum(A[i,i,i,i])
733         *
734      */
735      Data
736      trace() const;
737    
738      /**
739         \brief
740         Return the sin of each data point of this Data object.
741         *
742    */    */
743    Data    Data
744    sin() const;    sin() const;
745    
746    /**    /**
747       \brief       \brief
748       Return the cos of Data.       Return the cos of each data point of this Data object.
749         *
750    */    */
751    Data    Data
752    cos() const;    cos() const;
753    
754    /**    /**
755       \brief       \brief
756       Return the tan of Data.       Return the tan of each data point of this Data object.
757         *
758    */    */
759    Data    Data
760    tan() const;    tan() const;
761    
762    /**    /**
763       \brief       \brief
764       Return the log to base 10 of Data.       Return the log to base 10 of each data point of this Data object.
765         *
766    */    */
767    Data    Data
768    log() const;    log() const;
769    
770    /**    /**
771       \brief       \brief
772       Return the natural log of Data.       Return the natural log of each data point of this Data object.
773         *
774    */    */
775    Data    Data
776    ln() const;    ln() const;
777    
778    /**    /**
779       \brief       \brief
780       Return a Data containing a slice of this Data.       Return the exponential function of each data point of this Data object.
781         *
782    */    */
783    Data    Data
784    getSlice(const DataArrayView::RegionType& region) const;    exp() const;
785    
786    /**    /**
787       \brief       \brief
788       Copy the specified region from the given value.       Return the square root of each data point of this Data object.
789       \param value - Input - Data to copy from.       *
      \param region - Input - Region to copy.  
790    */    */
791    void    Data
792    setSlice(const Data& value,    sqrt() const;
            const DataArrayView::RegionType& region);  
793    
794    /**    /**
795       \brief       \brief
796       Return the maximum absolute value.       Return the negation of each data point of this Data object.
797         *
798    */    */
799    double    Data
800    Lsup() const;    neg() const;
801    
802    /**    /**
803       \brief       \brief
804       Return the maximum value.       Return the identity of each data point of this Data object.
805         Simply returns this object unmodified.
806         *
807    */    */
808    double    Data
809    sup() const;    pos() const;
810    
811    /**    /**
812       \brief       \brief
813       Return the minimum value.       Return the given power of each data point of this Data object.
814    
815         \param right Input - the power to raise the object to.
816         *
817    */    */
818    double    Data
819    inf() const;    powD(const Data& right) const;
820    
821    /**    /**
822       \brief       \brief
823       Returns a slice from this.       Return the given power of each data point of this boost python object.
824    */      
825         \param right Input - the power to raise the object to.
826         *
827       */
828    Data    Data
829    getItem(const boost::python::object& key) const;    powO(const boost::python::object& right) const;
830    
831    /**    /**
832       \brief       \brief
833       Copies slice from value into this.       writes the object to a file in the DX file format
834    */    */
835    void    void
836    setItem(const boost::python::object& key,    saveDX(std::string fileName) const;
           const Data& value);  
837    
838    /**    /**
839       \brief       \brief
840       Convert the underlying data type to match the RHS.       writes the object to a file in the VTK file format
      \param right - Input - data type to match.  
841    */    */
842    void    void
843    typeMatch(const Data& right);    saveVTK(std::string fileName) const;
844    
845      /**
846         \brief
847         Overloaded operator +=
848         \param right - Input - The right hand side.
849         *
850      */
851      Data& operator+=(const Data& right);
852      Data& operator+=(const boost::python::object& right);
853    
854      /**
855         \brief
856         Overloaded operator -=
857         \param right - Input - The right hand side.
858         *
859      */
860      Data& operator-=(const Data& right);
861      Data& operator-=(const boost::python::object& right);
862    
863     /**
864         \brief
865         Overloaded operator *=
866         \param right - Input - The right hand side.
867         *
868      */
869      Data& operator*=(const Data& right);
870      Data& operator*=(const boost::python::object& right);
871    
872     /**
873         \brief
874         Overloaded operator /=
875         \param right - Input - The right hand side.
876         *
877      */
878      Data& operator/=(const Data& right);
879      Data& operator/=(const boost::python::object& right);
880    
881    /**    /**
882       \brief       \brief
# Line 663  class Data { Line 886  class Data {
886    probeInterpolation(const FunctionSpace& functionspace) const;    probeInterpolation(const FunctionSpace& functionspace) const;
887    
888    /**    /**
889         Data object slicing methods.
890      */
891    
892      /**
893       \brief       \brief
894       Assign the given value to the tag. Implicitly converts this       Returns a slice from this Data object.
895       object to type DataTagged. Throws an exception if this object  
896       cannot be converted to a DataTagged object.       /description
897       \param tagKey - Input - Integer key.       Implements the [] get operator in python.
898       \param value - Input - Value to associate with given key.       Calls getSlice.
899    
900         \param key - Input - python slice tuple specifying
901         slice to return.
902      */
903      Data
904      getItem(const boost::python::object& key) const;
905    
906      /**
907         \brief
908         Copies slice from value into this Data object.
909    
910         Implements the [] set operator in python.
911         Calls setSlice.
912    
913         \param key - Input - python slice tuple specifying
914         slice to copy from value.
915         \param value - Input - Data object to copy from.
916    */    */
917    void    void
918    setTaggedValue(int tagKey,    setItemD(const boost::python::object& key,
919                   const boost::python::object& value);             const Data& value);
920    
921      void
922      setItemO(const boost::python::object& key,
923               const boost::python::object& value);
924    
925      // These following public methods should be treated as private.
926    
927    /**    /**
928       \brief       \brief
929       Assign the given value to the tag. Implicitly converts this       Perform the given unary operation on every element of every data point in
930       object to type DataTagged. Throws an exception if this object       this Data object.
      cannot be converted to a DataTagged object.  
      \param tagKey - Input - Integer key.  
      \param value - Input - Value to associate with given key.  
      Note: removed for now - this version not needed, and breaks escript.cpp  
931    */    */
932    /*    template <class UnaryFunction>
933      inline
934    void    void
935    setTaggedValue(int tagKey,    unaryOp(UnaryFunction operation);
936                   const DataArrayView& value);  
937      /**
938         \brief
939         Return a Data object containing the specified slice of
940         this Data object.
941         \param region - Input - Region to copy.
942         *
943      */
944      Data
945      getSlice(const DataArrayView::RegionType& region) const;
946    
947      /**
948         \brief
949         Copy the specified slice from the given value into this
950         Data object.
951         \param value - Input - Data to copy from.
952         \param region - Input - Region to copy.
953         *
954      */
955      void
956      setSlice(const Data& value,
957               const DataArrayView::RegionType& region);
958    
959      /**
960         \brief
961         Archive the current Data object to the given file.
962         \param fileName - Input - file to archive to.
963    */    */
964      void
965      archiveData(const std::string fileName);
966    
967      /**
968         \brief
969         Extract the Data object archived in the given file, overwriting
970         the current Data object.
971         Note - the current object must be of type DataEmpty.
972         \param fileName - Input - file to extract from.
973         \param fspace - Input - a suitable FunctionSpace descibing the data.
974      */
975      void
976      extractData(const std::string fileName,
977                  const FunctionSpace& fspace);
978    
979     protected:
980    
981   private:   private:
982    
983    /**    /**
984       \brief       \brief
985         Check *this and the right operand are compatible. Throws
986         an exception if they aren't.
987         \param right - Input - The right hand side.
988      */
989      inline
990      void
991      operandCheck(const Data& right) const
992      {
993        return m_data->operandCheck(*(right.m_data.get()));
994      }
995    
996      /**
997         \brief
998         Perform the specified reduction algorithm on every element of every data point in
999         this Data object according to the given function and return the single value result.
1000      */
1001      template <class BinaryFunction>
1002      inline
1003      double
1004      algorithm(BinaryFunction operation,
1005                double initial_value) const;
1006    
1007      /**
1008         \brief
1009         Reduce each data-point in this Data object using the given operation. Return a Data
1010         object with the same number of data-points, but with each data-point containing only
1011         one value - the result of the reduction operation on the corresponding data-point in
1012         this Data object
1013      */
1014      template <class BinaryFunction>
1015      inline
1016      Data
1017      dp_algorithm(BinaryFunction operation,
1018                   double initial_value) const;
1019    
1020      /**
1021         \brief
1022         Perform the given binary operation on all of the data's elements.
1023         The underlying type of the right hand side (right) determines the final
1024         type of *this after the operation. For example if the right hand side
1025         is expanded *this will be expanded if necessary.
1026         RHS is a Data object.
1027      */
1028      template <class BinaryFunction>
1029      inline
1030      void
1031      binaryOp(const Data& right,
1032               BinaryFunction operation);
1033    
1034      /**
1035         \brief
1036         Perform the given binary operation on all of the data's elements.
1037         RHS is a boost::python object.
1038      */
1039      template <class BinaryFunction>
1040      inline
1041      void
1042      binaryOp(const boost::python::object& right,
1043               BinaryFunction operation);
1044    
1045      /**
1046         \brief
1047         Convert the data type of the RHS to match this.
1048         \param right - Input - data type to match.
1049      */
1050      void
1051      typeMatchLeft(Data& right) const;
1052    
1053      /**
1054         \brief
1055         Convert the data type of this to match the RHS.
1056         \param right - Input - data type to match.
1057      */
1058      void
1059      typeMatchRight(const Data& right);
1060    
1061      /**
1062         \brief
1063       Construct a Data object of the appropriate type.       Construct a Data object of the appropriate type.
1064    */    */
1065    template <class IValueType>    template <class IValueType>
# Line 712  class Data { Line 1079  class Data {
1079    reshapeDataPoint(const DataArrayView::ShapeType& shape);    reshapeDataPoint(const DataArrayView::ShapeType& shape);
1080    
1081    //    //
1082    // pointer to the actual data    // pointer to the actual data object
1083    boost::shared_ptr<DataAbstract> m_data;    boost::shared_ptr<DataAbstract> m_data;
1084    
1085      //
1086      // pointer to the internal profiling data
1087      struct profDataEntry *profData;
1088    
1089  };  };
1090    
1091  template <class IValueType>  template <class IValueType>
# Line 730  Data::initialise(const IValueType& value Line 1101  Data::initialise(const IValueType& value
1101    // within the shared_ptr constructor.    // within the shared_ptr constructor.
1102    if (expanded) {    if (expanded) {
1103      DataAbstract* temp=new DataExpanded(value,what);      DataAbstract* temp=new DataExpanded(value,what);
1104      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1105        m_data=temp_data;
1106    } else {    } else {
1107      DataAbstract* temp=new DataConstant(value,what);      DataAbstract* temp=new DataConstant(value,what);
1108      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1109        m_data=temp_data;
1110    }    }
1111  }  }
1112    
1113  inline  /**
1114  DataAbstract::ValueType::value_type*     Binary Data object operators.
1115  Data::getSampleData(DataAbstract::ValueType::size_type sampleNo)  */
 {  
   return m_data->getSampleData(sampleNo);  
 }  
   
 inline  
 DataAbstract::ValueType::value_type*  
 Data::getSampleDataByTag(int tag)  
 {  
   return m_data->getSampleDataByTag(tag);  
 }  
   
 inline  
 void  
 Data::operandCheck(const Data& right) const  
 {  
   return m_data->operandCheck(*(right.m_data.get()));  
 }  
   
 inline  
 int  
 Data::getNumSamples() const  
 {  
   return m_data->getNumSamples();  
 }  
   
 inline  
 std::string  
 Data::toString() const  
 {  
   return m_data->toString();  
 }  
1116    
1117  /**  /**
1118    \brief    \brief
# Line 876  std::ostream& operator<<(std::ostream& o Line 1218  std::ostream& operator<<(std::ostream& o
1218    NB: this operator does very little at this point, and isn't to    NB: this operator does very little at this point, and isn't to
1219    be relied on. Requires further implementation.    be relied on. Requires further implementation.
1220  */  */
1221  bool operator==(const Data& left, const Data& right);  //bool operator==(const Data& left, const Data& right);
1222    
1223    /**
1224      \brief
1225      Perform the given binary operation with this and right as operands.
1226      Right is a Data object.
1227    */
1228  template <class BinaryFunction>  template <class BinaryFunction>
1229  inline  inline
1230  void  void
# Line 907  Data::binaryOp(const Data& right, Line 1254  Data::binaryOp(const Data& right,
1254     operandCheck(tempRight);     operandCheck(tempRight);
1255     //     //
1256     // ensure this has the right type for the RHS     // ensure this has the right type for the RHS
1257     typeMatch(tempRight);     typeMatchRight(tempRight);
1258     //     //
1259     // Need to cast to the concrete types so that the correct binaryOp     // Need to cast to the concrete types so that the correct binaryOp
1260     // is called.     // is called.
# Line 933  Data::binaryOp(const Data& right, Line 1280  Data::binaryOp(const Data& right,
1280         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1281         escript::binaryOp(*leftC,*rightC,operation);         escript::binaryOp(*leftC,*rightC,operation);
1282       }       }
1283     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1284       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1285       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1286       EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");       EsysAssert((leftC!=0 && rightC!=0), "Programming error - casting to DataConstant.");
# Line 943  Data::binaryOp(const Data& right, Line 1288  Data::binaryOp(const Data& right,
1288     }     }
1289  }  }
1290    
1291    /**
1292      \brief
1293      Perform the given binary operation with this and right as operands.
1294      Right is a boost::python object.
1295    */
1296  template <class BinaryFunction>  template <class BinaryFunction>
1297  inline  inline
1298  void  void
# Line 963  Data::binaryOp(const boost::python::obje Line 1313  Data::binaryOp(const boost::python::obje
1313                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1314       }       }
1315     }     }
   
1316     if (isExpanded()) {     if (isExpanded()) {
      //  
      // Expanded data will be done in parallel  
1317       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1318       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1319       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
# Line 974  Data::binaryOp(const boost::python::obje Line 1321  Data::binaryOp(const boost::python::obje
1321       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1322       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1323       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1324     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1325       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1326       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1327       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1328     }     }
1329  }  }
1330    
1331    /**
1332      \brief
1333      Perform the given unary operation on other and return the result.
1334      Given operation is performed on each element of each data point, thus
1335      argument object is a rank n Data object, and returned object is a rank n
1336      Data object.
1337      Calls Data::unaryOp.
1338    */
1339    template <class UnaryFunction>
1340    inline
1341    Data
1342    unaryOp(const Data& other,
1343            UnaryFunction operation)
1344    {
1345      Data result;
1346      result.copy(other);
1347      result.unaryOp(operation);
1348      return result;
1349    }
1350    
1351    /**
1352      \brief
1353      Perform the given unary operation on this.
1354      Given operation is performed on each element of each data point.
1355      Calls escript::unaryOp.
1356    */
1357  template <class UnaryFunction>  template <class UnaryFunction>
1358  inline  inline
1359  void  void
1360  Data::unaryOp(UnaryFunction operation)  Data::unaryOp(UnaryFunction operation)
1361  {  {
1362    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1363      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1364      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1365      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
# Line 998  Data::unaryOp(UnaryFunction operation) Line 1367  Data::unaryOp(UnaryFunction operation)
1367      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1368      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1369      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1370    } else {    } else if (isConstant()) {
1371      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1372      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1373      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1374    }    }
1375  }  }
1376    
1377  template <class UnaryFunction>  /**
1378      \brief
1379      Perform the given Data object reduction algorithm on this and return the result.
1380      Given operation combines each element of each data point, thus argument
1381      object (*this) is a rank n Data object, and returned object is a scalar.
1382      Calls escript::algorithm.
1383    */
1384    template <class BinaryFunction>
1385  inline  inline
1386  double  double
1387  Data::algorithm(UnaryFunction operation) const  Data::algorithm(BinaryFunction operation, double initial_value) const
1388  {  {
1389    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1390      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1391      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1392      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1393    }    } else if (isTagged()) {
   else if (isTagged()) {  
1394      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1395      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1396      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1397    } else {    } else if (isConstant()) {
1398      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1399      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1400      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1401    }    }
1402      return 0;
1403  }  }
1404    
1405  template <class UnaryFunction>  /**
1406      \brief
1407      Perform the given data point reduction algorithm on data and return the result.
1408      Given operation combines each element within each data point into a scalar,
1409      thus argument object is a rank n Data object, and returned object is a
1410      rank 0 Data object.
1411      Calls escript::dp_algorithm.
1412    */
1413    template <class BinaryFunction>
1414  inline  inline
1415  Data  Data
1416  unaryOp(const Data& other,  Data::dp_algorithm(BinaryFunction operation, double initial_value) const
         UnaryFunction operation)  
1417  {  {
1418    //    Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1419    // Perform the given operation on a copy of the input data and return the result    if (isExpanded()) {
1420    Data result;      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1421    //      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1422    // perform a deep copy      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1423    result.copy(other);      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1424    result.unaryOp(operation);      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1425      } else if (isTagged()) {
1426        DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1427        DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1428        EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1429        EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1430        escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1431      } else if (isConstant()) {
1432        DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1433        DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1434        EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1435        EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1436        escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1437      }
1438    return result;    return result;
1439  }  }
1440    
1441  }  }
   
1442  #endif  #endif

Legend:
Removed from v.94  
changed lines
  Added in v.149

  ViewVC Help
Powered by ViewVC 1.1.26