]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Addition of maps in MEDCoupling
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 5 May 2017 07:27:34 +0000 (09:27 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 5 May 2017 07:27:34 +0000 (09:27 +0200)
src/MEDCoupling/CMakeLists.txt
src/MEDCoupling/MEDCouplingMap.cxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingMap.hxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingMap.txx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index f777468ddfd1878e3e2aa9214108fbbc17efbeb2..30695ac6fba1b85fdb5f8bd179a277e95bc62e12 100644 (file)
@@ -44,6 +44,7 @@ SET(medcoupling_SOURCES
   MEDCouplingMemArray.cxx
   MEDCouplingMemArrayFloat.cxx
   MEDCouplingMemArrayChar.cxx
+  MEDCouplingMap.cxx
   MEDCouplingTraits.cxx
   MEDCouplingTimeLabel.cxx
   MEDCouplingCMesh.cxx
diff --git a/src/MEDCoupling/MEDCouplingMap.cxx b/src/MEDCoupling/MEDCouplingMap.cxx
new file mode 100644 (file)
index 0000000..47c10f1
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "MEDCouplingMap.txx"
+
+using namespace MEDCoupling;
+
+template class MEDCoupling::MapKeyVal<int>;
diff --git a/src/MEDCoupling/MEDCouplingMap.hxx b/src/MEDCoupling/MEDCouplingMap.hxx
new file mode 100644 (file)
index 0000000..b63bd5c
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __MEDCOUPLING_MEDCOUPLINGMAP_HXX__
+#define __MEDCOUPLING_MEDCOUPLINGMAP_HXX__
+
+#include "MEDCoupling.hxx"
+#include "MCAuto.hxx"
+#include "MEDCouplingTimeLabel.hxx"
+#include "MEDCouplingRefCountObject.hxx"
+#include "InterpKernelException.hxx"
+
+#include <map>
+
+namespace MEDCoupling
+{  
+  template<class T>
+  class MapKeyVal : public RefCountObject, public TimeLabel
+  {
+  public:
+    static MCAuto< MapKeyVal<T> > New();
+    std::map<T,T>& data() { return _m; }
+    const std::map<T,T>& data() const { return _m; }
+    std::size_t getHeapMemorySizeWithoutChildren() const;
+    std::vector<const BigMemoryObject*> getDirectChildrenWithNull() const;
+    void updateTime() const { }
+  private:
+    MapKeyVal() { }
+    ~MapKeyVal() { }
+  private:
+    std::map<T,T> _m;
+  };
+
+  typedef MapKeyVal<int> MapII;
+}
+
+#endif
diff --git a/src/MEDCoupling/MEDCouplingMap.txx b/src/MEDCoupling/MEDCouplingMap.txx
new file mode 100644 (file)
index 0000000..1a43583
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __MEDCOUPLING_MEDCOUPLINGMAP_TXX__
+#define __MEDCOUPLING_MEDCOUPLINGMAP_TXX__
+
+#include "MEDCouplingMap.hxx"
+
+namespace MEDCoupling
+{
+  template<class T>
+  MCAuto< MapKeyVal<T> > MapKeyVal<T>::New()
+  {
+    MCAuto< MapKeyVal<T> > ret(new MapKeyVal<T>);
+    return ret;
+  }
+  
+  template<class T>
+  std::size_t MapKeyVal<T>::getHeapMemorySizeWithoutChildren() const
+  {
+    return _m.size()*sizeof(std::pair<T,T>);
+  }
+  
+  template<class T>
+  std::vector<const BigMemoryObject*> MapKeyVal<T>::getDirectChildrenWithNull() const
+  {
+    return std::vector<const BigMemoryObject*>();//not a bug no child. Leaf object !
+  }
+}
+
+#endif
index 3d4bed67ab3a03fd0b6b99a268d6696e0fceeeee..b5559feaa5da9e9e1d5c4acc11ca9b129a3077c9 100644 (file)
@@ -3984,38 +3984,6 @@ void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNb
   stream << "]";
 }
 
-/*!
- * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
- * i.e. a current value is used as in index to get a new value from \a indArrBg.
- *  \param [in] indArrBg - pointer to the first element of array of new values to assign
- *         to \a this array.
- *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
- *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
- *  \throw If \a this->getNumberOfComponents() != 1
- *  \throw If any value of \a this can't be used as a valid index for 
- *         [\a indArrBg, \a indArrEnd).
- *
- *  \sa changeValue
- */
-void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
-  int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
-  for(int i=0;i<nbOfTuples;i++,pt++)
-    {
-      if(*pt>=0 && *pt<nbElemsIn)
-        *pt=indArrBg[*pt];
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  declareAsNew();
-}
-
 /*!
  * Computes distribution of values of \a this one-dimensional array between given value
  * ranges (casts). This method is typically useful for entity number spliting by types,
@@ -4162,6 +4130,60 @@ bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
     }
 }
 
+
+/*!
+ * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
+ * i.e. a current value is used as in index to get a new value from \a indArrBg.
+ *  \param [in] indArrBg - pointer to the first element of array of new values to assign
+ *         to \a this array.
+ *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
+ *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
+ *  \throw If \a this->getNumberOfComponents() != 1
+ *  \throw If any value of \a this can't be used as a valid index for 
+ *         [\a indArrBg, \a indArrEnd).
+ *
+ *  \sa changeValue
+ */
+void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
+{
+  this->checkAllocated();
+  if(this->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
+  int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
+  for(int i=0;i<nbOfTuples;i++,pt++)
+    {
+      if(*pt>=0 && *pt<nbElemsIn)
+        *pt=indArrBg[*pt];
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  this->declareAsNew();
+}
+
+void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
+{
+  this->checkAllocated();
+  if(this->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
+  const std::map<int,int> dat(m.data());
+  int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
+  for(int i=0;i<nbOfTuples;i++,pt++)
+    {
+      std::map<int,int>::const_iterator it(dat.find(*pt));
+      if(it!=dat.end())
+        *pt=(*it).second;
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  this->declareAsNew();
+}
+
 /*!
  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
@@ -4229,11 +4251,11 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int
  */
 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
 {
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  MCAuto<DataArrayInt> ret(DataArrayInt::New());
   ret->alloc(newNbOfElem,1);
-  int nbOfOldNodes=getNumberOfTuples();
-  const int *old2New=getConstPointer();
-  int *pt=ret->getPointer();
+  int nbOfOldNodes(this->getNumberOfTuples());
+  const int *old2New(begin());
+  int *pt(ret->getPointer());
   for(int i=0;i!=nbOfOldNodes;i++)
     {
       int newp(old2New[i]);
@@ -4293,6 +4315,7 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
  *
  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
+ *  \sa invertArrayN2O2O2NOptimized
  *  \endif
  */
 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
@@ -4318,6 +4341,36 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
   return ret.retn();
 }
 
+/*!
+ * Creates a map, whose contents are computed
+ * from values of \a this array, which is supposed to contain a renumbering map in 
+ * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
+ * To know how to use the renumbering maps see \ref numbering.
+ *  \param [in] newNbOfElem - the number of tuples in the result array.
+ *  \return MapII  - the new instance of Map.
+ * 
+ *  \if ENABLE_EXAMPLES
+ *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
+ *
+ *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
+ *  \sa invertArrayN2O2O2N
+ *  \endif
+ */
+MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
+{
+  checkAllocated();
+  MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
+  std::map<int,int>& m(ret->data());
+  const int *new2Old(begin());
+  int nbOfNewElems(this->getNumberOfTuples());
+  for(int i=0;i<nbOfNewElems;i++)
+    {
+      int v(new2Old[i]);
+      m[v]=i;
+    }
+  return ret;
+}
+
 /*!
  * Equivalent to DataArrayInt::isEqual except that if false the reason of
  * mismatch is given.
index d1db9e7591efe38a003e2a576610e671e36c52dd..f22c61d439dd6061038fc66388d8da12e227fa55 100644 (file)
@@ -27,6 +27,7 @@
 #include "MEDCouplingRefCountObject.hxx"
 #include "InterpKernelException.hxx"
 #include "MEDCouplingTraits.hxx"
+#include "MEDCouplingMap.hxx"
 #include "BBTreePts.txx"
 
 #include <string>
@@ -560,12 +561,14 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const;
     MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArrBg, const int *indArrEnd);
+    MEDCOUPLING_EXPORT void transformWithIndArr(const MapKeyVal<int>& m);
     MEDCOUPLING_EXPORT DataArrayInt *transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const;
     MEDCOUPLING_EXPORT void splitByValueRange(const int *arrBg, const int *arrEnd,
                                               DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const;
     MEDCOUPLING_EXPORT bool isRange(int& strt, int& sttoopp, int& stteepp) const;
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const;
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const;
+    MEDCOUPLING_EXPORT MCAuto< MapKeyVal<int> > invertArrayN2O2O2NOptimized() const;
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const;
     MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const { return DataArrayTemplate<int>::mySelectByTupleId(new2OldBg,new2OldEnd); }
     MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const DataArrayInt& di) const { return DataArrayTemplate<int>::mySelectByTupleId(di); }
index 946415833a8b42a3efce8ef5709b36aaf22f77e7..08ba64fb0ac2f39392494ee1d078326221876b79 100644 (file)
 {
   $result=SWIG_NewPointerObj(SWIG_as_voidptr($1.retn()),SWIGTYPE_p_MEDCoupling__DataArrayFloat,SWIG_POINTER_OWN|0);
 }
+
+%typemap(out) MCAuto<MEDCoupling::MapII>
+{
+  $result=SWIG_NewPointerObj(SWIG_as_voidptr($1.retn()),SWIGTYPE_p_MEDCoupling__MapII,SWIG_POINTER_OWN|0);
+}
 //$$$$$$$$$$$$$$$$$$
 
 %newobject MEDCoupling::DataArray::deepCopy;
 %feature("unref") DataArrayAsciiChar "$this->decrRef();"
 %feature("unref") DataArrayByte "$this->decrRef();"
 
+%feature("unref") MapII "$this->decrRef();"
 %feature("unref") PartDefinition "$this->decrRef();"
 %feature("unref") DataArrayPartDefinition "$this->decrRef();"
 %feature("unref") SlicePartDefinition "$this->decrRef();"
@@ -250,6 +256,12 @@ namespace MEDCoupling
     } MEDCouplingAxisType;
 
   class DataArrayInt;
+
+  class MapII : public RefCountObject, public TimeLabel
+  {
+  public:
+    static MCAuto< MapII > New();
+  };
   
   class PartDefinition : public RefCountObject, public TimeLabel
   {