/[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

temp/escript/src/Data.h revision 1387 by trankine, Fri Jan 11 07:45:26 2008 UTC trunk/escript/src/Data.h revision 1952 by jfenwick, Thu Oct 30 06:16:00 2008 UTC
# Line 1  Line 1 
1    
 /* $Id$ */  
   
2  /*******************************************************  /*******************************************************
3   *  *
4   *           Copyright 2003-2007 by ACceSS MNRF  * Copyright (c) 2003-2008 by University of Queensland
5   *       Copyright 2007 by University of Queensland  * Earth Systems Science Computational Center (ESSCC)
6   *  * http://www.uq.edu.au/esscc
7   *                http://esscc.uq.edu.au  *
8   *        Primary Business: Queensland, Australia  * Primary Business: Queensland, Australia
9   *  Licensed under the Open Software License version 3.0  * Licensed under the Open Software License version 3.0
10   *     http://www.opensource.org/licenses/osl-3.0.php  * http://www.opensource.org/licenses/osl-3.0.php
11   *  *
12   *******************************************************/  *******************************************************/
13    
14    
15  /** \file Data.h */  /** \file Data.h */
16    
# Line 25  Line 24 
24  #include "BinaryOp.h"  #include "BinaryOp.h"
25  #include "UnaryOp.h"  #include "UnaryOp.h"
26  #include "DataException.h"  #include "DataException.h"
27    #include "DataTypes.h"
28    
29  extern "C" {  extern "C" {
30  #include "DataC.h"  #include "DataC.h"
# Line 34  extern "C" { Line 34  extern "C" {
34  #include "esysmpi.h"  #include "esysmpi.h"
35  #include <string>  #include <string>
36  #include <algorithm>  #include <algorithm>
37    #include <sstream>
38    
39    
40  #include <boost/shared_ptr.hpp>  #include <boost/shared_ptr.hpp>
41  #include <boost/python/object.hpp>  #include <boost/python/object.hpp>
# Line 50  class DataExpanded; Line 52  class DataExpanded;
52    
53  /**  /**
54     \brief     \brief
55     Data creates the appropriate Data object for the given construction     Data represents a collection of datapoints.
    arguments.  
56    
57     Description:     Description:
58     Data is essentially a factory class which creates the appropriate Data     Internally, the datapoints are actually stored by a DataAbstract object.
59     object for the given construction arguments. It retains control over     The specific instance of DataAbstract used may vary over the lifetime
60     the object created for the lifetime of the object.     of the Data object.
61     The type of Data object referred to may change during the lifetime of     Some methods on this class return references (eg getShape()).
62     the Data object.     These references should not be used after an operation which changes the underlying DataAbstract object.
63       Doing so will lead to invalid memory access.
64       This should not affect any methods exposed via boost::python.
65  */  */
66  class Data {  class Data {
67    
# Line 101  class Data { Line 104  class Data {
104         const FunctionSpace& what);         const FunctionSpace& what);
105    
106    /**    /**
107       \brief      \brief Copy Data from an existing vector
108       Constructor which copies data from a DataArrayView.    */
109    
      \param value - Input - Data value for a single point.  
      \param what - Input - A description of what this data represents.  
      \param expanded - Input - Flag, if true fill the entire container with  
                        the value. Otherwise a more efficient storage  
                        mechanism will be used.  
   */  
110    ESCRIPT_DLL_API    ESCRIPT_DLL_API
111    Data(const DataArrayView& value,    Data(const DataTypes::ValueType& value,
112         const FunctionSpace& what=FunctionSpace(),           const DataTypes::ShapeType& shape,
113         bool expanded=false);                   const FunctionSpace& what=FunctionSpace(),
114                     bool expanded=false);
115    
116    /**    /**
117       \brief       \brief
# Line 128  class Data { Line 126  class Data {
126    */    */
127    ESCRIPT_DLL_API    ESCRIPT_DLL_API
128    Data(double value,    Data(double value,
129         const DataArrayView::ShapeType& dataPointShape=DataArrayView::ShapeType(),         const DataTypes::ShapeType& dataPointShape=DataTypes::ShapeType(),
130         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
131         bool expanded=false);         bool expanded=false);
132    
# Line 141  class Data { Line 139  class Data {
139    */    */
140    ESCRIPT_DLL_API    ESCRIPT_DLL_API
141    Data(const Data& inData,    Data(const Data& inData,
142         const DataArrayView::RegionType& region);         const DataTypes::RegionType& region);
   
   /**  
      \brief  
      Constructor which will create Tagged data if expanded is false.  
      No attempt is made to ensure the tag keys match the tag keys  
      within the function space.  
   
      \param tagKeys - Input - List of tag values.  
      \param values - Input - List of values, one for each tag.  
      \param defaultValue - Input - A default value, used if tag doesn't exist.  
      \param what - Input - A description of what this data represents.  
      \param expanded - Input - Flag, if true fill the entire container with  
                        the appropriate values.  
     ==>*  
   */  
   ESCRIPT_DLL_API  
   Data(const DataTagged::TagListType& tagKeys,  
        const DataTagged::ValueListType& values,  
        const DataArrayView& defaultValue,  
        const FunctionSpace& what=FunctionSpace(),  
        bool expanded=false);  
143    
144    /**    /**
145       \brief       \brief
# Line 217  class Data { Line 194  class Data {
194         const boost::python::tuple& shape=boost::python::make_tuple(),         const boost::python::tuple& shape=boost::python::make_tuple(),
195         const FunctionSpace& what=FunctionSpace(),         const FunctionSpace& what=FunctionSpace(),
196         bool expanded=false);         bool expanded=false);
197    
198    
199    
200      /**
201        \brief Create a Data using an existing DataAbstract. Warning: The new object assumes ownership of the pointer!
202        Once you have passed the pointer, do not delete it.
203      */
204      ESCRIPT_DLL_API
205      Data(DataAbstract* underlyingdata);
206    
207    
208    /**    /**
209       \brief       \brief
210       Destructor       Destructor
# Line 225  class Data { Line 213  class Data {
213    ~Data();    ~Data();
214    
215    /**    /**
216       \brief       \brief Make this object a deep copy of "other".
      Perform a deep copy.  
217    */    */
218    ESCRIPT_DLL_API    ESCRIPT_DLL_API
219    void    void
220    copy(const Data& other);    copy(const Data& other);
221    
222    /**    /**
223         \brief Return a pointer to a deep copy of this object.
224      */
225      ESCRIPT_DLL_API
226      Data*
227      copySelf();
228    
229    
230    
231    
232      /**
233       Member access methods.       Member access methods.
234    */    */
235    
# Line 298  class Data { Line 295  class Data {
295       \brief       \brief
296       Return the tag number associated with the given data-point.       Return the tag number associated with the given data-point.
297    
      The data-point number here corresponds to the data-point number in the  
      numarray returned by convertToNumArray.  
298    */    */
299    ESCRIPT_DLL_API    ESCRIPT_DLL_API
300    int    int
# Line 313  class Data { Line 308  class Data {
308    escriptDataC    escriptDataC
309    getDataC();    getDataC();
310    
311    
312    
313    
314    
315    
316    // REMOVE ME
317    // ESCRIPT_DLL_API
318    // void
319    // CompareDebug(const Data& rd);
320    
321    
322    /**    /**
323       \brief       \brief
324       Return the C wrapper for the Data object - const version.       Return the C wrapper for the Data object - const version.
# Line 323  class Data { Line 329  class Data {
329    
330    /**    /**
331       \brief       \brief
332       Write the data as a string.       Write the data as a string. For large amounts of data, a summary is printed.
333    */    */
334    ESCRIPT_DLL_API    ESCRIPT_DLL_API
   inline  
335    std::string    std::string
336    toString() const    toString() const;
   {  
     return m_data->toString();  
   }  
337    
338    /**  
339       \brief  //  /**
340    /*     \brief
341       Return the DataArrayView of the point data. This essentially contains       Return the DataArrayView of the point data. This essentially contains
342       the shape information for each data point although it also may be used       the shape information for each data point although it also may be used
343       to manipulate the point data.       to manipulate the point data.*/
344    */  //  */
345    ESCRIPT_DLL_API  //   ESCRIPT_DLL_API
346    inline  //   inline
347    const DataArrayView&  //   const DataArrayView&
348    getPointDataView() const  //   getPointDataView() const
349    {  //   {
350       return m_data->getPointDataView();  //      return m_data->getPointDataView();
351    }  //   }
352    
353    /**    /**
354       \brief       \brief
# Line 392  class Data { Line 395  class Data {
395    
396    /**    /**
397       \brief       \brief
398       Return true if this Data is empty.       Return true if this Data holds an instance of DataEmpty. This is _not_ the same as asking if the object
399    contains datapoints.
400    */    */
401    ESCRIPT_DLL_API    ESCRIPT_DLL_API
402    bool    bool
# Line 424  class Data { Line 428  class Data {
428    */    */
429    ESCRIPT_DLL_API    ESCRIPT_DLL_API
430    inline    inline
431    const AbstractDomain&  //   const AbstractDomain&
432      const_Domain_ptr
433    getDomain() const    getDomain() const
434    {    {
435       return getFunctionSpace().getDomain();       return getFunctionSpace().getDomain();
436    }    }
437    
438    
439      /**
440         \brief
441         Return the domain.
442         TODO: For internal use only.   This should be removed.
443      */
444      ESCRIPT_DLL_API
445      inline
446    //   const AbstractDomain&
447      Domain_ptr
448      getDomainPython() const
449      {
450         return getFunctionSpace().getDomainPython();
451      }
452    
453    /**    /**
454       \brief       \brief
455       Return a copy of the domain.       Return a copy of the domain.
# Line 444  class Data { Line 464  class Data {
464    */    */
465    ESCRIPT_DLL_API    ESCRIPT_DLL_API
466    inline    inline
467    int    unsigned int
468    getDataPointRank() const    getDataPointRank() const
469    {    {
470      return m_data->getPointDataView().getRank();      return m_data->getRank();
471    }    }
472    
473    /**    /**
# Line 484  class Data { Line 504  class Data {
504    {    {
505      return m_data->getNumDPPSample();      return m_data->getNumDPPSample();
506    }    }
507    
508    
509      /**
510        \brief
511        Return the number of values in the shape for this object.
512      */
513      ESCRIPT_DLL_API
514      int
515      getNoValues() const
516      {
517        return m_data->getNoValues();
518      }
519    
520    
521    /**    /**
522       \brief       \brief
523       dumps the object into a netCDF file       dumps the object into a netCDF file
# Line 519  class Data { Line 553  class Data {
553      return m_data->getSampleDataByTag(tag);      return m_data->getSampleDataByTag(tag);
554    }    }
555    
556    //  /**
557    /*     \brief
558         Return a view into the data for the data point specified.
559         NOTE: Construction of the DataArrayView is a relatively expensive
560         operation.
561         \param sampleNo - Input -
562         \param dataPointNo - Input -*/
563    //  */
564    //   ESCRIPT_DLL_API
565    //   inline
566    //   DataArrayView
567    //   getDataPoint(int sampleNo,
568    //                int dataPointNo)
569    //   {
570    //                 return m_data->getDataPoint(sampleNo,dataPointNo);
571    //   }
572    
573    
574    /**    /**
575       \brief       \brief
576       Return a view into the data for the data point specified.       Return a view into the data for the data point specified.
# Line 528  class Data { Line 580  class Data {
580       \param dataPointNo - Input -       \param dataPointNo - Input -
581    */    */
582    ESCRIPT_DLL_API    ESCRIPT_DLL_API
583      DataTypes::ValueType::const_reference
584      getDataPoint(int sampleNo, int dataPointNo) const;
585    
586    
587      ESCRIPT_DLL_API
588      DataTypes::ValueType::reference
589      getDataPoint(int sampleNo, int dataPointNo);
590    
591    
592    
593      /**
594         \brief
595         Return the offset for the given sample and point within the sample
596      */
597      ESCRIPT_DLL_API
598    inline    inline
599    DataArrayView    DataTypes::ValueType::size_type
600    getDataPoint(int sampleNo,    getDataOffset(int sampleNo,
601                 int dataPointNo)                 int dataPointNo)
602    {    {
603                  return m_data->getDataPoint(sampleNo,dataPointNo);                  return m_data->getPointOffset(sampleNo,dataPointNo);
604    }    }
605    
606    /**    /**
# Line 541  class Data { Line 608  class Data {
608       Return a reference to the data point shape.       Return a reference to the data point shape.
609    */    */
610    ESCRIPT_DLL_API    ESCRIPT_DLL_API
611    const DataArrayView::ShapeType&    inline
612    getDataPointShape() const;    const DataTypes::ShapeType&
613      getDataPointShape() const
614      {
615        return m_data->getShape();
616      }
617    
618    /**    /**
619       \brief       \brief
# Line 566  class Data { Line 637  class Data {
637       Return the number of doubles stored for this Data.       Return the number of doubles stored for this Data.
638    */    */
639    ESCRIPT_DLL_API    ESCRIPT_DLL_API
640    DataArrayView::ValueType::size_type    DataTypes::ValueType::size_type
641    getLength() const;    getLength() const;
642    
643    
# Line 599  class Data { Line 670  class Data {
670    setTaggedValue(int tagKey,    setTaggedValue(int tagKey,
671                   const boost::python::object& value);                   const boost::python::object& value);
672    
673    
674    //  /**
675    //     \brief
676    //     Assign the given value to the tag. Implicitly converts this
677    //     object to type DataTagged if it is constant.
678    //
679    //     \param tagKey - Input - Integer key.
680    //     \param value - Input - Value to associate with given key.
681    //    ==>*
682    //  */
683    //   ESCRIPT_DLL_API
684    //   void
685    //   setTaggedValueFromCPP(int tagKey,
686    //                         const DataArrayView& value);
687    
688    /**    /**
689       \brief       \brief
690       Assign the given value to the tag. Implicitly converts this       Assign the given value to the tag. Implicitly converts this
691       object to type DataTagged if it is constant.       object to type DataTagged if it is constant.
692    
693       \param tagKey - Input - Integer key.       \param tagKey - Input - Integer key.
694         \param pointshape - Input - The shape of the value parameter
695       \param value - Input - Value to associate with given key.       \param value - Input - Value to associate with given key.
696      ==>*       \param dataOffset - Input - Offset of the begining of the point within the value parameter
697    */    */
698    ESCRIPT_DLL_API    ESCRIPT_DLL_API
699    void    void
700    setTaggedValueFromCPP(int tagKey,    setTaggedValueFromCPP(int tagKey,
701                          const DataArrayView& value);              const DataTypes::ShapeType& pointshape,
702                            const DataTypes::ValueType& value,
703                int dataOffset=0);
704    
705    
706    
707    /**    /**
708      \brief      \brief
# Line 732  class Data { Line 823  class Data {
823    /**    /**
824       \brief       \brief
825       Return the maximum absolute value of this Data object.       Return the maximum absolute value of this Data object.
826         For Data which contain no samples (or tagged Data for which no tags in use have a value)
827         zero is returned.
828       *       *
829    */    */
830    ESCRIPT_DLL_API    ESCRIPT_DLL_API
# Line 741  class Data { Line 834  class Data {
834    /**    /**
835       \brief       \brief
836       Return the maximum value of this Data object.       Return the maximum value of this Data object.
837       *       For Data which contain no samples (or tagged Data for which no tags in use have a value)
838         a large negative value is returned.
839    */    */
840    ESCRIPT_DLL_API    ESCRIPT_DLL_API
841    double    double
# Line 750  class Data { Line 844  class Data {
844    /**    /**
845       \brief       \brief
846       Return the minimum value of this Data object.       Return the minimum value of this Data object.
847         For Data which contain no samples (or tagged Data for which no tags in use have a value)
848         a large positive value is returned.
849       *       *
850    */    */
851    ESCRIPT_DLL_API    ESCRIPT_DLL_API
# Line 1212  class Data { Line 1308  class Data {
1308    */    */
1309    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1310    Data    Data
1311    getSlice(const DataArrayView::RegionType& region) const;    getSlice(const DataTypes::RegionType& region) const;
1312    
1313    /**    /**
1314       \brief       \brief
# Line 1225  class Data { Line 1321  class Data {
1321    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1322    void    void
1323    setSlice(const Data& value,    setSlice(const Data& value,
1324             const DataArrayView::RegionType& region);             const DataTypes::RegionType& region);
   
   /**  
      \brief  
      Archive the current Data object to the given file.  
      \param fileName - Input - file to archive to.  
   */  
   ESCRIPT_DLL_API  
   void  
   archiveData(const std::string fileName);  
   
   /**  
      \brief  
      Extract the Data object archived in the given file, overwriting  
      the current Data object.  
      Note - the current object must be of type DataEmpty.  
      \param fileName - Input - file to extract from.  
      \param fspace - Input - a suitable FunctionSpace descibing the data.  
   */  
   ESCRIPT_DLL_API  
   void  
   extractData(const std::string fileName,  
               const FunctionSpace& fspace);  
   
1325    
1326    /**    /**
1327       \brief       \brief
# Line 1290  class Data { Line 1363  class Data {
1363    /**    /**
1364       \brief       \brief
1365       return the object produced by the factory, which is a DataConstant or DataExpanded       return the object produced by the factory, which is a DataConstant or DataExpanded
1366        TODO Ownership of this object should be explained in doco.
1367    */    */
1368    ESCRIPT_DLL_API    ESCRIPT_DLL_API
1369          DataAbstract*          DataAbstract*
1370          borrowData(void) const;          borrowData(void) const;
1371    
1372    
1373      /**
1374         \brief
1375         Return a pointer to the beginning of the datapoint at the specified offset.
1376         TODO Eventually these should be inlined.
1377         \param i - position(offset) in the underlying datastructure
1378      */
1379      ESCRIPT_DLL_API
1380            DataTypes::ValueType::const_reference
1381            getDataAtOffset(DataTypes::ValueType::size_type i) const;
1382    
1383    
1384      ESCRIPT_DLL_API
1385            DataTypes::ValueType::reference
1386            getDataAtOffset(DataTypes::ValueType::size_type i);
1387    
1388   protected:   protected:
1389    
1390   private:   private:
# Line 1370  class Data { Line 1460  class Data {
1460       \brief       \brief
1461       Construct a Data object of the appropriate type.       Construct a Data object of the appropriate type.
1462    */    */
1463    template <class IValueType>  
1464    void    void
1465    initialise(const IValueType& value,    initialise(const DataTypes::ValueType& value,
1466             const DataTypes::ShapeType& shape,
1467               const FunctionSpace& what,               const FunctionSpace& what,
1468               bool expanded);               bool expanded);
1469    
1470      void
1471      initialise(const boost::python::numeric::array& value,
1472                     const FunctionSpace& what,
1473                     bool expanded);
1474    
1475    //    //
1476    // flag to protect the data object against any update    // flag to protect the data object against any update
1477    bool m_protected;    bool m_protected;
1478    
1479    //    //
1480    // pointer to the actual data object    // pointer to the actual data object
1481    boost::shared_ptr<DataAbstract> m_data;  //   boost::shared_ptr<DataAbstract> m_data;
1482      DataAbstract_ptr m_data;
1483    
1484  };  };
1485    
1486  template <class IValueType>  
1487  void  
1488  Data::initialise(const IValueType& value,  /**
1489                   const FunctionSpace& what,     Modify a filename for MPI parallel output to multiple files
1490                   bool expanded)  */
1491  {  char *Escript_MPI_appendRankToFileName(const char *, int, int);
   //  
   // Construct a Data object of the appropriate type.  
   // Construct the object first as there seems to be a bug which causes  
   // undefined behaviour if an exception is thrown during construction  
   // within the shared_ptr constructor.  
   if (expanded) {  
     DataAbstract* temp=new DataExpanded(value,what);  
     boost::shared_ptr<DataAbstract> temp_data(temp);  
     m_data=temp_data;  
   } else {  
     DataAbstract* temp=new DataConstant(value,what);  
     boost::shared_ptr<DataAbstract> temp_data(temp);  
     m_data=temp_data;  
   }  
 }  
1492    
1493  /**  /**
1494     Binary Data object operators.     Binary Data object operators.
# Line 1532  C_GeneralTensorProduct(Data& arg0, Line 1614  C_GeneralTensorProduct(Data& arg0,
1614                       int transpose=0);                       int transpose=0);
1615    
1616    
 /**  
   \brief  
   Compute a tensor operation with two Data objects  
   \param arg0 - Input - Data object  
   \param arg1 - Input - Data object  
   \param operation - Input - Binary op functor  
 */  
 template <typename BinaryFunction>  
 ESCRIPT_DLL_API  
 Data  
 C_TensorBinaryOperation(Data const &arg0,  
                         Data const &arg1,  
                         BinaryFunction operation);  
1617    
1618  /**  // /**
1619    \brief  /*  \brief
1620    Return true if operands are equivalent, else return false.    Return true if operands are equivalent, else return false.
1621    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
1622    be relied on. Requires further implementation.    be relied on. Requires further implementation.*/
1623  */  //*/
1624  // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);  // ESCRIPT_DLL_API bool operator==(const Data& left, const Data& right);
1625    
1626  /**  /**
# Line 1567  Data::binaryOp(const Data& right, Line 1636  Data::binaryOp(const Data& right,
1636  {  {
1637     //     //
1638     // if this has a rank of zero promote it to the rank of the RHS     // if this has a rank of zero promote it to the rank of the RHS
1639     if (getPointDataView().getRank()==0 && right.getPointDataView().getRank()!=0) {     if (getDataPointRank()==0 && right.getDataPointRank()!=0) {
1640       throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");       throw DataException("Error - attempt to update rank zero object with object with rank bigger than zero.");
1641     }     }
1642     //     //
# Line 1646  Data::algorithm(BinaryFunction operation Line 1715  Data::algorithm(BinaryFunction operation
1715      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* leftC=dynamic_cast<DataConstant*>(m_data.get());
1716      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");      EsysAssert((leftC!=0), "Programming error - casting to DataConstant.");
1717      return escript::algorithm(*leftC,operation,initial_value);      return escript::algorithm(*leftC,operation,initial_value);
1718      } else if (isEmpty()) {
1719        throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1720    }    }
1721    return 0;    return 0;
1722  }  }
# Line 1663  inline Line 1734  inline
1734  Data  Data
1735  Data::dp_algorithm(BinaryFunction operation, double initial_value) const  Data::dp_algorithm(BinaryFunction operation, double initial_value) const
1736  {  {
1737    if (isExpanded()) {    if (isEmpty()) {
1738      Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());      throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1739      }
1740      else if (isExpanded()) {
1741        Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1742      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());      DataExpanded* dataE=dynamic_cast<DataExpanded*>(m_data.get());
1743      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());      DataExpanded* resultE=dynamic_cast<DataExpanded*>(result.m_data.get());
1744      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");      EsysAssert((dataE!=0), "Programming error - casting data to DataExpanded.");
1745      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");      EsysAssert((resultE!=0), "Programming error - casting result to DataExpanded.");
1746      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);      escript::dp_algorithm(*dataE,*resultE,operation,initial_value);
1747      return result;      return result;
1748    } else if (isTagged()) {    }
1749      else if (isTagged()) {
1750      DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());      DataTagged* dataT=dynamic_cast<DataTagged*>(m_data.get());
     DataArrayView::ShapeType viewShape;  
     DataArrayView::ValueType viewData(1);  
     viewData[0]=0;  
     DataArrayView defaultValue(viewData,viewShape);  
     DataTagged::TagListType keys;  
     DataTagged::ValueListType values;  
     DataTagged::DataMapType::const_iterator i;  
     for (i=dataT->getTagLookup().begin();i!=dataT->getTagLookup().end();i++) {  
       keys.push_back(i->first);  
       values.push_back(defaultValue);  
     }  
     Data result(keys,values,defaultValue,getFunctionSpace());  
     DataTagged* resultT=dynamic_cast<DataTagged*>(result.m_data.get());  
1751      EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");      EsysAssert((dataT!=0), "Programming error - casting data to DataTagged.");
1752      EsysAssert((resultT!=0), "Programming error - casting result to DataTagged.");      DataTypes::ValueType defval(1);
1753        defval[0]=0;
1754        DataTagged* resultT=new DataTagged(getFunctionSpace(), DataTypes::scalarShape, defval, dataT);
1755      escript::dp_algorithm(*dataT,*resultT,operation,initial_value);      escript::dp_algorithm(*dataT,*resultT,operation,initial_value);
1756      return result;      return Data(resultT);   // note: the Data object now owns the resultT pointer
1757    } else if (isConstant()) {    }
1758      Data result(0,DataArrayView::ShapeType(),getFunctionSpace(),isExpanded());    else if (isConstant()) {
1759        Data result(0,DataTypes::ShapeType(),getFunctionSpace(),isExpanded());
1760      DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());      DataConstant* dataC=dynamic_cast<DataConstant*>(m_data.get());
1761      DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());      DataConstant* resultC=dynamic_cast<DataConstant*>(result.m_data.get());
1762      EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");      EsysAssert((dataC!=0), "Programming error - casting data to DataConstant.");
# Line 1703  Data::dp_algorithm(BinaryFunction operat Line 1768  Data::dp_algorithm(BinaryFunction operat
1768    return falseRetVal;    return falseRetVal;
1769  }  }
1770    
1771    /**
1772      \brief
1773      Compute a tensor operation with two Data objects
1774      \param arg0 - Input - Data object
1775      \param arg1 - Input - Data object
1776      \param operation - Input - Binary op functor
1777    */
1778  template <typename BinaryFunction>  template <typename BinaryFunction>
1779    inline
1780  Data  Data
1781  C_TensorBinaryOperation(Data const &arg_0,  C_TensorBinaryOperation(Data const &arg_0,
1782                          Data const &arg_1,                          Data const &arg_1,
1783                          BinaryFunction operation)                          BinaryFunction operation)
1784  {  {
1785      if (arg_0.isEmpty() || arg_1.isEmpty())
1786      {
1787         throw DataException("Error - Operations not permitted on instances of DataEmpty.");
1788      }
1789    // Interpolate if necessary and find an appropriate function space    // Interpolate if necessary and find an appropriate function space
1790    Data arg_0_Z, arg_1_Z;    Data arg_0_Z, arg_1_Z;
1791    if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {    if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) {
# Line 1730  C_TensorBinaryOperation(Data const &arg_ Line 1807  C_TensorBinaryOperation(Data const &arg_
1807    // Get rank and shape of inputs    // Get rank and shape of inputs
1808    int rank0 = arg_0_Z.getDataPointRank();    int rank0 = arg_0_Z.getDataPointRank();
1809    int rank1 = arg_1_Z.getDataPointRank();    int rank1 = arg_1_Z.getDataPointRank();
1810    DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();    DataTypes::ShapeType shape0 = arg_0_Z.getDataPointShape();
1811    DataArrayView::ShapeType shape1 = arg_1_Z.getDataPointShape();    DataTypes::ShapeType shape1 = arg_1_Z.getDataPointShape();
1812    int size0 = arg_0_Z.getDataPointSize();    int size0 = arg_0_Z.getDataPointSize();
1813    int size1 = arg_1_Z.getDataPointSize();    int size1 = arg_1_Z.getDataPointSize();
1814    
# Line 1742  C_TensorBinaryOperation(Data const &arg_ Line 1819  C_TensorBinaryOperation(Data const &arg_
1819    
1820      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
1821        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
1822        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);  /*      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
1823        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);
1824        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &((res.getPointDataView().getData())[0]);*/
1825          double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
1826          double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
1827          double *ptr_2 = &(res.getDataAtOffset(0));
1828    
1829        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1830      }      }
1831      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 1762  C_TensorBinaryOperation(Data const &arg_ Line 1843  C_TensorBinaryOperation(Data const &arg_
1843    
1844        // Prepare offset into DataConstant        // Prepare offset into DataConstant
1845        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
1846        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1847        // Get the views        // Get the views
1848        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
1849        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1850    //       // Get the pointers to the actual data
1851    //       double *ptr_1 = &((view_1.getData())[0]);
1852    //       double *ptr_2 = &((view_2.getData())[0]);
1853    
1854        // Get the pointers to the actual data        // Get the pointers to the actual data
1855        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
1856        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1857    
1858        // Compute a result for the default        // Compute a result for the default
1859        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1860        // Compute a result for each tag        // Compute a result for each tag
1861        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1862        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1863        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1864          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1865          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  /*        DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1866          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1867          double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
1868          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
1869            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1870            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1871    
1872          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1873        }        }
1874    
# Line 1800  C_TensorBinaryOperation(Data const &arg_ Line 1889  C_TensorBinaryOperation(Data const &arg_
1889          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
1890            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
1891            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
1892            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);  //           double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
1893            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1894            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
1895    
1896              double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
1897              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1898              double *ptr_2 = &(res.getDataAtOffset(offset_2));
1899            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1900          }          }
1901        }        }
# Line 1823  C_TensorBinaryOperation(Data const &arg_ Line 1916  C_TensorBinaryOperation(Data const &arg_
1916    
1917        // Prepare offset into DataConstant        // Prepare offset into DataConstant
1918        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
1919        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //       double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
1920          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
1921        // Get the views        // Get the views
1922        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
1923        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1924    //       // Get the pointers to the actual data
1925    //       double *ptr_0 = &((view_0.getData())[0]);
1926    //       double *ptr_2 = &((view_2.getData())[0]);
1927        // Get the pointers to the actual data        // Get the pointers to the actual data
1928        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
1929        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1930        // Compute a result for the default        // Compute a result for the default
1931        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1932        // Compute a result for each tag        // Compute a result for each tag
1933        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1934        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
1935        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1936          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1937          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1938          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1939          double *ptr_0 = &view_0.getData(0);  //         double *ptr_0 = &view_0.getData(0);
1940          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
1941            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1942            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
1943          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1944        }        }
1945    
# Line 1858  C_TensorBinaryOperation(Data const &arg_ Line 1957  C_TensorBinaryOperation(Data const &arg_
1957        res.tag();        // DataTagged output        res.tag();        // DataTagged output
1958        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
1959    
1960        // Get the views  //       // Get the views
1961        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
1962        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
1963        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
1964    //       // Get the pointers to the actual data
1965    //       double *ptr_0 = &((view_0.getData())[0]);
1966    //       double *ptr_1 = &((view_1.getData())[0]);
1967    //       double *ptr_2 = &((view_2.getData())[0]);
1968    
1969        // Get the pointers to the actual data        // Get the pointers to the actual data
1970        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
1971        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
1972        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
1973    
1974        // Compute a result for the default        // Compute a result for the default
1975        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
1976        // Merge the tags        // Merge the tags
# Line 1873  C_TensorBinaryOperation(Data const &arg_ Line 1978  C_TensorBinaryOperation(Data const &arg_
1978        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
1979        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
1980        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
1981          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
1982        }        }
1983        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
1984          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
1985        }        }
1986        // Compute a result for each tag        // Compute a result for each tag
1987        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
1988        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
1989          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  
1990          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
1991          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
1992          double *ptr_0 = &view_0.getData(0);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
1993          double *ptr_1 = &view_1.getData(0);  //         double *ptr_0 = &view_0.getData(0);
1994          double *ptr_2 = &view_2.getData(0);  //         double *ptr_1 = &view_1.getData(0);
1995    //         double *ptr_2 = &view_2.getData(0);
1996    
1997            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
1998            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
1999            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2000    
2001          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2002        }        }
2003    
# Line 1905  C_TensorBinaryOperation(Data const &arg_ Line 2016  C_TensorBinaryOperation(Data const &arg_
2016        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2017        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2018          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2019          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2020          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2021            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2022            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2023            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  
2024            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2025    //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2026              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2027              double *ptr_2 = &(res.getDataAtOffset(offset_2));
2028    
2029    
2030            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2031          }          }
2032        }        }
# Line 1932  C_TensorBinaryOperation(Data const &arg_ Line 2048  C_TensorBinaryOperation(Data const &arg_
2048          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2049            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2050            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2051            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);  
2052            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //           double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2053            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);  //           double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2054    //           double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2055    
2056              double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2057              double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2058              double *ptr_2 = &(res.getDataAtOffset(offset_2));
2059    
2060    
2061            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2062          }          }
2063        }        }
# Line 1954  C_TensorBinaryOperation(Data const &arg_ Line 2077  C_TensorBinaryOperation(Data const &arg_
2077        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2078        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2079          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2080          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2081          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2082            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2083            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2084            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2085            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2086            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2087          }          }
2088        }        }
# Line 1982  C_TensorBinaryOperation(Data const &arg_ Line 2105  C_TensorBinaryOperation(Data const &arg_
2105            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2106            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2107            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2108            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2109            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2110            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2111            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1, ptr_2, operation);
2112          }          }
2113        }        }
# Line 1998  C_TensorBinaryOperation(Data const &arg_ Line 2121  C_TensorBinaryOperation(Data const &arg_
2121    
2122      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2123        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape1, arg_1_Z.getFunctionSpace());      // DataConstant output
2124        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2125        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2126        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &(res.getDataAtOffset(0));
2127        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2128      }      }
2129      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 2018  C_TensorBinaryOperation(Data const &arg_ Line 2141  C_TensorBinaryOperation(Data const &arg_
2141    
2142        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2143        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2144        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2145        // Get the views        // Get the views
2146        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
2147        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2148        // Get the pointers to the actual data  //       // Get the pointers to the actual data
2149        double *ptr_1 = &((view_1.getData())[0]);  //       double *ptr_1 = &((view_1.getData())[0]);
2150        double *ptr_2 = &((view_2.getData())[0]);  //       double *ptr_2 = &((view_2.getData())[0]);
2151           double *ptr_1 = &(tmp_1->getDefaultValue(0));
2152           double *ptr_2 = &(tmp_2->getDefaultValue(0));
2153    
2154        // Compute a result for the default        // Compute a result for the default
2155        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2156        // Compute a result for each tag        // Compute a result for each tag
2157        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2158        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2159        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2160          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2161          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2162          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2163          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2164          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2165            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2166            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2167          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2168        }        }
2169    
# Line 2056  C_TensorBinaryOperation(Data const &arg_ Line 2184  C_TensorBinaryOperation(Data const &arg_
2184          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2185            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2186            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2187            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2188            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2189            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2190            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2191    
2192          }          }
# Line 2080  C_TensorBinaryOperation(Data const &arg_ Line 2208  C_TensorBinaryOperation(Data const &arg_
2208    
2209        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2210        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2211        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);  //       double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);
2212          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2213        // Get the views        // Get the views
2214        DataArrayView view_0 = tmp_0->getDefaultValue();  /*      DataArrayView view_0 = tmp_0->getDefaultValue();
2215        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2216        // Get the pointers to the actual data        // Get the pointers to the actual data
2217        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &((view_0.getData())[0]);
2218        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2219    
2220          // Get the pointers to the actual data
2221          double *ptr_0 = &(tmp_0->getDefaultValue(0));
2222          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2223    
2224    
2225        // Compute a result for the default        // Compute a result for the default
2226        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2227        // Compute a result for each tag        // Compute a result for each tag
2228        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2229        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2230        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2231          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2232          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2233          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2234          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2235          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2236            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2237            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2238    
2239          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2240        }        }
2241    
# Line 2116  C_TensorBinaryOperation(Data const &arg_ Line 2254  C_TensorBinaryOperation(Data const &arg_
2254        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2255    
2256        // Get the views        // Get the views
2257        DataArrayView view_0 = tmp_0->getDefaultValue();  /*      DataArrayView view_0 = tmp_0->getDefaultValue();
2258        DataArrayView view_1 = tmp_1->getDefaultValue();        DataArrayView view_1 = tmp_1->getDefaultValue();
2259        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2260        // Get the pointers to the actual data        // Get the pointers to the actual data
2261        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &((view_0.getData())[0]);
2262        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &((view_1.getData())[0]);
2263        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2264    
2265          // Get the pointers to the actual data
2266          double *ptr_0 = &(tmp_0->getDefaultValue(0));
2267          double *ptr_1 = &(tmp_1->getDefaultValue(0));
2268          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2269    
2270    
2271        // Compute a result for the default        // Compute a result for the default
2272        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);        tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2273        // Merge the tags        // Merge the tags
# Line 2130  C_TensorBinaryOperation(Data const &arg_ Line 2275  C_TensorBinaryOperation(Data const &arg_
2275        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2276        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2277        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2278          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2279        }        }
2280        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2281          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2282        }        }
2283        // Compute a result for each tag        // Compute a result for each tag
2284        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2285        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2286          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  
2287    /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2288          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2289          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2290          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2291          double *ptr_1 = &view_1.getData(0);          double *ptr_1 = &view_1.getData(0);
2292          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2293    
2294            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2295            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2296            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2297    
2298          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);          tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2299        }        }
2300    
# Line 2162  C_TensorBinaryOperation(Data const &arg_ Line 2313  C_TensorBinaryOperation(Data const &arg_
2313        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2314        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2315          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2316          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2317          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2318            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2319            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2320            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2321            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2322            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2323          }          }
2324        }        }
# Line 2189  C_TensorBinaryOperation(Data const &arg_ Line 2340  C_TensorBinaryOperation(Data const &arg_
2340          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2341            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2342            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2343            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2344            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2345            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2346            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2347          }          }
2348        }        }
# Line 2212  C_TensorBinaryOperation(Data const &arg_ Line 2363  C_TensorBinaryOperation(Data const &arg_
2363        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2364        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2365          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2366          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2367          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2368            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2369            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2370            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2371            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2372            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2373          }          }
2374        }        }
# Line 2240  C_TensorBinaryOperation(Data const &arg_ Line 2391  C_TensorBinaryOperation(Data const &arg_
2391            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2392            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2393            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2394            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2395            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2396            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2397            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);            tensor_binary_operation(size1, ptr_0[0], ptr_1, ptr_2, operation);
2398          }          }
2399        }        }
# Line 2256  C_TensorBinaryOperation(Data const &arg_ Line 2407  C_TensorBinaryOperation(Data const &arg_
2407    
2408      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {      if (arg_0_Z.isConstant()   && arg_1_Z.isConstant()) {
2409        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output        res = Data(0.0, shape0, arg_1_Z.getFunctionSpace());      // DataConstant output
2410        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2411        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[0]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(0));
2412        double *ptr_2 = &((res.getPointDataView().getData())[0]);        double *ptr_2 = &(res.getDataAtOffset(0));
2413        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2414      }      }
2415      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {      else if (arg_0_Z.isConstant()   && arg_1_Z.isTagged()) {
# Line 2276  C_TensorBinaryOperation(Data const &arg_ Line 2427  C_TensorBinaryOperation(Data const &arg_
2427    
2428        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2429        int offset_0 = tmp_0->getPointOffset(0,0);        int offset_0 = tmp_0->getPointOffset(0,0);
2430        double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);        double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2431        // Get the views        // Get the views
2432        DataArrayView view_1 = tmp_1->getDefaultValue();  /*      DataArrayView view_1 = tmp_1->getDefaultValue();
2433        DataArrayView view_2 = tmp_2->getDefaultValue();        DataArrayView view_2 = tmp_2->getDefaultValue();
2434        // Get the pointers to the actual data        // Get the pointers to the actual data
2435        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &((view_1.getData())[0]);
2436        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &((view_2.getData())[0]);*/
2437          //Get the pointers to the actual data
2438          double *ptr_1 = &(tmp_1->getDefaultValue(0));
2439          double *ptr_2 = &(tmp_2->getDefaultValue(0));
2440    
2441        // Compute a result for the default        // Compute a result for the default
2442        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2443        // Compute a result for each tag        // Compute a result for each tag
2444        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2445        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2446        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2447          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2448          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2449          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2450          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2451          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2452            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2453            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2454    
2455    
2456          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2457        }        }
2458    
# Line 2314  C_TensorBinaryOperation(Data const &arg_ Line 2473  C_TensorBinaryOperation(Data const &arg_
2473          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {          for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) {
2474            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1);
2475            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);            int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1);
2476            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2477            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2478            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2479            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2480          }          }
2481        }        }
# Line 2337  C_TensorBinaryOperation(Data const &arg_ Line 2496  C_TensorBinaryOperation(Data const &arg_
2496    
2497        // Prepare offset into DataConstant        // Prepare offset into DataConstant
2498        int offset_1 = tmp_1->getPointOffset(0,0);        int offset_1 = tmp_1->getPointOffset(0,0);
2499        double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);        double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2500        // Get the views        // Get the views
2501        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
2502        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2503    //       // Get the pointers to the actual data
2504    //       double *ptr_0 = &((view_0.getData())[0]);
2505    //       double *ptr_2 = &((view_2.getData())[0]);
2506        // Get the pointers to the actual data        // Get the pointers to the actual data
2507        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
2508        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
2509        // Compute a result for the default        // Compute a result for the default
2510        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2511        // Compute a result for each tag        // Compute a result for each tag
2512        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2513        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory        DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2514        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2515          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2516          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  /*        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2517          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2518          double *ptr_0 = &view_0.getData(0);          double *ptr_0 = &view_0.getData(0);
2519          double *ptr_2 = &view_2.getData(0);          double *ptr_2 = &view_2.getData(0);*/
2520            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2521            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2522          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2523        }        }
2524    
# Line 2373  C_TensorBinaryOperation(Data const &arg_ Line 2537  C_TensorBinaryOperation(Data const &arg_
2537        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());        DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2538    
2539        // Get the views        // Get the views
2540        DataArrayView view_0 = tmp_0->getDefaultValue();  //       DataArrayView view_0 = tmp_0->getDefaultValue();
2541        DataArrayView view_1 = tmp_1->getDefaultValue();  //       DataArrayView view_1 = tmp_1->getDefaultValue();
2542        DataArrayView view_2 = tmp_2->getDefaultValue();  //       DataArrayView view_2 = tmp_2->getDefaultValue();
2543    //       // Get the pointers to the actual data
2544    //       double *ptr_0 = &((view_0.getData())[0]);
2545    //       double *ptr_1 = &((view_1.getData())[0]);
2546    //       double *ptr_2 = &((view_2.getData())[0]);
2547    
2548        // Get the pointers to the actual data        // Get the pointers to the actual data
2549        double *ptr_0 = &((view_0.getData())[0]);        double *ptr_0 = &(tmp_0->getDefaultValue(0));
2550        double *ptr_1 = &((view_1.getData())[0]);        double *ptr_1 = &(tmp_1->getDefaultValue(0));
2551        double *ptr_2 = &((view_2.getData())[0]);        double *ptr_2 = &(tmp_2->getDefaultValue(0));
2552    
2553        // Compute a result for the default        // Compute a result for the default
2554        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);        tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2555        // Merge the tags        // Merge the tags
# Line 2387  C_TensorBinaryOperation(Data const &arg_ Line 2557  C_TensorBinaryOperation(Data const &arg_
2557        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();        const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2558        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();        const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup();
2559        for (i=lookup_0.begin();i!=lookup_0.end();i++) {        for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2560          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape          tmp_2->addTag(i->first); // use tmp_2 to get correct shape
2561        }        }
2562        for (i=lookup_1.begin();i!=lookup_1.end();i++) {        for (i=lookup_1.begin();i!=lookup_1.end();i++) {
2563          tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());          tmp_2->addTag(i->first);
2564        }        }
2565        // Compute a result for each tag        // Compute a result for each tag
2566        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();        const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup();
2567        for (i=lookup_2.begin();i!=lookup_2.end();i++) {        for (i=lookup_2.begin();i!=lookup_2.end();i++) {
2568          DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //         DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2569          DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);  //         DataArrayView view_1 = tmp_1->getDataPointByTag(i->first);
2570          DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //         DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2571          double *ptr_0 = &view_0.getData(0);  //         double *ptr_0 = &view_0.getData(0);
2572          double *ptr_1 = &view_1.getData(0);  //         double *ptr_1 = &view_1.getData(0);
2573          double *ptr_2 = &view_2.getData(0);  //         double *ptr_2 = &view_2.getData(0);
2574    
2575            double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2576            double *ptr_1 = &(tmp_1->getDataByTag(i->first,0));
2577            double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2578          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);          tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2579        }        }
2580    
# Line 2419  C_TensorBinaryOperation(Data const &arg_ Line 2593  C_TensorBinaryOperation(Data const &arg_
2593        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2594        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2595          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0          int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0
2596          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2597          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2598            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2599            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2600            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2601            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2602            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2603          }          }
2604        }        }
# Line 2446  C_TensorBinaryOperation(Data const &arg_ Line 2620  C_TensorBinaryOperation(Data const &arg_
2620          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2621            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2622            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2623            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2624            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2625            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2626            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2627          }          }
2628        }        }
# Line 2469  C_TensorBinaryOperation(Data const &arg_ Line 2643  C_TensorBinaryOperation(Data const &arg_
2643        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)        #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2644        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {        for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2645          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);          int offset_1 = tmp_1->getPointOffset(sampleNo_0,0);
2646          double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);          double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2647          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {          for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2648            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2649            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2650            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2651            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2652            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2653          }          }
2654        }        }
# Line 2497  C_TensorBinaryOperation(Data const &arg_ Line 2671  C_TensorBinaryOperation(Data const &arg_
2671            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2672            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0);
2673            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);            int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2674            double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);            double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2675            double *ptr_1 = &((arg_1_Z.getPointDataView().getData())[offset_1]);            double *ptr_1 = &(arg_1_Z.getDataAtOffset(offset_1));
2676            double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);            double *ptr_2 = &(res.getDataAtOffset(offset_2));
2677            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);            tensor_binary_operation(size0, ptr_0, ptr_1[0], ptr_2, operation);
2678          }          }
2679        }        }
# Line 2521  Data Line 2695  Data
2695  C_TensorUnaryOperation(Data const &arg_0,  C_TensorUnaryOperation(Data const &arg_0,
2696                         UnaryFunction operation)                         UnaryFunction operation)
2697  {  {
2698      if (arg_0.isEmpty())  // do this before we attempt to interpolate
2699      {
2700         throw DataException("Error - Operations not permitted on instances of DataEmpty.");
2701      }
2702    
2703    // Interpolate if necessary and find an appropriate function space    // Interpolate if necessary and find an appropriate function space
2704    Data arg_0_Z = Data(arg_0);    Data arg_0_Z = Data(arg_0);
2705    
2706    // Get rank and shape of inputs    // Get rank and shape of inputs
2707    int rank0 = arg_0_Z.getDataPointRank();  //  int rank0 = arg_0_Z.getDataPointRank();
2708    DataArrayView::ShapeType shape0 = arg_0_Z.getDataPointShape();    const DataTypes::ShapeType& shape0 = arg_0_Z.getDataPointShape();
2709    int size0 = arg_0_Z.getDataPointSize();    int size0 = arg_0_Z.getDataPointSize();
2710    
2711    // Declare output Data object    // Declare output Data object
# Line 2534  C_TensorUnaryOperation(Data const &arg_0 Line 2713  C_TensorUnaryOperation(Data const &arg_0
2713    
2714    if (arg_0_Z.isConstant()) {    if (arg_0_Z.isConstant()) {
2715      res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataConstant output      res = Data(0.0, shape0, arg_0_Z.getFunctionSpace());      // DataConstant output
2716      double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);  //     double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[0]);
2717      double *ptr_2 = &((res.getPointDataView().getData())[0]);  //     double *ptr_2 = &((res.getPointDataView().getData())[0]);
2718        double *ptr_0 = &(arg_0_Z.getDataAtOffset(0));
2719        double *ptr_2 = &(res.getDataAtOffset(0));
2720      tensor_unary_operation(size0, ptr_0, ptr_2, operation);      tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2721    }    }
2722    else if (arg_0_Z.isTagged()) {    else if (arg_0_Z.isTagged()) {
# Line 2548  C_TensorUnaryOperation(Data const &arg_0 Line 2729  C_TensorUnaryOperation(Data const &arg_0
2729      res.tag();      res.tag();
2730      DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());      DataTagged* tmp_2=dynamic_cast<DataTagged*>(res.borrowData());
2731    
2732      // Get the views  //     // Get the views
2733      DataArrayView view_0 = tmp_0->getDefaultValue();  //     DataArrayView view_0 = tmp_0->getDefaultValue();
2734      DataArrayView view_2 = tmp_2->getDefaultValue();  //     DataArrayView view_2 = tmp_2->getDefaultValue();
2735    //     // Get the pointers to the actual data
2736    //     double *ptr_0 = &((view_0.getData())[0]);
2737    //     double *ptr_2 = &((view_2.getData())[0]);
2738      // Get the pointers to the actual data      // Get the pointers to the actual data
2739      double *ptr_0 = &((view_0.getData())[0]);      double *ptr_0 = &(tmp_0->getDefaultValue(0));
2740      double *ptr_2 = &((view_2.getData())[0]);      double *ptr_2 = &(tmp_2->getDefaultValue(0));
2741      // Compute a result for the default      // Compute a result for the default
2742      tensor_unary_operation(size0, ptr_0, ptr_2, operation);      tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2743      // Compute a result for each tag      // Compute a result for each tag
2744      const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();      const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup();
2745      DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory      DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory
2746      for (i=lookup_0.begin();i!=lookup_0.end();i++) {      for (i=lookup_0.begin();i!=lookup_0.end();i++) {
2747        tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue());        tmp_2->addTag(i->first);
2748        DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);  //       DataArrayView view_0 = tmp_0->getDataPointByTag(i->first);
2749        DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);  //       DataArrayView view_2 = tmp_2->getDataPointByTag(i->first);
2750        double *ptr_0 = &view_0.getData(0);  //       double *ptr_0 = &view_0.getData(0);
2751        double *ptr_2 = &view_2.getData(0);  //       double *ptr_2 = &view_2.getData(0);
2752          double *ptr_0 = &(tmp_0->getDataByTag(i->first,0));
2753          double *ptr_2 = &(tmp_2->getDataByTag(i->first,0));
2754        tensor_unary_operation(size0, ptr_0, ptr_2, operation);        tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2755      }      }
2756    
# Line 2581  C_TensorUnaryOperation(Data const &arg_0 Line 2767  C_TensorUnaryOperation(Data const &arg_0
2767      #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)      #pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static)
2768      for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {      for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) {
2769        for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {        for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) {
2770    //         int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2771    //         int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2772    //         double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);
2773    //         double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);
2774          int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);          int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0);
2775          int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);          int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0);
2776          double *ptr_0 = &((arg_0_Z.getPointDataView().getData())[offset_0]);          double *ptr_0 = &(arg_0_Z.getDataAtOffset(offset_0));
2777          double *ptr_2 = &((res.getPointDataView().getData())[offset_2]);          double *ptr_2 = &(res.getDataAtOffset(offset_2));
2778          tensor_unary_operation(size0, ptr_0, ptr_2, operation);          tensor_unary_operation(size0, ptr_0, ptr_2, operation);
2779        }        }
2780      }      }
   
2781    }    }
2782    else {    else {
2783      throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");      throw DataException("Error - C_TensorUnaryOperation: unknown combination of inputs");

Legend:
Removed from v.1387  
changed lines
  Added in v.1952

  ViewVC Help
Powered by ViewVC 1.1.26