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

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

  ViewVC Help
Powered by ViewVC 1.1.26