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

Diff of /trunk/esys2/escript/src/Data/Data.h

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

revision 100 by jgs, Wed Dec 15 03:48:48 2004 UTC revision 121 by jgs, Fri May 6 04:26:16 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
# Line 23  Line 23 
23  #include "escript/Data/FunctionSpace.h"  #include "escript/Data/FunctionSpace.h"
24  #include "escript/Data/BinaryOp.h"  #include "escript/Data/BinaryOp.h"
25  #include "escript/Data/UnaryOp.h"  #include "escript/Data/UnaryOp.h"
26    #include "escript/Data/DataException.h"
27    
28  extern "C" {  extern "C" {
29  #include "escript/Data/DataC.h"  #include "escript/Data/DataC.h"
# Line 39  extern "C" { Line 40  extern "C" {
40  #include <boost/python/tuple.hpp>  #include <boost/python/tuple.hpp>
41  #include <boost/python/numeric.hpp>  #include <boost/python/numeric.hpp>
42    
43    namespace escript {
44    
45    //
46    // Forward declaration for various implimentations of Data.
47    class DataEmpty;
48    class DataConstant;
49    class DataTagged;
50    class DataExpanded;
51    
52  /**  /**
53     \brief     \brief
54     Data is essentially a factory class which creates the appropriate Data     Data creates the appropriate Data object for the given construction
55     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.  
56    
57     Description:     Description:
58     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 61  extern "C" {
61     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
62     the Data object.     the Data object.
63  */  */
   
 namespace escript {  
   
 //  
 // Forward declaration for various implimentations of Data.  
 class DataEmpty;  
 class DataConstant;  
 class DataTagged;  
 class DataExpanded;  
   
64  class Data {  class Data {
65    
66    public:    public:
67    
68      // These typedefs allow function names to be cast to pointers
69      // to functions of the appropriate type when calling unaryOp etc.
70    typedef double (*UnaryDFunPtr)(double);    typedef double (*UnaryDFunPtr)(double);
71    typedef double (*BinaryDFunPtr)(double,double);    typedef double (*BinaryDFunPtr)(double,double);
72    
73    /**    /**
74         Constructors.
75      */
76    
77      /**
78       \brief       \brief
79       Default constructor.       Default constructor.
80       Creates a DataEmpty object.       Creates a DataEmpty object.
# Line 88  class Data { Line 91  class Data {
91    /**    /**
92       \brief       \brief
93       Constructor from another Data object. If "what" is different from the       Constructor from another Data object. If "what" is different from the
94       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,
95       otherwise a shallow copy of inData is returned.       otherwise a shallow copy of inData is returned.
96    */    */
97    Data(const Data& inData,    Data(const Data& inData,
# Line 205  class Data { Line 208  class Data {
208    
209    /**    /**
210       \brief       \brief
211       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.  
212    */    */
   template <class UnaryFunction>  
213    void    void
214    unaryOp(UnaryFunction operation);    copy(const Data& other);
   
   /**  
      \brief  
      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.  
   */  
   template <class BinaryFunction>  
   void  
   binaryOp(const Data& right,  
            BinaryFunction operation);  
215    
216    /**    /**
217       \brief       Member access methods.
      Perform the given binary operation on all of the data's elements.  
218    */    */
   template <class BinaryFunction>  
   void  
   binaryOp(const boost::python::object& right,  
            BinaryFunction operation);  
219    
220    /**    /**
221       \brief       \brief
222       Overloaded operator +=       Return the values of all data-points as a single python numarray object.
      \param right - Input - The right hand side.  
223    */    */
224    Data& operator+=(const Data& right);    const boost::python::numeric::array
225    Data& operator+=(const boost::python::object& right);    convertToNumArray();
226    
227    /**    /**
228       \brief       \brief
229       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.  
   */  
   Data& operator-=(const Data& right);  
   Data& operator-=(const boost::python::object& right);  
   
  /**  
      \brief  
      Overloaded operator *=  
      \param right - Input - The right hand side.  
230    */    */
231    Data& operator*=(const Data& right);    const boost::python::numeric::array
232    Data& operator*=(const boost::python::object& right);    convertToNumArrayFromSampleNo(int sampleNo);
   
  /**  
      \brief  
      Overloaded operator /=  
      \param right - Input - The right hand side.  
   */  
   Data& operator/=(const Data& right);  
   Data& operator/=(const boost::python::object& right);  
233    
234    /**    /**
235       \brief       \brief
236       Return the power of Data.       Return the value of the specified data-point as a single python numarray object.
237    */    */
238    Data powD(const Data& right) const;    const boost::python::numeric::array
239    Data powO(const boost::python::object& right) const;    convertToNumArrayFromDPNo(int sampleNo,
240                                int dataPointNo);
241    
242    /**    /**
243       \brief       \brief
244       Return the C wrapper for the Data object.       Return the C wrapper for the Data object.
245    */    */
246    escriptDataC getDataC();    escriptDataC
247      getDataC();
248    
249    /**    /**
250       \brief       \brief
251       Return the C wrapper for the Data object - const version.       Return the C wrapper for the Data object - const version.
252    */    */
253    escriptDataC getDataC() const;    escriptDataC
254      getDataC() const;
255    
256    /**    /**
257       \brief       \brief
258       Write the data as a string.       Write the data as a string.
259    */    */
260    std::string toString() const;    inline
261      std::string
262      toString() const
263      {
264        return m_data->toString();
265      }
266    
267    /**    /**
268       \brief       \brief
# Line 312  class Data { Line 279  class Data {
279    
280    /**    /**
281       \brief       \brief
282       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.  
283    */    */
284    void    void
285    expand();    expand();
286    
287    /**    /**
288       \brief       \brief
289       If possible convert the Data type to tagged. This will only allow       If possible convert this Data to DataTagged. This will only allow
290       Constant data to be converted to tagged. An attempt to convert       Constant data to be converted to tagged. An attempt to convert
291       Expanded data to tagged will throw an exception.       Expanded data to tagged will throw an exception.
292    */    */
# Line 357  class Data { Line 309  class Data {
309    
310    /**    /**
311       \brief       \brief
312       Return true if this Data is empty.       Return true if this Data is constant.
313    */    */
314    bool    bool
315    isEmpty() const;    isConstant() const;
316    
317    /**    /**
318       \brief       \brief
319       Return true if this Data is constant.       Return true if this Data is empty.
320    */    */
321    bool    bool
322    isConstant() const;    isEmpty() const;
323    
324    /**    /**
325       \brief       \brief
# Line 418  class Data { Line 370  class Data {
370    
371    /**    /**
372       \brief       \brief
373       Return the number of data points per sample.       Return the number of samples.
374    */    */
375    inline    inline
376    int    int
377    getNumDataPointsPerSample() const    getNumSamples() const
378    {    {
379      return m_data->getNumDPPSample();      return m_data->getNumSamples();
380    }    }
381    
382    /**    /**
383       \brief       \brief
384       Return the number of samples.       Return the number of data points per sample.
385    */    */
386      inline
387    int    int
388    getNumSamples() const;    getNumDataPointsPerSample() const
389      {
390    /**      return m_data->getNumDPPSample();
391       \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;  
392    
393    /**    /**
394       \brief       \brief
# Line 449  class Data { Line 396  class Data {
396       preferred interface but is provided for use by C code.       preferred interface but is provided for use by C code.
397       \param sampleNo - Input - the given sample no.       \param sampleNo - Input - the given sample no.
398    */    */
399      inline
400    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
401    getSampleData(DataAbstract::ShapeType::size_type sampleNo);    getSampleData(DataAbstract::ValueType::size_type sampleNo)
402      {
403        return m_data->getSampleData(sampleNo);
404      }
405    
406    /**    /**
407       \brief       \brief
# Line 458  class Data { Line 409  class Data {
409       access data that isn't tagged an exception will be thrown.       access data that isn't tagged an exception will be thrown.
410       \param tag - Input - the tag key.       \param tag - Input - the tag key.
411    */    */
412      inline
413    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
414    getSampleDataByTag(int tag);    getSampleDataByTag(int tag)
415      {
416        return m_data->getSampleDataByTag(tag);
417      }
418    
419      /**
420         \brief
421         Assign the given value to the data-points referenced by the given
422         reference number.
423    
424         The value supplied is a python numarray object.  The data from this numarray
425         is unpacked into a DataArray, and this is used to set the corresponding
426         data-points in the underlying Data object.
427    
428         If the underlying Data object cannot be accessed via reference numbers, an
429         exception will be thrown.
430    
431         \param ref - Input - reference number.
432         \param value - Input - value to assign to data-points associated with
433                                the given reference number.
434      */
435      void
436      setRefValue(int ref,
437                  const boost::python::numeric::array& value);
438    
439      /**
440         \brief
441         Return the values associated with the data-points referenced by the given
442         reference number.
443    
444         The value supplied is a python numarray object. The data from the corresponding
445         data-points in this Data object are packed into the given numarray object.
446    
447         If the underlying Data object cannot be accessed via reference numbers, an
448         exception will be thrown.
449    
450         \param ref - Input - reference number.
451         \param value - Output - object to receive values from data-points
452                                 associated with the given reference number.
453      */
454      void
455      getRefValue(int ref,
456                  boost::python::numeric::array& value);
457    
458    /**    /**
459       \brief       \brief
# Line 486  class Data { Line 480  class Data {
480    
481    /**    /**
482       \brief       \brief
483       Return data point shape as a tuple of integers:       Return the data point shape as a tuple of integers.
484    */    */
485    boost::python::tuple    const boost::python::tuple
486    getShapeTuple() const;    getShapeTuple() const;
487    
488    /**    /**
# Line 501  class Data { Line 495  class Data {
495    
496    /**    /**
497       \brief       \brief
498       Return the number of doubles stored for Data.       Return the number of doubles stored for this Data.
499    */    */
500    DataArrayView::ValueType::size_type    DataArrayView::ValueType::size_type
501    getLength() const;    getLength() const;
502    
503    /**    /**
504       \brief       \brief
505       Interpolates this onto the given functionspace and returns the result as a Data object.       Assign the given value to the tag. Implicitly converts this
506         object to type DataTagged. Throws an exception if this object
507         cannot be converted to a DataTagged object.
508         \param tagKey - Input - Integer key.
509         \param value - Input - Value to associate with given key.
510      */
511      void
512      setTaggedValue(int tagKey,
513                     const boost::python::object& value);
514    
515      /**
516         \brief
517         Assign the given value to the tag. Implicitly converts this
518         object to type DataTagged. Throws an exception if this object
519         cannot be converted to a DataTagged object.
520         \param tagKey - Input - Integer key.
521         \param value - Input - Value to associate with given key.
522      */
523      void
524      setTaggedValueFromCPP(int tagKey,
525                            const DataArrayView& value);
526    
527      /**
528        \brief
529        Copy other Data object into this Data object where mask is positive.
530      */
531      void
532      copyWithMask(const Data& other,
533                   const Data& mask);
534    
535      /**
536         Data object operation methods and operators.
537      */
538    
539      /**
540         \brief
541         Interpolates this onto the given functionspace and returns
542         the result as a Data object.
543    */    */
544    Data    Data
545    interpolate(const FunctionSpace& functionspace) const;    interpolate(const FunctionSpace& functionspace) const;
# Line 540  class Data { Line 571  class Data {
571    
572    /**    /**
573       \brief       \brief
574       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.
575      */
576      Data
577      whereNegative() const;
578    
579      /**
580         \brief
581         Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
582    */    */
583    Data    Data
584    whereNonNegative() const;    whereNonNegative() const;
585    
586    /**    /**
587       \brief       \brief
588       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.
589    */    */
590    Data    Data
591    whereNegative() const;    whereNonPositive() const;
592    
593    /**    /**
594       \brief       \brief
595       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.
596    */    */
597    Data    Data
598    whereZero() const;    whereZero() const;
599    
600    /**    /**
601       \brief       \brief
602       Return the sin of Data.       Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
603      */
604      Data
605      whereNonZero() const;
606    
607      /**
608         \brief
609         Return the sin of each data point of this Data object.
610    */    */
611    Data    Data
612    sin() const;    sin() const;
613    
614    /**    /**
615       \brief       \brief
616       Return the cos of Data.       Return the cos of each data point of this Data object.
617    */    */
618    Data    Data
619    cos() const;    cos() const;
620    
621    /**    /**
622       \brief       \brief
623       Return the tan of Data.       Return the tan of each data point of this Data object.
624    */    */
625    Data    Data
626    tan() const;    tan() const;
627    
628    /**    /**
629       \brief       \brief
630       Return the log to base 10 of Data.       Return the log to base 10 of each data point of this Data object.
631    */    */
632    Data    Data
633    log() const;    log() const;
634    
635    /**    /**
636       \brief       \brief
637       Return the natural log of Data.       Return the natural log of each data point of this Data object.
638    */    */
639    Data    Data
640    ln() const;    ln() const;
641    
642    /**    /**
643       \brief       \brief
644       Return a Data containing a slice of this Data.       Return the maximum absolute value of this Data object.
645    */    */
646    Data    double
647    getSlice(const DataArrayView::RegionType& region) const;    Lsup() const;
648    
649    /**    /**
650       \brief       \brief
651       Copy the specified region from the given value.       Return the minimum absolute value of this Data object.
      \param value - Input - Data to copy from.  
      \param region - Input - Region to copy.  
652    */    */
653    void    double
654    setSlice(const Data& value,    Linf() const;
            const DataArrayView::RegionType& region);  
655    
656    /**    /**
657       \brief       \brief
658       Return the maximum absolute value.       Return the maximum value of this Data object.
659    */    */
660    double    double
661    Lsup() const;    sup() const;
662    
663    /**    /**
664       \brief       \brief
665       Return the maximum value.       Return the minimum value of this Data object.
666    */    */
667    double    double
668    sup() const;    inf() const;
669    
670    /**    /**
671       \brief       \brief
672       Return the minimum value.       Return the absolute value of each data point of this Data object.
673    */    */
674    double    Data
675    inf() const;    abs() const;
676    
677    /**    /**
678       \brief       \brief
679       Returns a slice from this.       Return the maximum value of each data point of this Data object.
680    */    */
681    Data    Data
682    getItem(const boost::python::object& key) const;    maxval() const;
683    
684    /**    /**
685       \brief       \brief
686       Copies slice from value into this.       Return the minimum value of each data point of this Data object.
687    */    */
688    void    Data
689    setItem(const boost::python::object& key,    minval() const;
           const Data& value);  
690    
691    /**    /**
692       \brief       \brief
693       Convert the underlying data type to match the RHS.       Return the (sample number, data-point number) of the data point with
694       \param right - Input - data type to match.       the minimum value in this Data object.
695      */
696      const boost::python::tuple
697      mindp() const;
698    
699      /**
700         \brief
701         Return the length of each data point of this Data object.
702         sqrt(sum(A[i,j,k,l]^2))
703      */
704      Data
705      length() const;
706    
707      /**
708         \brief
709         Return the sign of each data point of this Data object.
710         -1 for negative values, zero for zero values, 1 for positive values.
711      */
712      Data
713      sign() const;
714    
715      /**
716        \brief
717        Transpose each data point of this Data object around the given axis.
718        --* not implemented yet *--
719      */
720      Data
721      transpose(int axis) const;
722    
723      /**
724        \brief
725        Calculate the trace of each data point of this Data object.
726        sum(A[i,i,i,i])
727      */
728      Data
729      trace() const;
730    
731      /**
732        \brief
733        Return the exponential function of each data point of this Data object.
734      */
735      Data
736      exp() const;
737    
738      /**
739        \brief
740        Return the square root of each data point of this Data object.
741      */
742      Data
743      sqrt() const;
744    
745      /**
746        \brief
747        Return the negation of each data point of this Data object.
748      */
749      Data
750      neg() const;
751    
752      /**
753        \brief
754        Return the identity of each data point of this Data object.
755        Simply returns this object unmodified.
756      */
757      Data
758      pos() const;
759    
760      /**
761         \brief
762         Return the given power of each data point of this Data object.
763    
764         \param right Input - the power to raise the object to.
765      */
766      Data
767      powD(const Data& right) const;
768    
769      /**
770       * \brief
771       * Return the given power of each data point of this boost python object.
772       *
773       * \param right Input - the power to raise the object to.
774       */
775      Data
776      powO(const boost::python::object& right) const;
777    
778      /**
779        \brief
780        writes the object to a file in the DX file format
781    */    */
782    void    void
783    typeMatch(const Data& right);    saveDX(std::string fileName) const;
784    
785      /**
786        \brief
787        writes the object to a file in the VTK file format
788      */
789      void
790      saveVTK(std::string fileName) const;
791    
792      /**
793         \brief
794         Overloaded operator +=
795         \param right - Input - The right hand side.
796      */
797      Data& operator+=(const Data& right);
798      Data& operator+=(const boost::python::object& right);
799    
800      /**
801         \brief
802         Overloaded operator -=
803         \param right - Input - The right hand side.
804      */
805      Data& operator-=(const Data& right);
806      Data& operator-=(const boost::python::object& right);
807    
808     /**
809         \brief
810         Overloaded operator *=
811         \param right - Input - The right hand side.
812      */
813      Data& operator*=(const Data& right);
814      Data& operator*=(const boost::python::object& right);
815    
816     /**
817         \brief
818         Overloaded operator /=
819         \param right - Input - The right hand side.
820      */
821      Data& operator/=(const Data& right);
822      Data& operator/=(const boost::python::object& right);
823    
824    /**    /**
825       \brief       \brief
# Line 663  class Data { Line 829  class Data {
829    probeInterpolation(const FunctionSpace& functionspace) const;    probeInterpolation(const FunctionSpace& functionspace) const;
830    
831    /**    /**
832         Data object slicing methods.
833      */
834    
835      /**
836       \brief       \brief
837       Assign the given value to the tag. Implicitly converts this       Returns a slice from this Data object.
838       object to type DataTagged. Throws an exception if this object  
839       cannot be converted to a DataTagged object.       /description
840       \param tagKey - Input - Integer key.       Implements the [] get operator in python.
841       \param value - Input - Value to associate with given key.       Calls getSlice.
842    
843         \param key - Input - python slice tuple specifying
844         slice to return.
845      */
846      Data
847      getItem(const boost::python::object& key) const;
848    
849      /**
850         \brief
851         Copies slice from value into this Data object.
852    
853         Implements the [] set operator in python.
854         Calls setSlice.
855    
856         \param key - Input - python slice tuple specifying
857         slice to copy from value.
858         \param value - Input - Data object to copy from.
859    */    */
860    void    void
861    setTaggedValue(int tagKey,    setItemD(const boost::python::object& key,
862                   const boost::python::object& value);             const Data& value);
863    
864      void
865      setItemO(const boost::python::object& key,
866               const boost::python::object& value);
867    
868      // These following public methods should be treated as private.
869    
870    /**    /**
871       \brief       \brief
872       Assign the given value to the tag. Implicitly converts this       Perform the given unary operation on every element of every data point in
873       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  
874    */    */
875    /*    template <class UnaryFunction>
876      inline
877    void    void
878    setTaggedValue(int tagKey,    unaryOp(UnaryFunction operation);
879                   const DataArrayView& value);  
880      /**
881         \brief
882         Return a Data object containing the specified slice of
883         this Data object.
884         \param region - Input - Region to copy.
885    */    */
886      Data
887      getSlice(const DataArrayView::RegionType& region) const;
888    
889      /**
890         \brief
891         Copy the specified slice from the given value into this
892         Data object.
893         \param value - Input - Data to copy from.
894         \param region - Input - Region to copy.
895      */
896      void
897      setSlice(const Data& value,
898               const DataArrayView::RegionType& region);
899    
900      /**
901         \brief
902         Archive the current Data object to the given file.
903         \param fileName - Input - file to archive to.
904      */
905      void
906      archiveData(const std::string fileName);
907    
908      /**
909         \brief
910         Extract the Data object archived in the given file, overwriting
911         the current Data object.
912         Note - the current object must be of type DataEmpty.
913         \param fileName - Input - file to extract from.
914         \param fspace - Input - a suitable FunctionSpace descibing the data.
915      */
916      void
917      extractData(const std::string fileName,
918                  const FunctionSpace& fspace);
919    
920     protected:
921    
922   private:   private:
923    
924    /**    /**
925       \brief       \brief
926         Check *this and the right operand are compatible. Throws
927         an exception if they aren't.
928         \param right - Input - The right hand side.
929      */
930      inline
931      void
932      operandCheck(const Data& right) const
933      {
934        return m_data->operandCheck(*(right.m_data.get()));
935      }
936    
937      /**
938         \brief
939         Perform the specified reduction algorithm on every element of every data point in
940         this Data object according to the given function and return the single value result.
941      */
942      template <class UnaryFunction>
943      inline
944      double
945      algorithm(UnaryFunction operation) const;
946    
947      /**
948         \brief
949         Reduce each data-point in this Data object using the given operation. Return a Data
950         object with the same number of data-points, but with each data-point containing only
951         one value - the result of the reduction operation on the corresponding data-point in
952         this Data object
953      */
954      template <class UnaryFunction>
955      inline
956      Data
957      dp_algorithm(UnaryFunction operation) const;
958    
959      /**
960         \brief
961         Perform the given binary operation on all of the data's elements.
962         The underlying type of the right hand side (right) determines the final
963         type of *this after the operation. For example if the right hand side
964         is expanded *this will be expanded if necessary.
965         RHS is a Data object.
966      */
967      template <class BinaryFunction>
968      inline
969      void
970      binaryOp(const Data& right,
971               BinaryFunction operation);
972    
973      /**
974         \brief
975         Perform the given binary operation on all of the data's elements.
976         RHS is a boost::python object.
977      */
978      template <class BinaryFunction>
979      inline
980      void
981      binaryOp(const boost::python::object& right,
982               BinaryFunction operation);
983    
984      /**
985         \brief
986         Convert the data type of the RHS to match this.
987         \param right - Input - data type to match.
988      */
989      void
990      typeMatchLeft(Data& right) const;
991    
992      /**
993         \brief
994         Convert the data type of this to match the RHS.
995         \param right - Input - data type to match.
996      */
997      void
998      typeMatchRight(const Data& right);
999    
1000      /**
1001         \brief
1002       Construct a Data object of the appropriate type.       Construct a Data object of the appropriate type.
1003    */    */
1004    template <class IValueType>    template <class IValueType>
# Line 712  class Data { Line 1018  class Data {
1018    reshapeDataPoint(const DataArrayView::ShapeType& shape);    reshapeDataPoint(const DataArrayView::ShapeType& shape);
1019    
1020    //    //
1021    // pointer to the actual data    // pointer to the actual data object
1022    boost::shared_ptr<DataAbstract> m_data;    boost::shared_ptr<DataAbstract> m_data;
1023    
1024  };  };
# Line 730  Data::initialise(const IValueType& value Line 1036  Data::initialise(const IValueType& value
1036    // within the shared_ptr constructor.    // within the shared_ptr constructor.
1037    if (expanded) {    if (expanded) {
1038      DataAbstract* temp=new DataExpanded(value,what);      DataAbstract* temp=new DataExpanded(value,what);
1039      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1040        m_data=temp_data;
1041    } else {    } else {
1042      DataAbstract* temp=new DataConstant(value,what);      DataAbstract* temp=new DataConstant(value,what);
1043      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1044        m_data=temp_data;
1045    }    }
1046  }  }
1047    
1048  inline  /**
1049  DataAbstract::ValueType::value_type*     Binary Data object operators.
1050  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();  
 }  
1051    
1052  /**  /**
1053    \brief    \brief
# Line 876  std::ostream& operator<<(std::ostream& o Line 1153  std::ostream& operator<<(std::ostream& o
1153    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
1154    be relied on. Requires further implementation.    be relied on. Requires further implementation.
1155  */  */
1156  bool operator==(const Data& left, const Data& right);  //bool operator==(const Data& left, const Data& right);
1157    
1158    /**
1159      \brief
1160      Perform the given binary operation with this and right as operands.
1161      Right is a Data object.
1162    */
1163  template <class BinaryFunction>  template <class BinaryFunction>
1164  inline  inline
1165  void  void
# Line 907  Data::binaryOp(const Data& right, Line 1189  Data::binaryOp(const Data& right,
1189     operandCheck(tempRight);     operandCheck(tempRight);
1190     //     //
1191     // ensure this has the right type for the RHS     // ensure this has the right type for the RHS
1192     typeMatch(tempRight);     typeMatchRight(tempRight);
1193     //     //
1194     // Need to cast to the concrete types so that the correct binaryOp     // Need to cast to the concrete types so that the correct binaryOp
1195     // is called.     // is called.
# Line 933  Data::binaryOp(const Data& right, Line 1215  Data::binaryOp(const Data& right,
1215         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1216         escript::binaryOp(*leftC,*rightC,operation);         escript::binaryOp(*leftC,*rightC,operation);
1217       }       }
1218     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1219       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1220       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1221       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 1223  Data::binaryOp(const Data& right,
1223     }     }
1224  }  }
1225    
1226    /**
1227      \brief
1228      Perform the given binary operation with this and right as operands.
1229      Right is a boost::python object.
1230    */
1231  template <class BinaryFunction>  template <class BinaryFunction>
1232  inline  inline
1233  void  void
# Line 963  Data::binaryOp(const boost::python::obje Line 1248  Data::binaryOp(const boost::python::obje
1248                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1249       }       }
1250     }     }
   
