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

Diff of /trunk/escript/src/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 147 by jgs, Fri Aug 12 01:45:47 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);
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 fills the expanded Data object from values of a  python numarray object.
      Overloaded operator +=  
      \param right - Input - The right hand side.  
   */  
   Data& operator+=(const Data& right);  
   Data& operator+=(const boost::python::object& right);  
230    
   /**  
      \brief  
      Overloaded operator -=  
      \param right - Input - The right hand side.  
231    */    */
232    Data& operator-=(const Data& right);    void
233    Data& operator-=(const boost::python::object& right);    fillFromNumArray(const boost::python::numeric::array);
234      /**
  /**  
      \brief  
      Overloaded operator *=  
      \param right - Input - The right hand side.  
   */  
   Data& operator*=(const Data& right);  
   Data& operator*=(const boost::python::object& right);  
   
  /**  
235       \brief       \brief
236       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.  
237    */    */
238    Data& operator/=(const Data& right);    const boost::python::numeric::array
239    Data& operator/=(const boost::python::object& right);    convertToNumArrayFromSampleNo(int sampleNo);
240    
241    /**    /**
242       \brief       \brief
243       Return the power of Data.       Return the value of the specified data-point as a single python numarray object.
244    */    */
245    Data powD(const Data& right) const;    const boost::python::numeric::array
246    Data powO(const boost::python::object& right) const;    convertToNumArrayFromDPNo(int sampleNo,
247                                int dataPointNo);
248    
249    /**    /**
250       \brief       \brief
251       Return the C wrapper for the Data object.       Return the C wrapper for the Data object.
252    */    */
253    escriptDataC getDataC();    escriptDataC
254      getDataC();
255    
256    /**    /**
257       \brief       \brief
258       Return the C wrapper for the Data object - const version.       Return the C wrapper for the Data object - const version.
259    */    */
260    escriptDataC getDataC() const;    escriptDataC
261      getDataC() const;
262    
263    /**    /**
264       \brief       \brief
265       Write the data as a string.       Write the data as a string.
266    */    */
267    std::string toString() const;    inline
268      std::string
269      toString() const
270      {
271        return m_data->toString();
272      }
273    
274    /**    /**
275       \brief       \brief
# Line 312  class Data { Line 286  class Data {
286    
287    /**    /**
288       \brief       \brief
289       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.  
290    */    */
291    void    void
292    expand();    expand();
293    
294    /**    /**
295       \brief       \brief
296       If possible convert the Data type to tagged. This will only allow       If possible convert this Data to DataTagged. This will only allow
297       Constant data to be converted to tagged. An attempt to convert       Constant data to be converted to tagged. An attempt to convert
298       Expanded data to tagged will throw an exception.       Expanded data to tagged will throw an exception.
299    */    */
# Line 357  class Data { Line 316  class Data {
316    
317    /**    /**
318       \brief       \brief
319       Return true if this Data is empty.       Return true if this Data is constant.
320    */    */
321    bool    bool
322    isEmpty() const;    isConstant() const;
323    
324    /**    /**
325       \brief       \brief
326       Return true if this Data is constant.       Return true if this Data is empty.
327    */    */
328    bool    bool
329    isConstant() const;    isEmpty() const;
330    
331    /**    /**
332       \brief       \brief
# Line 418  class Data { Line 377  class Data {
377    
378    /**    /**
379       \brief       \brief
380       Return the number of data points per sample.       Return the number of samples.
381    */    */
382    inline    inline
383    int    int
384    getNumDataPointsPerSample() const    getNumSamples() const
385    {    {
386      return m_data->getNumDPPSample();      return m_data->getNumSamples();
387    }    }
388    
389    /**    /**
390       \brief       \brief
391       Return the number of samples.       Return the number of data points per sample.
392    */    */
393      inline
394    int    int
395    getNumSamples() const;    getNumDataPointsPerSample() const
396      {
397    /**      return m_data->getNumDPPSample();
398       \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;  
399    
400    /**    /**
401       \brief       \brief
# Line 449  class Data { Line 403  class Data {
403       preferred interface but is provided for use by C code.       preferred interface but is provided for use by C code.
404       \param sampleNo - Input - the given sample no.       \param sampleNo - Input - the given sample no.
405    */    */
406      inline
407    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
408    getSampleData(DataAbstract::ShapeType::size_type sampleNo);    getSampleData(DataAbstract::ValueType::size_type sampleNo)
409      {
410        return m_data->getSampleData(sampleNo);
411      }
412    
413    /**    /**
414       \brief       \brief
# Line 458  class Data { Line 416  class Data {
416       access data that isn't tagged an exception will be thrown.       access data that isn't tagged an exception will be thrown.
417       \param tag - Input - the tag key.       \param tag - Input - the tag key.
418    */    */
419      inline
420    DataAbstract::ValueType::value_type*    DataAbstract::ValueType::value_type*
421    getSampleDataByTag(int tag);    getSampleDataByTag(int tag)
422      {
423        return m_data->getSampleDataByTag(tag);
424      }
425    
426      /**
427         \brief
428         Assign the given value to the data-points referenced by the given
429         reference number.
430    
431         The value supplied is a python numarray object.  The data from this numarray
432         is unpacked into a DataArray, and this is used to set the corresponding
433         data-points in the underlying Data object.
434    
435         If the underlying Data object cannot be accessed via reference numbers, an
436         exception will be thrown.
437    
438         \param ref - Input - reference number.
439         \param value - Input - value to assign to data-points associated with
440                                the given reference number.
441      */
442      void
443      setRefValue(int ref,
444                  const boost::python::numeric::array& value);
445    
446      /**
447         \brief
448         Return the values associated with the data-points referenced by the given
449         reference number.
450    
451         The value supplied is a python numarray object. The data from the corresponding
452         data-points in this Data object are packed into the given numarray object.
453    
454         If the underlying Data object cannot be accessed via reference numbers, an
455         exception will be thrown.
456    
457         \param ref - Input - reference number.
458         \param value - Output - object to receive values from data-points
459                                 associated with the given reference number.
460      */
461      void
462      getRefValue(int ref,
463                  boost::python::numeric::array& value);
464    
465    /**    /**
466       \brief       \brief
# Line 486  class Data { Line 487  class Data {
487    
488    /**    /**
489       \brief       \brief
490       Return data point shape as a tuple of integers:       Return the data point shape as a tuple of integers.
491    */    */
492    boost::python::tuple    const boost::python::tuple
493    getShapeTuple() const;    getShapeTuple() const;
494    
495    /**    /**
# Line 501  class Data { Line 502  class Data {
502    
503    /**    /**
504       \brief       \brief
505       Return the number of doubles stored for Data.       Return the number of doubles stored for this Data.
506    */    */
507    DataArrayView::ValueType::size_type    DataArrayView::ValueType::size_type
508    getLength() const;    getLength() const;
509    
510    /**    /**
511       \brief       \brief
512       Interpolates this onto the given functionspace and returns the result as a Data object.       Assign the given value to the tag. Implicitly converts this
513         object to type DataTagged. Throws an exception if this object
514         cannot be converted to a DataTagged object.
515         \param tagKey - Input - Integer key.
516         \param value - Input - Value to associate with given key.
517      */
518      void
519      setTaggedValue(int tagKey,
520                     const boost::python::object& value);
521    
522      /**
523         \brief
524         Assign the given value to the tag. Implicitly converts this
525         object to type DataTagged. Throws an exception if this object
526         cannot be converted to a DataTagged object.
527         \param tagKey - Input - Integer key.
528         \param value - Input - Value to associate with given key.
529      */
530      void
531      setTaggedValueFromCPP(int tagKey,
532                            const DataArrayView& value);
533    
534      /**
535        \brief
536        Copy other Data object into this Data object where mask is positive.
537      */
538      void
539      copyWithMask(const Data& other,
540                   const Data& mask);
541    
542      /**
543         Data object operation methods and operators.
544      */
545    
546      /**
547         \brief
548         Interpolates this onto the given functionspace and returns
549         the result as a Data object.
550         *
551    */    */
552    Data    Data
553    interpolate(const FunctionSpace& functionspace) const;    interpolate(const FunctionSpace& functionspace) const;
# Line 517  class Data { Line 556  class Data {
556       \brief       \brief
557       Calculates the gradient of the data at the data points of functionspace.       Calculates the gradient of the data at the data points of functionspace.
558       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.
559         *
560    */    */
561    Data    Data
562    gradOn(const FunctionSpace& functionspace) const;    gradOn(const FunctionSpace& functionspace) const;
# Line 527  class Data { Line 567  class Data {
567    /**    /**
568       \brief       \brief
569       Calculate the integral over the function space domain.       Calculate the integral over the function space domain.
570         *
571    */    */
572    boost::python::numeric::array    boost::python::numeric::array
573    integrate() const;    integrate() const;
# Line 534  class Data { Line 575  class Data {
575    /**    /**
576       \brief       \brief
577       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.
578         *
579    */    */
580    Data    Data
581    wherePositive() const;    wherePositive() const;
582    
583    /**    /**
584       \brief       \brief
585       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.
586         *
587      */
588      Data
589      whereNegative() const;
590    
591      /**
592         \brief
593         Return a Data with a 1 for +ive or 0 values and a 0 for -ive values.
594         *
595    */    */
596    Data    Data
597    whereNonNegative() const;    whereNonNegative() const;
598    
599    /**    /**
600       \brief       \brief
601       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.
602         *
603    */    */
604    Data    Data
605    whereNegative() const;    whereNonPositive() const;
606    
607    /**    /**
608       \brief       \brief
609       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.
610         *
611    */    */
612    Data    Data
613    whereZero() const;    whereZero() const;
614    
615    /**    /**
616       \brief       \brief
617       Return the sin of Data.       Return a Data with a 0 for 0 values and a 1 for +ive or -ive values.
618         *
619      */
620      Data
621      whereNonZero() const;
622    
623      /**
624         \brief
625         Return the maximum absolute value of this Data object.
626         *
627      */
628      double
629      Lsup() const;
630    
631      /**
632         \brief
633         Return the minimum absolute value of this Data object.
634         *
635      */
636      double
637      Linf() const;
638    
639      /**
640         \brief
641         Return the maximum value of this Data object.
642         *
643      */
644      double
645      sup() const;
646    
647      /**
648         \brief
649         Return the minimum value of this Data object.
650         *
651      */
652      double
653      inf() const;
654    
655      /**
656         \brief
657         Return the absolute value of each data point of this Data object.
658         *
659      */
660      Data
661      abs() const;
662    
663      /**
664         \brief
665         Return the maximum value of each data point of this Data object.
666         *
667      */
668      Data
669      maxval() const;
670    
671      /**
672         \brief
673         Return the minimum value of each data point of this Data object.
674         *
675      */
676      Data
677      minval() const;
678    
679      /**
680         \brief
681         Return the (sample number, data-point number) of the data point with
682         the minimum value in this Data object.
683      */
684      const boost::python::tuple
685      mindp() const;
686    
687      /**
688         \brief
689         Return the length of each data point of this Data object.
690         sqrt(sum(A[i,j,k,l]^2))
691         *
692      */
693      Data
694      length() const;
695    
696      /**
697         \brief
698         Return the sign of each data point of this Data object.
699         -1 for negative values, zero for zero values, 1 for positive values.
700         *
701      */
702      Data
703      sign() const;
704    
705      /**
706         \brief
707         Transpose each data point of this Data object around the given axis.
708         --* not implemented yet *--
709         *
710      */
711      Data
712      transpose(int axis) const;
713    
714      /**
715         \brief
716         Calculate the trace of each data point of this Data object.
717         sum(A[i,i,i,i])
718         *
719      */
720      Data
721      trace() const;
722    
723      /**
724         \brief
725         Return the sin of each data point of this Data object.
726         *
727    */    */
728    Data    Data
729    sin() const;    sin() const;
730    
731    /**    /**
732       \brief       \brief
733       Return the cos of Data.       Return the cos of each data point of this Data object.
734         *
735    */    */
736    Data    Data
737    cos() const;    cos() const;
738    
739    /**    /**
740       \brief       \brief
741       Return the tan of Data.       Return the tan of each data point of this Data object.
742         *
743    */    */
744    Data    Data
745    tan() const;    tan() const;
746    
747    /**    /**
748       \brief       \brief
749       Return the log to base 10 of Data.       Return the log to base 10 of each data point of this Data object.
750         *
751    */    */
752    Data    Data
753    log() const;    log() const;
754    
755    /**    /**
756       \brief       \brief
757       Return the natural log of Data.       Return the natural log of each data point of this Data object.
758         *
759    */    */
760    Data    Data
761    ln() const;    ln() const;
762    
763    /**    /**
764       \brief       \brief
765       Return a Data containing a slice of this Data.       Return the exponential function of each data point of this Data object.
766         *
767    */    */
768    Data    Data
769    getSlice(const DataArrayView::RegionType& region) const;    exp() const;
770    
771    /**    /**
772       \brief       \brief
773       Copy the specified region from the given value.       Return the square root of each data point of this Data object.
774       \param value - Input - Data to copy from.       *
      \param region - Input - Region to copy.  
775    */    */
776    void    Data
777    setSlice(const Data& value,    sqrt() const;
            const DataArrayView::RegionType& region);  
778    
779    /**    /**
780       \brief       \brief
781       Return the maximum absolute value.       Return the negation of each data point of this Data object.
782         *
783    */    */
784    double    Data
785    Lsup() const;    neg() const;
786    
787    /**    /**
788       \brief       \brief
789       Return the maximum value.       Return the identity of each data point of this Data object.
790         Simply returns this object unmodified.
791         *
792    */    */
793    double    Data
794    sup() const;    pos() const;
795    
796    /**    /**
797       \brief       \brief
798       Return the minimum value.       Return the given power of each data point of this Data object.
799    
800         \param right Input - the power to raise the object to.
801         *
802    */    */
803    double    Data
804    inf() const;    powD(const Data& right) const;
805    
806    /**    /**
807       \brief       \brief
808       Returns a slice from this.       Return the given power of each data point of this boost python object.
809    */      
810         \param right Input - the power to raise the object to.
811         *
812       */
813    Data    Data
814    getItem(const boost::python::object& key) const;    powO(const boost::python::object& right) const;
815    
816    /**    /**
817       \brief       \brief
818       Copies slice from value into this.       writes the object to a file in the DX file format
819    */    */
820    void    void
821    setItem(const boost::python::object& key,    saveDX(std::string fileName) const;
           const Data& value);  
822    
823    /**    /**
824       \brief       \brief
825       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.  
826    */    */
827    void    void
828    typeMatch(const Data& right);    saveVTK(std::string fileName) const;
829    
830      /**
831         \brief
832         Overloaded operator +=
833         \param right - Input - The right hand side.
834         *
835      */
836      Data& operator+=(const Data& right);
837      Data& operator+=(const boost::python::object& right);
838    
839      /**
840         \brief
841         Overloaded operator -=
842         \param right - Input - The right hand side.
843         *
844      */
845      Data& operator-=(const Data& right);
846      Data& operator-=(const boost::python::object& right);
847    
848     /**
849         \brief
850         Overloaded operator *=
851         \param right - Input - The right hand side.
852         *
853      */
854      Data& operator*=(const Data& right);
855      Data& operator*=(const boost::python::object& right);
856    
857     /**
858         \brief
859         Overloaded operator /=
860         \param right - Input - The right hand side.
861         *
862      */
863      Data& operator/=(const Data& right);
864      Data& operator/=(const boost::python::object& right);
865    
866    /**    /**
867       \brief       \brief
# Line 663  class Data { Line 871  class Data {
871    probeInterpolation(const FunctionSpace& functionspace) const;    probeInterpolation(const FunctionSpace& functionspace) const;
872    
873    /**    /**
874         Data object slicing methods.
875      */
876    
877      /**
878       \brief       \brief
879       Assign the given value to the tag. Implicitly converts this       Returns a slice from this Data object.
880       object to type DataTagged. Throws an exception if this object  
881       cannot be converted to a DataTagged object.       /description
882       \param tagKey - Input - Integer key.       Implements the [] get operator in python.
883       \param value - Input - Value to associate with given key.       Calls getSlice.
884    
885         \param key - Input - python slice tuple specifying
886         slice to return.
887      */
888      Data
889      getItem(const boost::python::object& key) const;
890    
891      /**
892         \brief
893         Copies slice from value into this Data object.
894    
895         Implements the [] set operator in python.
896         Calls setSlice.
897    
898         \param key - Input - python slice tuple specifying
899         slice to copy from value.
900         \param value - Input - Data object to copy from.
901    */    */
902    void    void
903    setTaggedValue(int tagKey,    setItemD(const boost::python::object& key,
904                   const boost::python::object& value);             const Data& value);
905    
906      void
907      setItemO(const boost::python::object& key,
908               const boost::python::object& value);
909    
910      // These following public methods should be treated as private.
911    
912    /**    /**
913       \brief       \brief
914       Assign the given value to the tag. Implicitly converts this       Perform the given unary operation on every element of every data point in
915       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  
916    */    */
917    /*    template <class UnaryFunction>
918      inline
919    void    void
920    setTaggedValue(int tagKey,    unaryOp(UnaryFunction operation);
921                   const DataArrayView& value);  
922      /**
923         \brief
924         Return a Data object containing the specified slice of
925         this Data object.
926         \param region - Input - Region to copy.
927         *
928      */
929      Data
930      getSlice(const DataArrayView::RegionType& region) const;
931    
932      /**
933         \brief
934         Copy the specified slice from the given value into this
935         Data object.
936         \param value - Input - Data to copy from.
937         \param region - Input - Region to copy.
938         *
939      */
940      void
941      setSlice(const Data& value,
942               const DataArrayView::RegionType& region);
943    
944      /**
945         \brief
946         Archive the current Data object to the given file.
947         \param fileName - Input - file to archive to.
948    */    */
949      void
950      archiveData(const std::string fileName);
951    
952      /**
953         \brief
954         Extract the Data object archived in the given file, overwriting
955         the current Data object.
956         Note - the current object must be of type DataEmpty.
957         \param fileName - Input - file to extract from.
958         \param fspace - Input - a suitable FunctionSpace descibing the data.
959      */
960      void
961      extractData(const std::string fileName,
962                  const FunctionSpace& fspace);
963    
964     protected:
965    
966   private:   private:
967    
968    /**    /**
969       \brief       \brief
970         Check *this and the right operand are compatible. Throws
971         an exception if they aren't.
972         \param right - Input - The right hand side.
973      */
974      inline
975      void
976      operandCheck(const Data& right) const
977      {
978        return m_data->operandCheck(*(right.m_data.get()));
979      }
980    
981      /**
982         \brief
983         Perform the specified reduction algorithm on every element of every data point in
984         this Data object according to the given function and return the single value result.
985      */
986      template <class BinaryFunction>
987      inline
988      double
989      algorithm(BinaryFunction operation,
990                double initial_value) const;
991    
992      /**
993         \brief
994         Reduce each data-point in this Data object using the given operation. Return a Data
995         object with the same number of data-points, but with each data-point containing only
996         one value - the result of the reduction operation on the corresponding data-point in
997         this Data object
998      */
999      template <class BinaryFunction>
1000      inline
1001      Data
1002      dp_algorithm(BinaryFunction operation,
1003                   double initial_value) const;
1004    
1005      /**
1006         \brief
1007         Perform the given binary operation on all of the data's elements.
1008         The underlying type of the right hand side (right) determines the final
1009         type of *this after the operation. For example if the right hand side
1010         is expanded *this will be expanded if necessary.
1011         RHS is a Data object.
1012      */
1013      template <class BinaryFunction>
1014      inline
1015      void
1016      binaryOp(const Data& right,
1017               BinaryFunction operation);
1018    
1019      /**
1020         \brief
1021         Perform the given binary operation on all of the data's elements.
1022         RHS is a boost::python object.
1023      */
1024      template <class BinaryFunction>
1025      inline
1026      void
1027      binaryOp(const boost::python::object& right,
1028               BinaryFunction operation);
1029    
1030      /**
1031         \brief
1032         Convert the data type of the RHS to match this.
1033         \param right - Input - data type to match.
1034      */
1035      void
1036      typeMatchLeft(Data& right) const;
1037    
1038      /**
1039         \brief
1040         Convert the data type of this to match the RHS.
1041         \param right - Input - data type to match.
1042      */
1043      void
1044      typeMatchRight(const Data& right);
1045    
1046      /**
1047         \brief
1048       Construct a Data object of the appropriate type.       Construct a Data object of the appropriate type.
1049    */    */
1050    template <class IValueType>    template <class IValueType>
# Line 712  class Data { Line 1064  class Data {
1064    reshapeDataPoint(const DataArrayView::ShapeType& shape);    reshapeDataPoint(const DataArrayView::ShapeType& shape);
1065    
1066    //    //
1067    // pointer to the actual data    // pointer to the actual data object
1068    boost::shared_ptr<DataAbstract> m_data;    boost::shared_ptr<DataAbstract> m_data;
1069    
1070      //
1071      // pointer to the internal profiling data
1072      struct profDataEntry *profData;
1073    
1074  };  };
1075    
1076  template <class IValueType>  template <class IValueType>
# Line 730  Data::initialise(const IValueType& value Line 1086  Data::initialise(const IValueType& value
1086    // within the shared_ptr constructor.    // within the shared_ptr constructor.
1087    if (expanded) {    if (expanded) {
1088      DataAbstract* temp=new DataExpanded(value,what);      DataAbstract* temp=new DataExpanded(value,what);
1089      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1090        m_data=temp_data;
1091    } else {    } else {
1092      DataAbstract* temp=new DataConstant(value,what);      DataAbstract* temp=new DataConstant(value,what);
1093      m_data=boost::shared_ptr<DataAbstract>(temp);      boost::shared_ptr<DataAbstract> temp_data(temp);
1094        m_data=temp_data;
1095    }    }
1096  }  }
1097    
1098  inline  /**
1099  DataAbstract::ValueType::value_type*     Binary Data object operators.
1100  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();  
 }  
1101    
1102  /**  /**
1103    \brief    \brief
# Line 876  std::ostream& operator<<(std::ostream& o Line 1203  std::ostream& operator<<(std::ostream& o
1203    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
1204    be relied on. Requires further implementation.    be relied on. Requires further implementation.
1205  */  */
1206  bool operator==(const Data& left, const Data& right);  //bool operator==(const Data& left, const Data& right);
1207    
1208    /**
1209      \brief
1210      Perform the given binary operation with this and right as operands.
1211      Right is a Data object.
1212    */
1213  template <class BinaryFunction>  template <class BinaryFunction>
1214  inline  inline
1215  void  void
# Line 907  Data::binaryOp(const Data& right, Line 1239  Data::binaryOp(const Data& right,
1239     operandCheck(tempRight);     operandCheck(tempRight);
1240     //     //
1241     // ensure this has the right type for the RHS     // ensure this has the right type for the RHS
1242     typeMatch(tempRight);     typeMatchRight(tempRight);
1243     //     //
1244     // Need to cast to the concrete types so that the correct binaryOp     // Need to cast to the concrete types so that the correct binaryOp
1245     // is called.     // is called.
# Line 933  Data::binaryOp(const Data& right, Line 1265  Data::binaryOp(const Data& right,
1265         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");         EsysAssert((rightC!=0), "Programming error - casting to DataConstant.");
1266         escript::binaryOp(*leftC,*rightC,operation);         escript::binaryOp(*leftC,*rightC,operation);
1267       }       }
1268     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1269       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1270       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());       DataConstant* rightC=dynamic_cast<DataConstant*>(tempRight.m_data.get());
1271       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 1273  Data::binaryOp(const Data& right,
1273     }     }
1274  }  }
1275    
1276    /**
1277      \brief
1278      Perform the given binary operation with this and right as operands.
1279      Right is a boost::python object.
1280    */
1281  template <class BinaryFunction>  template <class BinaryFunction>
1282  inline  inline
1283  void  void
# Line 963  Data::binaryOp(const boost::python::obje Line 1298  Data::binaryOp(const boost::python::obje
1298                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));                    "Error - RHS shape doesn't match LHS shape.",temp.getView().getShape()));
1299       }       }
1300     }     }
   
