From b1681460da1d3c8e3a196e9b13410321587db207 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 5 May 2017 09:27:34 +0200 Subject: [PATCH] Addition of maps in MEDCoupling --- src/MEDCoupling/CMakeLists.txt | 1 + src/MEDCoupling/MEDCouplingMap.cxx | 25 +++++ src/MEDCoupling/MEDCouplingMap.hxx | 54 +++++++++ src/MEDCoupling/MEDCouplingMap.txx | 48 ++++++++ src/MEDCoupling/MEDCouplingMemArray.cxx | 125 +++++++++++++++------ src/MEDCoupling/MEDCouplingMemArray.hxx | 3 + src/MEDCoupling_Swig/MEDCouplingMemArray.i | 12 ++ 7 files changed, 232 insertions(+), 36 deletions(-) create mode 100644 src/MEDCoupling/MEDCouplingMap.cxx create mode 100644 src/MEDCoupling/MEDCouplingMap.hxx create mode 100644 src/MEDCoupling/MEDCouplingMap.txx diff --git a/src/MEDCoupling/CMakeLists.txt b/src/MEDCoupling/CMakeLists.txt index f777468dd..30695ac6f 100644 --- a/src/MEDCoupling/CMakeLists.txt +++ b/src/MEDCoupling/CMakeLists.txt @@ -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 index 000000000..47c10f1ea --- /dev/null +++ b/src/MEDCoupling/MEDCouplingMap.cxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingMap.hxx b/src/MEDCoupling/MEDCouplingMap.hxx new file mode 100644 index 000000000..b63bd5cdc --- /dev/null +++ b/src/MEDCoupling/MEDCouplingMap.hxx @@ -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 + +namespace MEDCoupling +{ + template + class MapKeyVal : public RefCountObject, public TimeLabel + { + public: + static MCAuto< MapKeyVal > New(); + std::map& data() { return _m; } + const std::map& data() const { return _m; } + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector getDirectChildrenWithNull() const; + void updateTime() const { } + private: + MapKeyVal() { } + ~MapKeyVal() { } + private: + std::map _m; + }; + + typedef MapKeyVal MapII; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingMap.txx b/src/MEDCoupling/MEDCouplingMap.txx new file mode 100644 index 000000000..1a43583ea --- /dev/null +++ b/src/MEDCoupling/MEDCouplingMap.txx @@ -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 + MCAuto< MapKeyVal > MapKeyVal::New() + { + MCAuto< MapKeyVal > ret(new MapKeyVal); + return ret; + } + + template + std::size_t MapKeyVal::getHeapMemorySizeWithoutChildren() const + { + return _m.size()*sizeof(std::pair); + } + + template + std::vector MapKeyVal::getDirectChildrenWithNull() const + { + return std::vector();//not a bug no child. Leaf object ! + } +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 3d4bed67a..b5559feaa 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -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=0 && *ptgetNumberOfComponents() != 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=0 && *ptdeclareAsNew(); +} + +void DataArrayInt::transformWithIndArr(const MapKeyVal& 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 dat(m.data()); + int nbOfTuples(getNumberOfTuples()),*pt(getPointer()); + for(int i=0;i::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 ret=DataArrayInt::New(); + MCAuto 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 > DataArrayInt::invertArrayN2O2O2NOptimized() const +{ + checkAllocated(); + MCAuto< MapKeyVal > ret(MapKeyVal::New()); + std::map& m(ret->data()); + const int *new2Old(begin()); + int nbOfNewElems(this->getNumberOfTuples()); + for(int i=0;i @@ -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& 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 > invertArrayN2O2O2NOptimized() const; MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const; MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const { return DataArrayTemplate::mySelectByTupleId(new2OldBg,new2OldEnd); } MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const DataArrayInt& di) const { return DataArrayTemplate::mySelectByTupleId(di); } diff --git a/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/MEDCoupling_Swig/MEDCouplingMemArray.i index 946415833..08ba64fb0 100644 --- a/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ b/src/MEDCoupling_Swig/MEDCouplingMemArray.i @@ -55,6 +55,11 @@ { $result=SWIG_NewPointerObj(SWIG_as_voidptr($1.retn()),SWIGTYPE_p_MEDCoupling__DataArrayFloat,SWIG_POINTER_OWN|0); } + +%typemap(out) MCAuto +{ + $result=SWIG_NewPointerObj(SWIG_as_voidptr($1.retn()),SWIGTYPE_p_MEDCoupling__MapII,SWIG_POINTER_OWN|0); +} //$$$$$$$$$$$$$$$$$$ %newobject MEDCoupling::DataArray::deepCopy; @@ -236,6 +241,7 @@ %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 { -- 2.39.2