1251     if (isExpanded()) {     if (isExpanded()) {
      //  
      // Expanded data will be done in parallel  
1252       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1253       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1254       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
# Line 974  Data::binaryOp(const boost::python::obje Line 1256  Data::binaryOp(const boost::python::obje
1256       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1257       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1258       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1259     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1260       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1261       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1262       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1263     }     }
1264  }  }
1265    
1266    /**
1267      \brief
1268      Perform the given unary operation on other and return the result.
1269      Given operation is performed on each element of each data point, thus
1270      argument object is a rank n Data object, and returned object is a rank n
1271      Data object.
1272      Calls Data::unaryOp.
1273    */
1274    template <class UnaryFunction>
1275    inline
1276    Data
1277    unaryOp(const Data& other,
1278            UnaryFunction operation)
1279    {
1280      Data result;
1281      result.copy(other);
1282      result.unaryOp(operation);
1283      return result;
1284    }
1285    
1286    /**
1287      \brief
1288      Perform the given unary operation on this.
1289      Given operation is performed on each element of each data point.
1290      Calls escript::unaryOp.
1291    */
1292  template <class UnaryFunction>  template <class UnaryFunction>
1293  inline  inline
1294  void  void
1295  Data::unaryOp(UnaryFunction operation)  Data::unaryOp(UnaryFunction operation)
1296  {  {
1297    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1298      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1299      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1300      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
# Line 998  Data::unaryOp(UnaryFunction operation) Line 1302  Data::unaryOp(UnaryFunction operation)
1302      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1303      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1304      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1305    } else {    } else if (isConstant()) {
1306      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1307      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1308      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1309    }    }
1310  }  }
1311    
1312    /**
1313      \brief
1314      Perform the given Data object reduction algorithm on this and return the result.
1315      Given operation combines each element of each data point, thus argument
1316      object (*this) is a rank n Data object, and returned object is a scalar.
1317      Calls escript::algorithm.
1318    */
1319  template <class UnaryFunction>  template <class UnaryFunction>
1320  inline  inline
1321  double  double
1322  Data::algorithm(UnaryFunction operation) const  Data::algorithm(UnaryFunction operation) const
1323  {  {
1324    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1325      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1326      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1327      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation);
1328    }    } else if (isTagged()) {
   else if (isTagged()) {  
1329      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1330      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1331      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation);
1332    } else {    } else if (isConstant()) {
1333      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1334      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1335      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation);
1336    }    }
1337      return 0;
1338  }  }
1339    
1340    /**
1341      \brief
1342      Perform the given data point reduction algorithm on data and return the result.
1343      Given operation combines each element within each data point into a scalar,
1344      thus argument object is a rank n Data object, and returned object is a
1345      rank 0 Data object.
1346      Calls escript::dp_algorithm.
1347    */
1348  template <class UnaryFunction>  template <class UnaryFunction>
1349  inline  inline
1350  Data  Data
1351  unaryOp(const Data& other,  Data::dp_algorithm(UnaryFunction operation) const
         UnaryFunction operation)  
1352  {  {
1353    //    Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1354    // Perform the given operation on a copy of the input data and return the result    if (isExpanded()) {
1355    Data result;      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1356    //      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1357    // perform a deep copy      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1358    result.copy(other);      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1359    result.unaryOp(operation);      escript::dp_algorithm(*dataE,*resultE,operation);
1360      } else if (isTagged()) {
1361        DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1362        DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1363        EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1364        EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1365        escript::dp_algorithm(*dataT,*resultT,operation);
1366      } else if (isConstant()) {
1367        DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1368        DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1369        EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1370        EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1371        escript::dp_algorithm(*dataC,*resultC,operation);
1372      }
1373    return result;    return result;
1374  }  }
1375    
1376  }  }
   
1377  #endif  #endif

Legend:
Removed from v.100  
changed lines
  Added in v.121

  ViewVC Help
Powered by ViewVC 1.1.26