1301     if (isExpanded()) {     if (isExpanded()) {
      //  
      // Expanded data will be done in parallel  
1302       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());       DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1303       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");       EsysAssert((leftC!=0),"Programming error - casting to DataExpanded.");
1304       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
# Line 974  Data::binaryOp(const boost::python::obje Line 1306  Data::binaryOp(const boost::python::obje
1306       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());       DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1307       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");       EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1308       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1309     } else {     } else if (isConstant()) {
      //  
      // can only be DataConstant  
1310       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());       DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1311       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");       EsysAssert((leftC!=0),"Programming error - casting to DataConstant.");
1312       escript::binaryOp(*leftC,temp.getView(),operation);       escript::binaryOp(*leftC,temp.getView(),operation);
1313     }     }
1314  }  }
1315    
1316    /**
1317      \brief
1318      Perform the given unary operation on other and return the result.
1319      Given operation is performed on each element of each data point, thus
1320      argument object is a rank n Data object, and returned object is a rank n
1321      Data object.
1322      Calls Data::unaryOp.
1323    */
1324    template <class UnaryFunction>
1325    inline
1326    Data
1327    unaryOp(const Data& other,
1328            UnaryFunction operation)
1329    {
1330      Data result;
1331      result.copy(other);
1332      result.unaryOp(operation);
1333      return result;
1334    }
1335    
1336    /**
1337      \brief
1338      Perform the given unary operation on this.
1339      Given operation is performed on each element of each data point.
1340      Calls escript::unaryOp.
1341    */
1342  template <class UnaryFunction>  template <class UnaryFunction>
1343  inline  inline
1344  void  void
1345  Data::unaryOp(UnaryFunction operation)  Data::unaryOp(UnaryFunction operation)
1346  {  {
1347    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1348      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1349      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1350      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
# Line 998  Data::unaryOp(UnaryFunction operation) Line 1352  Data::unaryOp(UnaryFunction operation)
1352      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1353      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1354      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1355    } else {    } else if (isConstant()) {
1356      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1357      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1358      escript::unaryOp(*leftC,operation);      escript::unaryOp(*leftC,operation);
1359    }    }
1360  }  }
1361    
1362  template <class UnaryFunction>  /**
1363      \brief
1364      Perform the given Data object reduction algorithm on this and return the result.
1365      Given operation combines each element of each data point, thus argument
1366      object (*this) is a rank n Data object, and returned object is a scalar.
1367      Calls escript::algorithm.
1368    */
1369    template <class BinaryFunction>
1370  inline  inline
1371  double  double
1372  Data::algorithm(UnaryFunction operation) const  Data::algorithm(BinaryFunction operation, double initial_value) const
1373  {  {
1374    if (isExpanded()) {    if (isExpanded()) {
     //  
     // Expanded data will be done in parallel  
1375      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* leftC=dynamic_cast<DataExpanded*>(m_data.get());
1376      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");      EsysAssert((leftC!=0), "Programming error - casting to DataExpanded.");
1377      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1378    }    } else if (isTagged()) {
   else if (isTagged()) {  
1379      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* leftC=dynamic_cast<DataTagged*>(m_data.get());
1380      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");      EsysAssert((leftC!=0), "Programming error - casting to DataTagged.");
1381      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1382    } else {    } else if (isConstant()) {
1383      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1384      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1385      return escript::algorithm(*leftC,operation);      return escript::algorithm(*leftC,operation,initial_value);
1386    }    }
1387      return 0;
1388  }  }
1389    
1390  template <class UnaryFunction>  /**
1391      \brief
1392      Perform the given data point reduction algorithm on data and return the result.
1393      Given operation combines each element within each data point into a scalar,
1394      thus argument object is a rank n Data object, and returned object is a
1395      rank 0 Data object.
1396      Calls escript::dp_algorithm.
1397    */
1398    template <class BinaryFunction>
1399  inline  inline
1400  Data  Data
1401  unaryOp(const Data& other,  Data::dp_algorithm(BinaryFunction operation, double initial_value) const
         UnaryFunction operation)  
1402  {  {
1403    //    Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());
1404    // Perform the given operation on a copy of the input data and return the result    if (isExpanded()) {
1405    Data result;      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1406    //      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1407    // perform a deep copy      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1408    result.copy(other);      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1409    result.unaryOp(operation);      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1410      } else if (isTagged()) {
1411        DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
1412        DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());
1413        EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1414        EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");
1415        escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1416      } else if (isConstant()) {
1417        DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1418        DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1419        EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
1420        EsysAssert((resultC!=0), "Programming error - casting result to DataConstant.");
1421        escript::dp_algorithm(*dataC,*resultC,operation,initial_value);
1422      }
1423    return result;    return result;
1424  }  }
1425    
1426  }  }
   
1427  #endif  #endif

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

  ViewVC Help
Powered by ViewVC 1.1.26